Skip to content

Commit

Permalink
fftools/ffprobe: handle multiple video streams
Browse files Browse the repository at this point in the history
  • Loading branch information
gnattu committed Dec 22, 2024
1 parent 31d75a3 commit 29f83bf
Showing 1 changed file with 89 additions and 7 deletions.
96 changes: 89 additions & 7 deletions debian/patches/0084-add-first-vframe-only-to-ffprobe.patch
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,112 @@ Index: FFmpeg/fftools/ffprobe.c
static char *output_format;
static char *stream_specifier;
static char *show_data_hash;
@@ -3159,6 +3161,14 @@ static int read_interval_packets(WriterC
@@ -3086,9 +3088,10 @@ static int read_interval_packets(WriterC
AVFormatContext *fmt_ctx = ifile->fmt_ctx;
AVPacket *pkt = NULL;
AVFrame *frame = NULL;
- int ret = 0, i = 0, frame_count = 0;
+ int ret = 0, i = 0, frame_count = 0, nb_video_streams = 0;
int64_t start = -INT64_MAX, end = interval->end;
int has_start = 0, has_end = interval->has_end && !interval->end_is_offset;
+ unsigned char *checked_stream = NULL;

av_log(NULL, AV_LOG_VERBOSE, "Processing read interval ");
log_read_interval(interval, NULL, AV_LOG_VERBOSE);
@@ -3127,12 +3130,51 @@ static int read_interval_packets(WriterC
ret = AVERROR(ENOMEM);
goto end;
}
+
+ if (only_show_first_video_frame) {
+ int si = 0;
+ checked_stream = av_calloc(nb_streams, sizeof(unsigned char));
+ if (!checked_stream) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+ for (si = 0; si < nb_streams; si ++) {
+ AVCodecParameters *par = ifile->streams[si].st->codecpar;
+ if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
+ nb_video_streams++;
+ selected_streams[si] = 1;
+ }
+ }
+ }
while (!av_read_frame(fmt_ctx, pkt)) {
if (fmt_ctx->nb_streams > nb_streams) {
REALLOCZ_ARRAY_STREAM(nb_streams_frames, nb_streams, fmt_ctx->nb_streams);
REALLOCZ_ARRAY_STREAM(nb_streams_packets, nb_streams, fmt_ctx->nb_streams);
REALLOCZ_ARRAY_STREAM(selected_streams, nb_streams, fmt_ctx->nb_streams);
- nb_streams = fmt_ctx->nb_streams;
+
+ if (checked_stream) {
+ unsigned char *checked_stream_extended = NULL;
+ int si = 0;
+ checked_stream_extended = av_calloc(fmt_ctx->nb_streams, sizeof(unsigned char));
+ if (!checked_stream) {
+ ret = AVERROR(ENOMEM);
+ goto end;
+ }
+
+ memcpy(checked_stream_extended, checked_stream, nb_streams * sizeof(unsigned char));
+ av_freep(&checked_stream);
+ checked_stream = checked_stream_extended;
+
+ nb_video_streams = 0;
+ for (si = 0; si < fmt_ctx->nb_streams; si ++) {
+ AVCodecParameters *par = ifile->streams[si].st->codecpar;
+ if (par->codec_type == AVMEDIA_TYPE_VIDEO) {
+ nb_video_streams++;
+ selected_streams[si] = 1;
+ }
+ }
+ }
+ nb_streams = (int)fmt_ctx->nb_streams;
}
if (selected_streams[pkt->stream_index]) {
AVRational tb = ifile->streams[pkt->stream_index].st->time_base;
@@ -3159,6 +3201,12 @@ static int read_interval_packets(WriterC
}

frame_count++;
+
+ if (only_show_first_video_frame) {
+ AVCodecParameters *par = ifile->streams[pkt->stream_index].st->codecpar;
+ if (par->codec_type != AVMEDIA_TYPE_VIDEO) {
+ continue;
+ }
+ if (par->codec_type != AVMEDIA_TYPE_VIDEO) continue;
+ }
+
if (do_read_packets) {
if (do_show_packets)
show_packet(w, ifile, pkt, i++);
@@ -3179,6 +3189,7 @@ static int read_interval_packets(WriterC
@@ -3179,6 +3227,16 @@ static int read_interval_packets(WriterC

while (process_frame(w, ifile, frame, pkt, &packet_new) > 0);
}
+ if (only_show_first_video_frame) break;
+ if (only_show_first_video_frame) {
+ int nb_checked_streams = 0, si = 0;
+ checked_stream[pkt->stream_index] = 1;
+ for (si = 0; si < nb_streams; si ++) {
+ nb_checked_streams += checked_stream[si];
+ }
+ if (nb_checked_streams >= nb_video_streams) {
+ break;
+ }
+ }
}
av_packet_unref(pkt);
}
@@ -4587,6 +4598,7 @@ static const OptionDef real_options[] =
@@ -3196,6 +3254,9 @@ static int read_interval_packets(WriterC
end:
av_frame_free(&frame);
av_packet_free(&pkt);
+ if (checked_stream) {
+ av_freep(&checked_stream);
+ }
if (ret < 0) {
av_log(NULL, AV_LOG_ERROR, "Could not read packets in interval ");
log_read_interval(interval, NULL, AV_LOG_ERROR);
@@ -4587,6 +4648,7 @@ static const OptionDef real_options[] =
{ "print_filename", OPT_TYPE_FUNC, OPT_FUNC_ARG, {.func_arg = opt_print_filename}, "override the printed input filename", "print_file"},
{ "find_stream_info", OPT_TYPE_BOOL, OPT_INPUT | OPT_EXPERT, { &find_stream_info },
"read and decode the streams to fill missing information with heuristics" },
Expand Down

0 comments on commit 29f83bf

Please sign in to comment.