Transcode with the some properties

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Transcode with the some properties

NDJORE 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.
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
_______________________________________________
ffmpeg-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Transcode with the some properties

Moritz Barsnick
Hi Boris,

On Mon, Nov 04, 2019 at 10:29:10 +0100, Boris wrote:
> 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 :

This list (ffmpeg-users) is primarily for the use of the command line
tool. For assistance with programming with the libav* libraries, please
refer to the mailing list libav-user:
https://ffmpeg.org/mailman/listinfo/libav-user

Also please note that your code was wrapped in a fashion making it hard
to read:

http://ffmpeg.org/pipermail/ffmpeg-user/2019-November/045902.html

You may want to avoid line breaks in your mailer, or attach a text file instead.

> But when I run exiftool on output  video and on input video, some values
> like video duration, encoder, bit rate,  are differente.
> Can someone tells me how can I do to keep the same parameters (metada) of
> the input video in the output video, please?

What are you exactly trying to achieve? If you want *exactly* the same
characteristics, you should probably just copy the stream (and the
metadata) instead of re-encoding.

Duration and bitrate are not metadata.

The encoder (metadata) will be different, because it is a different
encoder. ;-) You can manipulate the metadata though.

If you correctly determine the source's bitrate, you should be able to
set it for the encoding, and depending on the encoder, you may achieve
the exact same rate.

But the input stream may have more characteristics, such as:
- VBR,
- GOP size, or even
- placement of I-frames,
- use of B-frames
and so on. Which of these do you want to duplicate, which not? And why?

If you specify your actual needs more precisely, it may be easier to
come up with a recipe to fulfill them. On the other list, of course.
;-)

Cheers,
Moritz
_______________________________________________
ffmpeg-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: Transcode with the some properties

NDJORE BORIS
Hello Mortiz,

Le lun. 4 nov. 2019 à 17:23, Moritz Barsnick <[hidden email]> a écrit :

> Hi Boris,
>
> On Mon, Nov 04, 2019 at 10:29:10 +0100, Boris wrote:
> > 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 :
>
> This list (ffmpeg-users) is primarily for the use of the command line
> tool. For assistance with programming with the libav* libraries, please
> refer to the mailing list libav-user:
> https://ffmpeg.org/mailman/listinfo/libav-user
>
> Also please note that your code was wrapped in a fashion making it hard
> to read:
>
http://ffmpeg.org/pipermail/ffmpeg-user/2019-November/045902.html
>
> You may want to avoid line breaks in your mailer, or attach a text file
> instead.
>

Thank you. I will take into account your comments and suggestions .

>
> > But when I run exiftool on output  video and on input video, some values
> > like video duration, encoder, bit rate,  are differente.
> > Can someone tells me how can I do to keep the same parameters (metada) of
> > the input video in the output video, please?
>
> What are you exactly trying to achieve? If you want *exactly* the same
> characteristics, you should probably just copy the stream (and the
> metadata) instead of re-encoding.
>

My aim is  to manipulate motion vectors (+- operation) while transcoding.
But I want that the output video has as much as possible the same
properties as the output video.

>
> Duration and bitrate are not metadata.
>

Ok :).

>
> The encoder (metadata) will be different, because it is a different
> encoder. ;-) You can manipulate the metadata though.
>

Can you tell me how can I perform that ?

>
> If you correctly determine the source's bitrate, you should be able to
> set it for the encoding, and depending on the encoder, you may achieve
> the exact same rate.
>
> But the input stream may have more characteristics, such as:
> - VBR,
> - GOP size, or even
> - placement of I-frames,
> - use of B-frames
> and so on. Which of these do you want to duplicate, which not? And why?
>
> If you specify your actual needs more precisely, it may be easier to
> come up with a recipe to fulfill them. On the other list, of course.
> ;-)
>

Thank you so much. .

>
> Cheers,
> Moritz
>

Regards

> _______________________________________________
> ffmpeg-user mailing list
> [hidden email]
> https://ffmpeg.org/mailman/listinfo/ffmpeg-user
>
> To unsubscribe, visit link above, or email
> [hidden email] with subject "unsubscribe".
_______________________________________________
ffmpeg-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/ffmpeg-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".