hardware/intel/intel-driver
Revision | d966272b0b4dd9161eb9f69c07dcbdd1476e7886 (tree) |
---|---|
Time | 2015-03-19 11:01:29 |
Author | Qu,Pengfei <Pengfei.Qu@inte...> |
Commiter | Xiang, Haihao |
HEVC ENC:Added HEVC support in API function
Signed-off-by: Qu,Pengfei <Pengfei.Qu@intel.com>
(cherry picked from commit d4f1087a0606c7c8d2d5fd65d9f46990f41ce93a)
@@ -345,6 +345,7 @@ static struct hw_codec_info skl_hw_codec_info = { | ||
345 | 345 | .has_vp8_encoding = 1, |
346 | 346 | .has_h264_mvc_encoding = 1, |
347 | 347 | .has_hevc_decoding = 1, |
348 | + .has_hevc_encoding = 1, | |
348 | 349 | |
349 | 350 | .num_filters = 5, |
350 | 351 | .filters = { |
@@ -1,5 +1,5 @@ | ||
1 | 1 | /* |
2 | - * Copyright © 2009 Intel Corporation | |
2 | + * Copyright ?2009 Intel Corporation | |
3 | 3 | * |
4 | 4 | * Permission is hereby granted, free of charge, to any person obtaining a |
5 | 5 | * copy of this software and associated documentation files (the |
@@ -102,6 +102,9 @@ | ||
102 | 102 | #define HAS_HEVC_DECODING(ctx) ((ctx)->codec_info->has_hevc_decoding && \ |
103 | 103 | (ctx)->intel.has_bsd) |
104 | 104 | |
105 | +#define HAS_HEVC_ENCODING(ctx) ((ctx)->codec_info->has_hevc_encoding && \ | |
106 | + (ctx)->intel.has_bsd) | |
107 | + | |
105 | 108 | static int get_sampling_from_fourcc(unsigned int fourcc); |
106 | 109 | |
107 | 110 | /* Check whether we are rendering to X11 (VA/X11 or VA/GLX API) */ |
@@ -374,7 +377,10 @@ is_image_busy(struct i965_driver_data *i965, struct object_image *obj_image) | ||
374 | 377 | } |
375 | 378 | |
376 | 379 | #define I965_PACKED_HEADER_BASE 0 |
377 | -#define I965_PACKED_MISC_HEADER_BASE 3 | |
380 | +#define I965_SEQ_PACKED_HEADER_BASE 0 | |
381 | +#define I965_SEQ_PACKED_HEADER_END 2 | |
382 | +#define I965_PIC_PACKED_HEADER_BASE 2 | |
383 | +#define I965_PACKED_MISC_HEADER_BASE 4 | |
378 | 384 | |
379 | 385 | int |
380 | 386 | va_enc_packed_type_to_idx(int packed_type) |
@@ -391,15 +397,15 @@ va_enc_packed_type_to_idx(int packed_type) | ||
391 | 397 | |
392 | 398 | switch (packed_type) { |
393 | 399 | case VAEncPackedHeaderSequence: |
394 | - idx = I965_PACKED_HEADER_BASE + 0; | |
400 | + idx = I965_SEQ_PACKED_HEADER_BASE + 0; | |
395 | 401 | break; |
396 | 402 | |
397 | 403 | case VAEncPackedHeaderPicture: |
398 | - idx = I965_PACKED_HEADER_BASE + 1; | |
404 | + idx = I965_PIC_PACKED_HEADER_BASE + 0; | |
399 | 405 | break; |
400 | 406 | |
401 | 407 | case VAEncPackedHeaderSlice: |
402 | - idx = I965_PACKED_HEADER_BASE + 2; | |
408 | + idx = I965_PIC_PACKED_HEADER_BASE + 1; | |
403 | 409 | break; |
404 | 410 | |
405 | 411 | default: |
@@ -409,7 +415,7 @@ va_enc_packed_type_to_idx(int packed_type) | ||
409 | 415 | } |
410 | 416 | } |
411 | 417 | |
412 | - ASSERT_RET(idx < 4, 0); | |
418 | + ASSERT_RET(idx < 5, 0); | |
413 | 419 | return idx; |
414 | 420 | } |
415 | 421 |
@@ -463,7 +469,8 @@ i965_QueryConfigProfiles(VADriverContextP ctx, | ||
463 | 469 | profile_list[i++] = VAProfileH264StereoHigh; |
464 | 470 | } |
465 | 471 | |
466 | - if (HAS_HEVC_DECODING(i965)) { | |
472 | + if (HAS_HEVC_DECODING(i965)|| | |
473 | + HAS_HEVC_ENCODING(i965)) { | |
467 | 474 | profile_list[i++] = VAProfileHEVCMain; |
468 | 475 | } |
469 | 476 |
@@ -546,6 +553,9 @@ i965_QueryConfigEntrypoints(VADriverContextP ctx, | ||
546 | 553 | if (HAS_HEVC_DECODING(i965)) |
547 | 554 | entrypoint_list[n++] = VAEntrypointVLD; |
548 | 555 | |
556 | + if (HAS_HEVC_ENCODING(i965)) | |
557 | + entrypoint_list[n++] = VAEntrypointEncSlice; | |
558 | + | |
549 | 559 | break; |
550 | 560 | |
551 | 561 | default: |
@@ -637,7 +647,8 @@ i965_validate_config(VADriverContextP ctx, VAProfile profile, | ||
637 | 647 | break; |
638 | 648 | |
639 | 649 | case VAProfileHEVCMain: |
640 | - if (HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD)) | |
650 | + if ((HAS_HEVC_DECODING(i965) && (entrypoint == VAEntrypointVLD))|| | |
651 | + (HAS_HEVC_ENCODING(i965) && (entrypoint == VAEntrypointEncSlice))) | |
641 | 652 | va_status = VA_STATUS_SUCCESS; |
642 | 653 | else |
643 | 654 | va_status = VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; |
@@ -729,7 +740,8 @@ i965_GetConfigAttributes(VADriverContextP ctx, | ||
729 | 740 | profile == VAProfileH264Main || |
730 | 741 | profile == VAProfileH264High || |
731 | 742 | profile == VAProfileH264StereoHigh || |
732 | - profile == VAProfileH264MultiviewHigh) { | |
743 | + profile == VAProfileH264MultiviewHigh || | |
744 | + profile == VAProfileHEVCMain) { | |
733 | 745 | attrib_list[i].value |= (VA_ENC_PACKED_HEADER_RAW_DATA | |
734 | 746 | VA_ENC_PACKED_HEADER_SLICE); |
735 | 747 | } |
@@ -1886,6 +1898,8 @@ i965_CreateContext(VADriverContextP ctx, | ||
1886 | 1898 | obj_context->codec_state.encode.slice_header_index = |
1887 | 1899 | calloc(obj_context->codec_state.encode.max_slice_num, sizeof(int)); |
1888 | 1900 | |
1901 | + obj_context->codec_state.encode.vps_sps_seq_index = 0; | |
1902 | + | |
1889 | 1903 | obj_context->codec_state.encode.slice_index = 0; |
1890 | 1904 | packed_attrib = i965_lookup_config_attribute(obj_config, VAConfigAttribEncPackedHeaders); |
1891 | 1905 | if (packed_attrib) |
@@ -1972,6 +1986,20 @@ i965_create_buffer_internal(VADriverContextP ctx, | ||
1972 | 1986 | struct object_buffer *obj_buffer = NULL; |
1973 | 1987 | struct buffer_store *buffer_store = NULL; |
1974 | 1988 | int bufferID; |
1989 | + struct object_context *obj_context = NULL; | |
1990 | + struct object_config *obj_config = NULL; | |
1991 | + VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; | |
1992 | + | |
1993 | + if (i965->current_context_id == VA_INVALID_ID) | |
1994 | + return vaStatus; | |
1995 | + | |
1996 | + obj_context = CONTEXT(i965->current_context_id); | |
1997 | + | |
1998 | + if (!obj_context) | |
1999 | + return vaStatus; | |
2000 | + | |
2001 | + obj_config = obj_context->obj_config; | |
2002 | + assert(obj_config); | |
1975 | 2003 | |
1976 | 2004 | /* Validate type */ |
1977 | 2005 | switch (type) { |
@@ -2045,7 +2073,11 @@ i965_create_buffer_internal(VADriverContextP ctx, | ||
2045 | 2073 | struct i965_coded_buffer_segment *coded_buffer_segment; |
2046 | 2074 | |
2047 | 2075 | dri_bo_map(buffer_store->bo, 1); |
2048 | - coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual; | |
2076 | + if(obj_config->profile == VAProfileHEVCMain){ | |
2077 | + coded_buffer_segment = (struct i965_coded_buffer_segment *)(buffer_store->bo->virtual + ALIGN(size - 0x1000, 0x1000)); | |
2078 | + }else { | |
2079 | + coded_buffer_segment = (struct i965_coded_buffer_segment *)buffer_store->bo->virtual; | |
2080 | + } | |
2049 | 2081 | coded_buffer_segment->base.size = size - I965_CODEDBUFFER_HEADER_SIZE; |
2050 | 2082 | coded_buffer_segment->base.bit_offset = 0; |
2051 | 2083 | coded_buffer_segment->base.status = 0; |
@@ -2123,9 +2155,22 @@ i965_MapBuffer(VADriverContextP ctx, | ||
2123 | 2155 | void **pbuf) /* out */ |
2124 | 2156 | { |
2125 | 2157 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
2158 | + struct object_context *obj_context = NULL; | |
2159 | + struct object_config *obj_config = NULL; | |
2126 | 2160 | struct object_buffer *obj_buffer = BUFFER(buf_id); |
2127 | 2161 | VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; |
2128 | 2162 | |
2163 | + if (i965->current_context_id == VA_INVALID_ID) | |
2164 | + return vaStatus; | |
2165 | + | |
2166 | + obj_context = CONTEXT(i965->current_context_id); | |
2167 | + | |
2168 | + if (!obj_context) | |
2169 | + return vaStatus; | |
2170 | + | |
2171 | + obj_config = obj_context->obj_config; | |
2172 | + assert(obj_config); | |
2173 | + | |
2129 | 2174 | ASSERT_RET(obj_buffer && obj_buffer->buffer_store, VA_STATUS_ERROR_INVALID_BUFFER); |
2130 | 2175 | ASSERT_RET(obj_buffer->buffer_store->bo || obj_buffer->buffer_store->buffer, VA_STATUS_ERROR_INVALID_BUFFER); |
2131 | 2176 | ASSERT_RET(!(obj_buffer->buffer_store->bo && obj_buffer->buffer_store->buffer), VA_STATUS_ERROR_INVALID_BUFFER); |
@@ -2149,6 +2194,7 @@ i965_MapBuffer(VADriverContextP ctx, | ||
2149 | 2194 | if (obj_buffer->type == VAEncCodedBufferType) { |
2150 | 2195 | int i; |
2151 | 2196 | unsigned char *buffer = NULL; |
2197 | + unsigned int header_offset = I965_CODEDBUFFER_HEADER_SIZE; | |
2152 | 2198 | struct i965_coded_buffer_segment *coded_buffer_segment = (struct i965_coded_buffer_segment *)(obj_buffer->buffer_store->bo->virtual); |
2153 | 2199 | |
2154 | 2200 | if (!coded_buffer_segment->mapped) { |
@@ -2173,12 +2219,18 @@ i965_MapBuffer(VADriverContextP ctx, | ||
2173 | 2219 | //In JPEG End of Image (EOI = 0xDDF9) marker can be used for delimiter. |
2174 | 2220 | delimiter0 = 0xFF; |
2175 | 2221 | delimiter1 = 0xD9; |
2222 | + } else if (coded_buffer_segment->codec == CODEC_HEVC) { | |
2223 | + delimiter0 = HEVC_DELIMITER0; | |
2224 | + delimiter1 = HEVC_DELIMITER1; | |
2225 | + delimiter2 = HEVC_DELIMITER2; | |
2226 | + delimiter3 = HEVC_DELIMITER3; | |
2227 | + delimiter4 = HEVC_DELIMITER4; | |
2176 | 2228 | } else if (coded_buffer_segment->codec != CODEC_VP8) { |
2177 | 2229 | ASSERT_RET(0, VA_STATUS_ERROR_UNSUPPORTED_PROFILE); |
2178 | 2230 | } |
2179 | 2231 | |
2180 | 2232 | if(coded_buffer_segment->codec == CODEC_JPEG) { |
2181 | - for(i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 1 - 0x1000; i++) { | |
2233 | + for(i = 0; i < obj_buffer->size_element - header_offset - 1 - 0x1000; i++) { | |
2182 | 2234 | if( (buffer[i] == 0xFF) && (buffer[i + 1] == 0xD9)) { |
2183 | 2235 | break; |
2184 | 2236 | } |
@@ -2187,22 +2239,22 @@ i965_MapBuffer(VADriverContextP ctx, | ||
2187 | 2239 | } else if (coded_buffer_segment->codec != CODEC_VP8) { |
2188 | 2240 | /* vp8 coded buffer size can be told by vp8 internal statistics buffer, |
2189 | 2241 | so it don't need to traversal the coded buffer */ |
2190 | - for (i = 0; i < obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000; i++) { | |
2242 | + for (i = 0; i < obj_buffer->size_element - header_offset - 3 - 0x1000; i++) { | |
2191 | 2243 | if ((buffer[i] == delimiter0) && |
2192 | 2244 | (buffer[i + 1] == delimiter1) && |
2193 | 2245 | (buffer[i + 2] == delimiter2) && |
2194 | 2246 | (buffer[i + 3] == delimiter3) && |
2195 | 2247 | (buffer[i + 4] == delimiter4)) |
2196 | 2248 | break; |
2197 | - } | |
2249 | + } | |
2198 | 2250 | |
2199 | - if (i == obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 3 - 0x1000) { | |
2200 | - coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK; | |
2201 | - } | |
2251 | + if (i == obj_buffer->size_element - header_offset - 3 - 0x1000) { | |
2252 | + coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK; | |
2253 | + } | |
2202 | 2254 | coded_buffer_segment->base.size = i; |
2203 | 2255 | } |
2204 | 2256 | |
2205 | - if (coded_buffer_segment->base.size >= obj_buffer->size_element - I965_CODEDBUFFER_HEADER_SIZE - 0x1000) { | |
2257 | + if (coded_buffer_segment->base.size >= obj_buffer->size_element - header_offset - 0x1000) { | |
2206 | 2258 | coded_buffer_segment->base.status |= VA_CODED_BUF_STATUS_SLICE_OVERFLOW_MASK; |
2207 | 2259 | } |
2208 | 2260 |
@@ -2376,6 +2428,7 @@ i965_BeginPicture(VADriverContextP ctx, | ||
2376 | 2428 | obj_context->codec_state.encode.num_packed_header_params_ext = 0; |
2377 | 2429 | obj_context->codec_state.encode.num_packed_header_data_ext = 0; |
2378 | 2430 | obj_context->codec_state.encode.slice_index = 0; |
2431 | + obj_context->codec_state.encode.vps_sps_seq_index = 0; | |
2379 | 2432 | } else { |
2380 | 2433 | obj_context->codec_state.decode.current_render_target = render_target; |
2381 | 2434 | i965_release_buffer_store(&obj_context->codec_state.decode.pic_param); |
@@ -2579,11 +2632,14 @@ i965_encoder_render_picture(VADriverContextP ctx, | ||
2579 | 2632 | { |
2580 | 2633 | struct i965_driver_data *i965 = i965_driver_data(ctx); |
2581 | 2634 | struct object_context *obj_context = CONTEXT(context); |
2635 | + struct object_config *obj_config; | |
2582 | 2636 | VAStatus vaStatus = VA_STATUS_ERROR_UNKNOWN; |
2583 | 2637 | struct encode_state *encode; |
2584 | 2638 | int i; |
2585 | 2639 | |
2586 | 2640 | ASSERT_RET(obj_context, VA_STATUS_ERROR_INVALID_CONTEXT); |
2641 | + obj_config = obj_context->obj_config; | |
2642 | + ASSERT_RET(obj_config, VA_STATUS_ERROR_INVALID_CONFIG); | |
2587 | 2643 | |
2588 | 2644 | encode = &obj_context->codec_state.encode; |
2589 | 2645 | for (i = 0; i < num_buffers; i++) { |
@@ -2657,6 +2713,12 @@ i965_encoder_render_picture(VADriverContextP ctx, | ||
2657 | 2713 | if ((param->type == VAEncPackedHeaderRawData) || |
2658 | 2714 | (param->type == VAEncPackedHeaderSlice)) { |
2659 | 2715 | vaStatus = I965_RENDER_ENCODE_BUFFER(packed_header_params_ext); |
2716 | + } else if((obj_config->profile == VAProfileHEVCMain)&& | |
2717 | + (encode->last_packed_header_type == VAEncPackedHeaderSequence)) { | |
2718 | + vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx, | |
2719 | + obj_context, | |
2720 | + obj_buffer, | |
2721 | + va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index); | |
2660 | 2722 | } else { |
2661 | 2723 | vaStatus = i965_encoder_render_packed_header_parameter_buffer(ctx, |
2662 | 2724 | obj_context, |
@@ -2744,10 +2806,22 @@ i965_encoder_render_picture(VADriverContextP ctx, | ||
2744 | 2806 | (((encode->last_packed_header_type & VAEncPackedHeaderMiscMask) == VAEncPackedHeaderMiscMask) && |
2745 | 2807 | ((encode->last_packed_header_type & (~VAEncPackedHeaderMiscMask)) != 0)), |
2746 | 2808 | VA_STATUS_ERROR_ENCODING_ERROR); |
2747 | - vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, | |
2748 | - obj_context, | |
2749 | - obj_buffer, | |
2750 | - va_enc_packed_type_to_idx(encode->last_packed_header_type)); | |
2809 | + | |
2810 | + if((obj_config->profile == VAProfileHEVCMain)&& | |
2811 | + (encode->last_packed_header_type == VAEncPackedHeaderSequence)) { | |
2812 | + | |
2813 | + vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, | |
2814 | + obj_context, | |
2815 | + obj_buffer, | |
2816 | + va_enc_packed_type_to_idx(encode->last_packed_header_type) + encode->vps_sps_seq_index); | |
2817 | + encode->vps_sps_seq_index = (encode->vps_sps_seq_index + 1) % I965_SEQ_PACKED_HEADER_END; | |
2818 | + }else{ | |
2819 | + vaStatus = i965_encoder_render_packed_header_data_buffer(ctx, | |
2820 | + obj_context, | |
2821 | + obj_buffer, | |
2822 | + va_enc_packed_type_to_idx(encode->last_packed_header_type)); | |
2823 | + | |
2824 | + } | |
2751 | 2825 | } |
2752 | 2826 | encode->last_packed_header_type = 0; |
2753 | 2827 | break; |