ref: 02ebbf514bb593c06f844d86246fa24b50813503
parent: 71032b396f78666f6984e8ec2b80f6ee8d5c08f3
author: Matthew Stephure <matt.stephure@calgaryscientific.com>
date: Wed Jan 22 09:07:57 EST 2014
Add cpu yuv conversion
--- a/flex/Makefile
+++ b/flex/Makefile
@@ -3,7 +3,7 @@
FLASCC:=X
FLEX:=X
AS3COMPILER:=asc2.jar
-BASE_CFLAGS:=-Wno-write-strings -Wno-trigraphs -DFLASCC
+BASE_CFLAGS:=-Wno-write-strings -Wno-trigraphs -DFLASCC -04 --emit-llvm
$?UNAME=$(shell uname -s)
ifneq (,$(findstring CYGWIN,$(UNAME)))
@@ -30,8 +30,8 @@
fi
swc: check
- "$(FLASCC)/usr/bin/gcc" $(BASE_CFLAGS) -O4 $(SOURCES) -emit-swc=h264bsd -o h264bsd.swc
- "$(FLEX)/bin/mxmlc" -static-link-runtime-shared-libraries -compiler.omit-trace-statements=false -library-path=h264bsd.swc -debug=false h264test.as -o h264test.swf
+ "$(FLASCC)/usr/bin/gcc" $(BASE_CFLAGS) $(SOURCES) -emit-swc=h264bsd -o h264bsd.swc
+ "$(FLEX)/bin/mxmlc" -static-link-runtime-shared-libraries -compiler.omit-trace-statements=false -library-path=h264bsd.swc -debug=true h264test.as -o h264test.swf
clean:
--- a/src/h264bsd_decoder.c
+++ b/src/h264bsd_decoder.c
@@ -109,6 +109,9 @@
if (noOutputReordering)
pStorage->noReordering = HANTRO_TRUE;
+ pStorage->rgbConversionBuffer = NULL;
+ pStorage->rgbConversionBufferLength = 0;
+
return HANTRO_OK;
}
@@ -607,7 +610,7 @@
ASSERT(pStorage);
pOut = h264bsdDpbOutputPicture(pStorage->dpb);
-
+
if (pOut != NULL)
{
*picId = pOut->picId;
@@ -620,8 +623,59 @@
}
+
/*------------------------------------------------------------------------------
+ Function: h264bsdNextOutputPictureRGB
+
+ Functional description:
+ Get next output picture in display order, converted from YUV to RGB.
+ Freeing the resulting buffer is the callers responsibility.
+
+ 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
+ length The length of the resulting buffer
+
+ Returns:
+ pointer to the picture data
+ NULL if no pictures available for display
+
+------------------------------------------------------------------------------*/
+u8* h264bsdNextOutputPictureRGB(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs, u32 *length)
+{
+ /* Variables */
+
+ dpbOutPicture_t *pOut;
+ u8 *data;
+ /* Code */
+
+ ASSERT(pStorage);
+
+ pOut = h264bsdDpbOutputPicture(pStorage->dpb);
+
+ if (pOut != NULL)
+ {
+ *picId = pOut->picId;
+ *isIdrPic = pOut->isIdr;
+ *numErrMbs = pOut->numErrMbs;
+
+ data = yuv2rgb(pStorage, pOut->data);
+
+ *length = pStorage->rgbConversionBufferLength;
+ return data;
+ }
+ else
+ return(NULL);
+}
+
+/*------------------------------------------------------------------------------
+
Function: h264bsdPicWidth
Functional description:
@@ -1004,4 +1058,90 @@
void h264bsdFree(storage_t *pStorage)
{
free(pStorage);
+}
+
+int clamp(int input, int max, int min) {
+ return input > max ? max : input < min ? min : input;
+}
+
+u8* yuv2rgb(storage_t *pStorage, u8* yuvBytes)
+{
+ int w = h264bsdPicWidth(pStorage) * 16;
+ int h = h264bsdPicHeight(pStorage) * 16;
+ int rgbLength = w*h*4;
+ u8 * rgb = NULL;
+
+ int y1,y2,u,v,ruv,guv,buv,j,r=0;
+ int w_2 = w >> 1;
+ int W = w*4;
+
+
+ int uoffset = w*h;
+ int voffset = w*h+((w*h)>>2);
+ int luma = 0;
+
+ if (pStorage->rgbConversionBuffer != NULL && pStorage->rgbConversionBufferLength != rgbLength)
+ {
+ FREE(pStorage->rgbConversionBuffer);
+ pStorage->rgbConversionBufferLength = 0;
+ }
+
+ if (pStorage->rgbConversionBuffer == NULL)
+ {
+ pStorage->rgbConversionBuffer = (u8*)malloc(rgbLength);
+ if (pStorage->rgbConversionBuffer == NULL)
+ return NULL;
+ pStorage->rgbConversionBufferLength = rgbLength;
+ }
+
+ rgb = pStorage->rgbConversionBuffer;
+
+
+
+ for(; h-=2;)
+ {
+ for(j = w_2; j--; )
+ {
+ u = yuvBytes[uoffset++];
+ v = yuvBytes[voffset++];
+
+ ruv = 409*u-56992;
+ guv = 34784-208*u-100*v;
+ buv = 516*v-70688;
+
+ y2 = yuvBytes[luma + w]*298;
+ y1 = yuvBytes[luma++]*298;
+
+ rgb[r+W] = 0xff;
+ rgb[r++] = 0xff;
+ rgb[r+W] = y2+ruv>>8;
+ rgb[r++] = y1+ruv>>8;
+ rgb[r+W] = y2+guv>>8;
+ rgb[r++] = y1+guv>>8;
+ rgb[r+W] = y2+buv>>8;
+ rgb[r++] = y1+buv>>8;
+
+ y2 = yuvBytes[luma + w]*298;
+ y1 = yuvBytes[luma++]*298;
+ rgb[r+W] = 0xff;
+ rgb[r++] = 0xff;
+ rgb[r+W] = y2+ruv>>8;
+ rgb[r++] = y1+ruv>>8;
+ rgb[r+W] = y2+guv>>8;
+ rgb[r++] = y1+guv>>8;
+ rgb[r+W] = y2+buv>>8;
+ rgb[r++] = y1+buv>>8;
+ }
+
+ r += W;
+ luma += w;
+ }
+
+
+
+
+
+
+
+ return pStorage->rgbConversionBuffer;
}
--- a/src/h264bsd_decoder.h
+++ b/src/h264bsd_decoder.h
@@ -69,6 +69,8 @@
u8* h264bsdNextOutputPicture(storage_t *pStorage, u32 *picId, u32 *isIdrPic,
u32 *numErrMbs);
+u8* h264bsdNextOutputPictureRGB(storage_t *pStorage, u32 *picId, u32 *isIdrPic, u32 *numErrMbs, u32 *length);
+
u32 h264bsdPicWidth(storage_t *pStorage);
u32 h264bsdPicHeight(storage_t *pStorage);
u32 h264bsdVideoRange(storage_t *pStorage);
@@ -85,6 +87,7 @@
storage_t* h264bsdAlloc();
void h264bsdFree(storage_t *pStorage);
+u8* yuv2rgb(storage_t *pStorage, u8* yuvBytes);
#endif /* #ifdef H264SWDEC_DECODER_H */
--- a/src/h264bsd_storage.h
+++ b/src/h264bsd_storage.h
@@ -147,6 +147,8 @@
HEADERS_RDY to the user */
u32 intraConcealmentFlag; /* 0 gray picture for corrupted intra
1 previous frame used if available */
+ u8* rgbConversionBuffer; // used to performance yuv conversion
+ int rgbConversionBufferLength;
} storage_t;
/*------------------------------------------------------------------------------