[Libva] [PATCH 1/3] JPEG Encode: Added support for JPEG Encode in the driver.

Sirisha Muppavarapu sirisha.muppavarapu at intel.com
Mon Nov 10 23:03:34 PST 2014


---
 src/i965_defines.h     | 29 ++++++++++++++++
 src/i965_device_info.c |  6 ++++
 src/i965_drv_video.c   | 93 ++++++++++++++++++++++++++++++++++++++++----------
 src/i965_drv_video.h   |  6 +++-
 4 files changed, 115 insertions(+), 19 deletions(-)

diff --git a/src/i965_defines.h b/src/i965_defines.h
index f010ca2..33829db 100755
--- a/src/i965_defines.h
+++ b/src/i965_defines.h
@@ -379,9 +379,14 @@
 
 #define MFD_VC1_BSD_OBJECT                      MFX(2, 2, 1, 8)
 
+//MFX_JPEG #defines for JPEG decoder only
 #define MFX_JPEG_PIC_STATE                      MFX(2, 7, 0, 0)
 #define MFX_JPEG_HUFF_TABLE_STATE               MFX(2, 7, 0, 2)
 
+//MFC_JPEG #defines for JPEG encoder only
+#define MFC_JPEG_SCAN_OBJECT                    MFX(2, 7, 2, 9)
+#define MFC_JPEG_HUFF_TABLE_STATE               MFX(2, 7, 2, 3)
+
 #define MFD_JPEG_BSD_OBJECT                     MFX(2, 7, 1, 8)
 
 #define MFX_VP8_PIC_STATE                       MFX(2, 4, 0, 0)
@@ -800,9 +805,12 @@
 #define MFD_MODE_VLD            0
 #define MFD_MODE_IT             1
 
+#define MFX_SURFACE_YCRCB_NORMAL        0
+#define MFX_SURFACE_YCRCB_SWAPY         3
 #define MFX_SURFACE_PLANAR_420_8        4
 #define MFX_SURFACE_PLANAR_411_8        5
 #define MFX_SURFACE_PLANAR_422_8        6
+#define MFX_SURFACE_R8G8B8A8_UNORM      9
 #define MFX_SURFACE_MONOCHROME          12
 
 #define MPEG_I_PICTURE          1
@@ -820,5 +828,26 @@
 #define SUBSAMPLE_YUV444        4
 #define SUBSAMPLE_YUV411        5
 #define SUBSAMPLE_RGBX          6
+#define JPEG_ENC_SURFACE_NV12 1
+#define JPEG_ENC_SURFACE_UYVY 2
+#define JPEG_ENC_SURFACE_YUY2 3
+#define JPEG_ENC_SURFACE_Y8   4
+#define JPEG_ENC_SURFACE_RGB  5
+
+#define JPEG_ENC_MCU_YUV400     0
+#define JPEG_ENC_MCU_YUV420     1
+#define JPEG_ENC_MCU_YUV422H_2Y 2
+#define JPEG_ENC_MCU_RGB        3
+
+#define JPEG_ENC_ROUND_QUANT_DEFAULT 0
+#define JPEG_ENC_ROUND_QUANT_MINUS_128TH 1
+#define JPEG_ENC_ROUND_QUANT_PLUS_128TH 2
+#define JPEG_ENC_ROUND_QUANT_MINUS_64TH 3
+#define JPEG_ENC_ROUND_QUANT_PLUS_64TH 4
+#define JPEG_ENC_ROUND_QUANT_MINUS_32TH 5
+#define JPEG_ENC_ROUND_QUANT_MINUS_16TH 6
+#define JPEG_ENC_ROUND_QUANT_MINUS_8TH 7
+
+
 
 #endif /* _I965_DEFINES_H_ */
diff --git a/src/i965_device_info.c b/src/i965_device_info.c
index 77333f5..9547360 100755
--- a/src/i965_device_info.c
+++ b/src/i965_device_info.c
@@ -41,6 +41,10 @@
     (VA_RT_FORMAT_YUV400 | VA_RT_FORMAT_YUV411 | VA_RT_FORMAT_YUV422 | \
      VA_RT_FORMAT_YUV444)
 
