FFMPEG I / O的自定义读取功能

时间:2015-09-19 02:36:09

标签: c++ c audio casting ffmpeg

我需要创建一个自定义阅读回调函数,该函数可以将std::string形式的文件内容读入uint8_t * buf。我尝试了在互联网和堆栈溢出周围找到的多种不同的方法,但有时它可以工作,其他程序无限循环或停止执行中途。

我对amr / 3gp文件没有任何问题,但是由于某种原因,所有wav / pcm文件都会导致一些问题。所有我都知道它与我到目前为止的阅读功能有关。

理想情况下,我希望能够为程序提供任何类型的文件,然后将其转换。

这就是我从代码中调用readCallback函数的方法:

//create the buffer
uint8_t * avio_ctx_buffer = NULL;

//allocate space for the buffer using ffmpeg allocation method
avio_ctx_buffer = (uint8_t *) av_malloc(avio_ctx_buffer_size);

//Allocate and initialize an AVIOContext for buffered I/O.
//audio variable contains the contents of the audio file
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,0, &audio, &readCallback, NULL, NULL);

以下是适用于某些类型文件的回调函数:

static int readCallback(void* opaque, uint8_t * buf, int buf_size){  
  std::string * file =static_cast<std::string *>(opaque);
  if(file->length() == 0){
   return AVERROR_EOF; //if we reach to the end of the string, return
                       // return End of file
  }

  // Creating a vector of the string size
  std::vector<uint8_t> array(file->length());

  //Copying the contents of the string into the vector
  std::copy(file->begin(),file->end(),array.begin());

  //Copying the vector into buf
  std::copy(array.begin(),array.end(),buf);


  return file->length();

}

1 个答案:

答案 0 :(得分:1)

在推出一些东西后,我得到了一个使用std :: stringstream的解决方案,它适用于我目前测试的几种格式:3gp / amr,wav / pcm,mp3。

这是一段代码:

//Create a string stream that contains the audio
std::stringstream audio_stream(audio);

//create the buffer
uint8_t * avio_ctx_buffer = NULL;

//allocate space for the buffer using ffmpeg allocation method
avio_ctx_buffer = (uint8_t *) av_malloc(avio_ctx_buffer_size);


//Allocate and initialize an AVIOContext for buffered I/O.
//Pass the stringstream audio_stream
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size,0,&audio_stream, &readCallback, NULL, NULL);

回调函数:

static int readFunction1(void* opaque, uint8_t * buf, int buf_size){
   //Cast the opaque pointer to std::stringstream
   std::stringstream * me =static_cast<std::stringstream *>(opaque);

   //If we are at the end of the stream return FFmpeg's EOF
   if(me->tellg() == buf_size){
     return AVERROR_EOF;
   }
   // Read the stream into the buf and cast it to char *
   me->read((char*)buf, buf_size);

   //return how many characters extracted
   return me->tellg();
}