2013-02-12 5 views
1

J'essaye de convertir un vecteur de données d'image RVB (dérivé d'une image .png) au format YUV420p en utilisant libav.Encoder rgb à yuv420p en utilisant libav

Dans l'exemple de code de libav ce qui suit est utilisé pour créer une image fictive:

/* prepare a dummy image */ 
static void fill_yuv_image(AVFrame *pict, int frame_index, int width, int height) 
{ 
    int x, y, i; 

    i = frame_index; 

    /* Y */ 
    for(y=0;y<height;y++) { 
     for(x=0;x<width;x++) { 
      pict->data[0][y * pict->linesize[0] + x] = x + y + i * 3; 
     } 
    } 

    /* Cb and Cr */ 
    for(y=0;y<height/2;y++) { 
     for(x=0;x<width/2;x++) { 
      pict->data[1][y * pict->linesize[1] + x] = 128 + y + i * 2; 
      pict->data[2][y * pict->linesize[2] + x] = 64 + x + i * 5; 
     } 
    } 
} 

Je ne suis pas clair sur quelques petites choses ici:

Tout d'abord, dois-je réorganiser le RGB données dans le vecteur d'entrée de sorte qu'il est adapté pour l'encodage comme YUV420p? Deuxièmement, je comprends qu'il y a une valeur Y pour chaque pixel et que les valeurs Cb et Cr sont utilisées pour quatre (2x2) pixels. Ce que je ne comprends pas, c'est comment les données RVB sont "réduites" aux valeurs Cb et Cr - y a-t-il un exemple de comment faire cela n'importe où?

Répondre

0

Je ne suis pas tout à fait sûr de ce que vous essayez d'obtenir exactement, donc je vais répondre directement à vos questions mieux que je peux (se sentir libre de suivre avec des commentaires): éclaircissant

1) Vous transformera les données RVB en YUV, ce qui impliquera un réarrangement. Les données RGB emballées sont bien où elles sont. Vous n'avez pas vraiment besoin de l'ajuster. En fait, il serait probablement préférable de le laisser emballé comme il le fait pour des raisons de localisation du cache.

2) Comme vous le savez déjà, YUV 4: 2: 0 code un échantillon Y pour chaque pixel mais chaque bloc 2x2 partage une valeur Cb et une valeur Cr. Cependant, il existe également des données YUV 4: 4: 4. C'est là que chaque pixel obtient ses propres échantillons Y, Cb et Cr. Une stratégie simple pour convertir RGB -> YUV 4: 2: 0 est de convertir RGB -> YUV 4: 4: 4 et ensuite moyenne (moyenne arithmétique) chaque bloc de 2x2 échantillons Cb. Il existe d'autres algorithmes (comme les filtres qui impliquent davantage d'échantillons environnants), mais cela devrait fonctionner si vous expérimentez simplement comment cela fonctionne.

Une autre stratégie pour l'expérimentation (et la vitesse) consiste à calculer uniquement le plan Y et à maintenir les plans Cb et Cr constants à 128. Cela se traduira par une image en niveaux de gris.

Pour un vrai travail, vous voudrez probablement tirer parti des fonctions de conversion intégrées que libav peut offrir.

+0

Tout d'abord, merci pour votre réponse. Je travaille sur le programme d'animation OS Pencil2D. En ce moment j'essaye d'obtenir l'exportation de dossier fonctionnant. En tant que test, j'ai voulu encoder un fichier vidéo en utilisant une seule image (c'est-à-dire 2 secondes d'une image statique). – user2063909