[FFmpeg-devel] [PATCH] doc/examples/remuxing: switch to codecpar
Matthieu Bouron
matthieu.bouron at gmail.com
Wed Mar 29 12:13:56 EEST 2017
On Tue, Mar 28, 2017 at 10:06:31PM +0200, Michael Niedermayer wrote:
> On Tue, Mar 28, 2017 at 04:54:38PM +0200, Matthieu Bouron wrote:
> > On Tue, Mar 28, 2017 at 12:32 PM, Matthieu Bouron <matthieu.bouron at gmail.com
> > > wrote:
> >
> > > Also limits remuxing to audio, video and subtitle streams.
> > > ---
> > > doc/examples/remuxing.c | 48 ++++++++++++++++++++++++++++++
> > > +++++++++++-------
> > > 1 file changed, 41 insertions(+), 7 deletions(-)
> > >
> > > diff --git a/doc/examples/remuxing.c b/doc/examples/remuxing.c
> > > index 65437d9abd..8615c73842 100644
> > > --- a/doc/examples/remuxing.c
> > > +++ b/doc/examples/remuxing.c
> > > @@ -50,6 +50,9 @@ int main(int argc, char **argv)
> > > AVPacket pkt;
> > > const char *in_filename, *out_filename;
> > > int ret, i;
> > > + int stream_index = 0;
> > > + int *stream_mapping = NULL;
> > > + int stream_mapping_size = 0;
> > >
> > > if (argc < 3) {
> > > printf("usage: %s input output\n"
> > > @@ -83,25 +86,48 @@ int main(int argc, char **argv)
> > > goto end;
> > > }
> > >
> > > + stream_mapping_size = ifmt_ctx->nb_streams;
> > > + stream_mapping = av_mallocz_array(stream_mapping_size,
> > > sizeof(*stream_mapping));
> > > + if (!stream_mapping) {
> > > + ret = AVERROR(ENOMEM);
> > > + goto end;
> > > + }
> > > +
> > > ofmt = ofmt_ctx->oformat;
> > >
> > > for (i = 0; i < ifmt_ctx->nb_streams; i++) {
> > > + AVStream *out_stream;
> > > AVStream *in_stream = ifmt_ctx->streams[i];
> > > - AVStream *out_stream = avformat_new_stream(ofmt_ctx,
> > > in_stream->codec->codec);
> > > + AVCodecParameters *in_codecpar = in_stream->codecpar;
> > > +
> > > + if (in_codecpar->codec_type != AVMEDIA_TYPE_AUDIO &&
> > > + in_codecpar->codec_type != AVMEDIA_TYPE_VIDEO &&
> > > + in_codecpar->codec_type != AVMEDIA_TYPE_SUBTITLE) {
> > > + stream_mapping[i] = -1;
> > > + continue;
> > > + }
> > > +
> > > + stream_mapping[i] = stream_index++;
> > > +
> > > + out_stream = avformat_new_stream(ofmt_ctx, NULL);
> > > if (!out_stream) {
> > > fprintf(stderr, "Failed allocating output stream\n");
> > > ret = AVERROR_UNKNOWN;
> > > goto end;
> > > }
> > >
> > > - ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
> > > + ret = avcodec_parameters_copy(out_stream->codecpar, in_codecpar);
> > > if (ret < 0) {
> > > - fprintf(stderr, "Failed to copy context from input to output
> > > stream codec context\n");
> > > + fprintf(stderr, "Failed to copy copy codec parameters\n");
> > > + goto end;
> > > + }
> > > + out_stream->codecpar->codec_tag = 0;
> > > +
> > > + ret = avformat_transfer_internal_stream_timing_info(ofmt,
> > > out_stream, in_stream, AVFMT_TBCF_AUTO);
> > > + if (ret < 0) {
> > > + fprintf(stderr, "Failed to copy stream timing info\n");
> > > goto end;
> > > }
> > > - out_stream->codec->codec_tag = 0;
> > > - if (ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
> > > - out_stream->codec->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
> > > }
> > > av_dump_format(ofmt_ctx, 0, out_filename, 1);
> > >
> > > @@ -127,8 +153,14 @@ int main(int argc, char **argv)
> > > break;
> > >
> > > in_stream = ifmt_ctx->streams[pkt.stream_index];
> > > - out_stream = ofmt_ctx->streams[pkt.stream_index];
> > > + if (pkt.stream_index >= stream_mapping_size ||
> > > + stream_mapping[pkt.stream_index] < 0) {
> > > + av_packet_unref(&pkt);
> > > + continue;
> > > + }
> > >
> > > + pkt.stream_index = stream_mapping[pkt.stream_index];
> > > + out_stream = ofmt_ctx->streams[pkt.stream_index];
> > > log_packet(ifmt_ctx, &pkt, "in");
> > >
> > > /* copy packet */
> > > @@ -156,6 +188,8 @@ end:
> > > avio_closep(&ofmt_ctx->pb);
> > > avformat_free_context(ofmt_ctx);
> > >
> > > + av_freep(&stream_mapping);
> > > +
> > > if (ret < 0 && ret != AVERROR_EOF) {
> > > fprintf(stderr, "Error occurred: %s\n", av_err2str(ret));
> > > return 1;
> > > --
> > > 2.12.0
> > >
> > >
> > Patch pushed (taking into account wm4 and Moritz reviews).
>
> This changes timestamps and durations
> ./ffmpeg -i matrixbench_mpeg2.mpg -t 10 -vcodec copy -acodec copy ref.mpg
> doc/examples/remuxing ref.mpg old.mp4 >& OLD
> ...
> doc/examples/remuxing ref.mpg new.mp4 >& NEW
>
> ...
> in: pts:48600 pts_time:0.54 dts:48600 dts_time:0.54 duration:2160 duration_time:0.024 stream_index:1
> out: pts:25920 pts_time:0.54 dts:25920 dts_time:0.54 duration:1152 duration_time:0.024 stream_index:1
> in: pts:48600 pts_time:0.54 dts:45000 dts_time:0.5 duration:3600 duration_time:0.04 stream_index:0
> -out: pts:6912 pts_time:0.54 dts:6400 dts_time:0.5 duration:512 duration_time:0.04 stream_index:0
> +out: pts:48600 pts_time:0.54 dts:45000 dts_time:0.5 duration:3600 duration_time:0.04 stream_index:0
> in: pts:NOPTS pts_time:NOPTS dts:48600 dts_time:0.54 duration:3600 duration_time:0.04 stream_index:0
> -out: pts:NOPTS pts_time:NOPTS dts:6912 dts_time:0.54 duration:512 duration_time:0.04 stream_index:0
> +out: pts:NOPTS pts_time:NOPTS dts:48600 dts_time:0.54 duration:3600 duration_time:0.04 stream_index:0
> in: pts:52200 pts_time:0.58 dts:52200 dts_time:0.58 duration:3600 duration_time:0.04 stream_index:0
> -out: pts:7424 pts_time:0.58 dts:7424 dts_time:0.58 duration:512 duration_time:0.04 stream_index:0
> +out: pts:52200 pts_time:0.58 dts:52200 dts_time:0.58 duration:3600 duration_time:0.04 stream_index:0
> in: pts:55800 pts_time:0.62 dts:55800 dts_time:0.62 duration:3600 duration_time:0.04 stream_index:0
> -out: pts:7936 pts_time:0.62 dts:7936 dts_time:0.62 duration:512 duration_time:0.04 stream_index:0
> +out: pts:55800 pts_time:0.62 dts:55800 dts_time:0.62 duration:3600 duration_time:0.04 stream_index:0
> in: pts:50760 pts_time:0.564 dts:50760 dts_time:0.564 duration:2160 duration_time:0.024 stream_index:1
> out: pts:27072 pts_time:0.564 dts:27072 dts_time:0.564 duration:1152 duration_time:0.024 stream_index:1
>
> is this intended ?
The new code makes the output stream time base matches the input stream
one.
In this case, it matches 1/90000, making the output pts/duration match
the input ones. The output dst_time/duration_time matches the input
ones and matches the values we got before the patch applied.
Unless I miss something here, the new values are correct.
Matthieu
More information about the ffmpeg-devel
mailing list