shithub: h264bsd

Download patch

ref: c3340b05dbd4a6e4632e461284fe40a25dfad796
parent: b56a0e8ba7ba51fa0cda00ced01711159cf0c686
author: Sam Leitch <sam.leitch@calgaryscientific.com>
date: Mon Mar 17 12:26:00 EDT 2014

Added BGRA in addition to RGBA format (BGRA is used by Flex)

--- a/.gitignore
+++ b/.gitignore
@@ -7,3 +7,4 @@
 *.o
 node_modules
 js/h264bsd_asm.js.map
+*.suo
--- a/src/h264bsd_decoder.c
+++ b/src/h264bsd_decoder.c
@@ -626,7 +626,8 @@
     Function: h264bsdNextOutputPictureRGBA
 
         Functional description:
-            Get next output picture in display order, converted to ARGB.
+            Get next output picture in display order, converted to RGBA.
+            RGBA is the color format most commonly used by OpenGL.
 
         Inputs:
             pStorage    pointer to storage data structure
@@ -647,11 +648,52 @@
     u32 width = h264bsdPicWidth(pStorage) * 16;
     u32 height = h264bsdPicHeight(pStorage) * 16;
     u8* data = h264bsdNextOutputPicture(pStorage, picId, isIdrPic, numErrMbs);
+    size_t rgbSize = sizeof(u32) * width * height;
 
     if(data == NULL) return NULL;
 
+    if(pStorage->rgbConversionBufferSize < rgbSize)
+    {
+        if(pStorage->rgbConversionBuffer != NULL) free(pStorage->rgbConversionBuffer);
+        pStorage->rgbConversionBufferSize = rgbSize;
+        pStorage->rgbConversionBuffer = (u32*)malloc(rgbSize);
+    }
+
+    h264bsdConvertToRGBA(width, height, data, pStorage->rgbConversionBuffer);
+    return pStorage->rgbConversionBuffer;
+}
+
+/*------------------------------------------------------------------------------
+
+    Function: h264bsdNextOutputPictureRGBA
+
+        Functional description:
+            Get next output picture in display order, converted to BGRA.
+            BGRA is the color format most commonly used by Windows.
+
+        Inputs:
+            pStorage    pointer to storage data structure
+
+        Outputs:
+            picId       identifier of the picture will be stored here
+            isIdrPic    IDR flag of the picture will be stored here
+            numErrMbs   number of concealed macroblocks in the picture
+                        will be stored here
+
+        Returns:
+            pointer to the picture data
+            NULL if no pictures available for display
+
+------------------------------------------------------------------------------*/
+u32* h264bsdNextOutputPictureBGRA(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs)
+{
+    u32 width = h264bsdPicWidth(pStorage) * 16;
+    u32 height = h264bsdPicHeight(pStorage) * 16;
+    u8* data = h264bsdNextOutputPicture(pStorage, picId, isIdrPic, numErrMbs);
     size_t rgbSize = sizeof(u32) * width * height;
 
+    if(data == NULL) return NULL;
+
     if(pStorage->rgbConversionBufferSize < rgbSize)
     {
         if(pStorage->rgbConversionBuffer != NULL) free(pStorage->rgbConversionBuffer);
@@ -659,7 +701,7 @@
         pStorage->rgbConversionBuffer = (u32*)malloc(rgbSize);
     }
 
-    h264bsdConvertToRGBA(width, height, data, pStorage->rgbConversionBuffer);
+    h264bsdConvertToBGRA(width, height, data, pStorage->rgbConversionBuffer);
     return pStorage->rgbConversionBuffer;
 }
 
@@ -1055,10 +1097,11 @@
 
         Functional description:
             Convert decoded image data RGBA format.
+            RGBA is the color format most commonly used by OpenGL.
             RGBA format uses u32 pixels where the MSB is alpha.
             *Note* While this function is available, it is not heavily optimized.
             If possible, you should use decoded image data directly. 
-            This function should only be used when there is no other way to get ARGB data.
+            This function should only be used when there is no other way to get RGBA data.
 
         Inputs:
             width       width of the image in pixels
@@ -1066,7 +1109,7 @@
             data        pointer to decoded image data
 
         Outputs:
