2017-04-26 15 views
0

현재 FFmpeg을 SFML에 구현하려고하므로 읽을 오디오 파일의 범위가 더 넓어 지지만 m4a 파일을 열 때 [mov,mp4,m4a,3gp,3g2,mj2 @ #] moov atom not found 오류가 발생합니다. 이제는 사용자 정의 IOContext를 URL에서 열지 않고 파일을 읽을 때만 사용합니다. This page 여기에 m4a 파일을 열 때 스트림을 사용하지 않아도되지만 스트림으로 간주되는 IOContext는 무엇입니까? SFML이 작동하는 방식으로 URL을 열 수있는 방법이 없기 때문입니다.ffmpeg 라이브러리 m4a moov atom 사용자 정의 IOContext를 사용할 때 찾을 수 없습니다.

// Explanation of InputStream class 
class InputStream { 
    int64_t getSize() 
    int64_t read(void* data, int64_t size); 
    int64_t seek(int64_t position); 
    int64_t tell(); // Gets the stream position 
}; 

// Used for IOContext 
int read(void* opaque, uint8_t* buf, int buf_size) { 
    sf::InputStream* stream = (sf::InputStream*)opaque; 
    return (int)stream->read(buf, buf_size); 
} 
// Used for IOContext 
int64_t seek(void* opaque, int64_t offset, int whence) { 
    sf::InputStream* stream = (sf::InputStream*)opaque; 
    switch (whence) { 
    case SEEK_SET: 
     break; 
    case SEEK_CUR: 
     offset += stream->tell(); 
     break; 
    case SEEK_END: 
     offset = stream->getSize() - offset; 
    } 
    return (int64_t)stream->seek(offset); 
} 

bool open(sf::InputStream& stream) { 
    AVFormatContext* m_formatContext = NULL; 
    AVIOContext* m_ioContext = NULL; 
    uint8_t* m_ioContextBuffer = NULL; 
    size_t m_ioContextBufferSize = 0; 

    av_register_all(); 
    avformat_network_init(); 
    m_formatContext = avformat_alloc_context(); 

    m_ioContextBuffer = (uint8_t*)av_malloc(m_ioContextBufferSize); 
    if (!m_ioContextBuffer) { 
     close(); 
     return false; 
    } 
    m_ioContext = avio_alloc_context(
     m_ioContextBuffer, m_ioContextBufferSize, 
     0, &stream, &::read, NULL, &::seek 
    ); 
    if (!m_ioContext) { 
     close(); 
     return false; 
    } 
    m_formatContext = avformat_alloc_context(); 
    m_formatContext->pb = m_ioContext; 

    if (avformat_open_input(&m_formatContext, NULL, NULL, NULL) != 0) { 
     // FAILS HERE 
     close(); 
     return false; 
    } 

    //... 

    return true; 
} 

답변

0

단 하나의 문제가 있으며 내 탐색 기능이있는 것으로 나타났습니다. 외관상으로는 ffmpeg에는 유효한 다른 whence 선택권이있다 AVSEEK_SIZE. 구현 방법은 다음과 같습니다. 이것 후에 그것은 작동합니다.

int64_t seek(void* opaque, int64_t offset, int whence) { 
    sf::InputStream* stream = (sf::InputStream*)opaque; 
    switch (whence) { 
    case SEEK_SET: 
     break; 
    case SEEK_CUR: 
     offset += stream->tell(); 
     break; 
    case SEEK_END: 
     offset = stream->getSize() - offset; 
     break; 
    case AVSEEK_SIZE: 
     return (int64_t)stream->getSize(); 
    } 
    return (int64_t)stream->seek(offset); 
}