[Libav-user] Transcode with the some properties

Boris ndjoreboris at gmail.com
Mon Nov 4 13:22:32 EET 2019


Le lun. 4 nov. 2019 à 11:47, Andrew Randrianasulu <randrianasulu at gmail.com>
a écrit :

> В сообщении от Monday 04 November 2019 12:29:10 Boris написал(а):
> > Hello,
> > I want to transcode video with exactly the same properties of the input
> > video in the output video.
> > I use the transcoding.cc code. In the static int open_output_file(const
> > char *filename) function, I set  encoder parameters like this :
> >
> > if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
> >                         {
> >                                 enc_ctx->height = dec_ctx->height;
> >                                 enc_ctx->width = dec_ctx->width;
> >                                 enc_ctx->sample_aspect_ratio =
> > dec_ctx->sample_aspect_ratio;
> >
> > enc_ctx->global_quality=dec_ctx->global_quality;
> >                                 enc_ctx->gop_size=dec_ctx->gop_size;
> >                                 enc_ctx->bit_rate=dec_ctx->bit_rate;
> >                                 enc_ctx->time_base=dec_ctx->time_base;
> >                                 enc_ctx->delay=dec_ctx->delay;
> >
> > //**********************************************
> >
>  enc_ctx->rc_max_rate=dec_ctx->rc_max_rate;
> >
>  enc_ctx->rc_min_rate=dec_ctx->rc_min_rate;
> >                                 /* take first format from list of
> supported
> > formats */
> >                                 if (encoder->pix_fmts)
> >                                 {
> >                                         enc_ctx->pix_fmt =
> > encoder->pix_fmts[0];
> >                                 }
> >                                 else
> >                                 {
> >                                         enc_ctx->pix_fmt =
> dec_ctx->pix_fmt;
> >                                 }
> >                                 // video time_base can be set to whatever
> > is handy and supported by encoder
> >                                 // enc_ctx->time_base =
> > av_inv_q(dec_ctx->framerate);
> >                         }
> >                         else
> >                         {
> >                                 enc_ctx->sample_rate =
> dec_ctx->sample_rate;
> >                                 enc_ctx->channel_layout =
> > dec_ctx->channel_layout;
> >                                 enc_ctx->channels =
> > av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
> >                                 /* take first format from list of
> supported
> > formats */
> >                                 enc_ctx->sample_fmt =
> > encoder->sample_fmts[0];
> >                                 enc_ctx->time_base = (AVRational){1,
> > enc_ctx->sample_rate};
> >                         }
> >                         /* Third parameter can be used to pass settings
> to
> > encoder */
> >                         ret = avcodec_open2(enc_ctx, encoder, NULL);
> >                         if (ret < 0)
> >                         {
> >                                 av_log(NULL, AV_LOG_ERROR, "Cannot open
> > video encoder for stream #%u\n", i);
> >                                 return ret;
> >                         }
> >                         ret =
> > avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
> >                         if (ret < 0)
> >                         {
> >                                 av_log(NULL, AV_LOG_ERROR, "Failed to
> copy
> > encoder parameters to output stream #%u\n", i);
> >                                 return ret;
> >                         }
> >                         if (ofmt_ctx->oformat->flags &
> AVFMT_GLOBALHEADER)
> >                                 enc_ctx->flags |=
> > AV_CODEC_FLAG_GLOBAL_HEADER;
> >
> >                         out_stream->time_base = enc_ctx->time_base;
> >
> >
> > But when I run exiftool on output  video and on input video, some values
> > like video duration, encoder, bit rate,  are differente.
>
> Hm, video duration chnage sounds like most unwelcome one ...
> But are codec parameters even supposed to be the same after different
> encoder run over output of another encoder?

I recall term 'bit exact', but is this applicable to re-encoding with lossy
> codecs?
>

I'm not sure but I thought it could be done. If you have things that I do
not know, do not hesitate to share them with me,please.

Regards

Hello

> > Can someone tells me how can I do to keep the same parameters (metada) of
> > the input video in the output video, please?
> >
> > The entire open_output_file function is the following :
> >
> > static int open_output_file(const char *filename)
> > {
> >          AVStream *out_stream;
> >         AVStream *in_stream;
> >         AVCodecContext *dec_ctx, *enc_ctx;
> >         AVCodec *encoder;
> >         int ret;
> >         unsigned int i;
> >         ofmt_ctx = NULL;
> >         avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, filename);
> >         if (!ofmt_ctx)
> >         {
> >                 av_log(NULL, AV_LOG_ERROR, "Could not create output
> > context\n");
> >                 return AVERROR_UNKNOWN;
> >         }
> >
> >         for (i = 0; i < ifmt_ctx->nb_streams; i++)
> >         {
> >                 out_stream = avformat_new_stream(ofmt_ctx, NULL);
> >                 if (!out_stream)
> >                 {
> >                         av_log(NULL, AV_LOG_ERROR, "Failed allocating
> > output stream\n");
> >                         return AVERROR_UNKNOWN;
> >                 }
> >
> >                 in_stream = ifmt_ctx->streams[i];
> >                 dec_ctx = stream_ctx[i].dec_ctx;
> >
> >                 if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO ||
> > dec_ctx->codec_type == AVMEDIA_TYPE_AUDIO)
> >                 {
> >                         //AVCodecID codec_id = dec_ctx->codec_type ==
> > AVMEDIA_TYPE_VIDEO ? AV_CODEC_ID_MPEG4:dec_ctx->codec_id;
> >                         /* in this example, we choose transcoding to same
> > codec */
> >                         //encoder = dec_ctx->codec_type ==
> > AVMEDIA_TYPE_VIDEO ?
> >
> avcodec_find_encoder(AV_CODEC_ID_H264):avcodec_find_encoder(dec_ctx->codec_id);//(AV_CODEC_ID_MPEG4):avcodec_find_encoder(dec_ctx->codec_id);
> >                         encoder = dec_ctx->codec_type ==
> AVMEDIA_TYPE_VIDEO
> > ?
> >
> avcodec_find_encoder(AV_CODEC_ID_MPEG4):avcodec_find_encoder(dec_ctx->codec_id);
> >                         // if(dec_ctx->codec_type ==
> >
> AVMEDIA_TYPE_VIDEO){encoder=avcodec_find_encoder(AV_CODEC_ID_MPEG4);}else{encoder=avcodec_find_encoder(dec_ctx->codec_id);}
> >                         //encoder =
> avcodec_find_encoder(dec_ctx->codec_id);
> >                         if (!encoder)
> >                         {
> >                                 av_log(NULL, AV_LOG_FATAL, "Necessary
> > encoder not found\n");
> >                                 return AVERROR_INVALIDDATA;
> >                         }
> >                         enc_ctx = avcodec_alloc_context3(encoder);
> >                         if (!enc_ctx)
> >                         {
> >                                 av_log(NULL, AV_LOG_FATAL, "Failed to
> > allocate the encoder context\n");
> >                                 return AVERROR(ENOMEM);
> >  }
> >
> >                         /* In this example, we transcode to same
> properties
> > (picture size,
> >                         * sample rate etc.). These properties can be
> > changed for output
> >                         * streams easily using filters */
> >                         if (dec_ctx->codec_type == AVMEDIA_TYPE_VIDEO)
> >                         {
> >                                 enc_ctx->height = dec_ctx->height;
> >                                 enc_ctx->width = dec_ctx->width;
> >                                 enc_ctx->sample_aspect_ratio =
> > dec_ctx->sample_aspect_ratio;
> >
> > enc_ctx->global_quality=dec_ctx->global_quality;
> >                                 enc_ctx->gop_size=dec_ctx->gop_size;
> >                                 enc_ctx->bit_rate=dec_ctx->bit_rate;
> >                                 enc_ctx->time_base=dec_ctx->time_base;
> >                                 enc_ctx->delay=dec_ctx->delay;
> >
> > //**********************************************
> >
>  enc_ctx->rc_max_rate=dec_ctx->rc_max_rate;
> >
>  enc_ctx->rc_min_rate=dec_ctx->rc_min_rate;
> >                                 /* take first format from list of
> supported
> > formats */
> >                                 if (encoder->pix_fmts)
> >                                 {
> >                                         enc_ctx->pix_fmt =
> > encoder->pix_fmts[0];
> >                                 }
> >                                 else
> >                                 {
> >                                         enc_ctx->pix_fmt =
> dec_ctx->pix_fmt;
> >                                 }
> >                                 // video time_base can be set to whatever
> > is handy and supported by encoder
> >                                 // enc_ctx->time_base =
> > av_inv_q(dec_ctx->framerate);
> >                         }
> >                         else
> >                         {
> >                                 enc_ctx->sample_rate =
> dec_ctx->sample_rate;
> >                                 enc_ctx->channel_layout =
> > dec_ctx->channel_layout;
> >                                 enc_ctx->channels =
> > av_get_channel_layout_nb_channels(enc_ctx->channel_layout);
> >                                 /* take first format from list of
> supported
> > formats */
> >                                 enc_ctx->sample_fmt =
> > encoder->sample_fmts[0];
> >                                 enc_ctx->time_base = (AVRational){1,
> > enc_ctx->sample_rate};
> >                         }
> >                         /* Third parameter can be used to pass settings
> to
> > encoder */
> >                         ret = avcodec_open2(enc_ctx, encoder, NULL);
> >                         if (ret < 0)
> >                         {
> >                                 av_log(NULL, AV_LOG_ERROR, "Cannot open
> > video encoder for stream #%u\n", i);
> >                                 return ret;
> >                         }
> >                         ret =
> > avcodec_parameters_from_context(out_stream->codecpar, enc_ctx);
> >                         if (ret < 0)
> >                         {
> >                                 av_log(NULL, AV_LOG_ERROR, "Failed to
> copy
> > encoder parameters to output stream #%u\n", i);
> >                                 return ret;
> >                         }
> >                         if (ofmt_ctx->oformat->flags &
> AVFMT_GLOBALHEADER)
> >  enc_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
> >
> >                         out_stream->time_base = enc_ctx->time_base;
> >                         stream_ctx[i].enc_ctx = enc_ctx;
> >                 }
> >                 else if (dec_ctx->codec_type == AVMEDIA_TYPE_UNKNOWN)
> >                 {
> >                         av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d
> > is of unknown type, cannot proceed\n", i);
> >                         return AVERROR_INVALIDDATA;
> >                 }
> >                 else
> >                 {
> >                         // if this stream must be remuxed
> >                         ret =
> avcodec_parameters_copy(out_stream->codecpar,
> > in_stream->codecpar);
> >                         //ifmt_ctx->streams[i]->codec);
> >                         if (ret < 0)
> >                         {
> >                                 av_log(NULL, AV_LOG_ERROR, "Copying
> > parameters for stream #%u failed\n", i);
> >                                 return ret;
> >                         }
> >                         out_stream->time_base = in_stream->time_base;
> >                 }
> >
> >         }
> >         av_dump_format(ofmt_ctx, 0, filename, 1);
> >
> >         if (!(ofmt_ctx->oformat->flags & AVFMT_NOFILE))
> >         {
> >                 ret = avio_open(&ofmt_ctx->pb, filename,
> AVIO_FLAG_WRITE);
> >                 if (ret < 0)
> >                 {
> >                         av_log(NULL, AV_LOG_ERROR, "Could not open output
> > file '%s'", filename);
> >                         return ret;
> >                 }
> >         }
> >
> >         /* init muxer, write output file header */
> >         ret = avformat_write_header(ofmt_ctx, NULL);
> >         if (ret < 0)
> >         {
> >                 av_log(NULL, AV_LOG_ERROR, "Error occurred when opening
> > output file\n");
> >                 return ret;
> >         }
> >         return 0;
> > }
> >
> > Rgards
> >
>
>
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> To unsubscribe, visit link above, or email
> libav-user-request at ffmpeg.org with subject "unsubscribe".
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20191104/8395d677/attachment.html>


More information about the Libav-user mailing list