-            rgbData     pointer to the buffer where the RGB data will be written
+            rgbaData     pointer to the buffer where the RGBA data will be written
 
         Returns:
             none
@@ -1073,10 +1116,10 @@
 
 ------------------------------------------------------------------------------*/
 
-void h264bsdConvertToRGBA(u32 width, u32 height, u8* data, u32 *rgbData)
+void h264bsdConvertToRGBA(u32 width, u32 height, u8* data, u32 *rgbaData)
 {
-    const u32 w = width;
-    const u32 h = height;
+    const int w = (int)width;
+    const int h = (int)height;
 
     int x = 0;
     int y = 0;
@@ -1087,7 +1130,7 @@
     u8* luma = data;
     u8* cb = data + ySize;
     u8* cr = data + ySize + uSize;
-    u32* rgb = rgbData;
+    u32* rgba = rgbaData;
 
     while(y < h)
     {
@@ -1104,10 +1147,91 @@
         pixel = (pixel << 8) + g;
         pixel = (pixel << 8) + r;
 
-        *rgb = pixel;
+        *rgba = pixel;
 
         ++x;
-        ++rgb;
+        ++rgba;
+        ++luma;
+
+        if(!(x & 1))
+        {
+            ++cb;
+            ++cr;
+        }
+
+        if(x < w) continue;
+
+        x = 0;
+        ++y;
+
+        if(y & 1)
+        {
+            cb -= w/2;
+            cr -= w/2;
+        }
+    }
+}
+
+/*------------------------------------------------------------------------------
+
+    Function: h264bsdConvertToBGRA
+
+        Functional description:
+            Convert decoded image data BGRA format.
+            BGRA is the color format most commonly used by Windows.
+            BGRA format uses u32 pixels where the MSB is alpha.
+            *Note* While this function is available, it is not heavily optimized.
+            If possible, you should use decoded image data directly. 
+            This function should only be used when there is no other way to get BGRA data.
+
+        Inputs:
+            width       width of the image in pixels
+            height      height of the image in pixels
+            data        pointer to decoded image data
+
+        Outputs:
+            bgraData     pointer to the buffer where the BGRA data will be written
+
+        Returns:
+            none
+
+------------------------------------------------------------------------------*/
+
+void h264bsdConvertToBGRA(u32 width, u32 height, u8* data, u32 *bgraData)
+{
+    const int w = (int)width;
+    const int h = (int)height;
+
+    int x = 0;
+    int y = 0;
+
+    size_t ySize = w * h;
+    size_t uSize = w/2 * h/2;
+
+    u8* luma = data;
+    u8* cb = data + ySize;
+    u8* cr = data + ySize + uSize;
+    u32* bgra = bgraData;
+
+    while(y < h)
+    {
+        int c = *luma - 16;
+        int d = *cb - 128;
+        int e = *cr - 128;
+
+        u32 r = (u32)CLIP1((298*c         + 409*e + 128) >> 8);
+        u32 g = (u32)CLIP1((298*c - 100*d - 208*e + 128) >> 8);
+        u32 b = (u32)CLIP1((298*c + 516*d         + 128) >> 8);
+
+        u32 pixel = 0xff;
+        pixel = (pixel << 8) + r;
+        pixel = (pixel << 8) + g;
+        pixel = (pixel << 8) + b;
+
+        *bgra = pixel;
+
+        ++x;
+        ++bgra;
         ++luma;
 
         if(!(x & 1))
--- a/src/h264bsd_decoder.h
+++ b/src/h264bsd_decoder.h
@@ -68,6 +68,7 @@
 
 u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs);
 u32* h264bsdNextOutputPictureRGBA(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs);
+u32* h264bsdNextOutputPictureBGRA(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs);
 
 u32 h264bsdPicWidth(storage_t *pStorage);
 u32 h264bsdPicHeight(storage_t *pStorage);
@@ -87,6 +88,7 @@
 void h264bsdFree(storage_t *pStorage);
 
 void h264bsdConvertToRGBA(u32 width, u32 height, u8* data, u32 *rgbData);
+void h264bsdConvertToBGRA(u32 width, u32 height, u8* data, u32 *rgbData);
 
 #endif /* #ifdef H264SWDEC_DECODER_H */