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