+/* Extra set of chroma formats supported for JPEG encoding (beyond YUV 4:2:0) */
+#define EXTRA_JPEG_ENC_CHROMA_FORMATS \
+    (VA_RT_FORMAT_YUV400| VA_RT_FORMAT_YUV422 | VA_RT_FORMAT_YUV444)     
+     
 /* Defines VA profile as a 32-bit unsigned integer mask */
 #define VA_PROFILE_MASK(PROFILE) \
     (1U << VAProfile##PROFILE)
@@ -271,6 +275,7 @@ static struct hw_codec_info chv_hw_codec_info = {
                               VA_PROFILE_MASK(H264MultiviewHigh)),
     .h264_dec_chroma_formats = EXTRA_H264_DEC_CHROMA_FORMATS,
     .jpeg_dec_chroma_formats = EXTRA_JPEG_DEC_CHROMA_FORMATS,
+    .jpeg_enc_chroma_formats = EXTRA_JPEG_ENC_CHROMA_FORMATS,
 
     .has_mpeg2_decoding = 1,
     .has_mpeg2_encoding = 1,
@@ -278,6 +283,7 @@ static struct hw_codec_info chv_hw_codec_info = {
     .has_h264_encoding = 1,
     .has_vc1_decoding = 1,
     .has_jpeg_decoding = 1,
+    .has_jpeg_encoding = 1,
     .has_vpp = 1,
     .has_accelerated_getimage = 1,
     .has_accelerated_putimage = 1,
diff --git a/src/i965_drv_video.c b/src/i965_drv_video.c
index 03ee60f..d087bb1 100644
--- a/src/i965_drv_video.c
+++ b/src/i965_drv_video.c
@@ -71,6 +71,9 @@
 
 #define HAS_JPEG_DECODING(ctx)  ((ctx)->codec_info->has_jpeg_decoding && \
                                  (ctx)->intel.has_bsd)
+                                                                  
+#define HAS_JPEG_ENCODING(ctx)  ((ctx)->codec_info->has_jpeg_encoding && \
+                                 (ctx)->intel.has_bsd)      
 
 #define HAS_VPP(ctx)    ((ctx)->codec_info->has_vpp)
 
@@ -444,7 +447,8 @@ i965_QueryConfigProfiles(VADriverContextP ctx,
         profile_list[i++] = VAProfileNone;
     }
 
