2013-01-08 3 views
1

Je souhaite convertir par programme un fichier vidéo mp4 (avec le codec h264) en images RVB uniques. Avec la ligne de commande, cela ressemble à:AVFrame to RGB - artefacts de décodage

ffmpeg -i test1080.mp4 -r 30 image-%3d.jpg 

L'utilisation de cette commande produit un ensemble d'images sympa. Mais lorsque j'essaie de faire par programme la même chose, certaines images (probablement des images B et P) semblent étranges (par exemple, ont des zones déformées avec des informations de différence, etc.). La lecture et le code de conversion est le suivant:

AVFrame *frame = avcodec_alloc_frame(); 
AVFrame *frameRGB = avcodec_alloc_frame(); 

AVPacket packet; 

int buffer_size=avpicture_get_size(PIX_FMT_RGB24, m_codecCtx->width, 
    m_codecCtx->height); 
uint8_t *buffer = new uint8_t[buffer_size]; 

avpicture_fill((AVPicture *)frameRGB, buffer, PIX_FMT_RGB24, 
    m_codecCtx->width, m_codecCtx->height); 

while (true) 
{ 
    // Read one packet into `packet` 
    if (av_read_frame(m_formatCtx, &packet) < 0) { 
     break; // End of stream. Done decoding. 
    } 

    if (avcodec_decode_video(m_codecCtx, frame, &buffer_size, packet.data, packet.size) < 1) { 
     break; // Error in decoding 
    } 

    if (!buffer_size) { 
     break; 
    } 

    // Convert 
    img_convert((AVPicture *)frameRGB, PIX_FMT_RGB24, (AVPicture*)frame, 
     m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height); 

    // RGB data is now available in frameRGB for further processing 
} 

Comment puis-je convertir le flux vidéo de sorte que chaque image finale montre toutes les données d'image, de sorte que les informations de B et trames P est inclus dans tous les cadres?

[EDIT:] Une image exemple montrant les objets est ici: http://imageshack.us/photo/my-images/201/sampleq.jpg/

Cordialement,

Répondre

0

Si le troisième argument de avcodec_decode_video retourne une valeur nulle, cela ne signifie pas l'erreur. Cela signifie que le cadre n'est pas encore prêt. Vous devez continuer à lire les images jusqu'à ce que la valeur devienne différente de zéro.

if (!buffer_size) { 
    continue; 
} 

UPD

Essayez d'ajouter le chèque et afficher uniquement les images clés, il vous aidera à isoler le problème.

while (true) 
{ 
    // Read one packet into `packet` 
    if (av_read_frame(m_formatCtx, &packet) < 0) { 
    break; // End of stream. Done decoding. 
    } 

    if (avcodec_decode_video(m_codecCtx, frame, &buffer_size, 
     packet.data, packet.size) < 1) 
    { 
    break; // Error in decoding 
    } 

    if (!buffer_size) { 
    continue; // <-- It's important! 
    } 

    // check for key frame 
    if (packet.flags & AV_PKT_FLAG_KEY) 
    { 
    // Convert 
    img_convert((AVPicture *)frameRGB, PIX_FMT_RGB24, (AVPicture*)frame, 
     m_codecCtx->pix_fmt, m_codecCtx->width, m_codecCtx->height); 
    } 
} 
+0

Merci pour l'indice. Je l'ai déjà expérimenté mais le résultat est le même. J'ai vérifié comment l'utilitaire ffmpeg effectue la conversion et cela implique beaucoup d'autres étapes. En ce moment j'essaie de comprendre ce qui est exactement nécessaire. – Hyndrix

+0

Pouvez-vous partager l'image d'exemple avec des artefacts? – pogorskiy

+0

Vous êtes ici: http://imageshack.us/photo/my-images/201/sampleq.jpg/ – Hyndrix