Browse code

ffmpeg: stop using AVStream.codec on stream copy

This commit is based on commit 35c8580 from Anton Khirnov <anton@khirnov.net>
which was skipped in b8945c4.

The avcodec_copy_context() call in the encode path is left in place for now
as AVStream.codec is apparently still required even after porting ffmpeg to
the new bsf API.

Tested-by: Michael Niedermayer <michael@niedermayer.cc>
Signed-off-by: James Almer <jamrial@gmail.com>

James Almer authored on 2016/09/27 22:10:44
Showing 3 changed files
... ...
@@ -516,6 +516,7 @@ static void ffmpeg_cleanup(int ret)
516 516
         av_dict_free(&ost->encoder_opts);
517 517
 
518 518
         av_parser_close(ost->parser);
519
+        avcodec_free_context(&ost->parser_avctx);
519 520
 
520 521
         av_freep(&ost->forced_keyframes);
521 522
         av_expr_free(ost->forced_keyframes_pexpr);
... ...
@@ -1899,7 +1900,7 @@ static void do_streamcopy(InputStream *ist, OutputStream *ost, const AVPacket *p
1899 1899
        && ost->st->codecpar->codec_id != AV_CODEC_ID_MPEG2VIDEO
1900 1900
        && ost->st->codecpar->codec_id != AV_CODEC_ID_VC1
1901 1901
        ) {
1902
-        int ret = av_parser_change(ost->parser, ost->st->codec,
1902
+        int ret = av_parser_change(ost->parser, ost->parser_avctx,
1903 1903
                              &opkt.data, &opkt.size,
1904 1904
                              pkt->data, pkt->size,
1905 1905
                              pkt->flags & AV_PKT_FLAG_KEY);
... ...
@@ -2723,9 +2724,7 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
2723 2723
             exit_program(1);
2724 2724
         }
2725 2725
         /*
2726
-         * FIXME: this is only so that the bitstream filters and parsers (that still
2727
-         * work with a codec context) get the parameter values.
2728
-         * This should go away with the new BSF/parser API.
2726
+         * FIXME: ost->st->codec should't be needed here anymore.
2729 2727
          */
2730 2728
         ret = avcodec_copy_context(ost->st->codec, ost->enc_ctx);
2731 2729
         if (ret < 0)
... ...
@@ -2757,15 +2756,11 @@ static int init_output_stream(OutputStream *ost, char *error, int error_len)
2757 2757
         ost->st->time_base = av_add_q(ost->enc_ctx->time_base, (AVRational){0, 1});
2758 2758
         ost->st->codec->codec= ost->enc_ctx->codec;
2759 2759
     } else if (ost->stream_copy) {
2760
-        // copy timebase while removing common factors
2761
-        ost->st->time_base = av_add_q(ost->st->codec->time_base, (AVRational){0, 1});
2762
-
2763 2760
         /*
2764
-         * FIXME: this is only so that the bitstream filters and parsers (that still
2765
-         * work with a codec context) get the parameter values.
2766
-         * This should go away with the new BSF/parser API.
2761
+         * FIXME: will the codec context used by the parser during streamcopy
2762
+         * This should go away with the new parser API.
2767 2763
          */
2768
-        ret = avcodec_parameters_to_context(ost->st->codec, ost->st->codecpar);
2764
+        ret = avcodec_parameters_to_context(ost->parser_avctx, ost->st->codecpar);
2769 2765
         if (ret < 0)
2770 2766
             return ret;
2771 2767
     }
... ...
@@ -3007,12 +3002,13 @@ static int transcode_init(void)
3007 3007
                 ost->frame_rate = ist->framerate;
3008 3008
             ost->st->avg_frame_rate = ost->frame_rate;
3009 3009
 
3010
-            ost->st->time_base = ist->st->time_base;
3011
-
3012 3010
             ret = avformat_transfer_internal_stream_timing_info(oc->oformat, ost->st, ist->st, copy_tb);
3013 3011
             if (ret < 0)
3014 3012
                 return ret;
3015 3013
 
3014
+            // copy timebase while removing common factors
3015
+            ost->st->time_base = av_add_q(av_stream_get_codec_timebase(ost->st), (AVRational){0, 1});
3016
+
3016 3017
             if (ist->st->nb_side_data) {
3017 3018
                 ost->st->side_data = av_realloc_array(NULL, ist->st->nb_side_data,
3018 3019
                                                       sizeof(*ist->st->side_data));
... ...
@@ -3038,6 +3034,9 @@ static int transcode_init(void)
3038 3038
             }
3039 3039
 
3040 3040
             ost->parser = av_parser_init(par_dst->codec_id);
3041
+            ost->parser_avctx = avcodec_alloc_context3(NULL);
3042
+            if (!ost->parser_avctx)
3043
+                return AVERROR(ENOMEM);
3041 3044
 
3042 3045
             switch (par_dst->codec_type) {
3043 3046
             case AVMEDIA_TYPE_AUDIO:
... ...
@@ -477,6 +477,7 @@ typedef struct OutputStream {
477 477
     int keep_pix_fmt;
478 478
 
479 479
     AVCodecParserContext *parser;
480
+    AVCodecContext       *parser_avctx;
480 481
 
481 482
     /* stats */
482 483
     // combined size of all the packets written
... ...
@@ -2300,6 +2300,7 @@ loop_end:
2300 2300
         avio_read(pb, attachment, len);
2301 2301
 
2302 2302
         ost = new_attachment_stream(o, oc, -1);
2303
+        ost->stream_copy               = 0;
2303 2304
         ost->attachment_filename       = o->attachments[i];
2304 2305
         ost->st->codecpar->extradata      = attachment;
2305 2306
         ost->st->codecpar->extradata_size = len;
... ...
@@ -2309,6 +2310,7 @@ loop_end:
2309 2309
         avio_closep(&pb);
2310 2310
     }
2311 2311
 
2312
+#if FF_API_LAVF_AVCTX
2312 2313
     for (i = nb_output_streams - oc->nb_streams; i < nb_output_streams; i++) { //for all streams of this output file
2313 2314
         AVDictionaryEntry *e;
2314 2315
         ost = output_streams[i];
... ...
@@ -2319,6 +2321,7 @@ loop_end:
2319 2319
             if (av_opt_set(ost->st->codec, "flags", e->value, 0) < 0)
2320 2320
                 exit_program(1);
2321 2321
     }
2322
+#endif
2322 2323
 
2323 2324
     if (!oc->nb_streams && !(oc->oformat->flags & AVFMT_NOSTREAMS)) {
2324 2325
         av_dump_format(oc, nb_output_files - 1, oc->filename, 1);