[FFmpeg-devel] ffmpeg/ffprobe: Change verbosity level for reporting of empty streams in a Transport Stream

Submitted by Pedro Andres Aranda Gutierrez on May 20, 2017, 10:19 a.m.

Details

Message ID CAO48Bk_EQcoMk0h=m9yCPbeg3abVGPZ4OXjJmET7m1+AmmYzhw@mail.gmail.com
State New
Headers show

Commit Message

Pedro Andres Aranda Gutierrez May 20, 2017, 10:19 a.m.
Rationale:

Some satellite PVRs store empty streams in recorded transport stream. The
list is of empty streams is sometimes too big to fit one screen-full and
you can't see what ffmpeg is actually doing.

Proposal:
Make the verbosity level required to show empty streams AV_LOG_VERBOSE
instead of AV_LOG_INFO

Impact:
Changes affect only libavformat/dump.c

Patch attached. The approach has been to set the loglevel in some
dump_function at call time. These functions have been renamed to
dump_function_loglevel and new inline functions to replicate the original
dump_function have been added.

KNOWN CAVEAT:
This behaviour for ffmpeg is inherited by ffprobe. Not tested on ffplay.

Best regards,
Pedro A. Aranda

Patch hide | download patch | download mbox

diff --git a/libavformat/dump.c b/libavformat/dump.c
index 8fd58a0..771fbeb 100644
--- a/libavformat/dump.c
+++ b/libavformat/dump.c
@@ -130,32 +130,44 @@  static void print_fps(double d, const char *postfix)
         av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);
 }
 
-static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
+/* dump metatadata information wiht a specific log level */
+
+static void dump_metadata_loglevel(void *ctx, AVDictionary *m, const char *indent, int loglevel)
 {
     if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) {
         AVDictionaryEntry *tag = NULL;
 
-        av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
+        av_log(ctx, loglevel, "%sMetadata:\n", indent);
         while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX)))
             if (strcmp("language", tag->key)) {
                 const char *p = tag->value;
-                av_log(ctx, AV_LOG_INFO,
+                av_log(ctx, loglevel,
                        "%s  %-16s: ", indent, tag->key);
                 while (*p) {
                     char tmp[256];
                     size_t len = strcspn(p, "\x8\xa\xb\xc\xd");
                     av_strlcpy(tmp, p, FFMIN(sizeof(tmp), len+1));
-                    av_log(ctx, AV_LOG_INFO, "%s", tmp);
+                    av_log(ctx, loglevel, "%s", tmp);
                     p += len;
-                    if (*p == 0xd) av_log(ctx, AV_LOG_INFO, " ");
-                    if (*p == 0xa) av_log(ctx, AV_LOG_INFO, "\n%s  %-16s: ", indent, "");
+                    if (*p == 0xd) av_log(ctx, loglevel, " ");
+                    if (*p == 0xa) av_log(ctx, loglevel, "\n%s  %-16s: ", indent, "");
                     if (*p) p++;
                 }
-                av_log(ctx, AV_LOG_INFO, "\n");
+                av_log(ctx, loglevel, "\n");
             }
     }
 }
 
+/*
+  This is the function that is used through the file,
+  will only call the new version with explicit loglevel
+  when dumping TS information.
+*/
+static inline void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
+{
+	dump_metadata_loglevel(ctx, m, indent, AV_LOG_INFO);
+}
+
 /* param change side data*/
 static void dump_paramchange(void *ctx, AVPacketSideData *sd)
 {
@@ -378,78 +390,84 @@  static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *
     }
 }
 
