[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