[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
Sun Dec 9 14:47:34 CET 2012


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
-------------- 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..7f74c27 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -287,10 +287,11 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
         }
 
         if (of->codec_tag) {
+            unsigned int 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', ' '))
+                && (   !av_codec_get_tag2(of->codec_tag, codec->codec_id, &codec_tag)
+                    || 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 +300,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 +311,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 1ad410e..c94de1a 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -108,6 +108,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);
@@ -116,7 +117,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 0f13304..f24e181 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -2472,10 +2472,20 @@ 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;
+        *tag = ff_codec_get_tag(tags[i], id);
+        if(av_codec_get_id(tags, *tag) == id)
+            return 1;
     }
     return 0;
 }
@@ -3968,10 +3978,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 0128e73..aecb920 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -30,7 +30,7 @@
 #include "libavutil/avutil.h"
 
 #define LIBAVFORMAT_VERSION_MAJOR 54
-#define LIBAVFORMAT_VERSION_MINOR 48
+#define LIBAVFORMAT_VERSION_MINOR 49
 #define LIBAVFORMAT_VERSION_MICRO 100
 
 #define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \


More information about the ffmpeg-devel mailing list