Hi All,<div><br></div><div>I'm new to FFmpeg programming and I'm having a strange issue with H264 file framerates.</div><div><br></div><div>I'm simply trying to capture video from an NTSC camera using a Matrox capture card.  I wrote a simple application to capture 10 seconds of video to an MP4 file.  The program works, sort of.  I get an MP4 file but it plays very quickly.  If I look at the details of the file the framerate is somewhere in the thousands (it changes based on the number of frames I capture, which is also strange).</div>
<div><br></div><div>I'm using Win7/64 with FFmpeg compiled with MinGW64.  I've tried the pre-built binaries from zeranoe with the same results.</div><div><br></div><div>Here's the code:</div><div><br></div><div>
<div>#include <mil.h></div><div>#include <iostream></div><div>extern "C"</div><div>{</div><div>  #include <libavformat/avformat.h></div><div>  #include <libswscale/swscale.h></div><div>  #include <libavutil/imgutils.h></div>
<div>}</div><div><br></div><div>using namespace std;</div><div><br></div><div>const unsigned long RGB_BUFFER_SIZE = 640 * 480 * 3;</div><div><br></div><div>MIL_ID          mil_buffers[10];</div><div>unsigned char   *p_raw_buffer;</div>
<div>SwsContext      *p_sws_context;</div><div>AVFrame         *p_out_frame;</div><div>AVFormatContext *p_format_context;</div><div>AVStream        *p_output_stream;</div><div><br></div><div>static MIL_INT MFTYPE hook_handler(MIL_INT hook_type, MIL_ID event_id, void MPTYPE *p_user_data)</div>
<div>{</div><div>  static unsigned long count = 0;</div><div><br></div><div>  AVPicture picture_in;</div><div>  AVPacket  pkt;</div><div>  int       got_packet_ptr;</div><div><br></div><div>  // get frame into BGR buffer</div>
<div>  MIL_ID current_buf;</div><div>  MdigGetHookInfo(event_id, M_MODIFIED_BUFFER+M_BUFFER_ID, &current_buf);</div><div>  MbufGetColor(current_buf, M_PACKED+M_BGR24, M_ALL_BANDS, p_raw_buffer);</div><div><br></div><div>
  // fill the input picture with the BGR data and convert it to YUV420P</div><div>  avpicture_fill(&picture_in, p_raw_buffer, PIX_FMT_BGR24, 640, 480);</div><div>  sws_scale(p_sws_context, picture_in.data, picture_in.linesize, 0, 480, p_out_frame->data, p_out_frame->linesize);</div>
<div><br></div><div>  av_init_packet(&pkt);</div><div>  AVCodecContext *p_codec_context = p_output_stream->codec;</div><div>  pkt.data = NULL;</div><div>  pkt.size = 0;</div><div>  p_out_frame->pts = count;</div>
<div>  int result = avcodec_encode_video2(p_codec_context, &pkt, p_out_frame, &got_packet_ptr);</div><div>  if (result < 0)</div><div>  {</div><div>    cout << "Error encoding frame." << endl;</div>
<div>  }</div><div>  if (got_packet_ptr)</div><div>  {</div><div>    av_interleaved_write_frame(p_format_context, &pkt);</div><div>  }</div><div><br></div><div>  ++count;</div><div><br></div><div>  return M_NULL;</div>
<div>} // hook_handler</div><div><br></div><div>int</div><div>main(int argc, char *argv[])</div><div>{</div><div>  // MIL setup</div><div>  MIL_ID mil_app  = MappAlloc(M_DEFAULT, M_NULL);</div><div>  MIL_ID mil_sys  = MsysAlloc(M_SYSTEM_MORPHIS, M_DEFAULT, M_DEFAULT, M_NULL);</div>
<div>  MIL_ID mil_dig  = MdigAlloc(mil_sys, M_DEFAULT, MIL_TEXT("M_NTSC"), M_DEFAULT, M_NULL);</div><div>  for (int x = 0; x < 10; ++x)</div><div>  {</div><div>    MbufAllocColor(mil_sys, 3, 640, 480, M_UNSIGNED+8, M_IMAGE+M_GRAB, &mil_buffers[x]);</div>
<div>  }</div><div>  p_raw_buffer = new unsigned char[RGB_BUFFER_SIZE];</div><div>  MdigChannel(mil_dig, M_CH4);</div><div><br></div><div>  // FFmpeg setup</div><div>  av_register_all();</div><div><br></div><div>  // get the scaling context to transform input image to YUV420P</div>
<div>  p_sws_context = sws_getContext(640, 480, PIX_FMT_BGR24, 640, 480, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);</div><div><br></div><div>  // allocate the output frame</div><div>  p_out_frame = avcodec_alloc_frame();</div>
<div>  p_out_frame->format = PIX_FMT_YUV420P;</div><div>  p_out_frame->width  = 640;</div><div>  p_out_frame->height = 480;</div><div>  av_image_alloc(p_out_frame->data, p_out_frame->linesize, 640, 480, PIX_FMT_YUV420P, 1);</div>
<div>  p_out_frame->pts = 0;</div><div>  </div><div>  // allocate the output format context</div><div>  avformat_alloc_output_context2(&p_format_context, NULL, NULL, "test.mp4");</div><div>  </div><div>  AVOutputFormat *p_output_format = p_format_context->oformat;</div>
<div><br></div><div>  AVCodec *p_codec = avcodec_find_encoder(CODEC_ID_H264);</div><div><br></div><div>  // format the output video stream</div><div>  p_output_stream = avformat_new_stream(p_format_context, p_codec);</div>
<div><br></div><div>  AVCodecContext *p_codec_context = p_output_stream->codec;</div><div><br></div><div>  // set up the codec context</div><div>  avcodec_get_context_defaults3(p_codec_context, p_codec);</div><div>  p_codec_context->codec_id = CODEC_ID_H264;</div>
<div>  p_codec_context->bit_rate = 400000;</div><div>  p_codec_context->width = 640;</div><div>  p_codec_context->height = 480;</div><div>  p_codec_context->qmin = 10;</div><div>  p_codec_context->qmax = 42;</div>
<div>  p_codec_context->time_base.den = 30;</div><div>  p_codec_context->time_base.num = 1;</div><div>  p_codec_context->gop_size = 10;</div><div>  p_codec_context->pix_fmt = PIX_FMT_YUV420P;</div><div>  p_codec_context->ticks_per_frame = 2;</div>
<div>  p_codec_context->flags |= CODEC_FLAG_GLOBAL_HEADER;</div><div><br></div><div>  // open the codec context</div><div>  avcodec_open2(p_codec_context, p_codec, NULL);</div><div><br></div><div>  // open the io context</div>
<div>  avio_open2(&p_format_context->pb, "test.mp4", AVIO_FLAG_WRITE, NULL, NULL);</div><div><br></div><div>  av_dump_format(p_format_context, 0, "test.mp4", 1);</div><div><br></div><div>  // write the file header</div>
<div>  avformat_write_header(p_format_context, NULL);</div><div><br></div><div>  // process 300 frames (10 seconds of video)</div><div>  cout << "Starting processing..." << endl << endl;  </div>
<div>  MdigProcess(mil_dig, mil_buffers, 9, M_SEQUENCE+M_COUNT(300), M_DEFAULT, hook_handler, M_NULL);</div><div>  cout << endl << "Processing done." << endl << "Press any key to continue...";</div>
<div><br></div><div>  // flush the (possibly) buffered frames to the output file</div><div>  int      got_packet_ptr;</div><div>  do</div><div>  {</div><div>    AVPacket pkt;</div><div>    pkt.data = NULL;</div><div>    pkt.size = 0;</div>
<div>    int result = avcodec_encode_video2(p_codec_context, &pkt, NULL, &got_packet_ptr);</div><div>    if (result < 0)</div><div>    {</div><div>      cout << "Error encoding frame." << endl;</div>
<div>    }</div><div>    if (got_packet_ptr)</div><div>    {</div><div>      av_interleaved_write_frame(p_format_context, &pkt);</div><div>      av_free_packet(&pkt);</div><div>    }</div><div>  } while (got_packet_ptr);</div>
<div><br></div><div>  // write the file trailer</div><div>  av_write_trailer(p_format_context);</div><div><br></div><div>  // clean up</div><div>  avformat_free_context(p_format_context);</div><div>  av_freep(&p_out_frame->data[0]);</div>
<div>  av_free(p_out_frame);</div><div>  sws_freeContext(p_sws_context);</div><div><br></div><div>  delete [] p_raw_buffer;</div><div>  for (int x = 0; x < 10; ++x)</div><div>  {</div><div>    MbufFree(mil_buffers[x]);</div>
<div>  }</div><div>  MdigFree(mil_dig);</div><div>  MsysFree(mil_sys);</div><div>  MappFree(mil_app);</div><div><br></div><div>  getchar();</div><div>  return 0;</div><div>} // main</div></div><div><br></div><div>Any help would be greatly appreciated.</div>
<div><br></div><div>Thanks,</div><div>Noah</div><div><br></div>