On 01/02/2012 04:12 PM, Stefano Sabatini wrote:
On date Sunday 2012-01-01 01:56:16 +0100, Thomas Kühnel encoded:
Decoding now happens outside of show_frame().
I also noticed a segfault caused by files with unsupported video
codecs and added a check to prevent this.
From 8b467add7cf21ca84c85e5c50ec1f6c4a0113307 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20K=C3=BChnel?=<[email protected]>
Date: Fri, 23 Sep 2011 22:51:42 +0200
Subject: [PATCH] avprobe: Print frame-based metadata
---
avprobe.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++--
doc/avprobe.texi | 7 ++++++
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/avprobe.c b/avprobe.c
index de9657b..767cdef 100644
--- a/avprobe.c
+++ b/avprobe.c
@@ -35,6 +35,7 @@ const int program_birth_year = 2007;
static int do_show_format = 0;
static int do_show_packets = 0;
static int do_show_streams = 0;
+static int do_show_frames = 0;
static int show_value_unit = 0;
static int use_value_prefix = 0;
@@ -150,14 +151,65 @@ static void show_packet(AVFormatContext *fmt_ctx,
AVPacket *pkt)
printf("[/PACKET]\n");
}
+static void show_frame(AVFrame *frame)
+{
+ char val_str[128];
+ AVDictionaryEntry *tag = NULL;
+
+ printf("[FRAME]\n");
+ printf("pict_type=%c\n",
av_get_picture_type_char(frame->pict_type));
+ printf("coded_picture_number=%d\n", frame->coded_picture_number);
+ printf("display_picture_number=%d\n", frame->display_picture_number);
+ printf("interlaced_frame=%d\n", frame->interlaced_frame);
+ printf("top_field_first=%d\n", frame->top_field_first);
+ printf("repeat_pict=%d\n", frame->repeat_pict);
+ printf("reference=%d\n", frame->reference);
+ printf("key_frame=%d\n", frame->key_frame);
+ printf("pts=%s\n", ts_value_string (val_str,
sizeof(val_str), frame->pts));
+
+ while ((tag = av_dict_get(frame->metadata, "", tag,
AV_DICT_IGNORE_SUFFIX)))
+ printf("TAG:%s=%s\n", tag->key, tag->value);
+ printf("[/FRAME]\n");
+}
+
+static int get_video_frame(AVFormatContext *fmt_ctx, AVFrame *frame,
+ AVPacket *pkt)
+{
+ AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+ int got_picture = 0;
+
+ if (dec_ctx->codec_id != CODEC_ID_NONE&&
+ dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
This check may be moved to the calling code, and avoid a pointless
function call, alternatively you may inline the function.
Okay, it's inline now.
+ avcodec_decode_video2(dec_ctx, frame,&got_picture, pkt);
+ return got_picture;
+}
+
static void show_packets(AVFormatContext *fmt_ctx)
{
AVPacket pkt;
+ int i;
+ AVFrame frame;
av_init_packet(&pkt);
- while (!av_read_frame(fmt_ctx,&pkt))
- show_packet(fmt_ctx,&pkt);
+ while (!av_read_frame(fmt_ctx,&pkt)) {
+ if (do_show_packets)
+ show_packet(fmt_ctx,&pkt);
+ if (do_show_frames&&
+ get_video_frame(fmt_ctx,&frame,&pkt)) {
+ show_frame(&frame);
+ av_destruct_packet(&pkt);
+ }
+ }
+ av_init_packet(&pkt);
+ pkt.data = NULL;
+ pkt.size = 0;
+ //Flush remaining frames that are cached in the decoder
+ for (i = 0; i< fmt_ctx->nb_streams; i++) {
+ pkt.stream_index = i;
+ while (get_video_frame(fmt_ctx,&frame,&pkt))
+ show_frame(&frame);
+ }
}
[...]
Looks good to me otherwise, thanks.
Audio frame printing could be added in a second moment.
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel
>From 47c0ad353b51d691a6c3101ac465208a13bd71e8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Thomas=20K=C3=BChnel?= <[email protected]>
Date: Fri, 23 Sep 2011 22:51:42 +0200
Subject: [PATCH] avprobe: Print frame-based metadata
---
avprobe.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++--
doc/avprobe.texi | 7 ++++++
2 files changed, 66 insertions(+), 3 deletions(-)
diff --git a/avprobe.c b/avprobe.c
index de9657b..801a0e7 100644
--- a/avprobe.c
+++ b/avprobe.c
@@ -35,6 +35,7 @@ const int program_birth_year = 2007;
static int do_show_format = 0;
static int do_show_packets = 0;
static int do_show_streams = 0;
+static int do_show_frames = 0;
static int show_value_unit = 0;
static int use_value_prefix = 0;
@@ -150,14 +151,65 @@ static void show_packet(AVFormatContext *fmt_ctx, AVPacket *pkt)
printf("[/PACKET]\n");
}
+static void show_frame(AVFrame *frame)
+{
+ char val_str[128];
+ AVDictionaryEntry *tag = NULL;
+
+ printf("[FRAME]\n");
+ printf("pict_type=%c\n", av_get_picture_type_char(frame->pict_type));
+ printf("coded_picture_number=%d\n", frame->coded_picture_number);
+ printf("display_picture_number=%d\n", frame->display_picture_number);
+ printf("interlaced_frame=%d\n", frame->interlaced_frame);
+ printf("top_field_first=%d\n", frame->top_field_first);
+ printf("repeat_pict=%d\n", frame->repeat_pict);
+ printf("reference=%d\n", frame->reference);
+ printf("key_frame=%d\n", frame->key_frame);
+ printf("pts=%s\n", ts_value_string (val_str, sizeof(val_str), frame->pts));
+
+ while ((tag = av_dict_get(frame->metadata, "", tag, AV_DICT_IGNORE_SUFFIX)))
+ printf("TAG:%s=%s\n", tag->key, tag->value);
+ printf("[/FRAME]\n");
+}
+
+static av_always_inline int get_video_frame(AVFormatContext *fmt_ctx,
+ AVFrame *frame, AVPacket *pkt)
+{
+ AVCodecContext *dec_ctx = fmt_ctx->streams[pkt->stream_index]->codec;
+ int got_picture = 0;
+
+ if (dec_ctx->codec_id != CODEC_ID_NONE &&
+ dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
+ avcodec_decode_video2(dec_ctx, frame, &got_picture, pkt);
+ return got_picture;
+}
+
static void show_packets(AVFormatContext *fmt_ctx)
{
AVPacket pkt;
+ int i;
+ AVFrame frame;
av_init_packet(&pkt);
- while (!av_read_frame(fmt_ctx, &pkt))
- show_packet(fmt_ctx, &pkt);
+ while (!av_read_frame(fmt_ctx, &pkt)) {
+ if (do_show_packets)
+ show_packet(fmt_ctx, &pkt);
+ if (do_show_frames &&
+ get_video_frame(fmt_ctx, &frame, &pkt)) {
+ show_frame(&frame);
+ av_destruct_packet(&pkt);
+ }
+ }
+ av_init_packet(&pkt);
+ pkt.data = NULL;
+ pkt.size = 0;
+ //Flush remaining frames that are cached in the decoder
+ for (i = 0; i < fmt_ctx->nb_streams; i++) {
+ pkt.stream_index = i;
+ while (get_video_frame(fmt_ctx, &frame, &pkt))
+ show_frame(&frame);
+ }
}
static void show_stream(AVFormatContext *fmt_ctx, int stream_idx)
@@ -315,7 +367,7 @@ static int probe_file(const char *filename)
if ((ret = open_input_file(&fmt_ctx, filename)))
return ret;
- if (do_show_packets)
+ if (do_show_packets || do_show_frames)
show_packets(fmt_ctx);
if (do_show_streams)
@@ -325,6 +377,9 @@ static int probe_file(const char *filename)
if (do_show_format)
show_format(fmt_ctx);
+ for (i = 0; i < fmt_ctx->nb_streams; i++)
+ if (fmt_ctx->streams[i]->codec->codec_id != CODEC_ID_NONE)
+ avcodec_close(fmt_ctx->streams[i]->codec);
avformat_close_input(&fmt_ctx);
return 0;
}
@@ -389,6 +444,7 @@ static const OptionDef options[] = {
{ "show_format", OPT_BOOL, {(void*)&do_show_format} , "show format/container info" },
{ "show_packets", OPT_BOOL, {(void*)&do_show_packets}, "show packets info" },
{ "show_streams", OPT_BOOL, {(void*)&do_show_streams}, "show streams info" },
+ { "show_frames", OPT_BOOL, {(void*)&do_show_frames} , "show frames info" },
{ "default", HAS_ARG | OPT_AUDIO | OPT_VIDEO | OPT_EXPERT, {(void*)opt_default}, "generic catch all option", "" },
{ NULL, },
};
diff --git a/doc/avprobe.texi b/doc/avprobe.texi
index 6b2c800..85016b2 100644
--- a/doc/avprobe.texi
+++ b/doc/avprobe.texi
@@ -108,6 +108,13 @@ multimedia stream.
Each media stream information is printed within a dedicated section
with name "STREAM".
+@item -show_frames
+Show information about each video frame contained in the input multimedia
+stream.
+
+The information for each single frame is printed within a dedicated
+section with name "FRAME".
+
@end table
@c man end
--
1.7.8.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel