2017-04-26 6 views
0

J'essaie actuellement d'implémenter FFmpeg dans SFML, donc j'ai une plus large gamme de fichiers audio à lire, mais je reçois l'erreur [mov,mp4,m4a,3gp,3g2,mj2 @ #] moov atom not found lors de l'ouverture d'un fichier m4a. Maintenant, cela ne se produit que lorsque j'utilise un IOContext personnalisé pour lire le fichier au lieu de l'ouvrir depuis l'URL. This page dit ici que je ne suis pas censé utiliser les flux pour ouvrir les fichiers m4a, mais est-ce qu'un IOContext est considéré comme un flux? Parce que je n'ai aucun moyen de l'ouvrir comme une URL car c'est ainsi que fonctionne SFML.ffmpeg bibliothèque m4a moov atome introuvable lors de l'utilisation personnalisée 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; 
} 

Répondre

0

Il s'est avéré qu'il y avait un seul problème et c'était avec ma fonction de recherche. Apparemment, ffmpeg a une autre option disponible AVSEEK_SIZE. Voici la mise en œuvre. Après cela, cela fonctionne.

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); 
}