Hi,

I am new in using libav and cannot find a solution to my problem. We have a
server program that can capture video from webcam and save the stream into
an flv file (on linux). This program was not written by us, we cannot modify
it. My task is to write a program that listens to a target directory, and if
new flv file appears, start processing it immediately. I use libavformat and
libavcodec to read from flv and decode frames.

The problem is that I start reading the flv file before it is finished. When
av_read_frame reaches EOF, it will not continue any more, even if new data
arrive later. This is because av_find_stream_info reads the packets into a
buffer at the beginning (when the flv file is small), and when the end of
this buffer is reached, it is not updated, no new data are added to it. I
did not find the solution how to update the buffer, or how to treat the file
as an endless stream.

The corresponding part of my code is attached.

Thanks for help in advance,
Zsolt
bool FrameManager::open(const char *video)
{
  // Open video file
  if (avformat_open_input(&m_pFormatCtx, video, NULL, NULL) != 0)
  {
    cerr << "Error: [" << video << "] cannot open to read" << endl;
    return false;
  }

  // Retrieve stream information
  if (av_find_stream_info(m_pFormatCtx) < 0)
  {
    cerr << "Error: [" << video << "] cannot find stream information" << endl;
    return false;
  }

  // Dump information about file onto standard error
  //dump_format(pFormatCtx, 0, video, false);

  // Find the first video stream
  m_videoStream = -1;
  for (uint i = 0; i < m_pFormatCtx->nb_streams; ++i)
    if(m_pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
    {
      m_videoStream = i;
      break;
    }
  if (m_videoStream == -1)
  {
    cerr << "Error: [" << video << "] cannot find a video stream" << endl;
    return false;
  }

  // Get a pointer to the codec context for the video stream
  m_pCodecCtx = m_pFormatCtx->streams[m_videoStream]->codec;

  // Find the decoder for the video stream
  m_pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);
  if (m_pCodec == NULL)
  {
    cerr << "Error: [" << video << "] codec not found" << endl;
    return false;
  }

  // Open codec
  if (avcodec_open(m_pCodecCtx, m_pCodec)<0)
  {
    cerr << "Error: [" << video << "] cannot open codec" << endl;
    return false;
  }

  // Hack to correct wrong frame rates that seem to be generated by some codecs
  if (m_pCodecCtx->time_base.num > 1000 && m_pCodecCtx->time_base.den == 1)
    m_pCodecCtx->time_base.den = 1000;

  return true;
}


bool FrameManager::getNextFrame(Frame &frame, bool &eof)
{
  // Allocate video frame
  AVFrame *pFrame = avcodec_alloc_frame();

  // Allocate an AVFrame structure
  AVFrame *pFrameRGB = avcodec_alloc_frame();
  if (!pFrame || !pFrameRGB)
  {
    cerr << "Error: cannot allocate AVFrame structure" << endl;
    return false;
  }

  // Determine required buffer size and allocate buffer
  int numBytes = avpicture_get_size(PIX_FMT_RGB24, 
				    m_pCodecCtx->width, m_pCodecCtx->height);

  uint8_t *buffer = new uint8_t[numBytes];

  // Assign appropriate parts of buffer to image planes in pFrameRGB
  avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24,
		 m_pCodecCtx->width, m_pCodecCtx->height);

  AVPacket packet;

  bool reterror = false;
  while (true)
  {
    int ret = av_read_frame(m_pFormatCtx, &packet);

    if (ret < 0)
    {
      // error or end of file
      if (ret == AVERROR_EOF)
	eof = true;
      else
	reterror = true;

      break;
    }

    // ... do something useful with the packet ...

    av_free_packet(&packet);

    break;
  }

  delete [] buffer;
  av_free(pFrameRGB);
  av_free(pFrame);
  
  return !reterror;
}


void FrameManager::close()
{
  // Close the codec
  avcodec_close(m_pCodecCtx);

  // Close the video file
  av_close_input_file(m_pFormatCtx);

  m_pFormatCtx = NULL;
  m_pCodecCtx = NULL;
  m_pCodec = NULL;
}



_______________________________________________
libav-api mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-api

Reply via email to