]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/mux.c
Merge commit '9200514ad8717c63f82101dc394f4378854325bf'
[ffmpeg] / libavformat / mux.c
index eb0b9739c22a5b5c7c1f3f24bd34118bbd6ffa41..33301f1d790a646403278a0ee42f0565784d92bc 100644 (file)
@@ -117,24 +117,24 @@ AVRational ff_choose_timebase(AVFormatContext *s, AVStream *st, int min_precisio
 
 enum AVChromaLocation ff_choose_chroma_location(AVFormatContext *s, AVStream *st)
 {
-    AVCodecContext *avctx = st->codec;
-    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(avctx->pix_fmt);
+    AVCodecParameters *par = st->codecpar;
+    const AVPixFmtDescriptor *pix_desc = av_pix_fmt_desc_get(par->format);
 
-    if (avctx->chroma_sample_location != AVCHROMA_LOC_UNSPECIFIED)
-        return avctx->chroma_sample_location;
+    if (par->chroma_location != AVCHROMA_LOC_UNSPECIFIED)
+        return par->chroma_location;
 
     if (pix_desc) {
         if (pix_desc->log2_chroma_h == 0) {
             return AVCHROMA_LOC_TOPLEFT;
         } else if (pix_desc->log2_chroma_w == 1 && pix_desc->log2_chroma_h == 1) {
-            if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order == AV_FIELD_PROGRESSIVE) {
-                switch (avctx->codec_id) {
+            if (par->field_order == AV_FIELD_UNKNOWN || par->field_order == AV_FIELD_PROGRESSIVE) {
+                switch (par->codec_id) {
                 case AV_CODEC_ID_MJPEG:
                 case AV_CODEC_ID_MPEG1VIDEO: return AVCHROMA_LOC_CENTER;
                 }
             }
-            if (avctx->field_order == AV_FIELD_UNKNOWN || avctx->field_order != AV_FIELD_PROGRESSIVE) {
-                switch (avctx->codec_id) {
+            if (par->field_order == AV_FIELD_UNKNOWN || par->field_order != AV_FIELD_PROGRESSIVE) {
+                switch (par->codec_id) {
                 case AV_CODEC_ID_MPEG2VIDEO: return AVCHROMA_LOC_LEFT;
                 }
             }
@@ -214,12 +214,12 @@ static int validate_codec_tag(AVFormatContext *s, AVStream *st)
     for (n = 0; s->oformat->codec_tag[n]; n++) {
         avctag = s->oformat->codec_tag[n];
         while (avctag->id != AV_CODEC_ID_NONE) {
-            if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codec->codec_tag)) {
+            if (avpriv_toupper4(avctag->tag) == avpriv_toupper4(st->codecpar->codec_tag)) {
                 id = avctag->id;
-                if (id == st->codec->codec_id)
+                if (id == st->codecpar->codec_id)
                     return 1;
             }
-            if (avctag->id == st->codec->codec_id)
+            if (avctag->id == st->codecpar->codec_id)
                 tag = avctag->tag;
             avctag++;
         }
@@ -237,7 +237,7 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
     int ret = 0, i;
     AVStream *st;
     AVDictionary *tmp = NULL;
-    AVCodecContext *codec = NULL;
+    AVCodecParameters *par = NULL;
     AVOutputFormat *of = s->oformat;
     const AVCodecDescriptor *desc;
     AVDictionaryEntry *e;
@@ -251,6 +251,8 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
         (ret = av_opt_set_dict2(s->priv_data, &tmp, AV_OPT_SEARCH_CHILDREN)) < 0)
         goto fail;
 
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
     if (s->nb_streams && s->streams[0]->codec->flags & AV_CODEC_FLAG_BITEXACT) {
         if (!(s->flags & AVFMT_FLAG_BITEXACT)) {
 #if FF_API_LAVF_BITEXACT
@@ -268,6 +270,8 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
 #endif
         }
     }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
 
     // some sanity checks
     if (s->nb_streams == 0 && !(of->flags & AVFMT_NOSTREAMS)) {
@@ -277,58 +281,72 @@ static int init_muxer(AVFormatContext *s, AVDictionary **options)
     }
 
     for (i = 0; i < s->nb_streams; i++) {
-        st    = s->streams[i];
-        codec = st->codec;
+        st  = s->streams[i];
+        par = st->codecpar;
 
 #if FF_API_LAVF_CODEC_TB
 FF_DISABLE_DEPRECATION_WARNINGS
-        if (!st->time_base.num && codec->time_base.num) {
+        if (!st->time_base.num && st->codec->time_base.num) {
             av_log(s, AV_LOG_WARNING, "Using AVStream.codec.time_base as a "
                    "timebase hint to the muxer is deprecated. Set "
                    "AVStream.time_base instead.\n");
-            avpriv_set_pts_info(st, 64, codec->time_base.num, codec->time_base.den);
+            avpriv_set_pts_info(st, 64, st->codec->time_base.num, st->codec->time_base.den);
+        }
+FF_ENABLE_DEPRECATION_WARNINGS
+#endif
+
+#if FF_API_LAVF_AVCTX
+FF_DISABLE_DEPRECATION_WARNINGS
+        if (st->codecpar->codec_type == AVMEDIA_TYPE_UNKNOWN &&
+            st->codec->codec_type    != AVMEDIA_TYPE_UNKNOWN) {
+            av_log(s, AV_LOG_WARNING, "Using AVStream.codec to pass codec "
+                   "parameters to muxers is deprecated, use AVStream.codecpar "
+                   "instead.\n");
+            ret = avcodec_parameters_from_context(st->codecpar, st->codec);
+            if (ret < 0)
+                goto fail;
         }
 FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
         if (!st->time_base.num) {
             /* fall back on the default timebase values */
-            if (codec->codec_type == AVMEDIA_TYPE_AUDIO && codec->sample_rate)
-                avpriv_set_pts_info(st, 64, 1, codec->sample_rate);
+            if (par->codec_type == AVMEDIA_TYPE_AUDIO && par->sample_rate)
+                avpriv_set_pts_info(st, 64, 1, par->sample_rate);
             else
                 avpriv_set_pts_info(st, 33, 1, 90000);
         }
 
-        switch (codec->codec_type) {
+        switch (par->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
-            if (codec->sample_rate <= 0) {
+            if (par->sample_rate <= 0) {
                 av_log(s, AV_LOG_ERROR, "sample rate not set\n");
                 ret = AVERROR(EINVAL);
                 goto fail;
             }
-            if (!codec->block_align)
-                codec->block_align = codec->channels *
-                                     av_get_bits_per_sample(codec->codec_id) >> 3;
+            if (!par->block_align)
+                par->block_align = par->channels *
+                                   av_get_bits_per_sample(par->codec_id) >> 3;
             break;
         case AVMEDIA_TYPE_VIDEO:
-            if ((codec->width <= 0 || codec->height <= 0) &&
+            if ((par->width <= 0 || par->height <= 0) &&
                 !(of->flags & AVFMT_NODIMENSIONS)) {
                 av_log(s, AV_LOG_ERROR, "dimensions not set\n");
                 ret = AVERROR(EINVAL);
                 goto fail;
             }
-            if (av_cmp_q(st->sample_aspect_ratio, codec->sample_aspect_ratio)
-                && fabs(av_q2d(st->sample_aspect_ratio) - av_q2d(codec->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
+            if (av_cmp_q(st->sample_aspect_ratio, par->sample_aspect_ratio)
+                && fabs(av_q2d(st->sample_aspect_ratio) - av_q2d(par->sample_aspect_ratio)) > 0.004*av_q2d(st->sample_aspect_ratio)
             ) {
                 if (st->sample_aspect_ratio.num != 0 &&
                     st->sample_aspect_ratio.den != 0 &&
-                    codec->sample_aspect_ratio.num != 0 &&
-                    codec->sample_aspect_ratio.den != 0) {
+                    par->sample_aspect_ratio.num != 0 &&
+                    par->sample_aspect_ratio.den != 0) {
                     av_log(s, AV_LOG_ERROR, "Aspect ratio mismatch between muxer "
                            "(%d/%d) and encoder layer (%d/%d)\n",
                            st->sample_aspect_ratio.num, st->sample_aspect_ratio.den,
-                           codec->sample_aspect_ratio.num,
-                           codec->sample_aspect_ratio.den);
+                           par->sample_aspect_ratio.num,
+                           par->sample_aspect_ratio.den);
                     ret = AVERROR(EINVAL);
                     goto fail;
                 }
@@ -336,36 +354,36 @@ FF_ENABLE_DEPRECATION_WARNINGS
             break;
         }
 
-        desc = avcodec_descriptor_get(codec->codec_id);
+        desc = avcodec_descriptor_get(par->codec_id);
         if (desc && desc->props & AV_CODEC_PROP_REORDER)
             st->internal->reorder = 1;
 
         if (of->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', ' '))
+            if (   par->codec_tag
+                && par->codec_id == AV_CODEC_ID_RAWVIDEO
+                && (   av_codec_get_tag(of->codec_tag, par->codec_id) == 0
+                    || av_codec_get_tag(of->codec_tag, par->codec_id) == 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
-                codec->codec_tag = 0;
+                par->codec_tag = 0;
             }
-            if (codec->codec_tag) {
+            if (par->codec_tag) {
                 if (!validate_codec_tag(s, st)) {
                     char tagbuf[32], tagbuf2[32];
-                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), codec->codec_tag);
-                    av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, codec->codec_id));
+                    av_get_codec_tag_string(tagbuf, sizeof(tagbuf), par->codec_tag);
+                    av_get_codec_tag_string(tagbuf2, sizeof(tagbuf2), av_codec_get_tag(s->oformat->codec_tag, par->codec_id));
                     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, tagbuf2);
+                           tagbuf, par->codec_tag, par->codec_id, tagbuf2);
                     ret = AVERROR_INVALIDDATA;
                     goto fail;
                 }
             } else
-                codec->codec_tag = av_codec_get_tag(of->codec_tag, codec->codec_id);
+                par->codec_tag = av_codec_get_tag(of->codec_tag, par->codec_id);
         }
 
-        if (codec->codec_type != AVMEDIA_TYPE_ATTACHMENT)
+        if (par->codec_type != AVMEDIA_TYPE_ATTACHMENT)
             s->internal->nb_interleaved_streams++;
     }
 
@@ -421,12 +439,12 @@ static int init_pts(AVFormatContext *s)
         int64_t den = AV_NOPTS_VALUE;
         st = s->streams[i];
 
-        switch (st->codec->codec_type) {
+        switch (st->codecpar->codec_type) {
         case AVMEDIA_TYPE_AUDIO:
-            den = (int64_t)st->time_base.num * st->codec->sample_rate;
+            den = (int64_t)st->time_base.num * st->codecpar->sample_rate;
             break;
         case AVMEDIA_TYPE_VIDEO:
-            den = (int64_t)st->time_base.num * st->codec->time_base.den;
+            den = (int64_t)st->time_base.num * st->time_base.den;
             break;
         default:
             break;
@@ -490,10 +508,11 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
 
 
 #if FF_API_COMPUTE_PKT_FIELDS2
+FF_DISABLE_DEPRECATION_WARNINGS
 //FIXME merge with compute_pkt_fields
 static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *pkt)
 {
-    int delay = FFMAX(st->codec->has_b_frames, st->codec->max_b_frames > 0);
+    int delay = FFMAX(st->codecpar->video_delay, st->internal->avctx->max_b_frames > 0);
     int num, den, i;
     int frame_size;
 
@@ -553,8 +572,8 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
 
     if (st->cur_dts && st->cur_dts != AV_NOPTS_VALUE &&
         ((!(s->oformat->flags & AVFMT_TS_NONSTRICT) &&
-          st->codec->codec_type != AVMEDIA_TYPE_SUBTITLE &&
-          st->codec->codec_type != AVMEDIA_TYPE_DATA &&
+          st->codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE &&
+          st->codecpar->codec_type != AVMEDIA_TYPE_DATA &&
           st->cur_dts >= pkt->dts) || st->cur_dts > pkt->dts)) {
         av_log(s, AV_LOG_ERROR,
                "Application provided invalid, non monotonically increasing dts to muxer in stream %d: %s >= %s\n",
@@ -591,11 +610,12 @@ static int compute_muxer_pkt_fields(AVFormatContext *s, AVStream *st, AVPacket *
         }
         break;
     case AVMEDIA_TYPE_VIDEO:
-        frac_add(st->priv_pts, (int64_t)st->time_base.den * st->codec->time_base.num);
+        frac_add(st->priv_pts, (int64_t)st->time_base.den * st->time_base.num);
         break;
     }
     return 0;
 }
+FF_ENABLE_DEPRECATION_WARNINGS
 #endif
 
 /**
@@ -715,7 +735,7 @@ static int check_packet(AVFormatContext *s, AVPacket *pkt)
         return AVERROR(EINVAL);
     }
 
-    if (s->streams[pkt->stream_index]->codec->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
+    if (s->streams[pkt->stream_index]->codecpar->codec_type == AVMEDIA_TYPE_ATTACHMENT) {
         av_log(s, AV_LOG_ERROR, "Received a packet for an attachment stream.\n");
         return AVERROR(EINVAL);
     }
@@ -853,7 +873,7 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
             st->interleaver_chunk_size      = 0;
             this_pktl->pkt.flags |= CHUNK_START;
             if (max && st->interleaver_chunk_duration > max) {
-                int64_t syncoffset = (st->codec->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;
+                int64_t syncoffset = (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)*max/2;
                 int64_t syncto = av_rescale(pkt->dts + syncoffset, 1, max)*max - syncoffset;
 
                 st->interleaver_chunk_duration += (pkt->dts - syncto)/8 - max;
@@ -898,12 +918,12 @@ static int interleave_compare_dts(AVFormatContext *s, AVPacket *next,
     AVStream *st2 = s->streams[next->stream_index];
     int comp      = av_compare_ts(next->dts, st2->time_base, pkt->dts,
                                   st->time_base);
-    if (s->audio_preload && ((st->codec->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codec->codec_type == AVMEDIA_TYPE_AUDIO))) {
-        int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO);
-        int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO);
+    if (s->audio_preload && ((st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) != (st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO))) {
+        int64_t ts = av_rescale_q(pkt ->dts, st ->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
+        int64_t ts2= av_rescale_q(next->dts, st2->time_base, AV_TIME_BASE_Q) - s->audio_preload*(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO);
         if (ts == ts2) {
-            ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codec->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
-               -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codec->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
+            ts= ( pkt ->dts* st->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st ->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)* st->time_base.den)*st2->time_base.den
+               -( next->dts*st2->time_base.num*AV_TIME_BASE - s->audio_preload*(int64_t)(st2->codecpar->codec_type == AVMEDIA_TYPE_AUDIO)*st2->time_base.den)* st->time_base.den;
             ts2=0;
         }
         comp= (ts>ts2) - (ts<ts2);
@@ -930,9 +950,9 @@ int ff_interleave_packet_per_dts(AVFormatContext *s, AVPacket *out,
     for (i = 0; i < s->nb_streams; i++) {
         if (s->streams[i]->last_in_packet_buffer) {
             ++stream_count;
-        } else if (s->streams[i]->codec->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
-                   s->streams[i]->codec->codec_id != AV_CODEC_ID_VP8 &&
-                   s->streams[i]->codec->codec_id != AV_CODEC_ID_VP9) {
+        } else if (s->streams[i]->codecpar->codec_type != AVMEDIA_TYPE_ATTACHMENT &&
+                   s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP8 &&
+                   s->streams[i]->codecpar->codec_id != AV_CODEC_ID_VP9) {
             ++noninterleaved_count;
         }
     }
@@ -1025,6 +1045,26 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
     if (pkt) {
         AVStream *st = s->streams[pkt->stream_index];
 
+        if (s->oformat->check_bitstream) {
+            if (!st->internal->bitstream_checked) {
+                if ((ret = s->oformat->check_bitstream(s, pkt)) < 0)
+                    goto fail;
+                else if (ret == 1)
+                    st->internal->bitstream_checked = 1;
+            }
+        }
+
+        av_apply_bitstream_filters(st->internal->avctx, pkt, st->internal->bsfc);
+        if (pkt->size == 0 && pkt->side_data_elems == 0)
+            return 0;
+        if (!st->codecpar->extradata && st->internal->avctx->extradata) {
+            int eret = ff_alloc_extradata(st->codecpar, st->internal->avctx->extradata_size);
+            if (eret < 0)
+                return AVERROR(ENOMEM);
+            st->codecpar->extradata_size = st->internal->avctx->extradata_size;
+            memcpy(st->codecpar->extradata, st->internal->avctx->extradata, st->internal->avctx->extradata_size);
+        }
+
         if (s->debug & FF_FDEBUG_TS)
             av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame size:%d dts:%s pts:%s\n",
                 pkt->size, av_ts2str(pkt->dts), av_ts2str(pkt->pts));
@@ -1038,17 +1078,6 @@ int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt)
             ret = AVERROR(EINVAL);
             goto fail;
         }
-
-        if (s->oformat->check_bitstream) {
-            if (!st->internal->bitstream_checked) {
-                if ((ret = s->oformat->check_bitstream(s, pkt)) < 0)
-                    goto fail;
-                else if (ret == 1)
-                    st->internal->bitstream_checked = 1;
-            }
-        }
-
-        av_apply_bitstream_filters(st->codec, pkt, st->internal->bsfc);
     } else {
         av_log(s, AV_LOG_TRACE, "av_interleaved_write_frame FLUSH\n");
         flush = 1;