-    if (HAS_JPEG_DECODING(i965)) {
+    if (HAS_JPEG_DECODING(i965) ||
+        HAS_JPEG_ENCODING(i965)) {
         profile_list[i++] = VAProfileJPEGBaseline;
     }
 
@@ -519,6 +523,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx,
     case VAProfileJPEGBaseline:
         if (HAS_JPEG_DECODING(i965))
             entrypoint_list[n++] = VAEntrypointVLD;
+        
+        if (HAS_JPEG_ENCODING(i965))
+            entrypoint_list[n++] = VAEntrypointEncPicture;
         break;
 
     case VAProfileVP8Version0_3:
@@ -587,7 +594,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile,
         break;
 
     case VAProfileJPEGBaseline:
-        if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) {
+        if ((HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD) ||
+            (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)) {
             va_status = VA_STATUS_SUCCESS;
         } else {
             va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT;
@@ -646,6 +654,9 @@ i965_get_default_chroma_formats(VADriverContextP ctx, VAProfile profile,
     case VAProfileJPEGBaseline:
         if (HAS_JPEG_DECODING(i965) && entrypoint == VAEntrypointVLD)
             chroma_formats |= i965->codec_info->jpeg_dec_chroma_formats;
+        if (HAS_JPEG_ENCODING(i965) && entrypoint == VAEntrypointEncPicture)
+            chroma_formats |= i965->codec_info->jpeg_enc_chroma_formats;
+        
         break;
 
     default:
@@ -717,6 +728,20 @@ i965_GetConfigAttributes(VADriverContextP ctx,
                     attrib_list[i].value = ENCODER_QUALITY_RANGE;
 		break;
 	    }
+    
+    case VAConfigAttribEncJPEG: 
+        if( entrypoint == VAEntrypointEncPicture) {
+            VAConfigAttribValEncJPEG *configVal = (VAConfigAttribValEncJPEG*)&(attrib_list[i].value);
+            (configVal->bits).arithmatic_coding_mode = 0; // Huffman coding is used
+            (configVal->bits).progressive_dct_mode = 0;   // Only Sequential DCT is supported
+            (configVal->bits).non_interleaved_mode = 1;   // Support both interleaved and non-interleaved
+            (configVal->bits).differential_mode = 0;      // Baseline DCT is non-differential 
+            (configVal->bits).max_num_components = 3;     // Only 3 components supported
+            (configVal->bits).max_num_scans = 1;          // Only 1 scan per frame
+            (configVal->bits).max_num_huffman_tables = 3; // Max 3 huffman tables
+            (configVal->bits).max_num_quantization_tables = 3; // Max 3 quantization tables
+        }
+        break;
 
         case VAConfigAttribDecSliceMode:
             if (entrypoint == VAEntrypointVLD)
@@ -1807,6 +1832,12 @@ i965_CreateContext(VADriverContextP ctx,
             return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
         render_state->interleaved_uv = 1;
         break;
+    case VAProfileJPEGBaseline: { //for gen8 devices
+        if (!HAS_JPEG_ENCODING(i965))
+            return VA_STATUS_ERROR_UNSUPPORTED_PROFILE;
+        render_state->interleaved_uv = 1;
+        break;
+    }        
     default:
         render_state->interleaved_uv = !!(IS_GEN6(i965->intel.device_info) || IS_GEN7(i965->intel.device_info) || IS_GEN8(i965->intel.device_info));
         break;
@@ -1839,7 +1870,8 @@ i965_CreateContext(VADriverContextP ctx,
             obj_context->codec_state.proc.current_render_target = VA_INVALID_ID;
             assert(i965->codec_info->proc_hw_context_init);
             obj_context->hw_context = i965->codec_info->proc_hw_context_init(ctx, obj_config);
-        } else if (VAEntrypointEncSlice == obj_config->entrypoint) { /*encode routin only*/
+         } else if ((VAEntrypointEncSlice == obj_config->entrypoint) || 
+                   (VAEntrypointEncPicture == obj_config->entrypoint)) { /*encode routine only*/
             VAConfigAttrib *packed_attrib;
             obj_context->codec_type = CODEC_ENC;
             memset(&obj_context->codec_state.encode, 0, sizeof(obj_context->codec_state.encode));
@@ -2149,24 +2181,42 @@ i965_MapBuffer(VADriverContextP ctx,
                     delimiter2 = MPEG2_DELIMITER2;
                     delimiter3 = MPEG2_DELIMITER3;
                     delimiter4 = MPEG2_DELIMITER4;
-                } else {
+                } else if(coded_buffer_segment->codec == CODEC_JPEG) {
+                    //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter.
+                    delimiter0 = 0xFF;
+                    delimiter1 = 0xD9;
+                }  else {
                     ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE);
                 }
 
-                for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
-                    if ((buffer[i] == delimiter0) &&
-                        (buffer[i + 1] == delimiter1) &&
-                        (buffer[i + 2] == delimiter2) &&
-                        (buffer[i + 3] == delimiter3) &&
-                        (buffer[i + 4] == delimiter4))
-                        break;
-                }
+                if(coded_buffer_segment->codec == CODEC_JPEG) {
+                    for(i = 0; i <  obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 1 - 0x1000; i++) {
+                        if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) {
+                            break;
+                        }
+                   }
+
+                   if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 1 - 0x1000) {
+                       coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+                   }
+ 
+                   coded_buffer_segment->base.size = i + 2;
+                } else {
+                    for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) {
+                        if ((buffer[i] == delimiter0) &&
+                            (buffer[i + 1] == delimiter1) &&
+                            (buffer[i + 2] == delimiter2) &&
+                            (buffer[i + 3] == delimiter3) &&
+                            (buffer[i + 4] == delimiter4))
+                            break;
+                        }
 
-                if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
-                    coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+                        if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) {
+                            coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK;
+                        }
+                    coded_buffer_segment->base.size = i;
                 }
 
