[FFmpeg-devel] [PATCH]Fix default stream flag value wrt matroska muxing

Carl Eugen Hoyos cehoyos at ag.or.at
Mon Jan 28 00:17:58 CET 2013


Hi!

The matroska specification describes a stream flag "FlagDefault" that defaults 
to "default".
FFmpeg has a stream disposition AV_DISPOSITION_DEFAULT. Since disposition is 
initialized to "0", the default value for the FFmpeg flag is "not default".
The result is that except for a corner case (forced flag set) whenever a 
matroska stream is used as input, the output stream is set as "default" in 
matroska files because either the flag was set and is written or it was not 
set, then it is not written and the matroska default value takes effect, see 
ticket #1815.

Attached is a possibility to fix this problem by adding an additional flag to 
tell if the value is set or not.
I am not convinced that always writing the matroska "FlagDefault" instead is a 
better solution because it would suddenly make nearly all streams in matroska 
files written by lavf "non-default".

Please review, Carl Eugen
-------------- next part --------------
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 8330c6b..aaf7c8f 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -628,6 +628,7 @@ typedef struct AVIndexEntry {
  * It can also be accessed at any time in AVStream.attached_pic.
  */
 #define AV_DISPOSITION_ATTACHED_PIC      0x0400
+#define AV_DISPOSITION_DEFAULT_VALID     0x4000 /**< the value of AV_DISPOSITION_DEFAULT is valid */
 
 /**
  * Options for behavior on timestamp wrap detection.
diff --git a/libavformat/matroskadec.c b/libavformat/matroskadec.c
index 1a15558..e60fdfd 100644
--- a/libavformat/matroskadec.c
+++ b/libavformat/matroskadec.c
@@ -1726,6 +1726,7 @@ static int matroska_read_header(AVFormatContext *s)
 
         if (track->flag_default)
             st->disposition |= AV_DISPOSITION_DEFAULT;
+        st->disposition |= AV_DISPOSITION_DEFAULT_VALID;
         if (track->flag_forced)
             st->disposition |= AV_DISPOSITION_FORCED;
 
diff --git a/libavformat/matroskaenc.c b/libavformat/matroskaenc.c
index c167c01..6b814db 100644
--- a/libavformat/matroskaenc.c
+++ b/libavformat/matroskaenc.c
@@ -570,7 +570,7 @@ static int mkv_write_tracks(AVFormatContext *s)
         tag = av_dict_get(st->metadata, "language", NULL, 0);
         put_ebml_string(pb, MATROSKA_ID_TRACKLANGUAGE, tag ? tag->value:"und");
 
-        if (st->disposition)
+        if (st->disposition & AV_DISPOSITION_DEFAULT_VALID)
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGDEFAULT, !!(st->disposition & AV_DISPOSITION_DEFAULT));
         if (st->disposition & AV_DISPOSITION_FORCED)
             put_ebml_uint(pb, MATROSKA_ID_TRACKFLAGFORCED, 1);
diff --git a/libavformat/mpeg.c b/libavformat/mpeg.c
index 4eaffd8..5127a69 100644
--- a/libavformat/mpeg.c
+++ b/libavformat/mpeg.c
@@ -713,6 +713,7 @@ static int vobsub_read_header(AVFormatContext *s)
 
     if (langidx < s->nb_streams)
         s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT;
+    s->streams[langidx]->disposition |= AV_DISPOSITION_DEFAULT_VALID;
 
     ff_subtitles_queue_finalize(&vobsub->q);
 
diff --git a/libavformat/nutdec.c b/libavformat/nutdec.c
index f260a3e..067bb03 100644
--- a/libavformat/nutdec.c
+++ b/libavformat/nutdec.c
@@ -445,9 +445,11 @@ static void set_disposition_bits(AVFormatContext *avf, char *value,
             flag = ff_nut_dispositions[i].flag;
     if (!flag)
         av_log(avf, AV_LOG_INFO, "unknown disposition type '%s'\n", value);
-    for (i = 0; i < avf->nb_streams; ++i)
+    for (i = 0; i < avf->nb_streams; ++i) {
         if (stream_id == i || stream_id == -1)
             avf->streams[i]->disposition |= flag;
+        avf->streams[i]->disposition |= AV_DISPOSITION_DEFAULT_VALID;
+    }
 }
 
 static int decode_info_header(NUTContext *nut)


More information about the ffmpeg-devel mailing list