2015-09-19 60 views
-1

我需要創建一個自定義閱讀回調函數,該函數可以將std::string文件的內容讀取到uint8_t * buf中。我嘗試了在互聯網和計算器上找到的多種不同的方法,但有時它可以工作,而其他程序無限循環或中途停止執行。FFMPEG I/O的自定義閱讀功能

我沒有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

tyring一些東西了一會兒之後,我使用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(); 
}