-                coded_buffer_segment->base.size = i;
                 coded_buffer_segment->mapped = 1;
             } else {
                 assert(coded_buffer_segment->base.buf);
@@ -2462,6 +2512,7 @@ i965_decoder_render_picture(VADriverContextP ctx,
 // DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_control, pic_control)
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(qmatrix, q_matrix)
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(iqmatrix, iq_matrix)
+DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(huffman_table, huffman_table)
 /* extended buffer */
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(sequence_parameter_ext, seq_param_ext)
 DEF_RENDER_ENCODE_SINGLE_BUFFER_FUNC(picture_parameter_ext, pic_param_ext)
@@ -2565,6 +2616,10 @@ i965_encoder_render_picture(VADriverContextP ctx,
             vaStatus = I965_RENDER_ENCODE_BUFFER(picture_parameter_ext);
             break;
 
+        case VAHuffmanTableBufferType:
+            vaStatus = I965_RENDER_ENCODE_BUFFER(huffman_table);
+            break;
+
         case VAEncSliceParameterBufferType:
             vaStatus = I965_RENDER_ENCODE_BUFFER(slice_parameter_ext);
             if (vaStatus == VA_STATUS_SUCCESS) {
@@ -2780,7 +2835,8 @@ i965_RenderPicture(VADriverContextP ctx,
 
     if (VAEntrypointVideoProc == obj_config->entrypoint) {
         vaStatus = i965_proc_render_picture(ctx, context, buffers, num_buffers);
-    } else if (VAEntrypointEncSlice == obj_config->entrypoint ) {
+    } else if ((VAEntrypointEncSlice == obj_config->entrypoint ) || 
+               (VAEntrypointEncPicture == obj_config->entrypoint)) {
         vaStatus = i965_encoder_render_picture(ctx, context, buffers, num_buffers);
     } else {
         vaStatus = i965_decoder_render_picture(ctx, context, buffers, num_buffers);
@@ -2803,7 +2859,7 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
     if (obj_context->codec_type == CODEC_PROC) {
         ASSERT_RET(VAEntrypointVideoProc == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
     } else if (obj_context->codec_type == CODEC_ENC) {
-        ASSERT_RET(VAEntrypointEncSlice == obj_config->entrypoint, VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
+        ASSERT_RET(((VAEntrypointEncSlice == obj_config->entrypoint) || (VAEntrypointEncPicture == obj_config->entrypoint)), VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT);
 
         if (obj_context->codec_state.encode.num_packed_header_params_ext !=
                obj_context->codec_state.encode.num_packed_header_data_ext) {
@@ -2815,7 +2871,8 @@ i965_EndPicture(VADriverContextP ctx, VAContextID context)
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
         if (!(obj_context->codec_state.encode.seq_param ||
-                obj_context->codec_state.encode.seq_param_ext)) {
+                obj_context->codec_state.encode.seq_param_ext) &&
+                (VAEntrypointEncPicture != obj_config->entrypoint)) {
             return VA_STATUS_ERROR_INVALID_PARAMETER;
         }
         if ((obj_context->codec_state.encode.num_slice_params <=0) &&
diff --git a/src/i965_drv_video.h b/src/i965_drv_video.h
index ac028eb..dde9399 100644
--- a/src/i965_drv_video.h
+++ b/src/i965_drv_video.h
@@ -33,6 +33,7 @@
 #include <va/va.h>
 #include <va/va_enc_h264.h>
 #include <va/va_enc_mpeg2.h>
+#include <va/va_enc_jpeg.h>
 #include <va/va_vpp.h>
 #include <va/va_backend.h>
 #include <va/va_backend_vpp.h>
@@ -142,6 +143,7 @@ struct encode_state
     struct buffer_store *iq_matrix;
     struct buffer_store *q_matrix;
     struct buffer_store **slice_params;
+    struct buffer_store *huffman_table;
     int max_slice_params;
     int num_slice_params;
 
@@ -347,6 +349,7 @@ struct hw_codec_info
     unsigned int h264_mvc_dec_profiles;
     unsigned int h264_dec_chroma_formats;
     unsigned int jpeg_dec_chroma_formats;
+    unsigned int jpeg_enc_chroma_formats;
 
     unsigned int has_mpeg2_decoding:1;
     unsigned int has_mpeg2_encoding:1;
@@ -449,6 +452,7 @@ va_enc_packed_type_to_idx(int packed_type);
 #define CODEC_H264      0
 #define CODEC_MPEG2     1
 #define CODEC_H264_MVC  2
+#define CODEC_JPEG      3
 
 #define H264_DELIMITER0 0x00
 #define H264_DELIMITER1 0x00
@@ -469,7 +473,7 @@ struct i965_coded_buffer_segment
     unsigned char codec;
 };
 
-#define I965_CODEDBUFFER_HEADER_SIZE   ALIGN(sizeof(struct i965_coded_buffer_segment), 64)
+#define I965_CODEDBUFFER_HEADER_SIZE   ALIGN(sizeof(struct i965_coded_buffer_segment), 0x1000)
 
 extern VAStatus i965_MapBuffer(VADriverContextP ctx,
 		VABufferID buf_id,       /* in */
-- 
2.1.0



More information about the Libva mailing list