[Libva] [PATCH] JPEG Encode: Added support for UYVY/YUY2/Y8 formats

Xiang, Haihao haihao.xiang at intel.com
Sat Dec 13 06:24:45 PST 2014


Applied

Thanks
Haihao


>-----Original Message-----
>From: Libva [mailto:libva-bounces at lists.freedesktop.org] On Behalf Of Sirisha
>Muppavarapu
>Sent: Wednesday, December 10, 2014 5:11 AM
>To: Muppavarapu, Sirisha; libva at lists.freedesktop.org
>Subject: [Libva] [PATCH] JPEG Encode: Added support for UYVY/YUY2/Y8
>formats
>
>---
> test/encode/jpegenc.c       | 181 +++++++++++++++++++-------------------------
> test/encode/jpegenc_utils.h |   6 +-
> 2 files changed, 81 insertions(+), 106 deletions(-)
>
>diff --git a/test/encode/jpegenc.c b/test/encode/jpegenc.c index
>dababdc..cfe56f8 100644
>--- a/test/encode/jpegenc.c
>+++ b/test/encode/jpegenc.c
>@@ -25,8 +25,8 @@
>  * Simple JPEG encoder based on libVA.
>  *
>  * Usage:
>- * ./jpegenc <width> <height> <input file> <output file> <input filetype
>0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGB)> q <quality>
>- * Currently supporting only I420 and NV12 input file formats.
>+ * ./jpegenc <width> <height> <input file> <output file> <input
>+ filetype 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGBA) q <quality>
>+ * Currently supporting only I420/NV12/UYVY/YUY2/Y8 input file formats.
>  */
>
> #include "sysdeps.h"
>@@ -63,8 +63,8 @@
>
> void show_help()
> {
>-    printf("Usage: ./jpegenc <width> <height> <input file> <output file>
><fourcc value 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGB)> q
><quality>\n");
>-    printf("Currently supporting only I420 and NV12 input file formats.\n");
>+    printf("Usage: ./jpegenc <width> <height> <input file> <output file>
><fourcc value 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGBA)> q
><quality>\n");
>+    printf("Currently supporting only I420/NV12/UYVY/YUY2/Y8 input file
>+ formats.\n");
>     printf("Example: ./jpegenc 1024 768 input_file.yuv output.jpeg 0 50\n\n");
>     return;
> }
>@@ -94,8 +94,7 @@ void
>jpegenc_pic_param_init(VAEncPictureParameterBufferJPEG *pic_param,int
>width
>     } else {
>         pic_param->component_id[0] = pic_param->quantiser_table_selector[0]
>= 0;
>         pic_param->component_id[1] = pic_param->quantiser_table_selector[1]
>= 1;
>-        pic_param->component_id[2] = 2;
>-        pic_param->quantiser_table_selector[2] = 1;
>+        pic_param->component_id[2] = 2;
>+ pic_param->quantiser_table_selector[2] = 1;
>     }
>
>     pic_param->quality = quality;
>@@ -125,8 +124,8 @@ void jpegenc_qmatrix_init(VAQMatrixBufferJPEG
>*quantization_param, YUVComponentS
>
> void jpegenc_hufftable_init(VAHuffmanTableBufferJPEGBaseline
>*hufftable_param, YUVComponentSpecs yuvComp)  {
>-
>     hufftable_param->load_huffman_table[0] = 1; //Load Luma Hufftable
>+
>     if(yuvComp.fourcc_val == VA_FOURCC_Y800) {
>         hufftable_param->load_huffman_table[1] = 0; //Do not load Chroma
>Hufftable for Y8
>     } else {
>@@ -143,7 +142,6 @@ void
>jpegenc_hufftable_init(VAHuffmanTableBufferJPEGBaseline
>*hufftable_param, Y
>    //Load AC Values
>    memcpy(hufftable_param->huffman_table[0].ac_values,
>jpeg_hufftable_luma_ac+17, 162);
>    memset(hufftable_param->huffman_table[0].pad, 0, 2);
>-
>
>    //Load Chroma hufftable values if needed
>    if(yuvComp.fourcc_val != VA_FOURCC_Y800) { @@ -180,6 +178,7 @@ void
>jpegenc_slice_param_init(VAEncSliceParameterBufferJPEG *slice_param,
>YUVCom
>         slice_param->components[2].dc_table_selector = 1;
>         slice_param->components[2].ac_table_selector = 1;
>     }
>+
> }
>
>
>@@ -228,8 +227,8 @@ void populate_frame_header(JPEGFrameHeader
>*frameHdr, YUVComponentSpecs yuvComp,
>         } else {
>             //Analyzing the sampling factors for U/V, they are 1 for all formats
>except for Y8.
>             //So, it is okay to have the code below like this. For Y8, we wont reach
>this code.
>-            frameHdr->JPEGComponent[i].Hi = 1;
>-            frameHdr->JPEGComponent[i].Vi = 1;
>+            frameHdr->JPEGComponent[i].Hi = yuvComp.u_h_subsample;
>+            frameHdr->JPEGComponent[i].Vi = yuvComp.u_v_subsample;
>             frameHdr->JPEGComponent[i].Tqi = 1;
>         }
>     }
>@@ -301,7 +300,7 @@ void populate_scan_header(JPEGScanHeader
>*scanHdr, YUVComponentSpecs yuvComp)
>         scanHdr->ScanComponent[2].Tdj = 1;
>         scanHdr->ScanComponent[2].Taj = 1;
>     }
>-
>+
>     scanHdr->Ss = 0;  //0 for Baseline
>     scanHdr->Se = 63; //63 for Baseline
>     scanHdr->Ah = 0;  //0 for Baseline
>@@ -384,7 +383,7 @@ int build_packed_jpeg_header_buffer(unsigned char
>**header_buffer, YUVComponentS
>
>     //Add HuffTable AC and DC for Y,U/V components
>     JPEGHuffSection acHuffSectionHdr, dcHuffSectionHdr;
>-
>+
>     for(i=0; (i<yuvComp.num_components && (i<=1)); i++) {
>         //Add DC component (Tc = 0)
>         populate_huff_section_header(&dcHuffSectionHdr, i, 0); @@ -416,6
>+415,8 @@ int build_packed_jpeg_header_buffer(unsigned char
>**header_buffer, YUVComponentS
>             bitstream_put_ui(&bs, acHuffSectionHdr.Vij[j], 8);
>         }
>
>+        if((yuvComp.fourcc_val == VA_FOURCC_Y800) )
>+            break;
>     }
>
>     //Add Restart Interval if restart_interval is not 0 @@ -455,21 +456,24 @@
>int build_packed_jpeg_header_buffer(unsigned char **header_buffer,
>YUVComponentS
>     return bs.bit_offset;
> }
>
>+
> //Upload the yuv image from the file to the VASurface  void
>upload_yuv_to_surface(VADisplay va_dpy, FILE *yuv_fp, VASurfaceID
>surface_id, YUVComponentSpecs yuvComp, int picture_width, int
>picture_height, int frame_size)  {
>-
>     VAImage surface_image;
>     VAStatus va_status;
>     void *surface_p = NULL;
>     unsigned char newImageBuffer[frame_size];
>     unsigned char *y_src, *u_src, *v_src;
>-    unsigned char *y_dst, *u_dst, *v_dst;
>+    unsigned char *y_dst, *u_dst;
>     int y_size = picture_width * picture_height;
>-    int u_size = (picture_width >> 1) * (picture_height >> 1);
>+    int u_size = 0;
>     int row, col;
>     size_t n_items;
>-
>+
>+    //u_size is used for I420, NV12 formats only
>+    u_size = ((picture_width >> 1) * (picture_height >> 1));
>+
>     memset(newImageBuffer,0,frame_size);
>     do {
>         n_items = fread(newImageBuffer, frame_size, 1, yuv_fp); @@ -487,89
>+491,60 @@ void upload_yuv_to_surface(VADisplay va_dpy, FILE *yuv_fp,
>VASurfaceID surface_i
>
>     y_dst = surface_p + surface_image.offsets[0];
>     u_dst = surface_p + surface_image.offsets[1]; /* UV offset for NV12 */
>-    v_dst = surface_p + surface_image.offsets[2];
>
>-    /* Y plane */
>-    for (row = 0; row < surface_image.height; row++) {
>-        memcpy(y_dst, y_src, surface_image.width);
>-        y_dst += surface_image.pitches[0];
>-        y_src += picture_width;
>-    }
>+    if((yuvComp.fourcc_val == VA_FOURCC_NV12) || (yuvComp.fourcc_val
>== VA_FOURCC_I420) ||
>+       (yuvComp.fourcc_val == VA_FOURCC_Y800) ) {
>
>-    if(yuvComp.num_components > 1 ) {
>+        /* Y plane */
>+        for (row = 0; row < surface_image.height; row++) {
>+            memcpy(y_dst, y_src, surface_image.width);
>+            y_dst += surface_image.pitches[0];
>+            y_src += picture_width;
>+        }
>
>-        switch(yuvComp.fourcc_val) {
>-
>-            case VA_FOURCC_NV12: {
>-                for (row = 0; row < surface_image.height/2; row++) {
>-                    memcpy(u_dst, u_src, surface_image.width);
>-                    u_dst += surface_image.pitches[1];
>-                    u_src += (picture_width);
>-                }
>-                break;
>-            }
>-
>-            case VA_FOURCC_I420: {
>-                for (row = 0; row < surface_image.height / 2; row++) {
>-                    for (col = 0; col < surface_image.width / 2; col++) {
>-                    u_dst[col * 2] = u_src[col];
>-                    u_dst[col * 2 + 1] = v_src[col];
>-                    }
>-
>-                    u_dst += surface_image.pitches[1];
>-                    u_src += (picture_width / 2);
>-                    v_src += (picture_width / 2);
>+        if(yuvComp.num_components > 1) {
>+
>+            switch(yuvComp.fourcc_val) {
>+                case VA_FOURCC_NV12: {
>+                    for (row = 0; row < surface_image.height/2; row++) {
>+                        memcpy(u_dst, u_src, surface_image.width);
>+                        u_dst += surface_image.pitches[1];
>+                        u_src += (picture_width);
>+                    }
>+                    break;
>                 }
>
>-                break;
>-            }
>-
>-            //TO DO: Code for below formats needs to be fixed.
>-            //This will come as enhancement to the feature.
>-            case VA_FOURCC_UYVY:
>-            case VA_FOURCC_YUY2: {
>-                const int U = 1;
>-                const int V = 2;
>-
>-                u_dst = surface_p + surface_image.offsets[U];
>-                v_dst = surface_p + surface_image.offsets[V];
>-
>-                for (row = 0; row < surface_image.height / 2; row++) {
>-                    memcpy(u_dst, u_src, surface_image.width / 2);
>-                    memcpy(v_dst, v_src, surface_image.width / 2);
>-                    u_dst += surface_image.pitches[U];
>-                    v_dst += surface_image.pitches[V];
>-                    u_src += (picture_width / 2);
>-                    v_src += (picture_width / 2);
>+                case VA_FOURCC_I420: {
>+                    for (row = 0; row < surface_image.height / 2; row++) {
>+                        for (col = 0; col < surface_image.width / 2; col++) {
>+                             u_dst[col * 2] = u_src[col];
>+                             u_dst[col * 2 + 1] = v_src[col];
>+                         }
>+
>+                         u_dst += surface_image.pitches[1];
>+                         u_src += (picture_width / 2);
>+                         v_src += (picture_width / 2);
>+                    }
>+                    break;
>                 }
>+            }//end of switch
>+       }//end of if check
>+    } else if((yuvComp.fourcc_val == VA_FOURCC_UYVY) ||
>+ (yuvComp.fourcc_val == VA_FOURCC_YUY2)) {
>+
>+        for(row = 0; row < surface_image.height; row++) {
>+            memcpy(y_dst, y_src, surface_image.width*2);
>+            y_dst += surface_image.pitches[0];
>+            y_src += picture_width*2;
>+        }
>
>-                break;
>-            }
>-
>-            case VA_FOURCC_444P: {
>-                const int U = 1;
>-                const int V = 2;
>-
>-                u_dst = surface_p + surface_image.offsets[U];
>-                v_dst = surface_p + surface_image.offsets[V];
>-
>-                for (row = 0; row < surface_image.height; row++) {
>-                    memcpy(u_dst, u_src, surface_image.width);
>-                    memcpy(v_dst, v_src, surface_image.width);
>-                    u_dst += surface_image.pitches[U];
>-                    v_dst += surface_image.pitches[V];
>-                    u_src += (picture_width);
>-                    v_src += (picture_width);
>-                }
>-                break;
>-            }
>-
>-            default: {
>-                //processing like Y8
>-                break;
>-            }
>-        } //end of switch
>-    } //end of if
>+    } else if(yuvComp.fourcc_val == VA_FOURCC_RGBA) {
>+
>+        for (row = 0; row < surface_image.height; row++) {
>+            memcpy(y_dst, y_src, surface_image.width*4);
>+            y_dst += surface_image.pitches[0];
>+            y_src += picture_width*4;
>+        }
>+    }
>
>     vaUnmapBuffer(va_dpy, surface_image.buf);
>     vaDestroyImage(va_dpy, surface_image.image_id); @@ -581,7 +556,7 @@
>void upload_yuv_to_surface(VADisplay va_dpy, FILE *yuv_fp, VASurfaceID
>surface_i  void init_yuv_component(YUVComponentSpecs *yuvComponent,
>int yuv_type, int *surface_type, VASurfaceAttrib *fourcc)  {
>
>-    //<fourcc value 0(NV12)/1(UYVY)/2(YUY2)/3(Y8)/4(RGB)>
>+    //<fourcc value 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGBA)>
>     switch(yuv_type)
>     {
>         case 0 :   //I420
>@@ -634,7 +609,7 @@ void init_yuv_component(YUVComponentSpecs
>*yuvComponent, int yuv_type, int *surf
>             yuvComponent->fourcc_val = fourcc->value.value.i =
>VA_FOURCC_Y800;
>             yuvComponent->num_components = 1;
>             yuvComponent->y_h_subsample = 1;
>-            yuvComponent->y_v_subsample = 0;
>+            yuvComponent->y_v_subsample = 1;
>             yuvComponent->u_h_subsample = 0;
>             yuvComponent->u_v_subsample = 0;
>             yuvComponent->v_h_subsample = 0; @@ -642,9 +617,9 @@ void
>init_yuv_component(YUVComponentSpecs *yuvComponent, int yuv_type,
>int *surf
>             break;
>         }
>
>-        case 5: { //RGB or YUV444
>-            yuvComponent->va_surface_format = (*surface_type) =
>VA_RT_FORMAT_YUV444;
>-            yuvComponent->fourcc_val = fourcc->value.value.i =
>VA_FOURCC_444P;
>+        case 5: { //RGBA
>+            yuvComponent->va_surface_format = (*surface_type) =
>VA_RT_FORMAT_RGB32;
>+            yuvComponent->fourcc_val = fourcc->value.value.i =
>+ VA_FOURCC_RGBA;
>             yuvComponent->num_components = 3;
>             yuvComponent->y_h_subsample = 1;
>             yuvComponent->y_v_subsample = 1; @@ -654,7 +629,7 @@ void
>init_yuv_component(YUVComponentSpecs *yuvComponent, int yuv_type,
>int *surf
>             yuvComponent->v_v_subsample = 1;
>             break;
>         }
>-
>+
>         default: {
>             printf("Unsupported format:\n");
>             show_help();
>@@ -723,7 +698,7 @@ int encode_input_image(FILE *yuv_fp, FILE *jpeg_fp,
>int picture_width, int pictu
>     vaGetConfigAttributes(va_dpy, VAProfileJPEGBaseline,
>VAEntrypointEncPicture, &attrib[0], 2);
>
>     // RT should be one of below.
>-    if(!((attrib[0].value & VA_RT_FORMAT_YUV420) || (attrib[0].value &
>VA_RT_FORMAT_YUV422)
>+    if(!((attrib[0].value & VA_RT_FORMAT_YUV420) || (attrib[0].value &
>+ VA_RT_FORMAT_YUV422) || (attrib[0].value & VA_RT_FORMAT_RGB32)
>         ||(attrib[0].value & VA_RT_FORMAT_YUV444) || (attrib[0].value &
>VA_RT_FORMAT_YUV400)))
>     {
>         /* Did not find the supported RT format */ @@ -935,7 +910,7 @@ int
>main(int argc, char *argv[])
>     fseeko(yuv_fp, (off_t)0, SEEK_END);
>     file_size = ftello(yuv_fp);
>
>-    //<input file type: 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGB)>
>+    //<input file type: 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGBA)>
>     switch(yuv_type)
>     {
>         case 0 :   //I420
>@@ -955,8 +930,8 @@ int main(int argc, char *argv[])
>             break;
>         }
>
>-        case 5: { //RGB or YUV444
>-            frame_size = 3 * (picture_width * picture_height) ;
>+        case 5: { //RGBA
>+            frame_size = 4 * (picture_width * picture_height) ;
>             break;
>         }
>
>@@ -970,7 +945,7 @@ int main(int argc, char *argv[])
>
>     if ( (file_size < frame_size) || (file_size % frame_size) ) {
>         fclose(yuv_fp);
>-        printf("The YUV file's size is not correct\n");
>+        printf("The YUV file's size is not correct: file_size=%zd,
>+ frame_size=%d\n", file_size, frame_size);
>         return -1;
>     }
>
>diff --git a/test/encode/jpegenc_utils.h b/test/encode/jpegenc_utils.h index
>ce6a476..e003c7e 100644
>--- a/test/encode/jpegenc_utils.h
>+++ b/test/encode/jpegenc_utils.h
>@@ -330,11 +330,11 @@ uint8_t jpeg_hufftable_chroma_ac[] = {  };
>
> typedef struct _YUVComponentSpecs {
>-    //One of 0(NV12)/1(UYVY)/2(YUY2)/3(Y8)/4(RGB)>
>+    //One of 0(I420)/1(NV12)/2(UYVY)/3(YUY2)/4(Y8)/5(RGBA)>
>     unsigned int yuv_type;
>-    // One of VA_RT_FORMAT_YUV420, VA_RT_FORMAT_YUV422,
>VA_RT_FORMAT_YUV400, VA_RT_FORMAT_YUV444
>+    // One of VA_RT_FORMAT_YUV420, VA_RT_FORMAT_YUV422,
>+ VA_RT_FORMAT_YUV400, VA_RT_FORMAT_YUV444,
>VA_RT_FORMAT_RGB32
>     unsigned int va_surface_format;
>-    //One of VA_FOURCC_I420, VA_FOURCC_NV12, VA_FOURCC_UYVY,
>VA_FOURCC_YUY2, VA_FOURCC_Y800, VA_FOURCC_444P
>+    //One of VA_FOURCC_I420, VA_FOURCC_NV12, VA_FOURCC_UYVY,
>+ VA_FOURCC_YUY2, VA_FOURCC_Y800, VA_FOURCC_444P,
>VA_FOURCC_RGBA
>     unsigned int fourcc_val; //Using this field to evaluate the input file type.
>     //no.of. components
>     unsigned int num_components;
>--
>2.1.0
>
>_______________________________________________
>Libva mailing list
>Libva at lists.freedesktop.org
>http://lists.freedesktop.org/mailman/listinfo/libva


More information about the Libva mailing list