2017-08-16 2 views
0

Ich habe versucht, YUYV Raw-Datei in YUV420 Raw-Datei in C++ zu konvertieren. Das Format ist wie in YUV Formats Page dokumentiert. Meine Ausgabedatei zeigt nach der Konvertierung ein grünliches Aussehen. Ich habe den Quellcode von Experts Exchange übernommen, um von YUYV anstelle von UYVY zu konvertieren. Hier ist meine Quellcode:Convert V4L2_PIX_FMT_YUYV (YUV 4: 2: 2) zu V4L2_PIX_FMT_YVU420 (YUV 4: 2: 0)

void conv422to420(uint8_t* src, uint8_t* dst) 
{ 
    uint8_t* pyFrame = dst; 
    uint8_t* puFrame = pyFrame + width_*height_; // Cb 
    uint8_t* pvFrame = puFrame + width_*height_/4; // Cr 

    int uvOffset = width_ * 2 * sizeof(uint8_t); 

    int i,j; 

    for(i=0; i<height_-1; i++) 
    { 
    for(j=0; j<width_; j+=2) 
    { 
     auto evenRow = ((i&1) == 0); 
     *pyFrame++ = *src++; 
     ++src; 
     uint16_t calc; 
     if (evenRow) 
     { 
      calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *pvFrame++ = (uint8_t) calc; 
     } 
     *pyFrame++ = *src++; 
     ++src; 
     if (evenRow) 
     { 
      calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *puFrame++ = (uint8_t) calc; 
     } 
    } 
    } 
} 

Im Allgemeinen habe ich den Durchschnitt der beiden U und zwei V-Werte in zwei benachbarten Reihen in YUYV die Werte in YUV420 zu sein. Ich bin mir nur nicht sicher, ob die "Mittelung" der richtige Weg ist, dies zu tun. Weil ich verwenden

ffmpeg -y -r 25,0 -f rawvideo reines es 1280x720 -pix_fmt yuyv422 -i yuyv422.yuv -pix_fmt yuv420p -f rawvideo reine -r 25,0 es 1280x720 -v debug yuv420p.yuv

, um die YUV420-Raw-Datei erfolgreich zu generieren, und das Diff für meine eigene Ausgabedatei unterscheidet sich drastisch von dem in U- und Y-Kanälen generierten ffmpeg.

Meine Frage ist also, gibt es eine Open-Source-Lösung für eine solche Konvertierung? Und was ist falsch mit meiner Lösung?

Antwort

0

Nach ein paar Versuchen des Debugging stellte sich heraus, dass es sich um ein kleines Problem handelte: Ich hätte den Zeiger src nach der Zuweisung der U V -Werte erhöhen sollen. Hier ist der Code:

uint8_t* pyFrame = dst; 
uint8_t* puFrame = pyFrame + width_*height_* sizeof(uint8_t); // Cb 
uint8_t* pvFrame = puFrame + width_*height_* sizeof(uint8_t)/4; // Cr 

int uvOffset = width_ * 2 * sizeof(uint8_t); 

int i,j; 

for(i=0; i<height_-1; i++) 
{ 
    for(j=0; j<width_; j+=2) 
    { 
     auto evenRow = ((i&1) == 0); 
     *pyFrame++ = *src++; 
     if (evenRow) 
     { 
      uint16_t calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *puFrame++ = *src; 
     } 
     ++src; 
     *pyFrame++ = *src++; 
     if (evenRow) 
     { 
      uint16_t calc = *src; 
      calc += *(src + uvOffset); 
      calc /= 2; 
      *pvFrame++ = (uint8_t) calc; 
     } 
     ++src; 
    } 
} 

Jetzt kann ich die Bilder sehen richtig umgesetzt. Ich bin mir immer noch nicht sicher, ob es das beste Verfahren ist, es zu mitteln. Wenn jemand die "Best Practice" hat, lass es mich wissen.