[FFmpeg-devel] [PATCH]Accept 0 as codec_tag in ffmpeg.c if it matches the codec_id

Carl Eugen Hoyos cehoyos at ag.or.at
Tue Dec 11 12:19:14 CET 2012


On Tuesday 11 December 2012 12:47:12 am Michael Niedermayer wrote:
> On Sun, Dec 09, 2012 at 02:47:34PM +0100, Carl Eugen Hoyos wrote:
> > On Saturday 08 December 2012 03:02:39 am Michael Niedermayer wrote:
> > > On Fri, Dec 07, 2012 at 01:15:21PM +0100, Carl Eugen Hoyos wrote:
> > > > Hi!
> > > >
> > > > Attached patch fixes ticket #1953 for me.
> > > >
> > > > I suspect the actual problem is that av_codec_get_tag() returns 0
> > > > both in case of failure and success, but that seems difficult to fix
> > > > without breaking API.
> > >
> > > i think we should add a new function that is free of this ambiguity
> >
> > New patch attached.
> >
> > Please review, Carl Eugen
>
> breaks fate also some of the changes from the old tp the new function
> look wrong. I dont think all the == 0 checks meant failure some
> actually meant the 0 tag

New patch attached that fixes both fate failures (that had different reasons).

Please review, Carl Eugen
-------------- next part --------------
diff --git a/ffmpeg.c b/ffmpeg.c
index 4b278a2..c966a8a 100644
--- a/ffmpeg.c
+++ b/ffmpeg.c
@@ -2033,9 +2033,10 @@ static int transcode_init(void)
             codec->codec_type = icodec->codec_type;
 
             if (!codec->codec_tag) {
+                unsigned int codec_tag;
                 if (!oc->oformat->codec_tag ||
                      av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == codec->codec_id ||
-                     av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0)
+                     !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag))
                     codec->codec_tag = icodec->codec_tag;
             }
 
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 7500881..f476056 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -1893,8 +1893,22 @@ enum AVCodecID av_codec_get_id(const struct AVCodecTag * const *tags, unsigned i
  *
  * @param tags list of supported codec_id-codec_tag pairs, as stored
  * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ *
+ * @deprecated deprecated in favor of av_codec_get_tag2
+ */
+attribute_deprecated unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id);
+
+/**
+ * Get the codec tag for the given codec id.
+ *
+ * @param tags list of supported codec_id - codec_tag pairs, as stored
+ * in AVInputFormat.codec_tag and AVOutputFormat.codec_tag
+ * @param id codec id that should be searched for in the list
+ * @param tag A pointer to the found tag
+ * @return 0 if id was not found in tags, != 0 if it was found
  */
-unsigned int av_codec_get_tag(const struct AVCodecTag * const *tags, enum AVCodecID id);
+int av_codec_get_tag2(const struct AVCodecTag * const *tags, enum AVCodecID id,
+                      unsigned int *tag);
 
 int av_find_default_stream_index(AVFormatContext *s);
 
