[Libav-user] fps porblem when saving video in mp4 container

Morduhaev, Igor (igorm@stats.com) igorm at stats.com
Thu Nov 22 12:30:21 CET 2012


When I decode frames from avi file and then decode them in x264 and save to mp4 file, the fps of the output file is always 12,800. Therefore the file is played very fast.

What could be the problem?

Thank you

const char* inFileName = "C:\\000227_C1_GAME.avi";
       const char* outFileName = "c:\\test.mp4";
       const char* outFileType = "mp4";

       av_register_all();

       AVFormatContext* inContainer = NULL;
       if(avformat_open_input(&inContainer, inFileName, NULL, NULL) < 0)
              exit(1);

       if(avformat_find_stream_info(inContainer, NULL) < 0)
              exit(1);

       // Find video stream
       int videoStreamIndex = -1;
       for (unsigned int i = 0; i < inContainer->nb_streams; ++i)
       {
              if (inContainer->streams[i] && inContainer->streams[i]->codec &&
                     inContainer->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
              {
                     videoStreamIndex = i;
                     break;
              }
       }
       if (videoStreamIndex == -1) exit(1);

       AVFormatContext* outContainer = NULL;
       if(avformat_alloc_output_context2(&outContainer, NULL, outFileType, outFileName) < 0)
              exit(1);

       // ----------------------------
       // Decoder
       // ----------------------------
       AVStream const *const inStream = inContainer->streams[videoStreamIndex];
       AVCodec *const decoder = avcodec_find_decoder(inStream->codec->codec_id);
       if(!decoder)
              exit(1);
       if(avcodec_open2(inStream->codec, decoder, NULL) < 0)
              exit(1);

       // ----------------------------
       // Encoder
       // ----------------------------
       AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_H264);
       if(!encoder)
              exit(1);
       AVStream *outStream = avformat_new_stream(outContainer, encoder);
       if(!outStream)
              exit(1);

       avcodec_get_context_defaults3(outStream->codec, encoder);

       // Construct encoder
       if(outContainer->oformat->flags & AVFMT_GLOBALHEADER)
              outStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;

       outStream->codec->coder_type = AVMEDIA_TYPE_VIDEO;
       outStream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
       outStream->codec->width = inStream->codec->width;
       outStream->codec->height = inStream->codec->height;
       outStream->codec->codec_id = encoder->id;
       outStream->codec->bit_rate = 400000;
       outStream->codec->time_base.den = 25;
       outStream->codec->time_base.num = 1;
       outStream->codec->gop_size = 250; // Keyframe interval(=GOP length). Determines maximum distance distance between I-frames
       outStream->codec->keyint_min = 25; // minimum GOP size
       outStream->codec->max_b_frames = 16; // maximum number of B-frames between non-B-frames
       outStream->codec->b_frame_strategy = 1; // decides the best number of B-frames to use. Default mode in x264.
       outStream->codec->scenechange_threshold = 40;
       outStream->codec->refs = 6; // abillity to reference frames other than the one immediately prior to the current frame. specify how many references can be used.
       outStream->codec->qmin = 10;
       outStream->codec->qmax = 51;
       outStream->codec->i_quant_factor = 0.71;

       if(outStream->codec->codec_id == AV_CODEC_ID_H264)
        av_opt_set(outStream->codec->priv_data, "preset", "slow", 0);

       // Open encoder
       if(avcodec_open2(outStream->codec, encoder, NULL) < 0)
              exit(1);

       // Open output container
       if(avio_open(&outContainer->pb, outFileName, AVIO_FLAG_WRITE) < 0)
              exit(1);

       AVFrame *decodedFrame = avcodec_alloc_frame();
       if(!decodedFrame)
              exit(1);
       AVFrame *encodeFrame = avcodec_alloc_frame();
       if(!encodeFrame)
              exit(1);
       encodeFrame->format = outStream->codec->pix_fmt;
       encodeFrame->width = outStream->codec->width;
       encodeFrame->height = outStream->codec->height;
       if(av_image_alloc(encodeFrame->data, encodeFrame->linesize,
                                    outStream->codec->width, outStream->codec->height,
                                    outStream->codec->pix_fmt, 1) < 0)
              exit(1);

       av_dump_format(inContainer, 0, inFileName,0);

       //Write header to ouput container
       avformat_write_header(outContainer, NULL);

       AVPacket decodePacket, encodedPacket;
       int got_frame, len;
       while(av_read_frame(inContainer, &decodePacket)>=0)
       {
              if (decodePacket.stream_index == videoStreamIndex)
              {
                     len = avcodec_decode_video2(inStream->codec, decodedFrame, &got_frame, &decodePacket);
                     if(len < 0)
                           exit(1);
                     if(got_frame)
                     {
                           av_init_packet(&encodedPacket);
                           encodedPacket.data = NULL;
                           encodedPacket.size = 0;
                           if(avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame) < 0)
                                  exit(1);
                           if(got_frame)
                           {
                                  if (outStream->codec->coded_frame->key_frame)
                                         encodedPacket.flags |= AV_PKT_FLAG_KEY;

                                  encodedPacket.stream_index = outStream->index;

                                  if(av_interleaved_write_frame(outContainer, &encodedPacket) < 0)
                                         exit(1);

                                  av_free_packet(&encodedPacket);
                           }
                     }
              }

              av_free_packet(&decodePacket);
       }
       av_write_trailer(outContainer);
       avio_close(outContainer->pb);

       avcodec_free_frame(&encodeFrame);
       avcodec_free_frame(&decodedFrame);

       avformat_free_context(outContainer);
       av_close_input_file(inContainer);

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://ffmpeg.org/pipermail/libav-user/attachments/20121122/dc10f0a4/attachment.html>


More information about the Libav-user mailing list