2011-01-22 5 views
4

J'ai une application qui génère un tas de jpgs que j'ai besoin de transformer en vidéo webm. J'essaye d'obtenir mes données rgb des jpegs dans l'échantillon de vpxenc. Je peux voir les formes de base des jpgs d'origine dans la vidéo de sortie, mais tout est vert teinté (même les pixels qui devraient être noirs sont à peu près à mi-chemin vert) et toutes les autres lignes de balayage ont des ordures.besoin de créer une vidéo webm à partir de trames RVB

Je suis en train de le nourrir VPX_IMG_FMT_YV12 données, ce qui je suppose est structuré comme si:

pour chaque trame données Y 8 bits moyennes 8 bits de chaque bloc de 2x2 V 8- moyennes de bits de chaque bloc 2x2 U

Voici une image source et une capture d'écran de la vidéo qui sort:

Images

Il est ENTI Compter possible que je fais la conversion RVB-> YV12 de manière incorrecte, mais même si je ne code que les données 8 bits Y et mettre les blocs U et V à 0, la vidéo ressemble à peu près la même chose. Je suis fondamentalement en cours d'exécution mes données RVB par cette équation:

// (R, G, and B are 0-255) 
float y = 0.299f*R + 0.587f*G + 0.114f*B; 
float v = (R-y)*0.713f; 
float u = (B-v)*0.565f; 

.. puis pour produire les 2x2 valeurs filtrées pour U et V que j'écris dans vpxenc, je viens de faire (a + b + c + d)/4, où a, b, c, d sont les valeurs U ou V de chaque bloc de pixels 2x2.

Je me demande donc:

  1. est-il un moyen plus facile (en code) pour prendre des données RVB et nourrir à vpx_codec_encode pour obtenir une belle vidéo WebM?

  2. Ma conversion RGB-> YV12 est-elle incorrecte quelque part?

Toute aide serait grandement appréciée.

+1

Pouvez-vous me dire si vous avez mis à jour le code? Iam debout devant le même problème ici ;-) merci –

Répondre

5

freefallr: Bien sûr. Voici le code. Notez qu'il convertit le RGB-> YUV en place et qu'il place la sortie YV12 dans pFullYPlane/pDownsampledUPlane/pDownsampledVPlane. Ce code produit de belles vidéos WebM lorsque j'ai modifié leur exemple vpxenc pour utiliser ces données.

void RGB_To_YV12(unsigned char *pRGBData, int nFrameWidth, int nFrameHeight, void *pFullYPlane, void *pDownsampledUPlane, void *pDownsampledVPlane) 
{ 
    int nRGBBytes = nFrameWidth * nFrameHeight * 3; 

    // Convert RGB -> YV12. We do this in-place to avoid allocating any more memory. 
    unsigned char *pYPlaneOut = (unsigned char*)pFullYPlane; 
    int nYPlaneOut = 0; 

    for (int i=0; i < nRGBBytes; i += 3) 
    { 
     unsigned char B = pRGBData[i+0]; 
     unsigned char G = pRGBData[i+1]; 
     unsigned char R = pRGBData[i+2]; 

     float y = (float)(R*66 + G*129 + B*25 + 128)/256 + 16; 
     float u = (float)(R*-38 + G*-74 + B*112 + 128)/256 + 128; 
     float v = (float)(R*112 + G*-94 + B*-18 + 128)/256 + 128; 

     // NOTE: We're converting pRGBData to YUV in-place here as well as writing out YUV to pFullYPlane/pDownsampledUPlane/pDownsampledVPlane. 
     pRGBData[i+0] = (unsigned char)y; 
     pRGBData[i+1] = (unsigned char)u; 
     pRGBData[i+2] = (unsigned char)v; 

     // Write out the Y plane directly here rather than in another loop. 
     pYPlaneOut[nYPlaneOut++] = pRGBData[i+0]; 
    } 

    // Downsample to U and V. 
    int halfHeight = nFrameHeight >> 1; 
    int halfWidth = nFrameWidth >> 1; 

    unsigned char *pVPlaneOut = (unsigned char*)pDownsampledVPlane; 
    unsigned char *pUPlaneOut = (unsigned char*)pDownsampledUPlane; 

    for (int yPixel=0; yPixel < halfHeight; yPixel++) 
    { 
     int iBaseSrc = ((yPixel*2) * nFrameWidth * 3); 

     for (int xPixel=0; xPixel < halfWidth; xPixel++) 
     { 
      pVPlaneOut[yPixel * halfWidth + xPixel] = pRGBData[iBaseSrc + 2]; 
      pUPlaneOut[yPixel * halfWidth + xPixel] = pRGBData[iBaseSrc + 1]; 

      iBaseSrc += 6; 
     } 
    } 
} 
+0

Je suggère également la lecture de ce http://en.wikipedia.org/wiki/YUV#Y.27UV420p_.28and_Y.27V12_or_YV12.29_to_RGB888_conversion si vous ne savez pas combien de temps les tampons d'entrée doivent être. –

0

Peu importe. Le schéma que j'utilisais était correct mais j'avais un bug dans le code de downsampling U/V.

+0

Pouvez-vous poster votre code de conversion RGB -> YUV, je voudrais jeter un oeil! –

+0

Je travaille également avec WebM! –

Questions connexes