diff options
| author | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-01-29 19:07:37 +0100 |
|---|---|---|
| committer | Gwenole Beauchesne <gwenole.beauchesne@intel.com> | 2012-02-01 23:56:41 +0100 |
| commit | 368731d104da84605fcf6683d6ce014916fe76b0 (patch) | |
| tree | 17c854ad111702a10ea55d3ba1a28efc28933a52 | |
| parent | 99ded53e66af1903f1d58ffbc24404d435a6de84 (diff) | |
h264: fix and simplify REF_IDX_STATE (ILK, SNB, IVB).
Original code was parsing RefPicList0/1 over what is actually available
and filled in, i.e. wrt. num_ref_idx_l0/1_minus1 + 1. Besides, bit 5 of
Reference List Entry set to 1 means a frame, not a field.
Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
| -rw-r--r-- | NEWS | 5 | ||||
| -rw-r--r-- | src/Makefile.am | 2 | ||||
| -rw-r--r-- | src/gen6_mfd.c | 77 | ||||
| -rw-r--r-- | src/gen7_mfd.c | 77 | ||||
| -rw-r--r-- | src/i965_avc_bsd.c | 60 | ||||
| -rw-r--r-- | src/i965_decoder_utils.c | 130 | ||||
| -rw-r--r-- | src/i965_decoder_utils.h | 45 |
7 files changed, 210 insertions, 186 deletions
@@ -1,6 +1,9 @@ -libva-driver-intel NEWS -- summary of changes. 2011-10-28 +libva-driver-intel NEWS -- summary of changes. 2012-02-DD Copyright (C) 2009-2011 Intel Corporation +Version 1.0.16 - DD.Feb.2012 +* Fix and simplify AVC_REF_IDX_STATE setup (ILK, SNB, IVB) + Version 1.0.15 - 28.Oct.2011 * Add auto-generated Debian packaging * Fix VC-1 decoding (TTFRM packing) diff --git a/src/Makefile.am b/src/Makefile.am index f472655..1e4bbf2 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -54,6 +54,7 @@ source_c = \ i965_avc_bsd.c \ i965_avc_hw_scoreboard.c\ i965_avc_ildb.c \ + i965_decoder_utils.c \ i965_drv_video.c \ i965_encoder.c \ i965_media.c \ @@ -77,6 +78,7 @@ source_h = \ i965_avc_hw_scoreboard.h\ i965_avc_ildb.h \ i965_decoder.h \ + i965_decoder_utils.h \ i965_defines.h \ i965_drv_video.h \ i965_encoder.h \ diff --git a/src/gen6_mfd.c b/src/gen6_mfd.c index a38360b..811135c 100644 --- a/src/gen6_mfd.c +++ b/src/gen6_mfd.c @@ -36,6 +36,7 @@ #include "i965_defines.h" #include "i965_drv_video.h" +#include "i965_decoder_utils.h" #include "gen6_mfd.h" @@ -781,81 +782,17 @@ gen6_mfd_avc_phantom_slice_state(VADriverContextP ctx, ADVANCE_BCS_BATCH(batch); } -static void +static inline void gen6_mfd_avc_ref_idx_state(VADriverContextP ctx, VAPictureParameterBufferH264 *pic_param, VASliceParameterBufferH264 *slice_param, struct gen6_mfd_context *gen6_mfd_context) { - struct intel_batchbuffer *batch = gen6_mfd_context->base.batch; - int i, j, num_ref_list; - struct { - unsigned char bottom_idc:1; - unsigned char frame_store_index:4; - unsigned char field_picture:1; - unsigned char long_term:1; - unsigned char non_exist:1; - } refs[32]; - - if (slice_param->slice_type == SLICE_TYPE_I || - slice_param->slice_type == SLICE_TYPE_SI) - return; - - if (slice_param->slice_type == SLICE_TYPE_P || - slice_param->slice_type == SLICE_TYPE_SP) { - num_ref_list = 1; - } else { - num_ref_list = 2; - } - - for (i = 0; i < num_ref_list; i++) { - VAPictureH264 *va_pic; - - if (i == 0) { - va_pic = slice_param->RefPicList0; - } else { - va_pic = slice_param->RefPicList1; - } - - BEGIN_BCS_BATCH(batch, 10); - OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2)); - OUT_BCS_BATCH(batch, i); - - for (j = 0; j < 32; j++) { - if (va_pic->flags & VA_PICTURE_H264_INVALID) { - refs[j].non_exist = 1; - refs[j].long_term = 1; - refs[j].field_picture = 1; - refs[j].frame_store_index = 0xf; - refs[j].bottom_idc = 1; - } else { - int frame_idx; - - for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface); frame_idx++) { - if (gen6_mfd_context->reference_surface[frame_idx].surface_id != VA_INVALID_ID && - va_pic->picture_id == gen6_mfd_context->reference_surface[frame_idx].surface_id) { - assert(frame_idx == gen6_mfd_context->reference_surface[frame_idx].frame_store_id); - break; - } - } - - assert(frame_idx < ARRAY_ELEMS(gen6_mfd_context->reference_surface)); - - refs[j].non_exist = 0; - refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE); - refs[j].field_picture = !!(va_pic->flags & - (VA_PICTURE_H264_TOP_FIELD | - VA_PICTURE_H264_BOTTOM_FIELD)); - refs[j].frame_store_index = frame_idx; - refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD); - } - - va_pic++; - } - - intel_batchbuffer_data(batch, refs, sizeof(refs)); - ADVANCE_BCS_BATCH(batch); - } + gen6_send_avc_ref_idx_state( + gen6_mfd_context->base.batch, + slice_param, + gen6_mfd_context->reference_surface + ); } static void diff --git a/src/gen7_mfd.c b/src/gen7_mfd.c index 07cc0c9..ca468cb 100644 --- a/src/gen7_mfd.c +++ b/src/gen7_mfd.c @@ -36,6 +36,7 @@ #include "i965_defines.h" #include "i965_drv_video.h" +#include "i965_decoder_utils.h" #include "gen7_mfd.h" @@ -750,81 +751,17 @@ gen7_mfd_avc_slice_state(VADriverContextP ctx, ADVANCE_BCS_BATCH(batch); } -static void +static inline void gen7_mfd_avc_ref_idx_state(VADriverContextP ctx, VAPictureParameterBufferH264 *pic_param, VASliceParameterBufferH264 *slice_param, struct gen7_mfd_context *gen7_mfd_context) { - struct intel_batchbuffer *batch = gen7_mfd_context->base.batch; - int i, j, num_ref_list; - struct { - unsigned char bottom_idc:1; - unsigned char frame_store_index:4; - unsigned char field_picture:1; - unsigned char long_term:1; - unsigned char non_exist:1; - } refs[32]; - - if (slice_param->slice_type == SLICE_TYPE_I || - slice_param->slice_type == SLICE_TYPE_SI) - return; - - if (slice_param->slice_type == SLICE_TYPE_P || - slice_param->slice_type == SLICE_TYPE_SP) { - num_ref_list = 1; - } else { - num_ref_list = 2; - } - - for (i = 0; i < num_ref_list; i++) { - VAPictureH264 *va_pic; - - if (i == 0) { - va_pic = slice_param->RefPicList0; - } else { - va_pic = slice_param->RefPicList1; - } - - BEGIN_BCS_BATCH(batch, 10); - OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2)); - OUT_BCS_BATCH(batch, i); - - for (j = 0; j < 32; j++) { - if (va_pic->flags & VA_PICTURE_H264_INVALID) { - refs[j].non_exist = 1; - refs[j].long_term = 1; - refs[j].field_picture = 1; - refs[j].frame_store_index = 0xf; - refs[j].bottom_idc = 1; - } else { - int frame_idx; - - for (frame_idx = 0; frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface); frame_idx++) { - if (gen7_mfd_context->reference_surface[frame_idx].surface_id != VA_INVALID_ID && - va_pic->picture_id == gen7_mfd_context->reference_surface[frame_idx].surface_id) { - assert(frame_idx == gen7_mfd_context->reference_surface[frame_idx].frame_store_id); - break; - } - } - - assert(frame_idx < ARRAY_ELEMS(gen7_mfd_context->reference_surface)); - - refs[j].non_exist = 0; - refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE); - refs[j].field_picture = !!(va_pic->flags & - (VA_PICTURE_H264_TOP_FIELD | - VA_PICTURE_H264_BOTTOM_FIELD)); - refs[j].frame_store_index = frame_idx; - refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD); - } - - va_pic++; - } - - intel_batchbuffer_data(batch, refs, sizeof(refs)); - ADVANCE_BCS_BATCH(batch); - } + gen6_send_avc_ref_idx_state( + gen7_mfd_context->base.batch, + slice_param, + gen7_mfd_context->reference_surface + ); } static void diff --git a/src/i965_avc_bsd.c b/src/i965_avc_bsd.c index 9fa9649..6f133a3 100644 --- a/src/i965_avc_bsd.c +++ b/src/i965_avc_bsd.c @@ -38,6 +38,7 @@ #include "i965_avc_bsd.h" #include "i965_media_h264.h" #include "i965_media.h" +#include "i965_decoder_utils.h" static void i965_avc_bsd_free_avc_bsd_surface(void **data) @@ -259,13 +260,7 @@ i965_avc_bsd_slice_state(VADriverContextP ctx, { struct intel_batchbuffer *batch = i965_h264_context->batch; int present_flag, cmd_len, list, j; - struct { - unsigned char bottom_idc:1; - unsigned char frame_store_index:4; - unsigned char field_picture:1; - unsigned char long_term:1; - unsigned char non_exist:1; - } refs[32]; + uint8_t ref_idx_state[32]; char weightoffsets[32 * 6]; /* don't issue SLICE_STATE for intra-prediction decoding */ @@ -302,53 +297,28 @@ i965_avc_bsd_slice_state(VADriverContextP ctx, OUT_BCS_BATCH(batch, present_flag); for (list = 0; list < 2; list++) { - int flag; + int flag, num_va_pics; VAPictureH264 *va_pic; if (list == 0) { - flag = PRESENT_REF_LIST0; - va_pic = slice_param->RefPicList0; + flag = PRESENT_REF_LIST0; + va_pic = slice_param->RefPicList0; + num_va_pics = slice_param->num_ref_idx_l0_active_minus1 + 1; } else { - flag = PRESENT_REF_LIST1; - va_pic = slice_param->RefPicList1; + flag = PRESENT_REF_LIST1; + va_pic = slice_param->RefPicList1; + num_va_pics = slice_param->num_ref_idx_l1_active_minus1 + 1; } if (!(present_flag & flag)) continue; - for (j = 0; j < 32; j++) { - if (va_pic->flags & VA_PICTURE_H264_INVALID) { - refs[j].non_exist = 1; - refs[j].long_term = 1; - refs[j].field_picture = 1; - refs[j].frame_store_index = 0xf; - refs[j].bottom_idc = 1; - } else { - int frame_idx; - - for (frame_idx = 0; frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list); frame_idx++) { - if (i965_h264_context->fsid_list[frame_idx].surface_id != VA_INVALID_ID && - va_pic->picture_id == i965_h264_context->fsid_list[frame_idx].surface_id) { - assert(frame_idx == i965_h264_context->fsid_list[frame_idx].frame_store_id); - break; - } - } - - assert(frame_idx < ARRAY_ELEMS(i965_h264_context->fsid_list)); - - refs[j].non_exist = 0; - refs[j].long_term = !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE); - refs[j].field_picture = !!(va_pic->flags & - (VA_PICTURE_H264_TOP_FIELD | - VA_PICTURE_H264_BOTTOM_FIELD)); - refs[j].frame_store_index = frame_idx; - refs[j].bottom_idc = !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD); - } - - va_pic++; - } - - intel_batchbuffer_data(batch, refs, sizeof(refs)); + gen5_fill_avc_ref_idx_state( + ref_idx_state, + va_pic, num_va_pics, + i965_h264_context->fsid_list + ); + intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state)); } i965_h264_context->weight128_luma_l0 = 0; diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c new file mode 100644 index 0000000..36f51c4 --- /dev/null +++ b/src/i965_decoder_utils.c @@ -0,0 +1,130 @@ +/* + * Copyright (C) 2006-2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include <assert.h> +#include <stddef.h> +#include "intel_batchbuffer.h" +#include "i965_decoder_utils.h" +#include "i965_defines.h" + +static inline uint8_t +get_ref_idx_state_1(const VAPictureH264 *va_pic, unsigned int frame_store_id) +{ + const unsigned int is_long_term = + !!(va_pic->flags & VA_PICTURE_H264_LONG_TERM_REFERENCE); + const unsigned int is_top_field = + !!(va_pic->flags & VA_PICTURE_H264_TOP_FIELD); + const unsigned int is_bottom_field = + !!(va_pic->flags & VA_PICTURE_H264_BOTTOM_FIELD); + + return ((is_long_term << 6) | + ((is_top_field ^ is_bottom_field ^ 1) << 5) | + (frame_store_id << 1) | + ((is_top_field ^ 1) & is_bottom_field)); +} + +/* Fill in Reference List Entries (Gen5+: ILK, SNB, IVB) */ +void +gen5_fill_avc_ref_idx_state( + uint8_t state[32], + const VAPictureH264 ref_list[32], + unsigned int ref_list_count, + const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] +) +{ + unsigned int i, n, frame_idx; + + for (i = 0, n = 0; i < ref_list_count; i++) { + const VAPictureH264 * const va_pic = &ref_list[i]; + + if (va_pic->flags & VA_PICTURE_H264_INVALID) + continue; + + for (frame_idx = 0; frame_idx < MAX_GEN_REFERENCE_FRAMES; frame_idx++) { + const GenFrameStore * const fs = &frame_store[frame_idx]; + if (fs->surface_id != VA_INVALID_ID && + fs->surface_id == va_pic->picture_id) { + assert(frame_idx == fs->frame_store_id); + break; + } + } + assert(frame_idx < MAX_GEN_REFERENCE_FRAMES); + state[n++] = get_ref_idx_state_1(va_pic, frame_idx); + } + + for (; n < 32; n++) + state[n] = 0xff; +} + +/* Emit Reference List Entries (Gen6+: SNB, IVB) */ +static void +gen6_send_avc_ref_idx_state_1( + struct intel_batchbuffer *batch, + unsigned int list, + const VAPictureH264 *ref_list, + unsigned int ref_list_count, + const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] +) +{ + uint8_t ref_idx_state[32]; + + BEGIN_BCS_BATCH(batch, 10); + OUT_BCS_BATCH(batch, MFX_AVC_REF_IDX_STATE | (10 - 2)); + OUT_BCS_BATCH(batch, list); + gen5_fill_avc_ref_idx_state( + ref_idx_state, + ref_list, ref_list_count, + frame_store + ); + intel_batchbuffer_data(batch, ref_idx_state, sizeof(ref_idx_state)); + ADVANCE_BCS_BATCH(batch); +} + +void +gen6_send_avc_ref_idx_state( + struct intel_batchbuffer *batch, + const VASliceParameterBufferH264 *slice_param, + const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] +) +{ + if (slice_param->slice_type == SLICE_TYPE_I || + slice_param->slice_type == SLICE_TYPE_SI) + return; + + /* RefPicList0 */ + gen6_send_avc_ref_idx_state_1( + batch, 0, + slice_param->RefPicList0, slice_param->num_ref_idx_l0_active_minus1 + 1, + frame_store + ); + + if (slice_param->slice_type != SLICE_TYPE_B) + return; + + /* RefPicList1 */ + gen6_send_avc_ref_idx_state_1( + batch, 1, + slice_param->RefPicList1, slice_param->num_ref_idx_l1_active_minus1 + 1, + frame_store + ); +} diff --git a/src/i965_decoder_utils.h b/src/i965_decoder_utils.h new file mode 100644 index 0000000..6390ecc --- /dev/null +++ b/src/i965_decoder_utils.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2006-2012 Intel Corporation + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the next + * paragraph) shall be included in all copies or substantial portions of the + * Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#ifndef I965_DECODER_UTILS_H +#define I965_DECODER_UTILS_H + +#include "i965_decoder.h" +#include "intel_batchbuffer.h" + +void +gen5_fill_avc_ref_idx_state( + uint8_t state[32], + const VAPictureH264 ref_list[32], + unsigned int ref_list_count, + const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] +); + +void +gen6_send_avc_ref_idx_state( + struct intel_batchbuffer *batch, + const VASliceParameterBufferH264 *slice_param, + const GenFrameStore frame_store[MAX_GEN_REFERENCE_FRAMES] +); + +#endif /* I965_DECODER_UTILS_H */ |
