Home | History | Annotate | Download | only in src
      1 /*
      2  * Copyright (c) 2011 Intel Corporation. All Rights Reserved.
      3  * Copyright (c) Imagination Technologies Limited, UK
      4  *
      5  * Permission is hereby granted, free of charge, to any person obtaining a
      6  * copy of this software and associated documentation files (the
      7  * "Software"), to deal in the Software without restriction, including
      8  * without limitation the rights to use, copy, modify, merge, publish,
      9  * distribute, sub license, and/or sell copies of the Software, and to
     10  * permit persons to whom the Software is furnished to do so, subject to
     11  * the following conditions:
     12  *
     13  * The above copyright notice and this permission notice (including the
     14  * next paragraph) shall be included in all copies or substantial portions
     15  * of the Software.
     16  *
     17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
     18  * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
     19  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
     20  * IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
     21  * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
     22  * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
     23  * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
     24  */
     25 
     26 /*
     27  * Authors:
     28  *    Li Zeng <li.zeng (at) intel.com>
     29  */
     30 #include "tng_vld_dec.h"
     31 #include "psb_drv_debug.h"
     32 #include "hwdefs/dxva_fw_ctrl.h"
     33 #include "hwdefs/reg_io2.h"
     34 #include "hwdefs/msvdx_offsets.h"
     35 #include "hwdefs/msvdx_cmds_io2.h"
     36 #include "va/va_dec_jpeg.h"
     37 #include "va/va_dec_vp8.h"
     38 
     39 #define GET_SURFACE_INFO_colocated_index(psb_surface) ((int) (psb_surface->extra_info[3]))
     40 #define SET_SURFACE_INFO_colocated_index(psb_surface, val) psb_surface->extra_info[3] = (uint32_t) val;
     41 
     42 /* Set MSVDX Front end register */
     43 void vld_dec_FE_state(object_context_p obj_context, psb_buffer_p buf)
     44 {
     45     psb_cmdbuf_p cmdbuf = obj_context->cmdbuf;
     46     context_DEC_p ctx = (context_DEC_p) obj_context->format_data;
     47     CTRL_ALLOC_HEADER *cmd_header = (CTRL_ALLOC_HEADER *)psb_cmdbuf_alloc_space(cmdbuf, sizeof(CTRL_ALLOC_HEADER));
     48 
     49     cmd_header->ui32Cmd_AdditionalParams = CMD_CTRL_ALLOC_HEADER;
     50     cmd_header->ui32ExternStateBuffAddr = 0;
     51     if (buf)
     52         RELOC(cmd_header->ui32ExternStateBuffAddr, 0, buf);
     53     cmd_header->ui32MacroblockParamAddr = 0; /* Only EC needs to set this */
     54 
     55     ctx->cmd_params = &cmd_header->ui32Cmd_AdditionalParams;
     56     ctx->p_slice_params = &cmd_header->ui32SliceParams;
     57     cmd_header->ui32SliceParams = 0;
     58 
     59     ctx->slice_first_pic_last = &cmd_header->uiSliceFirstMbYX_uiPicLastMbYX;
     60     *ctx->slice_first_pic_last = 0;
     61 
     62     ctx->p_range_mapping_base0 = &cmd_header->ui32AltOutputAddr[0];
     63     ctx->p_range_mapping_base1 = &cmd_header->ui32AltOutputAddr[1];
     64 
     65     ctx->alt_output_flags = &cmd_header->ui32AltOutputFlags;
     66 
     67     cmd_header->ui32AltOutputFlags = 0;
     68     cmd_header->ui32AltOutputAddr[0] = 0;
     69     cmd_header->ui32AltOutputAddr[1] = 0;
     70 }
     71 
     72 /* Programme the Alt output if there is a rotation*/
     73 void vld_dec_setup_alternative_frame(object_context_p obj_context)
     74 {
     75     uint32_t cmd = 0;
     76     psb_cmdbuf_p cmdbuf = obj_context->cmdbuf;
     77     context_DEC_p ctx = (context_DEC_p) obj_context->format_data;
     78     psb_surface_p src_surface = obj_context->current_render_target->psb_surface;
     79     psb_surface_p out_loop_surface = obj_context->current_render_target->out_loop_surface;
     80     int ved_scaling = (CONTEXT_SCALING(obj_context) && !ctx->yuv_ctx);
     81     uint32_t startX = 0, startY = 0, luma_addr_offset = 0, chroma_addr_offset = 0;
     82 
     83     /*  In VPP ctx, current_render_target is rotated surface */
     84     if (ctx->yuv_ctx && (VAEntrypointVideoProc == obj_context->entry_point)) {
     85         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Setup second-pass rotation\n");
     86         out_loop_surface = src_surface;
     87         src_surface = ctx->yuv_ctx->src_surface;
     88     }
     89 
     90     if (CONTEXT_ALTERNATIVE_OUTPUT(obj_context) || obj_context->entry_point == VAEntrypointVideoProc) {
     91         if (ved_scaling) {
     92             out_loop_surface = obj_context->current_render_target->scaling_surface;
     93 #ifndef BAYTRAIL
     94             tng_ved_write_scale_reg(obj_context);
     95 
     96             REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION, SCALE_INPUT_SIZE_SEL, 1);
     97             REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS,ALTERNATIVE_OUTPUT_PICTURE_ROTATION, SCALE_ENABLE, 1);
     98 #endif
     99         } else {
    100             startX = ((uint32_t)obj_context->current_render_target->offset_x_s + 0x3f) & ~0x3f;
    101             startY = ((uint32_t)obj_context->current_render_target->offset_y_s + 0x1) & ~0x1;
    102             luma_addr_offset = (((uint32_t)(startX + out_loop_surface->stride * startY))  + 0x3f ) & ~0x3f;
    103             chroma_addr_offset = (((uint32_t)(startX + out_loop_surface->stride * startY / 2))  + 0x3f ) & ~0x3f;
    104         }
    105 
    106         if (out_loop_surface == NULL) {
    107             drv_debug_msg(VIDEO_DEBUG_ERROR, "out-loop surface is NULL, abort msvdx alternative output\n");
    108             return;
    109         }
    110 
    111         if (GET_SURFACE_INFO_rotate(out_loop_surface) != obj_context->msvdx_rotate && !ved_scaling)
    112             drv_debug_msg(VIDEO_DEBUG_WARNING, "Display rotate mode does not match surface rotate mode!\n");
    113 
    114         /* CRendecBlock    RendecBlk( mCtrlAlloc , RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS) ); */
    115         psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, VC1_LUMA_RANGE_MAPPING_BASE_ADDRESS));
    116 
    117         psb_cmdbuf_rendec_write_address(cmdbuf, &out_loop_surface->buf, out_loop_surface->buf.buffer_ofs + luma_addr_offset);
    118         psb_cmdbuf_rendec_write_address(cmdbuf, &out_loop_surface->buf, out_loop_surface->buf.buffer_ofs + chroma_addr_offset + out_loop_surface->chroma_offset);
    119 
    120         psb_cmdbuf_rendec_end(cmdbuf);
    121 
    122         REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ALT_PICTURE_ENABLE, 1);
    123         REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_ROW_STRIDE, out_loop_surface->stride_mode);
    124         REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 0); /* FIXME Always generate Rec */
    125         REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , ROTATION_MODE, GET_SURFACE_INFO_rotate(out_loop_surface));
    126 
    127         RELOC(*ctx->p_range_mapping_base0, out_loop_surface->buf.buffer_ofs + luma_addr_offset, &out_loop_surface->buf);
    128         RELOC(*ctx->p_range_mapping_base1, out_loop_surface->buf.buffer_ofs + chroma_addr_offset + out_loop_surface->chroma_offset, &out_loop_surface->buf);
    129     }
    130 
    131     if (obj_context->profile == VAProfileVP8Version0_3 ||
    132         obj_context->profile == VAProfileJPEGBaseline || ctx->yuv_ctx) {
    133         psb_cmdbuf_rendec_start(cmdbuf, (REG_MSVDX_CMD_OFFSET + MSVDX_CMDS_AUX_LINE_BUFFER_BASE_ADDRESS_OFFSET));
    134         psb_cmdbuf_rendec_write_address(cmdbuf, &ctx->aux_line_buffer_vld, ctx->aux_line_buffer_vld.buffer_ofs);
    135         psb_cmdbuf_rendec_end(cmdbuf);
    136 
    137         REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION, USE_AUX_LINE_BUF, 1);
    138         if (ctx->yuv_ctx)
    139             REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION , RECON_WRITE_DISABLE, 1);
    140     }
    141 
    142     /* Set the rotation registers */
    143     psb_cmdbuf_rendec_start(cmdbuf, RENDEC_REGISTER_OFFSET(MSVDX_CMDS, ALTERNATIVE_OUTPUT_PICTURE_ROTATION));
    144     psb_cmdbuf_rendec_write(cmdbuf, cmd);
    145     *ctx->alt_output_flags = cmd;
    146 
    147     cmd = 0;
    148     REGIO_WRITE_FIELD_LITE(cmd, MSVDX_CMDS, EXTENDED_ROW_STRIDE, EXT_ROW_STRIDE, src_surface->stride / 64);
    149     psb_cmdbuf_rendec_write(cmdbuf, cmd);
    150 
    151     psb_cmdbuf_rendec_end(cmdbuf);
    152 }
    153 
    154 int vld_dec_slice_parameter_size(object_context_p obj_context)
    155 {
    156     int size;
    157 
    158     switch (obj_context->profile) {
    159     case VAProfileMPEG2Simple:
    160     case VAProfileMPEG2Main:
    161         size = sizeof(VASliceParameterBufferMPEG2);
    162         break;
    163     case VAProfileMPEG4Simple:
    164     case VAProfileMPEG4AdvancedSimple:
    165     case VAProfileMPEG4Main:
    166     case VAProfileH263Baseline:
    167         size = sizeof(VASliceParameterBufferMPEG4);
    168         break;
    169     case VAProfileH264Baseline:
    170     case VAProfileH264Main:
    171     case VAProfileH264High:
    172     case VAProfileH264ConstrainedBaseline:
    173         size = sizeof(VASliceParameterBufferH264);
    174         break;
    175     case VAProfileVC1Simple:
    176     case VAProfileVC1Main:
    177     case VAProfileVC1Advanced:
    178         size = sizeof(VASliceParameterBufferVC1);
    179         break;
    180     case VAProfileVP8Version0_3:
    181         size = sizeof(VASliceParameterBufferVP8);
    182     case VAProfileJPEGBaseline:
    183         size = sizeof(VASliceParameterBufferJPEGBaseline);
    184     default:
    185         size = 0;
    186         break;
    187     }
    188 
    189     return size;
    190 }
    191 
    192 VAStatus vld_dec_process_slice_data(context_DEC_p ctx, object_buffer_p obj_buffer)
    193 {
    194     VAStatus vaStatus = VA_STATUS_SUCCESS;
    195     void *slice_param;
    196     int buffer_idx = 0;
    197     unsigned int element_idx = 0, element_size;
    198 
    199     ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType));
    200 
    201     ASSERT(ctx->pic_params);
    202     ASSERT(ctx->slice_param_list_idx);
    203 
    204 #if 0
    205     if (!ctx->pic_params) {
    206         /* Picture params missing */
    207         return VA_STATUS_ERROR_UNKNOWN;
    208     }
    209 #endif
    210     if ((NULL == obj_buffer->psb_buffer) ||
    211         (0 == obj_buffer->size)) {
    212         /* We need to have data in the bitstream buffer */
    213         return VA_STATUS_ERROR_UNKNOWN;
    214     }
    215 
    216     element_size = vld_dec_slice_parameter_size(ctx->obj_context);
    217 
    218     while (buffer_idx < ctx->slice_param_list_idx) {
    219         object_buffer_p slice_buf = ctx->slice_param_list[buffer_idx];
    220         if (element_idx >= slice_buf->num_elements) {
    221             /* Move to next buffer */
    222             element_idx = 0;
    223             buffer_idx++;
    224             continue;
    225         }
    226 
    227         slice_param = slice_buf->buffer_data;
    228         slice_param = (void *)((unsigned long)slice_param + element_idx * element_size);
    229         element_idx++;
    230         vaStatus = vld_dec_process_slice(ctx, slice_param, obj_buffer);
    231         if (vaStatus != VA_STATUS_SUCCESS) {
    232             DEBUG_FAILURE;
    233             break;
    234         }
    235     }
    236     ctx->slice_param_list_idx = 0;
    237 
    238     return vaStatus;
    239 }
    240 /*
    241  * Adds a VASliceParameterBuffer to the list of slice params
    242  */
    243 VAStatus vld_dec_add_slice_param(context_DEC_p ctx, object_buffer_p obj_buffer)
    244 {
    245     ASSERT(obj_buffer->type == VASliceParameterBufferType);
    246     if (ctx->slice_param_list_idx >= ctx->slice_param_list_size) {
    247         unsigned char *new_list;
    248         ctx->slice_param_list_size += 8;
    249         new_list = realloc(ctx->slice_param_list,
    250                            sizeof(object_buffer_p) * ctx->slice_param_list_size);
    251         if (NULL == new_list) {
    252             return VA_STATUS_ERROR_ALLOCATION_FAILED;
    253         }
    254         ctx->slice_param_list = (object_buffer_p*) new_list;
    255     }
    256     ctx->slice_param_list[ctx->slice_param_list_idx] = obj_buffer;
    257     ctx->slice_param_list_idx++;
    258     return VA_STATUS_SUCCESS;
    259 }
    260 
    261 void vld_dec_write_kick(object_context_p obj_context)
    262 {
    263     psb_cmdbuf_p cmdbuf = obj_context->cmdbuf;
    264     *cmdbuf->cmd_idx++ = CMD_COMPLETION;
    265 }
    266 
    267 VAStatus vld_dec_process_slice(context_DEC_p ctx,
    268                                         void *vld_slice_param,
    269                                         object_buffer_p obj_buffer)
    270 {
    271     VAStatus vaStatus = VA_STATUS_SUCCESS;
    272     VASliceParameterBufferBase *slice_param = (VASliceParameterBufferBase *) vld_slice_param;
    273 
    274     ASSERT((obj_buffer->type == VASliceDataBufferType) || (obj_buffer->type == VAProtectedSliceDataBufferType));
    275 
    276     if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) ||
    277         (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL)) {
    278 #ifndef SLICE_HEADER_PARSING
    279         if (0 == slice_param->slice_data_size) {
    280             vaStatus = VA_STATUS_ERROR_UNKNOWN;
    281             DEBUG_FAILURE;
    282             return vaStatus;
    283         }
    284 #endif
    285         ASSERT(!ctx->split_buffer_pending);
    286 
    287         if (psb_context_get_next_cmdbuf(ctx->obj_context)) {
    288             vaStatus = VA_STATUS_ERROR_UNKNOWN;
    289             DEBUG_FAILURE;
    290             return vaStatus;
    291         }
    292         vld_dec_FE_state(ctx->obj_context, ctx->preload_buffer);
    293         ctx->begin_slice(ctx, slice_param);
    294         ctx->slice_data_buffer = obj_buffer->psb_buffer;
    295 #ifdef SLICE_HEADER_PARSING
    296         if (ctx->parse_enabled == 1)
    297             psb_cmdbuf_dma_write_key(ctx->obj_context->cmdbuf,
    298                                          ctx->SR_flags,
    299                                          ctx->parse_key);
    300         else
    301 #endif
    302             psb_cmdbuf_dma_write_bitstream(ctx->obj_context->cmdbuf,
    303                                          obj_buffer->psb_buffer,
    304                                          obj_buffer->psb_buffer->buffer_ofs + slice_param->slice_data_offset,
    305                                          slice_param->slice_data_size,
    306                                          ctx->bits_offset,
    307                                          ctx->SR_flags);
    308 
    309         if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_BEGIN) {
    310             ctx->split_buffer_pending = TRUE;
    311         }
    312     } else {
    313         ASSERT(ctx->split_buffer_pending);
    314         ASSERT(0 == slice_param->slice_data_offset);
    315         if (slice_param->slice_data_size) {
    316             psb_cmdbuf_dma_write_bitstream_chained(ctx->obj_context->cmdbuf,
    317                     obj_buffer->psb_buffer,
    318                     slice_param->slice_data_size);
    319         }
    320     }
    321 
    322     if ((slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_ALL) ||
    323         (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END)) {
    324         if (slice_param->slice_data_flag == VA_SLICE_DATA_FLAG_END) {
    325             ASSERT(ctx->split_buffer_pending);
    326         }
    327 
    328         ctx->process_slice(ctx, slice_param);
    329         vld_dec_write_kick(ctx->obj_context);
    330 
    331         ctx->split_buffer_pending = FALSE;
    332         ctx->obj_context->video_op = psb_video_vld;
    333         ctx->obj_context->flags = 0;
    334 
    335         ctx->end_slice(ctx);
    336 
    337         if (psb_context_submit_cmdbuf(ctx->obj_context)) {
    338             vaStatus = VA_STATUS_ERROR_UNKNOWN;
    339         }
    340     }
    341     return vaStatus;
    342 }
    343 
    344 VAStatus vld_dec_allocate_colocated_buffer(context_DEC_p ctx, object_surface_p obj_surface, uint32_t size)
    345 {
    346     psb_buffer_p buf;
    347     VAStatus vaStatus;
    348     psb_surface_p surface = obj_surface->psb_surface;
    349     int index = GET_SURFACE_INFO_colocated_index(surface);
    350 
    351     if (!index) {
    352         index = ctx->colocated_buffers_idx;
    353         if (index >= ctx->colocated_buffers_size) {
    354             return VA_STATUS_ERROR_UNKNOWN;
    355         }
    356 
    357         drv_debug_msg(VIDEO_DEBUG_GENERAL, "Allocating colocated buffer for surface %08x size = %08x\n", surface, size);
    358 
    359         buf = &(ctx->colocated_buffers[index]);
    360         vaStatus = psb_buffer_create(ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf);
    361         if (VA_STATUS_SUCCESS != vaStatus) {
    362             return vaStatus;
    363         }
    364         ctx->colocated_buffers_idx++;
    365         SET_SURFACE_INFO_colocated_index(surface, index + 1); /* 0 means unset, index is offset by 1 */
    366     } else {
    367         buf = &(ctx->colocated_buffers[index - 1]);
    368         if (buf->size < size) {
    369             psb_buffer_destroy(buf);
    370             vaStatus = psb_buffer_create(ctx->obj_context->driver_data, size, psb_bt_vpu_only, buf);
    371             if (VA_STATUS_SUCCESS != vaStatus) {
    372                 return vaStatus;
    373             }
    374             SET_SURFACE_INFO_colocated_index(surface, index); /* replace the original buffer */
    375         }
    376     }
    377     return VA_STATUS_SUCCESS;
    378 }
    379 
    380 psb_buffer_p vld_dec_lookup_colocated_buffer(context_DEC_p ctx, psb_surface_p surface)
    381 {
    382     int index = GET_SURFACE_INFO_colocated_index(surface);
    383     if (!index) {
    384         return NULL;
    385     }
    386     return &(ctx->colocated_buffers[index-1]); /* 0 means unset, index is offset by 1 */
    387 }
    388 
    389 VAStatus vld_dec_CreateContext(context_DEC_p ctx, object_context_p obj_context)
    390 {
    391     VAStatus vaStatus = VA_STATUS_SUCCESS;
    392 
    393     ctx->obj_context = obj_context;
    394     ctx->split_buffer_pending = FALSE;
    395     ctx->slice_param_list_size = 8;
    396     ctx->slice_param_list = (object_buffer_p*) calloc(1, sizeof(object_buffer_p) * ctx->slice_param_list_size);
    397     ctx->slice_param_list_idx = 0;
    398 
    399     if (NULL == ctx->slice_param_list) {
    400         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
    401         DEBUG_FAILURE;
    402         return vaStatus;
    403     }
    404 
    405     ctx->colocated_buffers_size = obj_context->num_render_targets;
    406     ctx->colocated_buffers_idx = 0;
    407     ctx->colocated_buffers = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s) * ctx->colocated_buffers_size);
    408     if (NULL == ctx->colocated_buffers) {
    409         vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED;
    410         DEBUG_FAILURE;
    411         free(ctx->slice_param_list);
    412     }
    413 
    414     if (vaStatus == VA_STATUS_SUCCESS) {
    415         vaStatus = psb_buffer_create(obj_context->driver_data,
    416                                      AUX_LINE_BUFFER_VLD_SIZE,
    417                                      psb_bt_cpu_vpu,
    418                                      &ctx->aux_line_buffer_vld);
    419         DEBUG_FAILURE;
    420     }
    421 
    422     return vaStatus;
    423 }
    424 
    425 void vld_dec_DestroyContext(context_DEC_p ctx)
    426 {
    427     int i;
    428     ctx->preload_buffer = NULL;
    429 
    430     psb_buffer_destroy(&ctx->aux_line_buffer_vld);
    431 
    432     if (ctx->slice_param_list) {
    433         free(ctx->slice_param_list);
    434         ctx->slice_param_list = NULL;
    435     }
    436 
    437     if (ctx->colocated_buffers) {
    438         for (i = 0; i < ctx->colocated_buffers_idx; ++i)
    439             psb_buffer_destroy(&(ctx->colocated_buffers[i]));
    440 
    441         free(ctx->colocated_buffers);
    442         ctx->colocated_buffers = NULL;
    443     }
    444 }
    445 
    446 VAStatus vld_dec_RenderPicture(
    447     object_context_p obj_context,
    448     object_buffer_p *buffers,
    449     int num_buffers)
    450 {
    451     int i;
    452     context_DEC_p ctx = (context_DEC_p) obj_context->format_data;
    453     VAStatus vaStatus = VA_STATUS_SUCCESS;
    454 
    455     for (i = 0; i < num_buffers; i++) {
    456         object_buffer_p obj_buffer = buffers[i];
    457         psb__dump_va_buffers_verbose(obj_buffer);
    458 
    459         switch (obj_buffer->type) {
    460         case VASliceParameterBufferType:
    461             vaStatus = vld_dec_add_slice_param(ctx, obj_buffer);
    462             DEBUG_FAILURE;
    463             break;
    464 
    465         case VASliceDataBufferType:
    466         case VAProtectedSliceDataBufferType:
    467             vaStatus = vld_dec_process_slice_data(ctx, obj_buffer);
    468             DEBUG_FAILURE;
    469             break;
    470 
    471         default:
    472             vaStatus = ctx->process_buffer(ctx, obj_buffer);
    473             DEBUG_FAILURE;
    474         }
    475         if (vaStatus != VA_STATUS_SUCCESS) {
    476             break;
    477         }
    478     }
    479 
    480     return vaStatus;
    481 }
    482 
    483 void vld_dec_yuv_rotate(object_context_p obj_context)
    484 {
    485     VAStatus vaStatus = VA_STATUS_SUCCESS;
    486     struct format_vtable_s *vtable = &tng_yuv_processor_vtable;
    487     struct surface_param_s surface_param;
    488     struct object_buffer_s buffer;
    489     object_buffer_p buffer_p = &buffer;
    490 
    491     surface_param.src_surface = obj_context->current_render_target->scaling_surface;
    492     surface_param.display_width =	obj_context->current_render_target->buffer_width_s;
    493     surface_param.display_height = obj_context->current_render_target->buffer_height_s;
    494     surface_param.coded_width = obj_context->current_render_target->width_s;
    495     surface_param.coded_height = obj_context->current_render_target->height_s;
    496 
    497     buffer.num_elements = 1;
    498     buffer.type = YUVProcessorSurfaceType;
    499     buffer.size = sizeof(struct surface_param_s);
    500     buffer.buffer_data = (unsigned char *)&surface_param;
    501 
    502     vtable->createContext(obj_context, NULL);
    503     vtable->beginPicture(obj_context);
    504     vtable->renderPicture(obj_context, &buffer_p, 1);
    505     vtable->endPicture(obj_context);
    506     vtable->destroyContext(obj_context);
    507 }
    508