diff --git a/libavformat/mux.c b/libavformat/mux.c
index 9bcee99..f59859d 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -287,10 +287,12 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
         }
 
         if (of->codec_tag) {
+            unsigned int codec_tag = 0;
+            av_codec_get_tag2(of->codec_tag, codec->codec_id, &codec_tag);
             if (   codec->codec_tag
                 && codec->codec_id == AV_CODEC_ID_RAWVIDEO
-                && (   av_codec_get_tag(of->codec_tag, codec->codec_id) == 0
-                    || av_codec_get_tag(of->codec_tag, codec->codec_id) == MKTAG('r', 'a', 'w', ' '))
+                && (   codec_tag == 0
+                    || codec_tag == MKTAG('r', 'a', 'w', ' '))
                 && !validate_codec_tag(s, st)) {
                 // the current rawvideo encoding system ends up setting
                 // the wrong codec_tag for avi/mov, we override it here
@@ -299,8 +301,10 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
             if (codec->codec_tag) {
                 if (!validate_codec_tag(s, st)) {
                     char tagbuf[32], cortag[32];
+                    unsigned int codec_tag = 0;
                     av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
-                    av_get_codec_tag_string(cortag, sizeof(cortag), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
+                    av_codec_get_tag2(s->oformat->codec_tag, codec->codec_id, &codec_tag);
+                    av_get_codec_tag_string(cortag, sizeof(cortag), codec_tag);
                     av_log(s, AV_LOG_ERROR,
                            "Tag %s/0x%08x incompatible with output codec id '%d' (%s)\n",
                            tagbuf, codec->codec_tag, codec->codec_id, cortag);
@@ -308,7 +312,7 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
                     goto fail;
                 }
             } else
-                codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id);
+                av_codec_get_tag2(of->codec_tag, codec->codec_id, &codec->codec_tag);
         }
 
         if (of->flags & AVFMT_GLOBALHEADER &&
diff --git a/libavformat/segment.c b/libavformat/segment.c
index 53feec4..7e8091b 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -111,6 +111,7 @@ static int segment_mux_init(AVFormatContext *s)
     for (i = 0; i < s->nb_streams; i++) {
         AVStream *st;
         AVCodecContext *icodec, *ocodec;
+        unsigned int codec_tag;
 
         if (!(st = avformat_new_stream(oc, NULL)))
             return AVERROR(ENOMEM);
@@ -119,7 +120,7 @@ static int segment_mux_init(AVFormatContext *s)
         avcodec_copy_context(ocodec, icodec);
         if (!oc->oformat->codec_tag ||
             av_codec_get_id (oc->oformat->codec_tag, icodec->codec_tag) == ocodec->codec_id ||
-            av_codec_get_tag(oc->oformat->codec_tag, icodec->codec_id) <= 0) {
+            !av_codec_get_tag2(oc->oformat->codec_tag, icodec->codec_id, &codec_tag)) {
             ocodec->codec_tag = icodec->codec_tag;
         } else {
             ocodec->codec_tag = 0;
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 596253b..88a30fe 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2480,10 +2480,25 @@ enum AVCodecID ff_get_pcm_codec_id(int bps, int flt, int be, int sflags)
 
 unsigned int av_codec_get_tag(const AVCodecTag * const *tags, enum AVCodecID id)
 {
+    unsigned int tag;
+    if (!av_codec_get_tag2(tags, id, &tag))
+        return 0;
+    return tag;
+}
+
+int av_codec_get_tag2(const AVCodecTag * const *tags, enum AVCodecID id,
+                      unsigned int *tag)
+{
     int i;
     for(i=0; tags && tags[i]; i++){
-        int tag= ff_codec_get_tag(tags[i], id);
-        if(tag) return tag;
+        const AVCodecTag *codec_tags = tags[i];
+        while (codec_tags->id != AV_CODEC_ID_NONE) {
+            if (codec_tags->id == id) {
+                *tag = codec_tags->tag;
+                return 1;
+            }
+            codec_tags++;
+        }
     }
     return 0;
 }
@@ -3976,10 +3991,11 @@ int64_t ff_iso8601_to_unix_time(const char *datestr)
 int avformat_query_codec(AVOutputFormat *ofmt, enum AVCodecID codec_id, int std_compliance)
 {
     if (ofmt) {
+        unsigned int codec_tag;
         if (ofmt->query_codec)
             return ofmt->query_codec(codec_id, std_compliance);
         else if (ofmt->codec_tag)
-            return !!av_codec_get_tag(ofmt->codec_tag, codec_id);
+            return !!av_codec_get_tag2(ofmt->codec_tag, codec_id, &codec_tag);
         else if (codec_id == ofmt->video_codec || codec_id == ofmt->audio_codec ||
                  codec_id == ofmt->subtitle_codec)
             return 1;
diff --git a/libavformat/version.h b/libavformat/version.h
index 3b2ba41..18e2d94 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,8 +30,8 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 49
-#define LIBAVFORMAT_VERSION_MICRO 101
+#define LIBAVFORMAT_VERSION_MINOR 50
+#define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
                                                LIBAVFORMAT_VERSION_MINOR, \


More information about the ffmpeg-devel mailing list