-static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
+static void dump_sidedata_loglevel(void *ctx, AVStream *st, const char *indent,
+								   int loglevel)
 {
     int i;
 
     if (st->nb_side_data)
-        av_log(ctx, AV_LOG_INFO, "%sSide data:\n", indent);
+        av_log(ctx, loglevel, "%sSide data:\n", indent);
 
     for (i = 0; i < st->nb_side_data; i++) {
         AVPacketSideData sd = st->side_data[i];
-        av_log(ctx, AV_LOG_INFO, "%s  ", indent);
+        av_log(ctx, loglevel, "%s  ", indent);
 
         switch (sd.type) {
         case AV_PKT_DATA_PALETTE:
-            av_log(ctx, AV_LOG_INFO, "palette");
+            av_log(ctx, loglevel, "palette");
             break;
         case AV_PKT_DATA_NEW_EXTRADATA:
-            av_log(ctx, AV_LOG_INFO, "new extradata");
+            av_log(ctx, loglevel, "new extradata");
             break;
         case AV_PKT_DATA_PARAM_CHANGE:
-            av_log(ctx, AV_LOG_INFO, "paramchange: ");
+            av_log(ctx, loglevel, "paramchange: ");
             dump_paramchange(ctx, &sd);
             break;
         case AV_PKT_DATA_H263_MB_INFO:
-            av_log(ctx, AV_LOG_INFO, "H.263 macroblock info");
+            av_log(ctx, loglevel, "H.263 macroblock info");
             break;
         case AV_PKT_DATA_REPLAYGAIN:
-            av_log(ctx, AV_LOG_INFO, "replaygain: ");
+            av_log(ctx, loglevel, "replaygain: ");
             dump_replaygain(ctx, &sd);
             break;
         case AV_PKT_DATA_DISPLAYMATRIX:
-            av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees",
+            av_log(ctx, loglevel, "displaymatrix: rotation of %.2f degrees",
                    av_display_rotation_get((int32_t *)sd.data));
             break;
         case AV_PKT_DATA_STEREO3D:
-            av_log(ctx, AV_LOG_INFO, "stereo3d: ");
+            av_log(ctx, loglevel, "stereo3d: ");
             dump_stereo3d(ctx, &sd);
             break;
         case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
-            av_log(ctx, AV_LOG_INFO, "audio service type: ");
+            av_log(ctx, loglevel, "audio service type: ");
             dump_audioservicetype(ctx, &sd);
             break;
         case AV_PKT_DATA_QUALITY_STATS:
-            av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c",
+            av_log(ctx, loglevel, "quality factor: %"PRId32", pict_type: %c",
                    AV_RL32(sd.data), av_get_picture_type_char(sd.data[4]));
             break;
         case AV_PKT_DATA_CPB_PROPERTIES:
-            av_log(ctx, AV_LOG_INFO, "cpb: ");
+            av_log(ctx, loglevel, "cpb: ");
             dump_cpb(ctx, &sd);
             break;
         case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
             dump_mastering_display_metadata(ctx, &sd);
             break;
         case AV_PKT_DATA_SPHERICAL:
-            av_log(ctx, AV_LOG_INFO, "spherical: ");
+            av_log(ctx, loglevel, "spherical: ");
             dump_spherical(ctx, st->codecpar, &sd);
             break;
         case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
             dump_content_light_metadata(ctx, &sd);
             break;
         default:
-            av_log(ctx, AV_LOG_INFO,
+            av_log(ctx, loglevel,
                    "unknown side data type %d (%d bytes)", sd.type, sd.size);
             break;
         }
 
-        av_log(ctx, AV_LOG_INFO, "\n");
+        av_log(ctx, loglevel, "\n");
     }
 }
 
+static inline void dump_sidedata(void *ctx, AVStream *st, const char *indent)
+{
+	dump_sidedata_loglevel(ctx, st, indent,AV_LOG_INFO);
+}
+
 /* "user interface" functions */
-static void dump_stream_format(AVFormatContext *ic, int i,
-                               int index, int is_output)
+static void dump_stream_format_loglevel(AVFormatContext *ic, int i,
+										int index, int is_output,int loglevel)
 {
     char buf[256];
     int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
@@ -482,17 +500,17 @@  static void dump_stream_format(AVFormatContext *ic, int i,
     avcodec_string(buf, sizeof(buf), avctx, is_output);
     avcodec_free_context(&avctx);
 
-    av_log(NULL, AV_LOG_INFO, "    Stream #%d:%d", index, i);
+    av_log(NULL, loglevel, "    Stream #%d:%d", index, i);
 
     /* the pid is an important information, so we display it */
     /* XXX: add a generic system */
     if (flags & AVFMT_SHOW_IDS)
-        av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
+        av_log(NULL, loglevel, "[0x%x]", st->id);
     if (lang)
-        av_log(NULL, AV_LOG_INFO, "(%s)", lang->value);
+        av_log(NULL, loglevel, "(%s)", lang->value);
     av_log(NULL, AV_LOG_DEBUG, ", %d, %d/%d", st->codec_info_nb_frames,
            st->time_base.num, st->time_base.den);
-    av_log(NULL, AV_LOG_INFO, ": %s", buf);
+    av_log(NULL, loglevel, ": %s", buf);
 
     if (st->sample_aspect_ratio.num &&
         av_cmp_q(st->sample_aspect_ratio, st->codecpar->sample_aspect_ratio)) {
@@ -501,7 +519,7 @@  static void dump_stream_format(AVFormatContext *ic, int i,
                   st->codecpar->width  * (int64_t)st->sample_aspect_ratio.num,
                   st->codecpar->height * (int64_t)st->sample_aspect_ratio.den,
                   1024 * 1024);
-        av_log(NULL, AV_LOG_INFO, ", SAR %d:%d DAR %d:%d",
+        av_log(NULL, loglevel, ", SAR %d:%d DAR %d:%d",
                st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
                display_aspect_ratio.num, display_aspect_ratio.den);
     }
@@ -513,7 +531,7 @@  static void dump_stream_format(AVFormatContext *ic, int i,
         int tbc = st->codec->time_base.den && st->codec->time_base.num;
 
         if (fps || tbr || tbn || tbc)
-            av_log(NULL, AV_LOG_INFO, "%s", separator);
+            av_log(NULL, loglevel, "%s", separator);
 
         if (fps)
             print_fps(av_q2d(st->avg_frame_rate), tbr || tbn || tbc ? "fps, " : "fps");
@@ -526,30 +544,36 @@  static void dump_stream_format(AVFormatContext *ic, int i,
     }
 
     if (st->disposition & AV_DISPOSITION_DEFAULT)
-        av_log(NULL, AV_LOG_INFO, " (default)");
+        av_log(NULL, loglevel, " (default)");
     if (st->disposition & AV_DISPOSITION_DUB)
-        av_log(NULL, AV_LOG_INFO, " (dub)");
+        av_log(NULL, loglevel, " (dub)");
     if (st->disposition & AV_DISPOSITION_ORIGINAL)
-        av_log(NULL, AV_LOG_INFO, " (original)");
+        av_log(NULL, loglevel, " (original)");
     if (st->disposition & AV_DISPOSITION_COMMENT)
-        av_log(NULL, AV_LOG_INFO, " (comment)");
+        av_log(NULL, loglevel, " (comment)");
     if (st->disposition & AV_DISPOSITION_LYRICS)
-        av_log(NULL, AV_LOG_INFO, " (lyrics)");
+        av_log(NULL, loglevel, " (lyrics)");
     if (st->disposition & AV_DISPOSITION_KARAOKE)
-        av_log(NULL, AV_LOG_INFO, " (karaoke)");
+        av_log(NULL, loglevel, " (karaoke)");
     if (st->disposition & AV_DISPOSITION_FORCED)
-        av_log(NULL, AV_LOG_INFO, " (forced)");
+        av_log(NULL, loglevel, " (forced)");
     if (st->disposition & AV_DISPOSITION_HEARING_IMPAIRED)
-        av_log(NULL, AV_LOG_INFO, " (hearing impaired)");
+        av_log(NULL, loglevel, " (hearing impaired)");
     if (st->disposition & AV_DISPOSITION_VISUAL_IMPAIRED)
-        av_log(NULL, AV_LOG_INFO, " (visual impaired)");
+        av_log(NULL, loglevel, " (visual impaired)");
     if (st->disposition & AV_DISPOSITION_CLEAN_EFFECTS)
-        av_log(NULL, AV_LOG_INFO, " (clean effects)");
-    av_log(NULL, AV_LOG_INFO, "\n");
+        av_log(NULL, loglevel, " (clean effects)");
+    av_log(NULL, loglevel, "\n");
+
+    dump_metadata_loglevel(NULL, st->metadata, "    ",loglevel);
 
-    dump_metadata(NULL, st->metadata, "    ");
+    dump_sidedata_loglevel(NULL, st, "    ",loglevel);
+}
 
-    dump_sidedata(NULL, st, "    ");
+static void inline dump_stream_format(AVFormatContext *ic, int i,
+									  int index, int is_output)
+{
+	dump_stream_format_loglevel(ic, i, index, is_output, AV_LOG_INFO);
 }
 
 void av_dump_format(AVFormatContext *ic, int index,
@@ -559,7 +583,8 @@  void av_dump_format(AVFormatContext *ic, int index,
     uint8_t *printed = ic->nb_streams ? av_mallocz(ic->nb_streams) : NULL;
     if (ic->nb_streams && !printed)
         return;
-
+	int av_log_level;
+	
     av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
            is_output ? "Output" : "Input",
            index,
@@ -617,9 +642,16 @@  void av_dump_format(AVFormatContext *ic, int index,
         for (j = 0; j < ic->nb_programs; j++) {
             AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata,
                                                   "name", NULL, 0);
-            av_log(NULL, AV_LOG_INFO, "  Program %d %s\n", ic->programs[j]->id,
+			/*
+			 Sometimes transport streams also have 'empty' programs (i.e. no streams inside).
+			 This can be annoying, so I'm raising the log level to AV_LOG_VERBOSE
+			 for 'empty' programs. Programs with streams get the normal AV_LOG_INFO level.
+			 */
+			av_log_level = (ic->programs[j]->nb_stream_indexes > 0) ?
+				AV_LOG_INFO : AV_LOG_VERBOSE;
+            av_log(NULL, av_log_level, "  Program %d %s\n", ic->programs[j]->id,
                    name ? name->value : "");
-            dump_metadata(NULL, ic->programs[j]->metadata, "    ");
+            dump_metadata_loglevel(NULL, ic->programs[j]->metadata, "    ", av_log_level);
             for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) {
                 dump_stream_format(ic, ic->programs[j]->stream_index[k],
                                    index, is_output);
@@ -633,7 +665,7 @@  void av_dump_format(AVFormatContext *ic, int index,
 
     for (i = 0; i < ic->nb_streams; i++)
         if (!printed[i])
-            dump_stream_format(ic, i, index, is_output);
+            dump_stream_format_loglevel(ic, i, index, is_output,AV_LOG_VERBOSE);
 
     av_free(printed);
 }