[FFmpeg-devel] Why created mp4 file from another mp4 file plays only 90ms instead of 7sec as the source?

Morduhaev, Igor (igorm@stats.com) igorm at stats.com
Wed Nov 14 14:21:32 CET 2012


 I started learning ffmpeg and for practice I use the following code to just save all frames of 1st video stream from inFileName to outFileName without reencoding.
At first sight it success , but the out.mp4 plays only 90ms instead of 7 seconds as the source(myfile.mp4). I checked the fps of the output file and it shows 533fps instead 25fps as in original mp4.

Any suggesting why it happens?


const char* inFileName = "C:\\myfile.mp4";

    const char* outFileName = "c:\\out.mp4";

    const char* outFileType = "mp4";



    av_register_all();



    AVFormatContext* inFormatCtx = NULL;

    int err = avformat_open_input(&inFormatCtx, inFileName, NULL, NULL);

    if (err < 0) exit(1);



    err = av_find_stream_info(inFormatCtx);

    if (err < 0) exit(1);



    // Find video stream

    int videoStreamIndex = -1;

    for (unsigned int i = 0; i < inFormatCtx->nb_streams; ++i)

    {

            if (inFormatCtx->streams[i] && inFormatCtx->streams[i]->codec &&

                           inFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)

            {

                   videoStreamIndex = i;

                   break;

            }

    }

    if (videoStreamIndex == -1) exit(1);



    AVOutputFormat* outFormat = av_guess_format(outFileType, NULL, NULL);

    if (!outFormat) exit(1);



    AVFormatContext* outFormatCtx = NULL;

    err = avformat_alloc_output_context2(&outFormatCtx, outFormat, NULL, NULL);

    if (err < 0 || !outFormatCtx) exit(1);



    err = avio_open(&outFormatCtx->pb, outFileName, AVIO_FLAG_WRITE);

    if (err < 0) exit(1);



    // Create and initiate output stream

    AVStream* outStream = av_new_stream(outFormatCtx, 0);

    AVStream const* const inStream = inFormatCtx->streams[videoStreamIndex];

    AVCodec* codec = NULL;

    avcodec_get_context_defaults3(outStream->codec, inStream->codec->codec);



    outStream->codec->coder_type = AVMEDIA_TYPE_VIDEO;

    outStream->codec->sample_aspect_ratio = outStream->sample_aspect_ratio = inStream->sample_aspect_ratio;

    outStream->disposition = inStream->disposition;

    outStream->codec->bits_per_raw_sample = inStream->codec->bits_per_raw_sample;

    outStream->codec->chroma_sample_location = inStream->codec->chroma_sample_location;

    outStream->codec->codec_id = inStream->codec->codec_id;

    outStream->codec->codec_type = inStream->codec->codec_type;

    outStream->codec->bit_rate = inStream->codec->bit_rate;

    outStream->codec->rc_max_rate = inStream->codec->rc_max_rate;

    outStream->codec->rc_buffer_size = inStream->codec->rc_buffer_size;



    if (!outStream->codec->codec_tag)

    {

        if (! outFormatCtx->oformat->codec_tag

            || av_codec_get_id (outFormatCtx->oformat->codec_tag, inStream->codec->codec_tag) == outStream->codec->codec_id

            || av_codec_get_tag(outFormatCtx->oformat->codec_tag, inStream->codec->codec_id) <= 0)

                   outStream->codec->codec_tag = inStream->codec->codec_tag;

    }



    size_t extra_size_alloc = (inStream->codec->extradata_size > 0) ? (inStream->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE) : 0;

    if (extra_size_alloc)

    {

            outStream->codec->extradata = (uint8_t*)av_malloc(extra_size_alloc);

            memcpy(outStream->codec->extradata, inStream->codec->extradata, inStream->codec->extradata_size);

    }

    outStream->codec->extradata_size = inStream->codec->extradata_size;



    AVRational input_time_base = inStream->time_base;

    AVRational frameRate;

    frameRate.num = inStream->r_frame_rate.num;

    frameRate.den = inStream->r_frame_rate.den;



    outStream->r_frame_rate = frameRate;

    outStream->codec->time_base = inStream->codec->time_base;

    outStream->codec->pix_fmt = inStream->codec->pix_fmt;

    outStream->codec->width = inStream->codec->width;

    outStream->codec->height = inStream->codec->height;

    outStream->codec->has_b_frames = inStream->codec->has_b_frames;

    if (!outStream->codec->sample_aspect_ratio.num)

    {

            AVRational r0 = {0, 1};

            outStream->codec->sample_aspect_ratio = outStream->sample_aspect_ratio = inStream->sample_aspect_ratio.num ? inStream->sample_aspect_ratio :

                                                                                     inStream->codec->sample_aspect_ratio.num ? inStream->codec->sample_aspect_ratio : r0;

    }



    avformat_write_header(outFormatCtx, NULL);



    AVPacket packet;

    while(av_read_frame(inFormatCtx, &packet)>=0)

    {

            if (packet.stream_index == videoStreamIndex)

            {

                   err = av_interleaved_write_frame(outFormatCtx, &packet);

                   if (err < 0) exit(1);

            }



            av_free_packet(&packet);

    }



    av_write_trailer(outFormatCtx);

    avio_close(outFormatCtx->pb);



    avformat_free_context(outFormatCtx);

    av_close_input_file(inFormatCtx);



More information about the ffmpeg-devel mailing list