[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