summaryrefslogtreecommitdiff
path: root/src/i965_decoder_utils.c
diff options
context:
space:
mode:
authorGwenole Beauchesne <gwenole.beauchesne@intel.com>2014-05-14 13:59:25 +0200
committerGwenole Beauchesne <gwenole.beauchesne@intel.com>2014-06-02 19:30:43 +0200
commit6d76944605a75872714744262ce0370581de9225 (patch)
tree1a95fe02762edb4391c91098f04efb82929ebe05 /src/i965_decoder_utils.c
parente29345cbdc26d5e4c6729100344eb8dbf9e35b65 (diff)
decoder: h264: factor out allocation of reconstructed surfaces.
Add new avc_ensure_surface_bo() helper function to factor out the allocatiion and initialization processes of the reconstructed VA surface buffer stores. Keep preferred native format (NV12) and initialize chroma values to 0.0 (0x80) when needed for "fake" grayscale (Y800) surfaces implemented on top of existing NV12. Signed-off-by: Gwenole Beauchesne <gwenole.beauchesne@intel.com>
Diffstat (limited to 'src/i965_decoder_utils.c')
-rw-r--r--src/i965_decoder_utils.c54
1 files changed, 53 insertions, 1 deletions
diff --git a/src/i965_decoder_utils.c b/src/i965_decoder_utils.c
index 7ebc3fa..18704fe 100644
--- a/src/i965_decoder_utils.c
+++ b/src/i965_decoder_utils.c
@@ -174,6 +174,58 @@ mpeg2_set_reference_surfaces(
}
}
+/* Ensure the supplied VA surface has valid storage for decoding the
+ current picture */
+VAStatus
+avc_ensure_surface_bo(
+ VADriverContextP ctx,
+ struct decode_state *decode_state,
+ struct object_surface *obj_surface,
+ const VAPictureParameterBufferH264 *pic_param
+)
+{
+ VAStatus va_status;
+ uint32_t hw_fourcc, fourcc, subsample;
+
+ /* Validate chroma format */
+ switch (pic_param->seq_fields.bits.chroma_format_idc) {
+ case 0: // Grayscale
+ fourcc = VA_FOURCC_Y800;
+ subsample = SUBSAMPLE_YUV400;
+ break;
+ case 1: // YUV 4:2:0
+ fourcc = VA_FOURCC_NV12;
+ subsample = SUBSAMPLE_YUV420;
+ break;
+ default:
+ return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT;
+ }
+
+ /* XXX: always allocate NV12 (YUV 4:2:0) surfaces for now */
+ hw_fourcc = VA_FOURCC_NV12;
+ subsample = SUBSAMPLE_YUV420;
+
+ /* (Re-)allocate the underlying surface buffer store, if necessary */
+ if (!obj_surface->bo || obj_surface->fourcc != hw_fourcc) {
+ i965_destroy_surface_storage(obj_surface);
+ va_status = i965_check_alloc_surface_bo(ctx, obj_surface, 1,
+ hw_fourcc, subsample);
+ if (va_status != VA_STATUS_SUCCESS)
+ return va_status;
+ }
+
+ /* Fake chroma components if grayscale is implemented on top of NV12 */
+ if (fourcc == VA_FOURCC_Y800 && hw_fourcc == VA_FOURCC_NV12) {
+ const uint32_t uv_offset = obj_surface->width * obj_surface->height;
+ const uint32_t uv_size = obj_surface->width * obj_surface->height / 2;
+
+ drm_intel_gem_bo_map_gtt(obj_surface->bo);
+ memset(obj_surface->bo->virtual + uv_offset, 0x80, uv_size);
+ drm_intel_gem_bo_unmap_gtt(obj_surface->bo);
+ }
+ return VA_STATUS_SUCCESS;
+}
+
/* Generate flat scaling matrices for H.264 decoding */
void
avc_gen_default_iq_matrix(VAIQMatrixBufferH264 *iq_matrix)
@@ -423,7 +475,7 @@ intel_update_avc_frame_store_index(VADriverContextP ctx,
* Sometimes a dummy frame comes from the upper layer library, call i965_check_alloc_surface_bo()
* to ake sure the store buffer is allocated for this reference frame
*/
- i965_check_alloc_surface_bo(ctx, obj_surface, 1, VA_FOURCC_NV12, SUBSAMPLE_YUV420);
+ avc_ensure_surface_bo(ctx, decode_state, obj_surface, pic_param);
slot_found = 0;
frame_idx = -1;