psb_drv_video.c revision 9f388f4488bba39eeac0c97ddaa6480362edf952
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 * Authors: 26 * Waldo Bastian <waldo.bastian@intel.com> 27 * 28 */ 29 30#include <va/va_backend.h> 31#include <va/va_backend_tpi.h> 32#include <va/va_backend_egl.h> 33#include <va/va_dricommon.h> 34 35#include "psb_drv_video.h" 36#include "psb_texture.h" 37#include "psb_cmdbuf.h" 38#include "lnc_cmdbuf.h" 39#include "pnw_cmdbuf.h" 40#include "psb_surface.h" 41 42#ifdef PSBVIDEO_MRST 43#include "psb_MPEG2.h" 44#include "psb_MPEG4.h" 45#include "psb_H264.h" 46#include "psb_VC1.h" 47#include "lnc_MPEG4ES.h" 48#include "lnc_H264ES.h" 49#include "lnc_H263ES.h" 50#endif 51#ifdef PSBVIDEO_MFLD 52#include "pnw_MPEG2.h" 53#include "pnw_MPEG4.h" 54#include "pnw_H264.h" 55#include "pnw_VC1.h" 56#include "pnw_MPEG4ES.h" 57#include "pnw_H264ES.h" 58#include "pnw_H263ES.h" 59#include "pnw_jpeg.h" 60#endif 61#include "psb_output.h" 62#include "lnc_ospm.h" 63#include "psb_texstreaming.h" 64#include <stdio.h> 65#include <string.h> 66#include <stdarg.h> 67#include <time.h> 68#include <unistd.h> 69#include <wsbm/wsbm_pool.h> 70#include <wsbm/wsbm_manager.h> 71#include <wsbm/wsbm_util.h> 72#include <wsbm/wsbm_fencemgr.h> 73#include <linux/videodev2.h> 74#include <sys/mman.h> 75#include <errno.h> 76#include <system/graphics.h> 77#include <gralloc.h> 78#include "android/psb_gralloc.h" 79#include "android/psb_android_glue.h" 80#include "psb_def.h" 81#include "psb_ws_driver.h" 82#include "ci_va.h" 83#include "pnw_rotate.h" 84 85#ifndef PSB_PACKAGE_VERSION 86#define PSB_PACKAGE_VERSION "Undefined" 87#endif 88 89#define PSB_DRV_VERSION PSB_PACKAGE_VERSION 90#define PSB_CHG_REVISION "(0X00000071)" 91 92#define PSB_STR_VENDOR_MRST "Intel GMA500-MRST-" PSB_DRV_VERSION " " PSB_CHG_REVISION 93#define PSB_STR_VENDOR_MFLD "Intel GMA500-MFLD-" PSB_DRV_VERSION " " PSB_CHG_REVISION 94 95#define MAX_UNUSED_BUFFERS 16 96 97#define PSB_MAX_FLIP_DELAY (1000/30/10) 98 99#ifdef DEBUG_TRACE 100#include <signal.h> 101#endif 102 103#define EXPORT __attribute__ ((visibility("default"))) 104 105#define INIT_DRIVER_DATA psb_driver_data_p driver_data = (psb_driver_data_p) ctx->pDriverData; 106#define INIT_FORMAT_VTABLE format_vtable_p format_vtable = ((profile < PSB_MAX_PROFILES) && (entrypoint < PSB_MAX_ENTRYPOINTS)) ? driver_data->profile2Format[profile][entrypoint] : NULL; 107 108#define CONFIG(id) ((object_config_p) object_heap_lookup( &driver_data->config_heap, id )) 109#define CONTEXT(id) ((object_context_p) object_heap_lookup( &driver_data->context_heap, id )) 110#define SURFACE(id) ((object_surface_p) object_heap_lookup( &driver_data->surface_heap, id )) 111#define BUFFER(id) ((object_buffer_p) object_heap_lookup( &driver_data->buffer_heap, id )) 112 113#define CONFIG_ID_OFFSET 0x01000000 114#define CONTEXT_ID_OFFSET 0x02000000 115#define SURFACE_ID_OFFSET 0x03000000 116#define BUFFER_ID_OFFSET 0x04000000 117#define IMAGE_ID_OFFSET 0x05000000 118#define SUBPIC_ID_OFFSET 0x06000000 119 120static int psb_get_device_info(VADriverContextP ctx); 121 122 123void psb_init_surface_pvr2dbuf(psb_driver_data_p driver_data); 124void psb_free_surface_pvr2dbuf(psb_driver_data_p driver_data); 125 126static FILE *psb_video_debug_fp = NULL; 127static FILE *psb_video_debug_dump_buffer_fp = NULL; 128static int debug_fp_count = 0; 129static FILE *psb_video_debug_nv_buffer_fp=NULL; 130 131/* 132 * read a config "env" for libva.conf or from environment setting 133 * liva.conf has higher priority 134 * return 0: the "env" is set, and the value is copied into env_value 135 * 1: the env is not set 136 */ 137int psb_parse_config(char *env, char *env_value) 138{ 139 char *token, *value, *saveptr; 140 char oneline[1024]; 141 FILE *fp = NULL; 142 char *env_ptr; 143 144 if (env == NULL) 145 return 1; 146 147 fp = fopen("/etc/psbvideo.conf", "r"); 148 while (fp && (fgets(oneline, 1024, fp) != NULL)) { 149 if (strlen(oneline) == 1) 150 continue; 151 token = strtok_r(oneline, "=\n", &saveptr); 152 value = strtok_r(NULL, "=\n", &saveptr); 153 154 if (NULL == token || NULL == value) 155 continue; 156 157 if (strcmp(token, env) == 0) { 158 if (env_value) 159 strcpy(env_value, value); 160 161 fclose(fp); 162 163 return 0; 164 } 165 } 166 if (fp) 167 fclose(fp); 168 169 env_ptr = getenv(env); 170 if (env_ptr) { 171 if (env_value) 172 strncpy(env_value, env_ptr, strlen(env_ptr)); 173 174 return 0; 175 } 176 177 return 1; 178} 179 180void psb__error_message(const char *msg, ...) 181{ 182 va_list args; 183 FILE *fp; 184 char tag[128]; 185 186 (void)tag; 187 188 if (psb_video_debug_fp == NULL) /* not set the debug */ 189 fp = stderr; 190 else 191 fp = psb_video_debug_fp; 192 193 fprintf(fp, "[0x%08lx]psb_drv_video error(%d:0x%08lx) ", 194 GetTickCount(), getpid(), pthread_self()); 195 va_start(args, msg); 196 vfprintf(fp, msg, args); 197#ifdef ANDROID 198 sprintf(tag, "pvr_drv_video[%d:0x%08lx]", getpid(), pthread_self()); 199 __android_log_vprint(ANDROID_LOG_ERROR, tag, msg, args); 200#endif 201 va_end(args); 202 203 fflush(fp); 204 fsync(fileno(fp)); 205} 206 207void psb__dump_buffers_allkinds(object_buffer_p obj_buffer ) 208{ 209 int i, j,k; 210 void *mapped_buffer; 211 int print_num; 212 213 if(psb_video_debug_dump_buffer_fp) { 214 fprintf(psb_video_debug_dump_buffer_fp, "%s", buffer_type_to_string(obj_buffer->type)); 215 print_num = fprintf(psb_video_debug_dump_buffer_fp, "BUFF SIZE :%d NUMELEMENTS:%d BUFF INFO:\n", obj_buffer->size, obj_buffer->num_elements); 216 217 switch(obj_buffer->type) { 218 case VAPictureParameterBufferType: 219 case VAIQMatrixBufferType: 220 case VASliceParameterBufferType: 221 j=0; 222 for(k=0;k < obj_buffer->size;++k) 223 print_num = fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ,",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 224 fprintf(psb_video_debug_dump_buffer_fp,"\n "); 225 break; 226 227 case VASliceGroupMapBufferType: 228 case VABitPlaneBufferType: 229// case VASliceDataBufferType: 230// case VAProtectedSliceDataBufferType: 231 psb_buffer_map(obj_buffer->psb_buffer, &mapped_buffer); 232 for(j=0; j<obj_buffer->size;++j) { 233 if(j%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 234 for(k=0;k < obj_buffer->num_elements;++k) 235 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(mapped_buffer+obj_buffer->num_elements*j+k))); 236 } 237 238 psb_buffer_unmap(obj_buffer->psb_buffer); 239 break; 240 241 case VASliceDataBufferType: 242 fprintf(psb_video_debug_dump_buffer_fp,"first 256 bytes:\n"); 243 psb_buffer_map(obj_buffer->psb_buffer, &mapped_buffer); 244 for(j=0; j<256;++j) { 245 if(j%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 246 for(k=0;k < obj_buffer->num_elements;++k) 247 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(mapped_buffer+obj_buffer->num_elements*j+k))); 248 } 249 psb_buffer_unmap(obj_buffer->psb_buffer); 250 break; 251 252 default: 253 break; 254 255 } 256 fprintf(psb_video_debug_dump_buffer_fp, "\n"); 257 fflush(psb_video_debug_dump_buffer_fp); 258 fsync(fileno(psb_video_debug_dump_buffer_fp)); 259 } 260 261} 262 263void psb__dump_buffers(object_buffer_p obj_buffer ) 264{ 265 int i, j,k; 266 void *mapped_buffer; 267 if(psb_video_debug_dump_buffer_fp) { 268 fprintf(psb_video_debug_dump_buffer_fp, "%s", buffer_type_to_string(obj_buffer->type)); 269 fprintf(psb_video_debug_dump_buffer_fp, "BUFF SIZE :%d NUMELEMENTS:%d BUFF INFO:\n", obj_buffer->size, obj_buffer->num_elements); 270 switch(obj_buffer->type) { 271 case VAPictureParameterBufferType: 272 for(j=0; j < 340; j = j+20) { 273 if(j==0) fprintf(psb_video_debug_dump_buffer_fp,"\nCurrPic:\n"); 274 else fprintf(psb_video_debug_dump_buffer_fp,"\nReferenceFrames%d\n", j / 20); 275 fprintf(psb_video_debug_dump_buffer_fp,"picture_id:"); 276 for(k=0;k < 4;++k) 277 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 278 fprintf(psb_video_debug_dump_buffer_fp," frame_idx:"); 279 for(k=4;k < 8;++k) 280 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 281 fprintf(psb_video_debug_dump_buffer_fp," flags:"); 282 for(k=8;k < 12;++k) 283 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 284 fprintf(psb_video_debug_dump_buffer_fp," TopFieldOrderCnt:"); 285 for(k=12;k < 16;++k) 286 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 287 fprintf(psb_video_debug_dump_buffer_fp," BottomFieldOrderCnt:"); 288 for(k=16;k < 20;++k) 289 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 290 } 291 j=340;k=0; 292 fprintf(psb_video_debug_dump_buffer_fp,"\npicture_width_in_mbs_minus1:"); 293 for(k=0;k < 2;++k) 294 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 295 j=342;k=0; 296 fprintf(psb_video_debug_dump_buffer_fp, "\npicture_height_in_mbs_minus1:"); 297 for(k=0;k < 2;++k) 298 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 299 j=344;k=0; 300 fprintf(psb_video_debug_dump_buffer_fp, "\nbit_depth_luma_minus8:"); 301 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 302 j=345;k=0; 303 fprintf(psb_video_debug_dump_buffer_fp, "\nbit_depth_chroma_minus8:"); 304 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 305 j=346;k=0; 306 fprintf(psb_video_debug_dump_buffer_fp, "\nnum_ref_frames:"); 307 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 308 j=348;k=0; 309 fprintf(psb_video_debug_dump_buffer_fp,"\nseq_fields_value:"); 310 for(k=0;k < 4;++k) 311 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 312 j=352;k=0; 313 fprintf(psb_video_debug_dump_buffer_fp,"\nnum_slice_groups_minus1:"); 314 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 315 j=353;k=0; 316 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_group_map_type:"); 317 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 318 j=354;k=0; 319 fprintf(psb_video_debug_dump_buffer_fp, "\nslice_group_change_rate_minus1:"); 320 for(k=0;k < 2;++k) 321 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 322 j=356;k=0; 323 fprintf(psb_video_debug_dump_buffer_fp,"\npic_init_qp_minus26:"); 324 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 325 j=357;k=0; 326 fprintf(psb_video_debug_dump_buffer_fp,"\npic_init_qs_minus26:"); 327 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 328 j=358;k=0; 329 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_qp_index_offset:"); 330 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 331 j=359;k=0; 332 fprintf(psb_video_debug_dump_buffer_fp, "\nsecond_chroma_qp_index_offset:"); 333 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 334 j=360;k=0; 335 fprintf(psb_video_debug_dump_buffer_fp,"\npic_fields_value:"); 336 for(k=0;k < 4;++k) 337 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 338 j=364;k=0; 339 fprintf(psb_video_debug_dump_buffer_fp,"\nframe_num:"); 340 for(k=0;k < 2;++k) 341 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 342 break; 343 344 case VAIQMatrixBufferType: 345 for(j=0;j<96;j=j+16) { 346 fprintf(psb_video_debug_dump_buffer_fp,"\nScalingList4x4_%d:", j/16); 347 for(k=0; k<16;++k) { 348 if(k%4 == 0) fprintf(psb_video_debug_dump_buffer_fp, "\n"); 349 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 350 } 351 } 352 for(j=96;j<224;j=j+64) { 353 fprintf(psb_video_debug_dump_buffer_fp,"\nScalingList4x4_%d:",( j-96)/64); 354 for(k=0; k<64;++k) { 355 if(k%8 == 0) fprintf(psb_video_debug_dump_buffer_fp, "\n"); 356 printf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 357 } 358 } 359 break; 360 361 case VASliceParameterBufferType: 362 j=0;k=0; 363 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_data_size:"); 364 for(k=0;k < 4;++k) 365 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 366 j=4;k=0; 367 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_data_offset:"); 368 for(k=0;k < 4;++k) 369 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 370 j=8;k=0; 371 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_data_flag:"); 372 for(k=0;k < 4;++k) 373 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 374 j=12;k=0; 375 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_data_bit_offset:"); 376 for(k=0;k < 2;++k) 377 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 378 j=14;k=0; 379 fprintf(psb_video_debug_dump_buffer_fp,"\nfirst_mb_in_slice:"); 380 for(k=0;k < 2;++k) 381 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 382 j=16;k=0; 383 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_type:"); 384 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 385 j=17;k=0; 386 fprintf(psb_video_debug_dump_buffer_fp,"\ndirect_spatial_mv_pred_flag:"); 387 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 388 j=18;k=0; 389 fprintf(psb_video_debug_dump_buffer_fp, "\nnum_ref_idx_l0_active_minus1:"); 390 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 391 j=19;k=0; 392 fprintf(psb_video_debug_dump_buffer_fp, "\nnum_ref_idx_l1_active_minus1:"); 393 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 394 j=20;k=0; 395 fprintf(psb_video_debug_dump_buffer_fp,"\ncabac_init_idc:"); 396 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 397 j=21;k=0; 398 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_qp_delta:"); 399 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 400 j=22;k=0; 401 fprintf(psb_video_debug_dump_buffer_fp, "\ndisable_deblocking_filter_idc:"); 402 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 403 j=23;k=0; 404 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_alpha_c0_offset_div2:"); 405 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 406 j=24;k=0; 407 fprintf(psb_video_debug_dump_buffer_fp,"\nslice_beta_offset_div2:"); 408 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 409 for(j=28; j < 668; j = j+20) { 410 fprintf(psb_video_debug_dump_buffer_fp,"\nRefPicList0 ListIndex=%d\n", (j -28)/ 20); 411 fprintf(psb_video_debug_dump_buffer_fp,"picture_id:"); 412 for(k=0;k < 4;++k) 413 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 414 fprintf(psb_video_debug_dump_buffer_fp," frame_idx:"); 415 for(k=4;k < 8;++k) 416 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 417 fprintf(psb_video_debug_dump_buffer_fp," flags:"); 418 for(k=8;k < 12;++k) 419 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 420 fprintf(psb_video_debug_dump_buffer_fp," TopFieldOrderCnt:"); 421 for(k=12;k < 16;++k) 422 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 423 fprintf(psb_video_debug_dump_buffer_fp," BottomFieldOrderCnt:"); 424 for(k=16;k < 20;++k) 425 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 426 } 427 for(j=668; j < 1308; j = j+20) { 428 fprintf(psb_video_debug_dump_buffer_fp,"\nRefPicList1 ListIndex=%d\n", (j -668)/ 20); 429 fprintf(psb_video_debug_dump_buffer_fp,"picture_id:"); 430 for(k=0;k < 4;++k) 431 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 432 fprintf(psb_video_debug_dump_buffer_fp," frame_idx:"); 433 for(k=4;k < 8;++k) 434 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 435 fprintf(psb_video_debug_dump_buffer_fp," flags:"); 436 for(k=8;k < 12;++k) 437 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 438 fprintf(psb_video_debug_dump_buffer_fp," TopFieldOrderCnt:"); 439 for(k=12;k < 16;++k) 440 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 441 fprintf(psb_video_debug_dump_buffer_fp," BottomFieldOrderCnt:"); 442 for(k=16;k < 20;++k) 443 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 444 } 445 j=1308;k=0; 446 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_log2_weight_denom:"); 447 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 448j=1309;k=0; 449 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_log2_weight_denom:"); 450 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 451 j=1310;k=0; 452 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_weight_l0_flag:"); 453 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 454 j=1312;k=0; 455 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_weight_l0:"); 456 for(j=1312;j<1376;j=j+2) { 457 if((j-1312)%16 == 0)fprintf(psb_video_debug_dump_buffer_fp,"\n"); 458 fprintf(psb_video_debug_dump_buffer_fp," :"); 459 for(k=0;k < 2;++k) 460 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 461 } 462 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_offset_l0:"); 463 for(j=1376;j<1440;j=j+2) { 464 if((j-1376)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 465 fprintf(psb_video_debug_dump_buffer_fp," "); 466 for(k=0;k < 2;++k) 467 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 468 } 469 j=1440;k=0; 470 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_weight_l0_flag:"); 471 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 472 j=1442;k=0; 473 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_weight_l0:"); 474 for(j=1442;j<1570;j=j+4) { 475 if((j-1442)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 476 fprintf(psb_video_debug_dump_buffer_fp," "); 477 for(k=0;k < 2;++k) 478 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 479 fprintf(psb_video_debug_dump_buffer_fp," , "); 480 for(k=2;k < 4;++k) 481 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 482 483 } 484 485 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_offset_l0:"); 486 for(j=1570;j<1698;j=j+4) { 487 if((j-1570)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 488 fprintf(psb_video_debug_dump_buffer_fp," "); 489 for(k=0;k < 2;++k) 490 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 491 fprintf(psb_video_debug_dump_buffer_fp," , "); 492 for(k=2;k < 4;++k) 493 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 494 } 495 j=1698;k=0; 496 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_weight_l1_flag:"); 497 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 498 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_weight_l1:"); 499 for(j=1700;j<1764;j=j+2) { 500 if((j-1700)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 501 fprintf(psb_video_debug_dump_buffer_fp," "); 502 for(k=0;k < 2;++k) 503 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 504 } 505 fprintf(psb_video_debug_dump_buffer_fp,"\nluma_offset_l1:"); 506 for(j=1764;j<1828;j=j+2) { 507 if((j-1764)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 508 fprintf(psb_video_debug_dump_buffer_fp," "); 509 for(k=0;k < 2;++k) 510 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 511 } 512 j=1828;k=0; 513 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_weight_l1_flag:"); 514 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 515 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_weight_l1:"); 516 for(j=1830;j<1958;j=j+4) { 517 if((j-1830)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 518 fprintf(psb_video_debug_dump_buffer_fp," "); 519 for(k=0;k < 2;++k) 520 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 521 fprintf(psb_video_debug_dump_buffer_fp," , "); 522 for(k=2;k < 4;++k) 523 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 524 } 525 fprintf(psb_video_debug_dump_buffer_fp,"\nchroma_offset_l1:"); 526 for(j=1958;j<2086;j=j+4) { 527 if((j-1958)%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 528 fprintf(psb_video_debug_dump_buffer_fp," "); 529 for(k=0;k < 2;++k) 530 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 531 fprintf(psb_video_debug_dump_buffer_fp," , "); 532 for(k=2;k < 4;++k) 533 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(obj_buffer->buffer_data+obj_buffer->num_elements*j+k))); 534 } 535 break; 536 537 case VASliceGroupMapBufferType: 538 /// case VASliceDataBufferType: 539 /// case VAProtectedSliceDataBufferType: 540 psb_buffer_map(obj_buffer->psb_buffer, &mapped_buffer); 541 for(j=0; j<obj_buffer->size;++j) { 542 if(j%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 543 for(k=0;k < obj_buffer->num_elements;++k) 544 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(mapped_buffer+obj_buffer->num_elements*j+k))); 545 } 546 psb_buffer_unmap(obj_buffer->psb_buffer); 547 break; 548 549 case VASliceDataBufferType: 550 fprintf(psb_video_debug_dump_buffer_fp,"first 256 bytes:\n"); 551 psb_buffer_map(obj_buffer->psb_buffer, &mapped_buffer); 552 for(j=0; j<256;++j) { 553 if(j%16 == 0) fprintf(psb_video_debug_dump_buffer_fp,"\n"); 554 for(k=0;k < obj_buffer->num_elements;++k) 555 fprintf(psb_video_debug_dump_buffer_fp,"0x%02lx ",*((unsigned char *)(mapped_buffer+obj_buffer->num_elements*j+k))); 556 } 557 psb_buffer_unmap(obj_buffer->psb_buffer); 558 break; 559 default: 560 break; 561 562 } 563 fprintf(psb_video_debug_dump_buffer_fp, "\n"); 564 fflush(psb_video_debug_dump_buffer_fp); 565 fsync(fileno(psb_video_debug_dump_buffer_fp)); 566 } 567 568} 569 570void psb__information_message(const char *msg, ...) 571{ 572 if (psb_video_debug_fp) { 573 va_list args; 574 char tag[128]; 575 576 (void)tag; 577 578 fprintf(psb_video_debug_fp, "[0x%08lx]psb_drv_video(%d:0x%08lx) ", 579 GetTickCount(), getpid(), pthread_self()); 580 va_start(args, msg); 581 vfprintf(psb_video_debug_fp, msg, args); 582#ifdef ANDROID 583 sprintf(tag, "pvr_drv_video[%d:0x%08lx]", getpid(), pthread_self()); 584 __android_log_vprint(ANDROID_LOG_DEBUG, tag, msg, args); 585#endif 586 va_end(args); 587 fflush(psb_video_debug_fp); 588 fsync(fileno(psb_video_debug_fp)); 589 } 590} 591 592 593static void psb__open_log(void) 594{ 595 char log_fn[1024]; 596 unsigned int suffix; 597#ifdef ANDROID 598 LOGD("psb__open_log.\n"); 599#endif 600 if(psb_parse_config("PSB_VIDEO_DEBUG_DUMP_BUFFER", &log_fn[0]) == 0) { 601 602 unsigned int suffix = 0xffff & ((unsigned int)time(NULL)); 603 if(strcmp(log_fn, "/dev/stdout") != 0) 604 sprintf(log_fn + strlen(log_fn), ".%d", suffix); 605 psb_video_debug_dump_buffer_fp = fopen(log_fn, "w"); 606 } 607 608 if(psb_parse_config("PSB_VIDEO_DEBUG_NV_BUFFER", &log_fn[0]) == 0) { 609 unsigned int suffix = 0xffff & ((unsigned int)time(NULL)); 610 if(strcmp(log_fn, "/dev/stdout") != 0) 611 sprintf(log_fn + strlen(log_fn), ".%d", suffix); 612 psb_video_debug_nv_buffer_fp = fopen(log_fn, "ab"); 613 } 614 615 if ((psb_video_debug_fp != NULL) && (psb_video_debug_fp != stderr)) { 616 debug_fp_count++; 617 return; 618 } 619 620 if (psb_parse_config("PSB_VIDEO_DEBUG", &log_fn[0]) != 0) 621 return; 622 623 suffix = 0xffff & ((unsigned int)time(NULL)); 624 snprintf(log_fn + strnlen(log_fn, 1024), 625 (1024 - 8 - strnlen(log_fn, 1024)), 626 ".%d.%d", getpid(), suffix); 627 psb_video_debug_fp = fopen(log_fn, "w"); 628 if (psb_video_debug_fp == 0) { 629 psb__error_message("Log file %s open failed, reason %s, fall back to stderr\n", 630 log_fn, strerror(errno)); 631 psb_video_debug_fp = stderr; 632 } else { 633 psb__information_message("Log file %s open successfully\n", log_fn); 634 debug_fp_count++; 635 } 636} 637 638static void psb__close_log(void) 639{ 640 if ((psb_video_debug_fp != NULL) & (psb_video_debug_fp != stderr)) { 641 debug_fp_count--; 642 if (debug_fp_count == 0) 643 fclose(psb_video_debug_fp); 644 } 645 646 if(psb_video_debug_nv_buffer_fp !=NULL) 647 fclose(psb_video_debug_nv_buffer_fp); 648 649 return; 650} 651 652void psb__dump_NV_buffers( 653 object_surface_p obj_surface, 654 short srcx, 655 short srcy, 656 unsigned short srcw, 657 unsigned short srch) 658{ 659 void *mapped_buffer; 660 void *mapped_buffer1, *mapped_buffer2; 661 if (psb_video_debug_nv_buffer_fp) { 662 psb_buffer_map(&obj_surface->psb_surface->buf, &mapped_buffer); 663 664 int j,k; 665 mapped_buffer1 = mapped_buffer +obj_surface->psb_surface->stride * srcy; 666 mapped_buffer2= mapped_buffer + obj_surface->psb_surface->stride * (obj_surface->height + srcy / 2); 667 mapped_buffer=mapped_buffer2; 668 for(j = 0; j < srch; ++j) 669 { 670 fwrite(mapped_buffer1, srcw, 1, psb_video_debug_nv_buffer_fp); 671 mapped_buffer1 += obj_surface->psb_surface->stride; 672 } 673 for(j = 0 ; j < srch /2; ++j) 674 { 675 for(k = 0; k < srcw; ++k) 676 { 677 if((k%2) == 0)fwrite(mapped_buffer2,1,1,psb_video_debug_nv_buffer_fp); 678 mapped_buffer2++; 679 } 680 mapped_buffer2 += obj_surface->psb_surface->stride-srcw; 681 } 682 mapped_buffer2=mapped_buffer; 683 for(j = 0 ; j < srch /2; ++j) 684 { 685 for(k = 0; k < srcw; ++k) 686 { 687 if((k%2) == 1)fwrite(mapped_buffer2,1,1,psb_video_debug_nv_buffer_fp); 688 mapped_buffer2++; 689 } 690 mapped_buffer2 += obj_surface->psb_surface->stride-srcw; 691 } 692 psb_buffer_unmap(&obj_surface->psb_surface->buf); 693 } 694} 695 696#ifdef DEBUG_TRACE 697void psb__trace_message(const char *msg, ...) 698{ 699 va_list args; 700 static const char *trace_file = 0; 701 static FILE *trace = 0; 702 703 if (!trace_file) { 704 char trace_fn[1024]; 705 706 if (psb_parse_config("PSB_VIDEO_TRACE", &trace_fn[0]) == 0) 707 trace_file = trace_fn; 708 709 if (trace_file) { 710 trace = fopen(trace_file, "w"); 711 if (trace) { 712 time_t curtime; 713 time(&curtime); 714 fprintf(trace, "---- %s\n---- Start Trace ----\n", ctime(&curtime)); 715 } 716 } else { 717 trace_file = "none"; 718 } 719 } 720 if (trace) { 721 if (msg) { 722 va_start(args, msg); 723 vfprintf(trace, msg, args); 724 va_end(args); 725 } else { 726 fflush(trace); 727 } 728 } 729} 730#endif 731 732VAStatus psb_QueryConfigProfiles( 733 VADriverContextP ctx, 734 VAProfile *profile_list, /* out */ 735 int *num_profiles /* out */ 736) 737{ 738 (void) ctx; /* unused */ 739 int i = 0; 740 VAStatus vaStatus = VA_STATUS_SUCCESS; 741 INIT_DRIVER_DATA 742 743 if (NULL == profile_list) { 744 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 745 DEBUG_FAILURE; 746 return vaStatus; 747 } 748 if (NULL == num_profiles) { 749 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 750 DEBUG_FAILURE; 751 return vaStatus; 752 } 753 754// profile_list[i++] = VAProfileMPEG2Simple; 755 profile_list[i++] = VAProfileMPEG2Main; 756 profile_list[i++] = VAProfileMPEG4Simple; 757 profile_list[i++] = VAProfileMPEG4AdvancedSimple; 758// profile_list[i++] = VAProfileMPEG4Main; 759 profile_list[i++] = VAProfileH264Baseline; 760 profile_list[i++] = VAProfileH264Main; 761 profile_list[i++] = VAProfileH264High; 762 profile_list[i++] = VAProfileVC1Simple; 763 profile_list[i++] = VAProfileVC1Main; 764 profile_list[i++] = VAProfileVC1Advanced; 765 766 if (IS_MFLD(driver_data)) { 767 profile_list[i++] = VAProfileH263Baseline; 768 profile_list[i++] = VAProfileJPEGBaseline; 769 } else if (IS_MRST(driver_data)) 770 profile_list[i++] = VAProfileH263Baseline; 771 profile_list[i++] = VAProfileH264ConstrainedBaseline; 772 773 /* If the assert fails then PSB_MAX_PROFILES needs to be bigger */ 774 ASSERT(i <= PSB_MAX_PROFILES); 775 *num_profiles = i; 776 777 return VA_STATUS_SUCCESS; 778} 779 780 781VAStatus psb_QueryConfigEntrypoints( 782 VADriverContextP ctx, 783 VAProfile profile, 784 VAEntrypoint *entrypoint_list, /* out */ 785 int *num_entrypoints /* out */ 786) 787{ 788 INIT_DRIVER_DATA 789 VAStatus vaStatus = VA_STATUS_SUCCESS; 790 int entrypoints = 0; 791 int i; 792 793 if (NULL == entrypoint_list) { 794 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 795 DEBUG_FAILURE; 796 return vaStatus; 797 } 798 if (NULL == num_entrypoints || profile >= PSB_MAX_PROFILES) { 799 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 800 DEBUG_FAILURE; 801 return vaStatus; 802 } 803 804 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { 805 if (driver_data->profile2Format[profile][i]) { 806 entrypoints++; 807 *entrypoint_list++ = i; 808 } 809 } 810 811 /* If the assert fails then PSB_MAX_ENTRYPOINTS needs to be bigger */ 812 ASSERT(entrypoints <= PSB_MAX_ENTRYPOINTS); 813 814 if (0 == entrypoints) { 815 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 816 } 817 818 *num_entrypoints = entrypoints; 819 return VA_STATUS_SUCCESS; 820} 821 822/* 823 * Figure out if we should return VA_STATUS_ERROR_UNSUPPORTED_PROFILE 824 * or VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT 825 */ 826static VAStatus psb__error_unsupported_profile_entrypoint(psb_driver_data_p driver_data, VAProfile profile, VAEntrypoint entrypoint) 827{ 828 /* Does the driver support _any_ entrypoint for this profile? */ 829 if (profile < PSB_MAX_PROFILES) { 830 int i; 831 832 for (i = 0; i < PSB_MAX_ENTRYPOINTS; i++) { 833 if (driver_data->profile2Format[profile][i]) { 834 /* There is an entrypoint, so the profile is supported */ 835 return VA_STATUS_ERROR_UNSUPPORTED_ENTRYPOINT; 836 } 837 } 838 } 839 return VA_STATUS_ERROR_UNSUPPORTED_PROFILE; 840} 841 842VAStatus psb_GetConfigAttributes( 843 VADriverContextP ctx, 844 VAProfile profile, 845 VAEntrypoint entrypoint, 846 VAConfigAttrib *attrib_list, /* in/out */ 847 int num_attribs 848) 849{ 850 INIT_DRIVER_DATA 851 INIT_FORMAT_VTABLE 852 int i; 853 VAStatus vaStatus = VA_STATUS_SUCCESS; 854 if (NULL == format_vtable) { 855 return psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); 856 } 857 if (NULL == attrib_list) { 858 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 859 DEBUG_FAILURE; 860 return vaStatus; 861 } 862 if (num_attribs <= 0) { 863 return VA_STATUS_ERROR_INVALID_PARAMETER; 864 } 865 866 /* Generic attributes */ 867 for (i = 0; i < num_attribs; i++) { 868 switch (attrib_list[i].type) { 869 case VAConfigAttribRTFormat: 870 attrib_list[i].value = VA_RT_FORMAT_YUV420; 871 if (entrypoint == VAEntrypointEncPicture) 872 attrib_list[i].value |= VA_RT_FORMAT_YUV422; 873 break; 874 875 default: 876 attrib_list[i].value = VA_ATTRIB_NOT_SUPPORTED; 877 break; 878 } 879 } 880 /* format specific attributes */ 881 format_vtable->queryConfigAttributes(profile, entrypoint, attrib_list, num_attribs); 882 883 return VA_STATUS_SUCCESS; 884} 885 886static VAStatus psb__update_attribute(object_config_p obj_config, VAConfigAttrib *attrib) 887{ 888 int i; 889 /* Check existing attributes */ 890 for (i = 0; i < obj_config->attrib_count; i++) { 891 if (obj_config->attrib_list[i].type == attrib->type) { 892 /* Update existing attribute */ 893 obj_config->attrib_list[i].value = attrib->value; 894 return VA_STATUS_SUCCESS; 895 } 896 } 897 if (obj_config->attrib_count < PSB_MAX_CONFIG_ATTRIBUTES) { 898 i = obj_config->attrib_count; 899 obj_config->attrib_list[i].type = attrib->type; 900 obj_config->attrib_list[i].value = attrib->value; 901 obj_config->attrib_count++; 902 return VA_STATUS_SUCCESS; 903 } 904 return VA_STATUS_ERROR_MAX_NUM_EXCEEDED; 905} 906 907static VAStatus psb__validate_config(object_config_p obj_config) 908{ 909 int i; 910 /* Check all attributes */ 911 for (i = 0; i < obj_config->attrib_count; i++) { 912 switch (obj_config->attrib_list[i].type) { 913 case VAConfigAttribRTFormat: 914 if (!(obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV420 915 || (obj_config->attrib_list[i].value == VA_RT_FORMAT_YUV422 && 916 obj_config->entrypoint == VAEntrypointEncPicture))) { 917 return VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 918 } 919 break; 920 921 default: 922 /* 923 * Ignore unknown attributes here, it 924 * may be format specific. 925 */ 926 break; 927 } 928 } 929 return VA_STATUS_SUCCESS; 930} 931 932static int psb_get_active_entrypoint_number( 933 VADriverContextP ctx, 934 unsigned int entrypoint) 935{ 936 INIT_DRIVER_DATA; 937 struct drm_lnc_video_getparam_arg arg; 938 int count = 0; 939 int ret; 940 941 if (VAEntrypointVLD > entrypoint || 942 entrypoint > VAEntrypointEncPicture) { 943 psb__error_message("%s :Invalid entrypoint %d.\n", 944 __FUNCTION__, entrypoint); 945 return -1; 946 } 947 948 arg.key = PNW_VIDEO_QUERY_ENTRY; 949 arg.value = (uint64_t)((unsigned long) &count); 950 arg.arg = (uint64_t)((unsigned int)&entrypoint); 951 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 952 &arg, sizeof(arg)); 953 if (ret) { 954 psb__error_message("%s drmCommandWriteRead fails %d.\n", 955 __FUNCTION__, ret); 956 return -1; 957 } 958 959 return count; 960} 961 962VAStatus psb_CreateConfig( 963 VADriverContextP ctx, 964 VAProfile profile, 965 VAEntrypoint entrypoint, 966 VAConfigAttrib *attrib_list, 967 int num_attribs, 968 VAConfigID *config_id /* out */ 969) 970{ 971 INIT_DRIVER_DATA 972 INIT_FORMAT_VTABLE 973 VAStatus vaStatus = VA_STATUS_SUCCESS; 974 int configID; 975 object_config_p obj_config; 976 int i; 977 978 /*echo 8 > /sys/module/pvrsrvkm/parameters/no_ec will disable error concealment*/ 979 if ((profile == VAProfileH264ConstrainedBaseline) && (VAEntrypointVLD == entrypoint)) { 980 char ec_disable[2]; 981 FILE *ec_fp = fopen("/sys/module/pvrsrvkm/parameters/no_ec", "r"); 982 if (ec_fp) { 983 if (fgets(ec_disable, 2, ec_fp) != NULL) { 984 /* force profile to VAProfileH264High */ 985 if (strcmp(ec_disable, "8") == 0) { 986 psb__information_message("disabled error concealment by setting profile to VAProfileH264High\n"); 987 profile = VAProfileH264High; 988 } 989 } 990 fclose(ec_fp); 991 } 992 } 993 994 if (NULL == config_id) { 995 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 996 return vaStatus; 997 } 998 999 if (num_attribs < 0) { 1000 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1001 } 1002 1003 if (NULL == attrib_list) { 1004 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1005 return vaStatus; 1006 } 1007 1008 if (NULL == format_vtable) { 1009 vaStatus = psb__error_unsupported_profile_entrypoint(driver_data, profile, entrypoint); 1010 } 1011 1012 if (VA_STATUS_SUCCESS != vaStatus) { 1013 return vaStatus; 1014 } 1015 1016 if ((IS_MFLD(driver_data)) && 1017 ((VAEntrypointEncPicture == entrypoint) 1018 || (VAEntrypointEncSlice == entrypoint))) { 1019 int active_slc, active_pic; 1020 /* Only allow one encoding entrypoint at the sametime. 1021 * But if video encoding request comes when process JPEG encoding, 1022 * it will wait until current JPEG picture encoding finish. 1023 * Further JPEG encoding should fall back to software path.*/ 1024 active_slc = psb_get_active_entrypoint_number(ctx, VAEntrypointEncSlice); 1025 active_pic = psb_get_active_entrypoint_number(ctx, VAEntrypointEncPicture); 1026 1027 if (active_slc > 0) { 1028 psb__error_message("There already is a active video encoding entrypoint." 1029 "Entrypoint %d isn't available.\n", entrypoint); 1030 return VA_STATUS_ERROR_HW_BUSY; 1031 } 1032 else if (active_pic > 0 && VAEntrypointEncPicture == entrypoint) { 1033 psb__error_message("There already is a active picture encoding entrypoint." 1034 "Entrypoint %d isn't available.\n", entrypoint); 1035 return VA_STATUS_ERROR_HW_BUSY; 1036 } 1037 } 1038 1039 configID = object_heap_allocate(&driver_data->config_heap); 1040 obj_config = CONFIG(configID); 1041 if (NULL == obj_config) { 1042 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1043 return vaStatus; 1044 } 1045 1046 1047 MEMSET_OBJECT(obj_config, struct object_config_s); 1048 1049 obj_config->profile = profile; 1050 obj_config->format_vtable = format_vtable; 1051 obj_config->entrypoint = entrypoint; 1052 obj_config->attrib_list[0].type = VAConfigAttribRTFormat; 1053 obj_config->attrib_list[0].value = VA_RT_FORMAT_YUV420; 1054 obj_config->attrib_count = 1; 1055 1056 for (i = 0; i < num_attribs; i++) { 1057 if (attrib_list[i].type > VAConfigAttribRateControl) 1058 return VA_STATUS_ERROR_ATTR_NOT_SUPPORTED; 1059 1060 vaStatus = psb__update_attribute(obj_config, &(attrib_list[i])); 1061 if (VA_STATUS_SUCCESS != vaStatus) { 1062 break; 1063 } 1064 } 1065 1066 if (VA_STATUS_SUCCESS == vaStatus) { 1067 vaStatus = psb__validate_config(obj_config); 1068 } 1069 1070 if (VA_STATUS_SUCCESS == vaStatus) { 1071 vaStatus = format_vtable->validateConfig(obj_config); 1072 } 1073 1074 /* Error recovery */ 1075 if (VA_STATUS_SUCCESS != vaStatus) { 1076 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 1077 } else { 1078 *config_id = configID; 1079 } 1080 1081 /* only VAProfileH264ConstrainedBaseline profile enable error concealment*/ 1082 if (IS_MRST(driver_data) && 1083 (getenv("PSB_VIDEO_NOEC") == NULL) 1084 && (profile == VAProfileH264ConstrainedBaseline)) { 1085 psb__information_message("profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n"); 1086 driver_data->ec_enabled = 1; 1087#ifdef MFLD_ERROR_CONCEALMENT 1088 } else if(IS_MFLD(driver_data) && 1089 (getenv("PSB_VIDEO_NOEC") == NULL) 1090 && (profile == VAProfileH264ConstrainedBaseline)) { 1091 psb__information_message("profile is VAProfileH264ConstrainedBaseline, error concealment is enabled. \n"); 1092 driver_data->ec_enabled = 1; 1093#endif 1094 } else { 1095 driver_data->ec_enabled = 0; 1096 } 1097 return vaStatus; 1098} 1099 1100VAStatus psb_DestroyConfig( 1101 VADriverContextP ctx, 1102 VAConfigID config_id 1103) 1104{ 1105 INIT_DRIVER_DATA 1106 VAStatus vaStatus = VA_STATUS_SUCCESS; 1107 object_config_p obj_config; 1108 1109 obj_config = CONFIG(config_id); 1110 if (NULL == obj_config) { 1111 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 1112 DEBUG_FAILURE; 1113 return vaStatus; 1114 } 1115 1116 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 1117 return vaStatus; 1118} 1119 1120VAStatus psb_QueryConfigAttributes( 1121 VADriverContextP ctx, 1122 VAConfigID config_id, 1123 VAProfile *profile, /* out */ 1124 VAEntrypoint *entrypoint, /* out */ 1125 VAConfigAttrib *attrib_list, /* out */ 1126 int *num_attribs /* out */ 1127) 1128{ 1129 INIT_DRIVER_DATA 1130 VAStatus vaStatus = VA_STATUS_SUCCESS; 1131 object_config_p obj_config; 1132 int i; 1133 1134 if (NULL == profile) { 1135 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1136 DEBUG_FAILURE; 1137 return vaStatus; 1138 } 1139 if (NULL == entrypoint) { 1140 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1141 DEBUG_FAILURE; 1142 return vaStatus; 1143 } 1144 if (NULL == attrib_list) { 1145 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1146 DEBUG_FAILURE; 1147 return vaStatus; 1148 } 1149 if (NULL == num_attribs) { 1150 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1151 DEBUG_FAILURE; 1152 return vaStatus; 1153 } 1154 obj_config = CONFIG(config_id); 1155 if (NULL == obj_config) { 1156 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 1157 DEBUG_FAILURE; 1158 return vaStatus; 1159 } 1160 1161 *profile = obj_config->profile; 1162 *entrypoint = obj_config->entrypoint; 1163 *num_attribs = obj_config->attrib_count; 1164 for (i = 0; i < obj_config->attrib_count; i++) { 1165 attrib_list[i] = obj_config->attrib_list[i]; 1166 } 1167 1168 return vaStatus; 1169} 1170 1171static void psb__destroy_surface(psb_driver_data_p driver_data, object_surface_p obj_surface) 1172{ 1173 if (NULL != obj_surface) { 1174 /* delete subpicture association */ 1175 psb_SurfaceDeassociateSubpict(driver_data, obj_surface); 1176 1177 psb_surface_sync(obj_surface->psb_surface); 1178 psb_surface_destroy(obj_surface->psb_surface); 1179 1180 if (obj_surface->psb_surface_rotate) { 1181 psb_surface_destroy(obj_surface->psb_surface_rotate); 1182 } 1183 1184 free(obj_surface->psb_surface); 1185 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1186 } 1187} 1188 1189static 1190VAStatus psb__checkSurfaceDimensions(psb_driver_data_p driver_data, int width, int height) 1191{ 1192 if (driver_data->video_sd_disabled) { 1193 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 1194 } 1195 if ((width <= 0) || (width * height > 5120 * 5120) || (height <= 0)) { 1196 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 1197 } 1198 if (driver_data->video_hd_disabled) { 1199 if ((width > 1024) || (height > 576)) { 1200 return VA_STATUS_ERROR_RESOLUTION_NOT_SUPPORTED; 1201 } 1202 } 1203 1204 return VA_STATUS_SUCCESS; 1205} 1206 1207 1208VAStatus psb_CreateSurfaces( 1209 VADriverContextP ctx, 1210 int width, 1211 int height, 1212 int format, 1213 int num_surfaces, 1214 VASurfaceID *surface_list, /* out */ 1215 VASurfaceAttrib *attrib_list, 1216 int num_attribs 1217) 1218{ 1219 INIT_DRIVER_DATA 1220 VAStatus vaStatus = VA_STATUS_SUCCESS; 1221 int i, height_origin, usage, buffer_stride = 0; 1222 int protected = (VA_RT_FORMAT_PROTECTED & format); 1223 unsigned long fourcc; 1224 VAExternalMemoryBuffers *external_buffers = NULL; 1225 buffer_handle_t handle; 1226 void *vaddr[2]; 1227 unsigned int *tmp_khandles = NULL; 1228 1229 format = format & (~VA_RT_FORMAT_PROTECTED); 1230 if (num_surfaces <= 0) { 1231 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1232 DEBUG_FAILURE; 1233 return vaStatus; 1234 } 1235 if (NULL == surface_list) { 1236 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1237 DEBUG_FAILURE; 1238 return vaStatus; 1239 } 1240 1241 if ((attrib_list != NULL) && (num_attribs > 0)) { 1242 for (i = 0; i < num_attribs; i++, attrib_list++) { 1243 if (!attrib_list) 1244 return VA_STATUS_ERROR_INVALID_PARAMETER; 1245 switch (attrib_list->type) { 1246 case VASurfaceAttribNativeHandle: 1247 if (external_buffers != NULL) { 1248 //only support one VASurfaceAttribNativeHandle attribute 1249 continue; 1250 } else if (attrib_list->value.type == VAGenericValueTypePointer) { 1251 external_buffers = (VAExternalMemoryBuffers *)attrib_list->value.value.p_val; 1252 } else { 1253 return VA_STATUS_ERROR_INVALID_PARAMETER; 1254 } 1255 break; 1256 default: 1257 psb__error_message("Unsupported attribute.\n"); 1258 return VA_STATUS_ERROR_INVALID_PARAMETER; 1259 } 1260 } 1261 } 1262 1263 /* We only support one format */ 1264 if ((VA_RT_FORMAT_YUV420 != format) 1265 && (VA_RT_FORMAT_YUV422 != format)) { 1266 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 1267 DEBUG_FAILURE; 1268 return vaStatus; 1269 } 1270 1271 /* the pixel_format also can only be NV12 */ 1272 if (external_buffers && (HAL_PIXEL_FORMAT_NV12_VED != external_buffers->pixel_format)) { 1273 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 1274 DEBUG_FAILURE; 1275 return vaStatus; 1276 } 1277 if (external_buffers) 1278 driver_data->native_window = external_buffers->native_window; 1279 1280 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 1281 if (VA_STATUS_SUCCESS != vaStatus) { 1282 DEBUG_FAILURE; 1283 return vaStatus; 1284 } 1285 1286 /* Adjust height to be a multiple of 32 (height of macroblock in interlaced mode) */ 1287 height_origin = height; 1288 height = (height + 0x1f) & ~0x1f; 1289 1290 if(external_buffers != NULL) { 1291 int size = num_surfaces * sizeof(unsigned int); 1292 1293 tmp_khandles = calloc(1, size); 1294 if (tmp_khandles == NULL) { 1295 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1296 DEBUG_FAILURE; 1297 return vaStatus; 1298 } 1299 } 1300 1301 for (i = 0; i < num_surfaces; i++) { 1302 int surfaceID; 1303 object_surface_p obj_surface; 1304 psb_surface_p psb_surface; 1305 1306 surfaceID = object_heap_allocate(&driver_data->surface_heap); 1307 obj_surface = SURFACE(surfaceID); 1308 if (NULL == obj_surface) { 1309 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1310 DEBUG_FAILURE; 1311 break; 1312 } 1313 MEMSET_OBJECT(obj_surface, struct object_surface_s); 1314 1315 obj_surface->surface_id = surfaceID; 1316 surface_list[i] = surfaceID; 1317 obj_surface->context_id = -1; 1318 obj_surface->width = width; 1319 obj_surface->height = height; 1320 obj_surface->width_r = width; 1321 obj_surface->height_r = height; 1322 obj_surface->height_origin = height_origin; 1323 1324 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 1325 if (NULL == psb_surface) { 1326 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1327 obj_surface->surface_id = VA_INVALID_SURFACE; 1328 1329 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1330 1331 DEBUG_FAILURE; 1332 break; 1333 } 1334 1335 switch (format) { 1336 case VA_RT_FORMAT_YUV422: 1337 fourcc = VA_FOURCC_YV16; 1338 break; 1339 case VA_RT_FORMAT_YUV420: 1340 default: 1341 fourcc = VA_FOURCC_NV12; 1342 break; 1343 } 1344 if (external_buffers != NULL) { 1345 switch (external_buffers->type) { 1346 case VAExternalMemoryAndroidGrallocBuffer: 1347 /*hard code the gralloc buffer usage*/ 1348 usage = GRALLOC_USAGE_SW_WRITE_OFTEN | GRALLOC_USAGE_HW_TEXTURE | GRALLOC_USAGE_HW_COMPOSER; 1349 handle = (buffer_handle_t)external_buffers->buffers[i]; 1350 if (gralloc_lock(handle, usage, 0, 0, width, height, (void **)&vaddr)) { 1351 vaStatus = VA_STATUS_ERROR_UNKNOWN; 1352 } else { 1353 vaStatus = psb_surface_create_from_ub(driver_data, width, height, fourcc, 1354 external_buffers, psb_surface, vaddr[0]); 1355 psb_surface->buf.handle = handle; 1356 obj_surface->share_info = (psb_surface_share_info_t *)vaddr[1]; 1357 memset(obj_surface->share_info, 0, sizeof(struct psb_surface_share_info_s)); 1358 obj_surface->share_info->force_output_method = protected ? OUTPUT_FORCE_OVERLAY : 0; 1359 obj_surface->share_info->width = obj_surface->width; 1360 obj_surface->share_info->height = obj_surface->height; 1361 1362 obj_surface->share_info->luma_stride = psb_surface->stride; 1363 obj_surface->share_info->chroma_u_stride = psb_surface->stride; 1364 obj_surface->share_info->chroma_v_stride = psb_surface->stride; 1365 obj_surface->share_info->format = VA_FOURCC_NV12; 1366 1367 obj_surface->share_info->khandle = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); 1368 obj_surface->share_info->khandles_count = num_surfaces; 1369 tmp_khandles[i] = obj_surface->share_info->khandle; 1370 1371 obj_surface->share_info->renderStatus = 0; 1372 1373 psb__information_message("%s : Create graphic buffer success" 1374 "surface_id= 0x%x, vaddr[0] (0x%x), vaddr[1] (0x%x)\n", __FUNCTION__, surfaceID, vaddr[0], vaddr[1]); 1375 gralloc_unlock(handle); 1376 } 1377 break; 1378 default: 1379 psb__error_message("Unsupported external buffer.\n"); 1380 } 1381 } else { 1382 vaStatus = psb_surface_create(driver_data, width, height, fourcc, 1383 protected, psb_surface); 1384 } 1385 if (VA_STATUS_SUCCESS != vaStatus) { 1386 free(psb_surface); 1387 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1388 obj_surface->surface_id = VA_INVALID_SURFACE; 1389 1390 DEBUG_FAILURE; 1391 break; 1392 } 1393 buffer_stride = psb_surface->stride; 1394 /* by default, surface fourcc is NV12 */ 1395 psb_surface->extra_info[4] = fourcc; 1396 obj_surface->psb_surface = psb_surface; 1397 } 1398 1399 /* Error recovery */ 1400 if (VA_STATUS_SUCCESS != vaStatus) { 1401 /* surface_list[i-1] was the last successful allocation */ 1402 for (; i--;) { 1403 object_surface_p obj_surface = SURFACE(surface_list[i]); 1404 psb__destroy_surface(driver_data, obj_surface); 1405 surface_list[i] = VA_INVALID_SURFACE; 1406 } 1407 psb__error_message("CreateSurfaces failed\n"); 1408 return vaStatus; 1409 } 1410 1411 if (VA_STATUS_SUCCESS == vaStatus && external_buffers != NULL) { 1412 int max_num_to_copy = num_surfaces; 1413 if(max_num_to_copy > MAX_SHARE_INFO_KHANDLES) { 1414 max_num_to_copy = MAX_SHARE_INFO_KHANDLES; 1415 } 1416 for (i = 0; i < num_surfaces; i++) { 1417 object_surface_p obj_surface = SURFACE(surface_list[i]); 1418 memcpy(obj_surface->share_info->khandles, tmp_khandles, 1419 sizeof(unsigned int) * max_num_to_copy); 1420 } 1421 } 1422 1423 if (tmp_khandles != NULL) 1424 free(tmp_khandles); 1425 1426 if (fourcc == VA_FOURCC_NV12) 1427 psb_add_video_bcd(ctx, width, height, buffer_stride, 1428 num_surfaces, surface_list); 1429 return vaStatus; 1430} 1431 1432 1433VAStatus psb_CreateSurfaceFromCIFrame( 1434 VADriverContextP ctx, 1435 unsigned long frame_id, 1436 VASurfaceID *surface /* out */ 1437) 1438{ 1439 INIT_DRIVER_DATA 1440 VAStatus vaStatus = VA_STATUS_SUCCESS; 1441 int surfaceID; 1442 object_surface_p obj_surface; 1443 psb_surface_p psb_surface; 1444 struct ci_frame_info frame_info; 1445 int ret = 0, fd = -1; 1446 char *camera_dev = NULL; 1447 1448 if (IS_MRST(driver_data) == 0) 1449 return VA_STATUS_ERROR_UNKNOWN; 1450 1451 camera_dev = getenv("PSB_VIDEO_CAMERA_DEVNAME"); 1452 1453 if (camera_dev) 1454 fd = open_device(camera_dev); 1455 else 1456 fd = open_device("/dev/video0"); 1457 if (fd == -1) 1458 return VA_STATUS_ERROR_UNKNOWN; 1459 1460 frame_info.frame_id = frame_id; 1461 ret = ci_get_frame_info(fd, &frame_info); 1462 close_device(fd); 1463 1464 if (ret != 0) 1465 return VA_STATUS_ERROR_UNKNOWN; 1466 1467 psb__information_message("CI Frame: id=0x%08x, %dx%d, stride=%d, offset=0x%08x, fourcc=0x%08x\n", 1468 frame_info.frame_id, frame_info.width, frame_info.height, 1469 frame_info.stride, frame_info.offset, frame_info.fourcc); 1470 1471 if (frame_info.stride & 0x3f) { 1472 psb__error_message("CI Frame must be 64byte aligned!\n"); 1473 /* return VA_STATUS_ERROR_UNKNOWN; */ 1474 } 1475 1476 if (frame_info.fourcc != VA_FOURCC_NV12) { 1477 psb__error_message("CI Frame must be NV12 format!\n"); 1478 return VA_STATUS_ERROR_UNKNOWN; 1479 } 1480 if (frame_info.offset & 0xfff) { 1481 psb__error_message("CI Frame offset must be page aligned!\n"); 1482 /* return VA_STATUS_ERROR_UNKNOWN; */ 1483 } 1484 1485 /* all sanity check passed */ 1486 surfaceID = object_heap_allocate(&driver_data->surface_heap); 1487 obj_surface = SURFACE(surfaceID); 1488 if (NULL == obj_surface) { 1489 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1490 DEBUG_FAILURE; 1491 return vaStatus; 1492 } 1493 1494 MEMSET_OBJECT(obj_surface, struct object_surface_s); 1495 1496 obj_surface->surface_id = surfaceID; 1497 *surface = surfaceID; 1498 obj_surface->context_id = -1; 1499 obj_surface->width = frame_info.width; 1500 obj_surface->height = frame_info.height; 1501 1502 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 1503 if (NULL == psb_surface) { 1504 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1505 obj_surface->surface_id = VA_INVALID_SURFACE; 1506 1507 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1508 1509 DEBUG_FAILURE; 1510 1511 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1512 obj_surface->surface_id = VA_INVALID_SURFACE; 1513 1514 return vaStatus; 1515 } 1516 1517 vaStatus = psb_surface_create_camera(driver_data, frame_info.width, frame_info.height, 1518 frame_info.stride, frame_info.stride * frame_info.height, 1519 psb_surface, 1520 0, /* not V4L2 */ 1521 frame_info.offset); 1522 if (VA_STATUS_SUCCESS != vaStatus) { 1523 free(psb_surface); 1524 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 1525 obj_surface->surface_id = VA_INVALID_SURFACE; 1526 1527 DEBUG_FAILURE; 1528 1529 return vaStatus; 1530 } 1531 1532 memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info)); 1533 psb_surface->extra_info[4] = VA_FOURCC_NV12; 1534 1535 obj_surface->psb_surface = psb_surface; 1536 1537 /* Error recovery */ 1538 if (VA_STATUS_SUCCESS != vaStatus) { 1539 object_surface_p obj_surface = SURFACE(*surface); 1540 psb__destroy_surface(driver_data, obj_surface); 1541 *surface = VA_INVALID_SURFACE; 1542 } 1543 1544 return vaStatus; 1545} 1546 1547VAStatus psb_DestroySurfaces( 1548 VADriverContextP ctx, 1549 VASurfaceID *surface_list, 1550 int num_surfaces 1551) 1552{ 1553 INIT_DRIVER_DATA 1554 int i; 1555 1556 if (num_surfaces <= 0) { 1557 return VA_STATUS_ERROR_INVALID_PARAMETER; 1558 } 1559 1560 if (NULL == surface_list) { 1561 /* This is a workaround for bug 3419. If libva surfaces and context are pre-allocated, 1562 * mix call the function with NULL & 0 parameters to notify video driver when decoder is destroyed. 1563 */ 1564#ifdef ANDROID 1565#include "android/psb_android_glue.h" 1566 if (driver_data->ts_source_created) { 1567 psb__information_message("In psb_release_video_bcd, call psb_android_texture_streaming_destroy to destroy texture streaming source.\n"); 1568 psb_android_texture_streaming_destroy(); 1569 driver_data->ts_source_created = 0; 1570 } 1571#endif 1572 return VA_STATUS_ERROR_INVALID_SURFACE; 1573 } 1574 1575 if (driver_data->bcd_registered != 0) 1576 if (VA_STATUS_SUCCESS != psb_release_video_bcd(ctx)) 1577 return VA_STATUS_ERROR_UNKNOWN; 1578 1579 /* Free PVR2D buffer wrapped from the surfaces */ 1580 psb_free_surface_pvr2dbuf(driver_data); 1581 1582 /* Make validation happy */ 1583 for (i = 0; i < num_surfaces; i++) { 1584 object_surface_p obj_surface = SURFACE(surface_list[i]); 1585 if (obj_surface == NULL) { 1586 return VA_STATUS_ERROR_INVALID_SURFACE; 1587 } 1588 if (obj_surface->derived_imgcnt > 0) { 1589 psb__error_message("Some surface is deriving by images\n"); 1590 return VA_STATUS_ERROR_OPERATION_FAILED; 1591 } 1592 } 1593 1594 for (i = 0; i < num_surfaces; i++) { 1595 object_surface_p obj_surface = SURFACE(surface_list[i]); 1596 1597 if (driver_data->cur_displaying_surface == surface_list[i]) { 1598 /* Surface is being displaying. Need to stop overlay here */ 1599 psb_coverlay_stop(ctx); 1600 } 1601 psb__information_message("%s : obj_surface->surface_id = 0x%x\n",__FUNCTION__, obj_surface->surface_id); 1602 psb__destroy_surface(driver_data, obj_surface); 1603 surface_list[i] = VA_INVALID_SURFACE; 1604 } 1605 1606 return VA_STATUS_SUCCESS; 1607} 1608 1609int psb_new_context(psb_driver_data_p driver_data, int ctx_type) 1610{ 1611 struct drm_lnc_video_getparam_arg arg; 1612 int ret = 0; 1613 1614 arg.key = IMG_VIDEO_NEW_CONTEXT; 1615 arg.value = (uint64_t)((unsigned long) & ctx_type); 1616 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 1617 &arg, sizeof(arg)); 1618 if (ret != 0) 1619 psb__error_message("Set context %d failed\n", ctx_type); 1620 1621 return ret; 1622} 1623 1624int psb_rm_context(psb_driver_data_p driver_data) 1625{ 1626 struct drm_lnc_video_getparam_arg arg; 1627 int tmp; 1628 int ret = 0; 1629 1630 arg.key = IMG_VIDEO_RM_CONTEXT; 1631 arg.value = (uint64_t)((unsigned long) & tmp); /* value is ignored */ 1632 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 1633 &arg, sizeof(arg)); 1634 if (ret != 0) 1635 psb__error_message("Remove context failed\n"); 1636 1637 return ret; 1638} 1639 1640VAStatus psb_CreateContext( 1641 VADriverContextP ctx, 1642 VAConfigID config_id, 1643 int picture_width, 1644 int picture_height, 1645 int flag, 1646 VASurfaceID *render_targets, 1647 int num_render_targets, 1648 VAContextID *context /* out */ 1649) 1650{ 1651 INIT_DRIVER_DATA 1652 VAStatus vaStatus = VA_STATUS_SUCCESS; 1653 object_config_p obj_config; 1654 int cmdbuf_num, encode = 0; 1655 int i; 1656 1657 if (num_render_targets <= 0) { 1658 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 1659 DEBUG_FAILURE; 1660 return vaStatus; 1661 } 1662 1663 if (NULL == render_targets) { 1664 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1665 DEBUG_FAILURE; 1666 return vaStatus; 1667 } 1668 if (NULL == context) { 1669 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 1670 DEBUG_FAILURE; 1671 return vaStatus; 1672 } 1673 1674 vaStatus = psb__checkSurfaceDimensions(driver_data, picture_width, picture_height); 1675 if (VA_STATUS_SUCCESS != vaStatus) { 1676 DEBUG_FAILURE; 1677 return vaStatus; 1678 } 1679 1680 obj_config = CONFIG(config_id); 1681 if (NULL == obj_config) { 1682 vaStatus = VA_STATUS_ERROR_INVALID_CONFIG; 1683 DEBUG_FAILURE; 1684 return vaStatus; 1685 } 1686 1687 int contextID = object_heap_allocate(&driver_data->context_heap); 1688 object_context_p obj_context = CONTEXT(contextID); 1689 if (NULL == obj_context) { 1690 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1691 DEBUG_FAILURE; 1692 return vaStatus; 1693 } 1694 1695 *context = contextID; 1696 1697 MEMSET_OBJECT(obj_context, struct object_context_s); 1698 1699 obj_context->driver_data = driver_data; 1700 obj_context->current_render_target = NULL; 1701 obj_context->is_oold = driver_data->is_oold; 1702 obj_context->context_id = contextID; 1703 obj_context->config_id = config_id; 1704 obj_context->picture_width = picture_width; 1705 obj_context->picture_height = picture_height; 1706 obj_context->num_render_targets = num_render_targets; 1707 obj_context->render_targets = (VASurfaceID *) calloc(1, num_render_targets * sizeof(VASurfaceID)); 1708 if (obj_context->render_targets == NULL) { 1709 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1710 DEBUG_FAILURE; 1711 1712 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1713 1714 return vaStatus; 1715 } 1716 1717 /* allocate buffer points for vaRenderPicture */ 1718 obj_context->num_buffers = 10; 1719 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * obj_context->num_buffers); 1720 if (obj_context->buffer_list == NULL) { 1721 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1722 DEBUG_FAILURE; 1723 1724 free(obj_context->render_targets); 1725 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1726 1727 return vaStatus; 1728 } 1729 1730 memset(obj_context->buffers_unused, 0, sizeof(obj_context->buffers_unused)); 1731 memset(obj_context->buffers_unused_count, 0, sizeof(obj_context->buffers_unused_count)); 1732 memset(obj_context->buffers_unused_tail, 0, sizeof(obj_context->buffers_unused_tail)); 1733 memset(obj_context->buffers_active, 0, sizeof(obj_context->buffers_active)); 1734 1735 if (obj_config->entrypoint == VAEntrypointEncSlice 1736 || obj_config->entrypoint == VAEntrypointEncPicture) { 1737 encode = 1; 1738 } 1739 1740 if (encode) 1741 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; 1742 else 1743 cmdbuf_num = PSB_MAX_CMDBUFS; 1744 1745 for (i = 0; i < num_render_targets; i++) { 1746 object_surface_p obj_surface = SURFACE(render_targets[i]); 1747 psb_surface_p psb_surface; 1748 1749 if (NULL == obj_surface) { 1750 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 1751 DEBUG_FAILURE; 1752 break; 1753 } 1754 1755 psb_surface = obj_surface->psb_surface; 1756 1757 /* Clear format specific surface info */ 1758 obj_context->render_targets[i] = render_targets[i]; 1759 obj_surface->context_id = contextID; /* Claim ownership of surface */ 1760#if 0 1761 /* for decode, move the surface into |TT */ 1762 if ((encode == 0) && /* decode */ 1763 ((psb_surface->buf.pl_flags & DRM_PSB_FLAG_MEM_RAR) == 0)) /* surface not in RAR */ 1764 psb_buffer_setstatus(&obj_surface->psb_surface->buf, 1765 WSBM_PL_FLAG_TT | WSBM_PL_FLAG_SHARED, DRM_PSB_FLAG_MEM_MMU); 1766#endif 1767 } 1768 1769 obj_context->va_flags = flag; 1770 obj_context->format_vtable = obj_config->format_vtable; 1771 obj_context->format_data = NULL; 1772 1773 if (VA_STATUS_SUCCESS == vaStatus) { 1774 vaStatus = obj_context->format_vtable->createContext(obj_context, obj_config); 1775 } 1776 1777 /* Error recovery */ 1778 if (VA_STATUS_SUCCESS != vaStatus) { 1779 obj_context->context_id = -1; 1780 obj_context->config_id = -1; 1781 obj_context->picture_width = 0; 1782 obj_context->picture_height = 0; 1783 free(obj_context->render_targets); 1784 free(obj_context->buffer_list); 1785 obj_context->num_buffers = 0; 1786 obj_context->render_targets = NULL; 1787 obj_context->num_render_targets = 0; 1788 obj_context->va_flags = 0; 1789 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1790 1791 return vaStatus; 1792 } 1793 1794 /* initialize cmdbuf */ 1795 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 1796 obj_context->lnc_cmdbuf_list[i] = NULL; 1797 } 1798 1799 for (i = 0; i < PNW_MAX_CMDBUFS_ENCODE; i++) { 1800 obj_context->pnw_cmdbuf_list[i] = NULL; 1801 } 1802 1803 for (i = 0; i < PSB_MAX_CMDBUFS; i++) { 1804 obj_context->cmdbuf_list[i] = NULL; 1805 } 1806 1807 for (i = 0; i < cmdbuf_num; i++) { 1808 void *cmdbuf; 1809 1810 if (encode) { /* Topaz encode context */ 1811 if (IS_MFLD(obj_context->driver_data)) 1812 cmdbuf = calloc(1, sizeof(struct pnw_cmdbuf_s)); 1813 else 1814 cmdbuf = calloc(1, sizeof(struct lnc_cmdbuf_s)); 1815 } else /* MSVDX decode context */ 1816 cmdbuf = calloc(1, sizeof(struct psb_cmdbuf_s)); 1817 1818 if (NULL == cmdbuf) { 1819 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1820 DEBUG_FAILURE; 1821 break; 1822 } 1823 1824 if (encode) { /* Topaz encode context */ 1825 if (IS_MFLD(obj_context->driver_data)) 1826 vaStatus = pnw_cmdbuf_create(obj_context, driver_data, (pnw_cmdbuf_p)cmdbuf); 1827 else 1828 vaStatus = lnc_cmdbuf_create(obj_context, driver_data, (lnc_cmdbuf_p)cmdbuf); 1829 } else /* MSVDX decode context */ 1830 vaStatus = psb_cmdbuf_create(obj_context, driver_data, (psb_cmdbuf_p)cmdbuf); 1831 1832 if (VA_STATUS_SUCCESS != vaStatus) { 1833 free(cmdbuf); 1834 DEBUG_FAILURE; 1835 break; 1836 } 1837 if (encode) { 1838 if (i >= LNC_MAX_CMDBUFS_ENCODE) { 1839 free(cmdbuf); 1840 DEBUG_FAILURE; 1841 break; 1842 } 1843 1844 if (IS_MFLD(obj_context->driver_data)) 1845 obj_context->pnw_cmdbuf_list[i] = (pnw_cmdbuf_p)cmdbuf; 1846 else 1847 obj_context->lnc_cmdbuf_list[i] = (lnc_cmdbuf_p)cmdbuf; 1848 } else 1849 obj_context->cmdbuf_list[i] = (psb_cmdbuf_p)cmdbuf; 1850 } 1851 obj_context->cmdbuf_current = -1; 1852 obj_context->cmdbuf = NULL; 1853 obj_context->lnc_cmdbuf = NULL; 1854 obj_context->pnw_cmdbuf = NULL; 1855 obj_context->frame_count = 0; 1856 obj_context->slice_count = 0; 1857 obj_context->msvdx_context = ((driver_data->msvdx_context_base & 0xff0000) >> 16) | 1858 ((contextID & 0xff000000) >> 16); 1859#ifdef ANDROID 1860 if(IS_MFLD(driver_data)) { 1861 obj_context->msvdx_context = ((driver_data->drm_fd & 0xf) << 4) | 1862 ((unsigned int)gettid() & 0xf); 1863 } 1864#endif 1865 obj_context->profile = obj_config->profile; 1866 obj_context->entry_point = obj_config->entrypoint; 1867 1868 /* Error recovery */ 1869 if (VA_STATUS_SUCCESS != vaStatus) { 1870 if (cmdbuf_num > LNC_MAX_CMDBUFS_ENCODE) 1871 cmdbuf_num = LNC_MAX_CMDBUFS_ENCODE; 1872 for (i = 0; i < cmdbuf_num; i++) { 1873 if (obj_context->lnc_cmdbuf_list[i]) { 1874 lnc_cmdbuf_destroy(obj_context->lnc_cmdbuf_list[i]); 1875 free(obj_context->lnc_cmdbuf_list[i]); 1876 obj_context->lnc_cmdbuf_list[i] = NULL; 1877 } 1878 if (obj_context->pnw_cmdbuf_list[i]) { 1879 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); 1880 free(obj_context->pnw_cmdbuf_list[i]); 1881 obj_context->pnw_cmdbuf_list[i] = NULL; 1882 } 1883 if (obj_context->cmdbuf_list[i]) { 1884 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); 1885 free(obj_context->cmdbuf_list[i]); 1886 obj_context->cmdbuf_list[i] = NULL; 1887 } 1888 } 1889 1890 obj_context->cmdbuf = NULL; 1891 obj_context->lnc_cmdbuf = NULL; 1892 1893 obj_context->context_id = -1; 1894 obj_context->config_id = -1; 1895 obj_context->picture_width = 0; 1896 obj_context->picture_height = 0; 1897 free(obj_context->render_targets); 1898 free(obj_context->buffer_list); 1899 obj_context->num_buffers = 0; 1900 obj_context->render_targets = NULL; 1901 obj_context->num_render_targets = 0; 1902 obj_context->va_flags = 0; 1903 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 1904 } else 1905 lnc_ospm_start(driver_data, encode); 1906 1907 psb_new_context(driver_data, (obj_config->profile << 8) | obj_config->entrypoint); 1908 1909 return vaStatus; 1910} 1911 1912static VAStatus psb__allocate_malloc_buffer(object_buffer_p obj_buffer, int size) 1913{ 1914 VAStatus vaStatus = VA_STATUS_SUCCESS; 1915 1916 obj_buffer->buffer_data = realloc(obj_buffer->buffer_data, size); 1917 if (NULL == obj_buffer->buffer_data) { 1918 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1919 DEBUG_FAILURE; 1920 } 1921 return vaStatus; 1922} 1923 1924static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer); 1925 1926static VAStatus psb__allocate_BO_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer, int size, unsigned char *data, VABufferType type) 1927{ 1928 VAStatus vaStatus = VA_STATUS_SUCCESS; 1929 1930 ASSERT(NULL == obj_buffer->buffer_data); 1931 1932 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { 1933 psb__information_message("Abandoning BO for buffer %08x type %s\n", obj_buffer->base.id, 1934 buffer_type_to_string(obj_buffer->type)); 1935 /* need to set psb_buffer aside and get another one */ 1936 obj_buffer->psb_buffer->status = psb_bs_abandoned; 1937 obj_buffer->psb_buffer = NULL; 1938 obj_buffer->size = 0; 1939 obj_buffer->alloc_size = 0; 1940 } 1941 1942 if (type == VAProtectedSliceDataBufferType) { 1943 if (obj_buffer->psb_buffer) { 1944 psb__information_message("RAR: old RAR slice buffer with RAR handle 0%08x, current RAR handle 0x%08x\n", 1945 obj_buffer->psb_buffer->rar_handle, (uint32_t)data); 1946 psb__information_message("RAR: force old RAR buffer destroy and new buffer re-allocation by set size=0\n"); 1947 obj_buffer->alloc_size = 0; 1948 } 1949 } 1950 1951 if (obj_buffer->alloc_size < (unsigned int)size) { 1952 psb__information_message("Buffer size mismatch: Need %d, currently have %d\n", size, obj_buffer->alloc_size); 1953 if (obj_buffer->psb_buffer) { 1954 if (obj_buffer->buffer_data) { 1955 psb__unmap_buffer(obj_buffer); 1956 } 1957 psb_buffer_destroy(obj_buffer->psb_buffer); 1958 obj_buffer->alloc_size = 0; 1959 } else { 1960 obj_buffer->psb_buffer = (psb_buffer_p) calloc(1, sizeof(struct psb_buffer_s)); 1961 if (NULL == obj_buffer->psb_buffer) { 1962 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 1963 DEBUG_FAILURE; 1964 } 1965 } 1966 if (VA_STATUS_SUCCESS == vaStatus) { 1967 psb__information_message("Allocate new GPU buffers for vaCreateBuffer:type=%s,size=%d.\n", 1968 buffer_type_to_string(obj_buffer->type), size); 1969 1970 size = (size + 0x7fff) & ~0x7fff; /* Round up */ 1971 if (obj_buffer->type == VAImageBufferType) /* Xserver side PutSurface, Image/subpicture buffer 1972 * should be shared between two process 1973 */ 1974 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu_shared, obj_buffer->psb_buffer); 1975 else if (obj_buffer->type == VAProtectedSliceDataBufferType) { 1976 if (IS_MFLD(driver_data)) 1977 vaStatus = psb_buffer_reference_imr(driver_data, (uint32_t)data, obj_buffer->psb_buffer); 1978 } else 1979 vaStatus = psb_buffer_create(driver_data, size, psb_bt_cpu_vpu, obj_buffer->psb_buffer); 1980 if (VA_STATUS_SUCCESS != vaStatus) { 1981 free(obj_buffer->psb_buffer); 1982 obj_buffer->psb_buffer = NULL; 1983 DEBUG_FAILURE; 1984 } else { 1985 obj_buffer->alloc_size = size; 1986 } 1987 } 1988 } 1989 return vaStatus; 1990} 1991 1992static VAStatus psb__map_buffer(object_buffer_p obj_buffer) 1993{ 1994 if (obj_buffer->psb_buffer) { 1995 return psb_buffer_map(obj_buffer->psb_buffer, &obj_buffer->buffer_data); 1996 } 1997 return VA_STATUS_SUCCESS; 1998} 1999 2000static VAStatus psb__unmap_buffer(object_buffer_p obj_buffer) 2001{ 2002 if (obj_buffer->psb_buffer) { 2003 obj_buffer->buffer_data = NULL; 2004 return psb_buffer_unmap(obj_buffer->psb_buffer); 2005 } 2006 return VA_STATUS_SUCCESS; 2007} 2008 2009static void psb__destroy_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) 2010{ 2011 if (obj_buffer->psb_buffer) { 2012 if (obj_buffer->buffer_data) { 2013 psb__unmap_buffer(obj_buffer); 2014 } 2015 psb_buffer_destroy(obj_buffer->psb_buffer); 2016 free(obj_buffer->psb_buffer); 2017 obj_buffer->psb_buffer = NULL; 2018 } 2019 2020 if (NULL != obj_buffer->buffer_data) { 2021 free(obj_buffer->buffer_data); 2022 obj_buffer->buffer_data = NULL; 2023 obj_buffer->size = 0; 2024 } 2025 2026 object_heap_free(&driver_data->buffer_heap, (object_base_p) obj_buffer); 2027} 2028 2029void psb__suspend_buffer(psb_driver_data_p driver_data, object_buffer_p obj_buffer) 2030{ 2031 if (obj_buffer->context) { 2032 VABufferType type = obj_buffer->type; 2033 object_context_p obj_context = obj_buffer->context; 2034 2035 /* Remove buffer from active list */ 2036 *obj_buffer->pptr_prev_next = obj_buffer->ptr_next; 2037 2038 /* Add buffer to tail of unused list */ 2039 obj_buffer->ptr_next = NULL; 2040 obj_buffer->last_used = obj_context->frame_count; 2041 if (obj_context->buffers_unused_tail[type]) { 2042 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused_tail[type]->ptr_next); 2043 } else { 2044 obj_buffer->pptr_prev_next = &(obj_context->buffers_unused[type]); 2045 } 2046 *obj_buffer->pptr_prev_next = obj_buffer; 2047 obj_context->buffers_unused_tail[type] = obj_buffer; 2048 obj_context->buffers_unused_count[type]++; 2049 2050 psb__information_message("Adding buffer %08x type %s to unused list. unused count = %d\n", obj_buffer->base.id, 2051 buffer_type_to_string(obj_buffer->type), obj_context->buffers_unused_count[type]); 2052 object_heap_suspend_object((object_base_p) obj_buffer, 1); /* suspend */ 2053 return; 2054 } 2055 2056 if (obj_buffer->psb_buffer && (psb_bs_queued == obj_buffer->psb_buffer->status)) { 2057 /* need to set psb_buffer aside */ 2058 obj_buffer->psb_buffer->status = psb_bs_abandoned; 2059 obj_buffer->psb_buffer = NULL; 2060 } 2061 2062 psb__destroy_buffer(driver_data, obj_buffer); 2063} 2064 2065static void psb__destroy_context(psb_driver_data_p driver_data, object_context_p obj_context) 2066{ 2067 int encode, i; 2068 2069 if (obj_context->entry_point == VAEntrypointEncSlice) 2070 encode = 1; 2071 else 2072 encode = 0; 2073 2074 lnc_ospm_stop(driver_data, encode); 2075 2076 obj_context->format_vtable->destroyContext(obj_context); 2077 2078 for (i = 0; i < PSB_MAX_BUFFERTYPES; i++) { 2079 object_buffer_p obj_buffer; 2080 obj_buffer = obj_context->buffers_active[i]; 2081 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { 2082 psb__information_message("%s: destroying active buffer %08x\n", __FUNCTION__, obj_buffer->base.id); 2083 psb__destroy_buffer(driver_data, obj_buffer); 2084 } 2085 obj_buffer = obj_context->buffers_unused[i]; 2086 for (; obj_buffer; obj_buffer = obj_buffer->ptr_next) { 2087 psb__information_message("%s: destroying unused buffer %08x\n", __FUNCTION__, obj_buffer->base.id); 2088 psb__destroy_buffer(driver_data, obj_buffer); 2089 } 2090 obj_context->buffers_unused_count[i] = 0; 2091 } 2092 2093 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 2094 if (obj_context->lnc_cmdbuf_list[i]) { 2095 lnc_cmdbuf_destroy(obj_context->lnc_cmdbuf_list[i]); 2096 free(obj_context->lnc_cmdbuf_list[i]); 2097 obj_context->lnc_cmdbuf_list[i] = NULL; 2098 } 2099 } 2100 2101 for (i = 0; i < LNC_MAX_CMDBUFS_ENCODE; i++) { 2102 if (obj_context->pnw_cmdbuf_list[i]) { 2103 pnw_cmdbuf_destroy(obj_context->pnw_cmdbuf_list[i]); 2104 free(obj_context->pnw_cmdbuf_list[i]); 2105 obj_context->pnw_cmdbuf_list[i] = NULL; 2106 } 2107 } 2108 2109 for (i = 0; i < PSB_MAX_CMDBUFS; i++) { 2110 if (obj_context->cmdbuf_list[i]) { 2111 psb_cmdbuf_destroy(obj_context->cmdbuf_list[i]); 2112 free(obj_context->cmdbuf_list[i]); 2113 obj_context->cmdbuf_list[i] = NULL; 2114 } 2115 } 2116 obj_context->cmdbuf = NULL; 2117 obj_context->lnc_cmdbuf = NULL; 2118 2119 obj_context->context_id = -1; 2120 obj_context->config_id = -1; 2121 obj_context->picture_width = 0; 2122 obj_context->picture_height = 0; 2123 if (obj_context->render_targets) 2124 free(obj_context->render_targets); 2125 obj_context->render_targets = NULL; 2126 obj_context->num_render_targets = 0; 2127 obj_context->va_flags = 0; 2128 2129 obj_context->current_render_target = NULL; 2130 if (obj_context->buffer_list) 2131 free(obj_context->buffer_list); 2132 obj_context->num_buffers = 0; 2133 2134 object_heap_free(&driver_data->context_heap, (object_base_p) obj_context); 2135 2136 psb_rm_context(driver_data); 2137} 2138 2139VAStatus psb_DestroyContext( 2140 VADriverContextP ctx, 2141 VAContextID context 2142) 2143{ 2144 INIT_DRIVER_DATA 2145 VAStatus vaStatus = VA_STATUS_SUCCESS; 2146 object_context_p obj_context = CONTEXT(context); 2147 if (NULL == obj_context) { 2148 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2149 DEBUG_FAILURE; 2150 return vaStatus; 2151 } 2152 2153 psb__destroy_context(driver_data, obj_context); 2154 2155 return vaStatus; 2156} 2157 2158VAStatus psb__CreateBuffer( 2159 psb_driver_data_p driver_data, 2160 object_context_p obj_context, /* in */ 2161 VABufferType type, /* in */ 2162 unsigned int size, /* in */ 2163 unsigned int num_elements, /* in */ 2164 unsigned char *data, /* in */ 2165 VABufferID *buf_desc /* out */ 2166) 2167{ 2168 VAStatus vaStatus = VA_STATUS_SUCCESS; 2169 int bufferID; 2170 object_buffer_p obj_buffer = obj_context ? obj_context->buffers_unused[type] : NULL; 2171 int unused_count = obj_context ? obj_context->buffers_unused_count[type] : 0; 2172 2173 2174 /* 2175 * Buffer Management 2176 * For each buffer type, maintain 2177 * - a LRU sorted list of unused buffers 2178 * - a list of active buffers 2179 * We only create a new buffer when 2180 * - no unused buffers are available 2181 * - the last unused buffer is still queued 2182 * - the last unused buffer was used very recently and may still be fenced 2183 * - used recently is defined as within the current frame_count (subject to tweaks) 2184 * 2185 * The buffer that is returned will be moved to the list of active buffers 2186 * - vaDestroyBuffer and vaRenderPicture will move the active buffer back to the list of unused buffers 2187 */ 2188 psb__information_message("Requesting buffer creation, size=%d,elements=%d,type=%s\n", size, num_elements, 2189 buffer_type_to_string(type)); 2190 2191 /* on MFLD, data is IMR offset, and could be 0 */ 2192 /* 2193 if ((type == VAProtectedSliceDataBufferType) && (data == NULL)) { 2194 psb__error_message("RAR: Create protected slice buffer, but RAR handle is NULL\n"); 2195 return VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE ; 2196 } 2197 */ 2198 2199 if (obj_buffer && obj_buffer->psb_buffer) { 2200 if (psb_bs_queued == obj_buffer->psb_buffer->status) { 2201 /* Buffer is still queued, allocate new buffer instead */ 2202 psb__information_message("Skipping idle buffer %08x, still queued\n", obj_buffer->base.id); 2203 obj_buffer = NULL; 2204 } else if ((obj_buffer->last_used == obj_context->frame_count) && (unused_count < MAX_UNUSED_BUFFERS)) { 2205 /* Buffer was used for this frame, allocate new buffer instead */ 2206 psb__information_message("Skipping idle buffer %08x, recently used. Unused = %d\n", obj_buffer->base.id, unused_count); 2207 obj_buffer = NULL; 2208 } else if (obj_context->frame_count - obj_buffer->last_used < 5) { 2209 /* Buffer was used for previous frame, allocate new buffer instead */ 2210 psb__information_message("Skipping idle buffer %08x used by frame %d. Unused = %d\n", obj_buffer->base.id, obj_buffer->last_used, unused_count); 2211 obj_buffer = NULL; 2212 } 2213 } 2214 2215 if (obj_buffer) { 2216 bufferID = obj_buffer->base.id; 2217 psb__information_message("Reusing buffer %08x type %s from unused list. Unused = %d\n", bufferID, 2218 buffer_type_to_string(type), unused_count); 2219 2220 /* Remove from unused list */ 2221 obj_context->buffers_unused[type] = obj_buffer->ptr_next; 2222 if (obj_context->buffers_unused[type]) { 2223 obj_context->buffers_unused[type]->pptr_prev_next = &(obj_context->buffers_unused[type]); 2224 ASSERT(obj_context->buffers_unused_tail[type] != obj_buffer); 2225 } else { 2226 ASSERT(obj_context->buffers_unused_tail[type] == obj_buffer); 2227 obj_context->buffers_unused_tail[type] = 0; 2228 } 2229 obj_context->buffers_unused_count[type]--; 2230 2231 object_heap_suspend_object((object_base_p)obj_buffer, 0); /* Make BufferID valid again */ 2232 ASSERT(type == obj_buffer->type); 2233 ASSERT(obj_context == obj_buffer->context); 2234 } else { 2235 bufferID = object_heap_allocate(&driver_data->buffer_heap); 2236 obj_buffer = BUFFER(bufferID); 2237 if (NULL == obj_buffer) { 2238 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2239 DEBUG_FAILURE; 2240 return vaStatus; 2241 } 2242 2243 MEMSET_OBJECT(obj_buffer, struct object_buffer_s); 2244 2245 psb__information_message("Allocating new buffer %08x type %s.\n", bufferID, buffer_type_to_string(type)); 2246 obj_buffer->type = type; 2247 obj_buffer->buffer_data = NULL; 2248 obj_buffer->psb_buffer = NULL; 2249 obj_buffer->size = 0; 2250 obj_buffer->max_num_elements = 0; 2251 obj_buffer->alloc_size = 0; 2252 obj_buffer->context = obj_context; 2253 } 2254 if (obj_context) { 2255 /* Add to front of active list */ 2256 obj_buffer->ptr_next = obj_context->buffers_active[type]; 2257 if (obj_buffer->ptr_next) { 2258 obj_buffer->ptr_next->pptr_prev_next = &(obj_buffer->ptr_next); 2259 } 2260 obj_buffer->pptr_prev_next = &(obj_context->buffers_active[type]); 2261 *obj_buffer->pptr_prev_next = obj_buffer; 2262 } 2263 2264 switch (obj_buffer->type) { 2265 case VABitPlaneBufferType: 2266 case VASliceDataBufferType: 2267 case VAResidualDataBufferType: 2268 case VAImageBufferType: 2269 case VASliceGroupMapBufferType: 2270 case VAEncCodedBufferType: 2271 case VAProtectedSliceDataBufferType: 2272 vaStatus = psb__allocate_BO_buffer(driver_data, obj_buffer, size * num_elements, data, obj_buffer->type); 2273 DEBUG_FAILURE; 2274 break; 2275 case VAPictureParameterBufferType: 2276 case VAIQMatrixBufferType: 2277 case VASliceParameterBufferType: 2278 case VAMacroblockParameterBufferType: 2279 case VADeblockingParameterBufferType: 2280 case VAEncSequenceParameterBufferType: 2281 case VAEncPictureParameterBufferType: 2282 case VAEncSliceParameterBufferType: 2283 case VAQMatrixBufferType: 2284 case VAEncMiscParameterBufferType: 2285 psb__information_message("Allocate new malloc buffers for vaCreateBuffer:type=%s,size=%d, buffer_data=%p.\n", 2286 buffer_type_to_string(type), size, obj_buffer->buffer_data); 2287 vaStatus = psb__allocate_malloc_buffer(obj_buffer, size * num_elements); 2288 DEBUG_FAILURE; 2289 break; 2290 2291 default: 2292 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; 2293 DEBUG_FAILURE; 2294 break;; 2295 } 2296 2297 if (VA_STATUS_SUCCESS == vaStatus) { 2298 obj_buffer->size = size; 2299 obj_buffer->max_num_elements = num_elements; 2300 obj_buffer->num_elements = num_elements; 2301 if (data && (obj_buffer->type != VAProtectedSliceDataBufferType)) { 2302 vaStatus = psb__map_buffer(obj_buffer); 2303 if (VA_STATUS_SUCCESS == vaStatus) { 2304 memcpy(obj_buffer->buffer_data, data, size * num_elements); 2305 2306 psb__unmap_buffer(obj_buffer); 2307 } 2308 } 2309 } 2310 if (VA_STATUS_SUCCESS == vaStatus) { 2311 *buf_desc = bufferID; 2312 } else { 2313 psb__destroy_buffer(driver_data, obj_buffer); 2314 } 2315 2316 return vaStatus; 2317} 2318 2319VAStatus psb_CreateBuffer( 2320 VADriverContextP ctx, 2321 VAContextID context, /* in */ 2322 VABufferType type, /* in */ 2323 unsigned int size, /* in */ 2324 unsigned int num_elements, /* in */ 2325 void *data, /* in */ 2326 VABufferID *buf_desc /* out */ 2327) 2328{ 2329 INIT_DRIVER_DATA 2330 VAStatus vaStatus = VA_STATUS_SUCCESS; 2331 2332 if (num_elements <= 0) { 2333 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2334 DEBUG_FAILURE; 2335 return vaStatus; 2336 } 2337 2338 switch (type) { 2339 case VABitPlaneBufferType: 2340 case VASliceDataBufferType: 2341 case VAProtectedSliceDataBufferType: 2342 case VAResidualDataBufferType: 2343 case VASliceGroupMapBufferType: 2344 case VAPictureParameterBufferType: 2345 case VAIQMatrixBufferType: 2346 case VASliceParameterBufferType: 2347 case VAMacroblockParameterBufferType: 2348 case VADeblockingParameterBufferType: 2349 case VAEncCodedBufferType: 2350 case VAEncSequenceParameterBufferType: 2351 case VAEncPictureParameterBufferType: 2352 case VAEncSliceParameterBufferType: 2353 case VAQMatrixBufferType: 2354 case VAEncMiscParameterBufferType: 2355 break; 2356 2357 default: 2358 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_BUFFERTYPE; 2359 DEBUG_FAILURE; 2360 return vaStatus; 2361 } 2362 2363 object_context_p obj_context = CONTEXT(context); 2364 if (NULL == obj_context) { 2365 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2366 DEBUG_FAILURE; 2367 return vaStatus; 2368 } 2369 if (NULL == buf_desc) { 2370 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2371 DEBUG_FAILURE; 2372 return vaStatus; 2373 } 2374 2375 return psb__CreateBuffer(driver_data, obj_context, type, size, num_elements, data, buf_desc); 2376} 2377 2378 2379VAStatus psb_BufferInfo( 2380 VADriverContextP ctx, 2381 VABufferID buf_id, /* in */ 2382 VABufferType *type, /* out */ 2383 unsigned int *size, /* out */ 2384 unsigned int *num_elements /* out */ 2385) 2386{ 2387 INIT_DRIVER_DATA 2388 VAStatus vaStatus = VA_STATUS_SUCCESS; 2389 2390 object_buffer_p obj_buffer = BUFFER(buf_id); 2391 if (NULL == obj_buffer) { 2392 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2393 DEBUG_FAILURE; 2394 return vaStatus; 2395 } 2396 2397 *type = obj_buffer->type; 2398 *size = obj_buffer->size; 2399 *num_elements = obj_buffer->num_elements; 2400 return VA_STATUS_SUCCESS; 2401} 2402 2403 2404VAStatus psb_BufferSetNumElements( 2405 VADriverContextP ctx, 2406 VABufferID buf_id, /* in */ 2407 unsigned int num_elements /* in */ 2408) 2409{ 2410 INIT_DRIVER_DATA 2411 VAStatus vaStatus = VA_STATUS_SUCCESS; 2412 object_buffer_p obj_buffer = BUFFER(buf_id); 2413 if (NULL == obj_buffer) { 2414 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2415 DEBUG_FAILURE; 2416 return vaStatus; 2417 } 2418 2419 if ((num_elements <= 0) || (num_elements > obj_buffer->max_num_elements)) { 2420 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2421 } 2422 if (VA_STATUS_SUCCESS == vaStatus) { 2423 obj_buffer->num_elements = num_elements; 2424 } 2425 2426 return vaStatus; 2427} 2428 2429VAStatus psb_MapBuffer( 2430 VADriverContextP ctx, 2431 VABufferID buf_id, /* in */ 2432 void **pbuf /* out */ 2433) 2434{ 2435 INIT_DRIVER_DATA 2436 VAStatus vaStatus = VA_STATUS_SUCCESS; 2437 object_buffer_p obj_buffer = BUFFER(buf_id); 2438 if (NULL == obj_buffer) { 2439 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2440 DEBUG_FAILURE; 2441 return vaStatus; 2442 } 2443 2444 2445 if (NULL == pbuf) { 2446 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2447 DEBUG_FAILURE; 2448 return vaStatus; 2449 } 2450 2451 vaStatus = psb__map_buffer(obj_buffer); 2452 if (VA_STATUS_SUCCESS != vaStatus) { 2453 DEBUG_FAILURE; 2454 return vaStatus; 2455 } 2456 2457 if (NULL != obj_buffer->buffer_data) { 2458 *pbuf = obj_buffer->buffer_data; 2459 2460 /* specifically for Topaz encode 2461 * write validate coded data offset in CodedBuffer 2462 */ 2463 if (obj_buffer->type == VAEncCodedBufferType) 2464 psb_codedbuf_map_mangle(ctx, obj_buffer, pbuf); 2465 /* *(IMG_UINT32 *)((unsigned char *)obj_buffer->buffer_data + 4) = 16; */ 2466 } else { 2467 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2468 } 2469 return vaStatus; 2470} 2471 2472VAStatus psb_UnmapBuffer( 2473 VADriverContextP ctx, 2474 VABufferID buf_id /* in */ 2475) 2476{ 2477 INIT_DRIVER_DATA 2478 VAStatus vaStatus = VA_STATUS_SUCCESS; 2479 object_buffer_p obj_buffer = BUFFER(buf_id); 2480 if (NULL == obj_buffer) { 2481 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2482 DEBUG_FAILURE; 2483 return vaStatus; 2484 } 2485 2486 vaStatus = psb__unmap_buffer(obj_buffer); 2487 2488 return vaStatus; 2489} 2490 2491 2492VAStatus psb_DestroyBuffer( 2493 VADriverContextP ctx, 2494 VABufferID buffer_id 2495) 2496{ 2497 INIT_DRIVER_DATA 2498 VAStatus vaStatus = VA_STATUS_SUCCESS; 2499 object_buffer_p obj_buffer = BUFFER(buffer_id); 2500 2501 if (NULL == obj_buffer) { 2502 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2503 DEBUG_FAILURE; 2504 return vaStatus; 2505 } 2506 2507 psb__suspend_buffer(driver_data, obj_buffer); 2508 return vaStatus; 2509} 2510 2511 2512VAStatus psb_BeginPicture( 2513 VADriverContextP ctx, 2514 VAContextID context, 2515 VASurfaceID render_target 2516) 2517{ 2518 INIT_DRIVER_DATA 2519 VAStatus vaStatus = VA_STATUS_SUCCESS; 2520 object_context_p obj_context; 2521 object_surface_p obj_surface; 2522 object_config_p obj_config; 2523 int i; 2524 2525 obj_context = CONTEXT(context); 2526 if (NULL == obj_context) { 2527 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2528 DEBUG_FAILURE; 2529 return vaStatus; 2530 } 2531 2532 /* Must not be within BeginPicture / EndPicture already */ 2533 ASSERT(obj_context->current_render_target == NULL); 2534 2535 obj_surface = SURFACE(render_target); 2536 if (NULL == obj_surface) { 2537 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2538 DEBUG_FAILURE; 2539 return vaStatus; 2540 } 2541 2542 obj_context->current_render_surface_id = render_target; 2543 obj_context->current_render_target = obj_surface; 2544 obj_context->slice_count = 0; 2545 2546 obj_config = CONFIG(obj_context->config_id); 2547 /* if the surface is decode render target, and in displaying */ 2548 if (obj_config && 2549 (obj_config->entrypoint != VAEntrypointEncSlice) && 2550 (driver_data->cur_displaying_surface == render_target)) 2551 psb__error_message("WARNING: rendering a displaying surface, may see tearing\n"); 2552 2553 if (VA_STATUS_SUCCESS == vaStatus) { 2554 vaStatus = obj_context->format_vtable->beginPicture(obj_context); 2555 } 2556 2557 /* want msvdx to do rotate 2558 * but check per-context stream type: interlace or not 2559 */ 2560 if ((obj_config->entrypoint != VAEntrypointEncSlice) && 2561 (obj_config->entrypoint != VAEntrypointEncPicture) && 2562 driver_data->native_window) { 2563 psb_RecalcRotate(ctx, obj_context); 2564 } 2565 2566 if (obj_context->interlaced_stream || driver_data->disable_msvdx_rotate) { 2567 obj_context->msvdx_rotate = 0; 2568 for (i = 0; i < obj_context->num_render_targets; i++) { 2569 object_surface_p obj_surface = SURFACE(obj_context->render_targets[i]); 2570 /*we invalidate all surfaces's rotate buffer share info here.*/ 2571 if (obj_surface->share_info) { 2572 obj_surface->share_info->surface_rotate = 0; 2573 } 2574 } 2575 } 2576 else 2577 obj_context->msvdx_rotate = driver_data->msvdx_rotate_want; 2578 2579 /* the main surface track current rotate information 2580 * try to reuse the allocated rotate surfaces and don't destroy them 2581 * thus the rotation info in obj_surface->psb_surface_rotate may not be updated 2582 */ 2583 SET_SURFACE_INFO_rotate(obj_surface->psb_surface, obj_context->msvdx_rotate); 2584 if (IS_MFLD(driver_data) && CONTEXT_ROTATE(obj_context)) { 2585 psb_CreateRotateSurface(ctx, obj_surface, obj_context->msvdx_rotate); 2586 } 2587 2588 if (driver_data->is_oold && !obj_surface->psb_surface->in_loop_buf) { 2589 psb_surface_p psb_surface = obj_surface->psb_surface; 2590 2591 psb_surface->in_loop_buf = calloc(1, sizeof(struct psb_buffer_s)); 2592 if (NULL == psb_surface->in_loop_buf) { 2593 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2594 DEBUG_FAILURE; 2595 return vaStatus; 2596 } 2597 2598 /* FIXME: For RAR surface, need allocate RAR buffer */ 2599 vaStatus = psb_buffer_create(obj_context->driver_data, 2600 psb_surface->size, 2601 psb_bt_surface, 2602 psb_surface->in_loop_buf); 2603 } else if (!driver_data->is_oold && obj_surface->psb_surface->in_loop_buf) { 2604 psb_surface_p psb_surface = obj_surface->psb_surface; 2605 2606 psb_buffer_destroy(psb_surface->in_loop_buf); 2607 free(psb_surface->in_loop_buf); 2608 psb_surface->in_loop_buf = NULL; 2609 } 2610 obj_context->is_oold = driver_data->is_oold; 2611 2612 psb__information_message("---BeginPicture 0x%08x for frame %d --\n", 2613 render_target, obj_context->frame_count); 2614#ifdef DEBUG_TRACE 2615 psb__trace_message("------Trace frame %d------\n", obj_context->frame_count); 2616#endif 2617 2618 return vaStatus; 2619} 2620 2621VAStatus psb_RenderPicture( 2622 VADriverContextP ctx, 2623 VAContextID context, 2624 VABufferID *buffers, 2625 int num_buffers 2626) 2627{ 2628 INIT_DRIVER_DATA 2629 VAStatus vaStatus = VA_STATUS_SUCCESS; 2630 object_context_p obj_context; 2631 object_buffer_p *buffer_list; 2632 int i; 2633 2634 obj_context = CONTEXT(context); 2635 if (NULL == obj_context) { 2636 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2637 DEBUG_FAILURE; 2638 return vaStatus; 2639 } 2640 2641 if (num_buffers <= 0) { 2642 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2643 DEBUG_FAILURE; 2644 return vaStatus; 2645 } 2646 2647 if (NULL == buffers) { 2648 /* Don't crash on NULL pointers */ 2649 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2650 DEBUG_FAILURE; 2651 return vaStatus; 2652 } 2653 /* Must be within BeginPicture / EndPicture */ 2654 ASSERT(obj_context->current_render_target != NULL); 2655 2656 if (num_buffers > obj_context->num_buffers) { 2657 free(obj_context->buffer_list); 2658 2659 obj_context->buffer_list = (object_buffer_p *) calloc(1, sizeof(object_buffer_p) * num_buffers); 2660 if (obj_context->buffer_list == NULL) { 2661 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 2662 obj_context->num_buffers = 0; 2663 } 2664 2665 obj_context->num_buffers = num_buffers; 2666 } 2667 buffer_list = obj_context->buffer_list; 2668 2669 if (VA_STATUS_SUCCESS == vaStatus) { 2670 /* Lookup buffer references */ 2671 for (i = 0; i < num_buffers; i++) { 2672 object_buffer_p obj_buffer = BUFFER(buffers[i]); 2673 if (NULL == obj_buffer) { 2674 vaStatus = VA_STATUS_ERROR_INVALID_BUFFER; 2675 DEBUG_FAILURE; 2676 return vaStatus; 2677 } 2678 buffer_list[i] = obj_buffer; 2679 psb__information_message("Render buffer %08x type %s\n", obj_buffer->base.id, 2680 buffer_type_to_string(obj_buffer->type)); 2681 } 2682 } 2683 2684 if (VA_STATUS_SUCCESS == vaStatus) { 2685 vaStatus = obj_context->format_vtable->renderPicture(obj_context, buffer_list, num_buffers); 2686 } 2687 2688 if (buffer_list) { 2689 /* Release buffers */ 2690 for (i = 0; i < num_buffers; i++) { 2691 if (buffer_list[i]) { 2692 psb__suspend_buffer(driver_data, buffer_list[i]); 2693 } 2694 } 2695 } 2696 2697 return vaStatus; 2698} 2699 2700VAStatus psb_EndPicture( 2701 VADriverContextP ctx, 2702 VAContextID context 2703) 2704{ 2705 INIT_DRIVER_DATA 2706 VAStatus vaStatus; 2707 object_context_p obj_context; 2708 2709 obj_context = CONTEXT(context); 2710 if (NULL == obj_context) { 2711 vaStatus = VA_STATUS_ERROR_INVALID_CONTEXT; 2712 DEBUG_FAILURE; 2713 return vaStatus; 2714 } 2715 2716 vaStatus = obj_context->format_vtable->endPicture(obj_context); 2717 2718 psb__information_message("---EndPicture for frame %d --\n", obj_context->frame_count); 2719 2720 obj_context->current_render_target = NULL; 2721 obj_context->frame_count++; 2722#ifdef DEBUG_TRACE 2723 psb__trace_message("FrameCount = %03d\n", obj_context->frame_count); 2724 psb__information_message("FrameCount = %03d\n", obj_context->frame_count); 2725 psb__trace_message(NULL); 2726#endif 2727 2728 return vaStatus; 2729} 2730 2731 2732static void psb__surface_usage( 2733 psb_driver_data_p driver_data, 2734 object_surface_p obj_surface, 2735 int *decode, int *encode, int *rc_enable 2736) 2737{ 2738 object_context_p obj_context; 2739 object_config_p obj_config; 2740 VAEntrypoint tmp; 2741 unsigned int eRCmode; 2742 int i; 2743 2744 2745 *decode = 0; 2746 *encode = 0; 2747 *rc_enable = 0; 2748 2749 obj_context = CONTEXT(obj_surface->context_id); 2750 if (NULL == obj_context) /* not associate with a context */ 2751 return; 2752 2753 obj_config = CONFIG(obj_context->config_id); 2754 if (NULL == obj_config) /* not have a validate context */ 2755 return; 2756 2757 tmp = obj_config->entrypoint; 2758 2759 *encode = (tmp == VAEntrypointEncSlice) || (tmp == VAEntrypointEncPicture); 2760 *decode = (VAEntrypointVLD <= tmp) && (tmp <= VAEntrypointDeblocking); 2761 2762 if (*encode) { 2763 for (i = 0; i < obj_config->attrib_count; i++) { 2764 if (obj_config->attrib_list[i].type == VAConfigAttribRateControl) 2765 break; 2766 } 2767 2768 if (i >= obj_config->attrib_count) 2769 eRCmode = VA_RC_NONE; 2770 else 2771 eRCmode = obj_config->attrib_list[i].value; 2772 2773 if (eRCmode == VA_RC_NONE) 2774 *rc_enable = 0; 2775 else 2776 *rc_enable = 1; 2777 } 2778} 2779 2780VAStatus psb_SyncSurface( 2781 VADriverContextP ctx, 2782 VASurfaceID render_target 2783) 2784{ 2785 INIT_DRIVER_DATA 2786 VAStatus vaStatus = VA_STATUS_SUCCESS; 2787 object_surface_p obj_surface; 2788 int decode = 0, encode = 0, rc_enable = 0; 2789 2790 psb__information_message("psb_SyncSurface: 0x%08x\n", render_target); 2791 2792 obj_surface = SURFACE(render_target); 2793 if (NULL == obj_surface) { 2794 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2795 DEBUG_FAILURE; 2796 return vaStatus; 2797 } 2798 2799 /* The cur_displaying_surface indicates the surface being displayed by overlay. 2800 * The diaplay_timestamp records the time point of put surface, which would 2801 * be set to zero while using texture blit.*/ 2802 2803 /* don't use mutex here for performance concern... */ 2804 //pthread_mutex_lock(&output->output_mutex); 2805 if (render_target == driver_data->cur_displaying_surface) 2806 vaStatus = VA_STATUS_ERROR_SURFACE_IN_DISPLAYING; 2807 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ 2808 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ 2809 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); 2810 /* The flip operation on current displaying surface could be delayed to 2811 * next VBlank and hadn't been finished yet. Then, the last displaying 2812 * surface shouldn't be freed, because the hardware may not 2813 * complete loading data of it. Any change of the last surface could 2814 * have a impect on the scrren.*/ 2815 if (NULL != cur_obj_surface) { 2816 while ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY) 2817 usleep(PSB_MAX_FLIP_DELAY * 1000); 2818 } 2819 } 2820 //pthread_mutex_unlock(&output->output_mutex); 2821 2822 if (vaStatus != VA_STATUS_ERROR_SURFACE_IN_DISPLAYING) 2823 vaStatus = psb_surface_sync(obj_surface->psb_surface); 2824 2825 /* report any error of decode for Android */ 2826 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable); 2827 2828 if (decode && IS_MRST(driver_data)) { 2829 struct drm_lnc_video_getparam_arg arg; 2830 uint32_t ret, handle, fw_status = 0; 2831 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); 2832 arg.key = IMG_VIDEO_DECODE_STATUS; 2833 arg.arg = (uint64_t)((unsigned long) & handle); 2834 arg.value = (uint64_t)((unsigned long) & fw_status); 2835 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 2836 &arg, sizeof(arg)); 2837 if (ret == 0) { 2838 if (fw_status != 0) 2839 vaStatus = VA_STATUS_ERROR_DECODING_ERROR; 2840 } else { 2841 psb__information_message("IMG_VIDEO_DECODE_STATUS ioctl return failed.\n"); 2842 vaStatus = VA_STATUS_ERROR_UNKNOWN; 2843 } 2844 } 2845 psb__dump_NV_buffers(obj_surface, 0, 0, obj_surface->width, obj_surface->height); 2846 DEBUG_FAILURE; 2847 return vaStatus; 2848} 2849 2850 2851VAStatus psb_QuerySurfaceStatus( 2852 VADriverContextP ctx, 2853 VASurfaceID render_target, 2854 VASurfaceStatus *status /* out */ 2855) 2856{ 2857 INIT_DRIVER_DATA 2858 VAStatus vaStatus = VA_STATUS_SUCCESS; 2859 object_surface_p obj_surface; 2860 VASurfaceStatus surface_status; 2861 int frame_skip = 0, encode = 0, decode = 0, rc_enable = 0; 2862 2863 obj_surface = SURFACE(render_target); 2864 if (NULL == obj_surface) { 2865 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2866 DEBUG_FAILURE; 2867 return vaStatus; 2868 } 2869 if (NULL == status) { 2870 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 2871 DEBUG_FAILURE; 2872 return vaStatus; 2873 } 2874 2875 vaStatus = psb_surface_query_status(obj_surface->psb_surface, &surface_status); 2876 2877 /* The cur_displaying_surface indicates the surface being displayed by overlay. 2878 * The diaplay_timestamp records the time point of put surface, which would 2879 * be set to zero while using texture blit.*/ 2880 pthread_mutex_lock(&driver_data->output_mutex); 2881 if (render_target == driver_data->cur_displaying_surface) 2882 surface_status = VASurfaceDisplaying; 2883 else if ((VA_INVALID_SURFACE != driver_data->cur_displaying_surface) /* use overlay */ 2884 && (render_target == driver_data->last_displaying_surface)) { /* It's the last displaying surface*/ 2885 object_surface_p cur_obj_surface = SURFACE(driver_data->cur_displaying_surface); 2886 /*The flip operation on current displaying surface could be delayed to 2887 * next VBlank and hadn't been finished yet. Then, the last displaying 2888 * surface shouldn't be freed, because the hardware may not 2889 * complete loading data of it. Any change of the last surface could 2890 * have a impect on the scrren.*/ 2891 if ((NULL != cur_obj_surface) 2892 && ((GetTickCount() - cur_obj_surface->display_timestamp) < PSB_MAX_FLIP_DELAY)) { 2893 surface_status = VASurfaceDisplaying; 2894 } 2895 } 2896 pthread_mutex_unlock(&driver_data->output_mutex); 2897 2898 /* try to get frameskip flag for encode */ 2899 psb__surface_usage(driver_data, obj_surface, &decode, &encode, &rc_enable); 2900 if (encode && rc_enable) { 2901 if (IS_MRST(driver_data)) 2902 lnc_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); 2903 else 2904 pnw_surface_get_frameskip(driver_data, obj_surface->psb_surface, &frame_skip); 2905 2906 if (frame_skip == 1) 2907 surface_status = surface_status | VASurfaceSkipped; 2908 } else if (decode) { 2909 2910 if(obj_surface->share_info->renderStatus == 1) { 2911 surface_status = VASurfaceDisplaying; 2912 }else if (obj_surface->share_info->renderStatus == 0) { 2913 surface_status = VASurfaceReady; 2914 } 2915 } 2916 2917 *status = surface_status; 2918 2919 return vaStatus; 2920} 2921 2922VAStatus psb_QuerySurfaceError( 2923 VADriverContextP ctx, 2924 VASurfaceID render_target, 2925 VAStatus error_status, 2926 void **error_info /*out*/ 2927) 2928{ 2929 INIT_DRIVER_DATA 2930 VAStatus vaStatus = VA_STATUS_SUCCESS; 2931 object_surface_p obj_surface; 2932 uint32_t i; 2933 2934 obj_surface = SURFACE(render_target); 2935 if (NULL == obj_surface) { 2936 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 2937 DEBUG_FAILURE; 2938 return vaStatus; 2939 } 2940 2941#ifdef MFLD_ERROR_CONCEALMENT 2942 if (driver_data->ec_enabled == 0) { 2943#else 2944 if (!IS_MRST(driver_data) || (driver_data->ec_enabled == 0)) { 2945#endif 2946 psb__information_message("error concealment is not supported for this profile.\n"); 2947 error_info = NULL; 2948 return VA_STATUS_ERROR_UNKNOWN; 2949 } 2950 2951 if (error_status == VA_STATUS_ERROR_DECODING_ERROR) { 2952 drm_psb_msvdx_decode_status_t *decode_status = driver_data->msvdx_decode_status; 2953 struct drm_lnc_video_getparam_arg arg; 2954 uint32_t ret, handle; 2955 handle = wsbmKBufHandle(wsbmKBuf(obj_surface->psb_surface->buf.drm_buf)); 2956 2957 arg.key = IMG_VIDEO_MB_ERROR; 2958 arg.arg = (uint64_t)((unsigned long) & handle); 2959 arg.value = (uint64_t)((unsigned long)decode_status); 2960 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 2961 &arg, sizeof(arg)); 2962 2963 if (decode_status->num_error_slice > MAX_MB_ERRORS) { 2964 psb__information_message("too much mb errors are reported.\n"); 2965 return VA_STATUS_ERROR_UNKNOWN; 2966 } 2967 i = 0; 2968 for (i = 0; i < decode_status->num_error_slice; ++i) { 2969 driver_data->surface_mb_error[i].status = 1; 2970 driver_data->surface_mb_error[i].start_mb = decode_status->start_error_mb_list[i]; 2971 driver_data->surface_mb_error[i].end_mb = decode_status->end_error_mb_list[i]; 2972 driver_data->surface_mb_error[i].decode_error_type = decode_status->slice_missing_or_error[i]; 2973 } 2974 driver_data->surface_mb_error[i].status = -1; 2975 *error_info = driver_data->surface_mb_error; 2976 2977 return vaStatus; 2978 } else { 2979 error_info = NULL; 2980 return VA_STATUS_ERROR_UNKNOWN; 2981 } 2982} 2983 2984VAStatus psb_LockSurface( 2985 VADriverContextP ctx, 2986 VASurfaceID surface, 2987 unsigned int *fourcc, /* following are output argument */ 2988 unsigned int *luma_stride, 2989 unsigned int *chroma_u_stride, 2990 unsigned int *chroma_v_stride, 2991 unsigned int *luma_offset, 2992 unsigned int *chroma_u_offset, 2993 unsigned int *chroma_v_offset, 2994 unsigned int *buffer_name, 2995 void **buffer 2996) 2997{ 2998 INIT_DRIVER_DATA 2999 VAStatus vaStatus = VA_STATUS_SUCCESS; 3000 unsigned char *surface_data; 3001 int ret; 3002 3003 object_surface_p obj_surface = SURFACE(surface); 3004 psb_surface_p psb_surface; 3005 if (NULL == obj_surface) { 3006 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 3007 DEBUG_FAILURE; 3008 return vaStatus; 3009 } 3010 3011 psb_surface = obj_surface->psb_surface; 3012 if (buffer_name) 3013 *buffer_name = (uint32_t)(wsbmKBufHandle(wsbmKBuf(psb_surface->buf.drm_buf))); 3014 3015 if (buffer) { /* map the surface buffer */ 3016 uint32_t srf_buf_ofs = 0; 3017 ret = psb_buffer_map(&psb_surface->buf, &surface_data); 3018 if (ret) { 3019 *buffer = NULL; 3020 vaStatus = VA_STATUS_ERROR_UNKNOWN; 3021 DEBUG_FAILURE; 3022 return vaStatus; 3023 } 3024 srf_buf_ofs = psb_surface->buf.buffer_ofs; 3025 *buffer = surface_data + srf_buf_ofs; 3026 } 3027 3028 *fourcc = VA_FOURCC_NV12; 3029 *luma_stride = psb_surface->stride; 3030 *chroma_u_stride = psb_surface->stride; 3031 *chroma_v_stride = psb_surface->stride; 3032 *luma_offset = 0; 3033 *chroma_u_offset = obj_surface->height * psb_surface->stride; 3034 *chroma_v_offset = obj_surface->height * psb_surface->stride + 1; 3035 3036 return vaStatus; 3037} 3038 3039 3040VAStatus psb_UnlockSurface( 3041 VADriverContextP ctx, 3042 VASurfaceID surface 3043) 3044{ 3045 INIT_DRIVER_DATA 3046 VAStatus vaStatus = VA_STATUS_SUCCESS; 3047 3048 object_surface_p obj_surface = SURFACE(surface); 3049 if (NULL == obj_surface) { 3050 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 3051 DEBUG_FAILURE; 3052 return vaStatus; 3053 } 3054 3055 psb_surface_p psb_surface = obj_surface->psb_surface; 3056 3057 psb_buffer_unmap(&psb_surface->buf); 3058 3059 return VA_STATUS_SUCCESS; 3060} 3061 3062VAStatus psb_GetEGLClientBufferFromSurface( 3063 VADriverContextP ctx, 3064 VASurfaceID surface, 3065 void **buffer 3066) 3067{ 3068 INIT_DRIVER_DATA 3069 VAStatus vaStatus = VA_STATUS_SUCCESS; 3070 3071 object_surface_p obj_surface = SURFACE(surface); 3072 if (NULL == obj_surface) { 3073 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 3074 DEBUG_FAILURE; 3075 return vaStatus; 3076 } 3077 3078 psb_surface_p psb_surface = obj_surface->psb_surface; 3079 *buffer = (unsigned char *)psb_surface->bc_buffer; 3080 3081 return vaStatus; 3082} 3083 3084VAStatus psb_CreateSurfaceFromV4L2Buf( 3085 VADriverContextP ctx, 3086 int v4l2_fd, /* file descriptor of V4L2 device */ 3087 struct v4l2_format *v4l2_fmt, /* format of V4L2 */ 3088 struct v4l2_buffer *v4l2_buf, /* V4L2 buffer */ 3089 VASurfaceID *surface /* out */ 3090) 3091{ 3092 INIT_DRIVER_DATA; 3093 VAStatus vaStatus = VA_STATUS_SUCCESS; 3094 int surfaceID; 3095 object_surface_p obj_surface; 3096 psb_surface_p psb_surface; 3097 int width, height, buf_stride, buf_offset, size; 3098 unsigned long *user_ptr = NULL; 3099 3100 if (IS_MRST(driver_data) == 0 && IS_MFLD(driver_data) == 0) { 3101 psb__error_message("CreateSurfaceFromV4L2Buf isn't supported on non-MRST platform\n"); 3102 return VA_STATUS_ERROR_UNKNOWN; 3103 } 3104 3105 /* Todo: 3106 * sanity check if the v4l2 device on MRST is supported 3107 */ 3108 if (V4L2_MEMORY_USERPTR == v4l2_buf->memory) { 3109 unsigned long tmp = (unsigned long)(v4l2_buf->m.userptr); 3110 3111 if (tmp & 0xfff) { 3112 psb__error_message("The buffer address 0x%08x must be page aligned\n", tmp); 3113 return VA_STATUS_ERROR_UNKNOWN; 3114 } 3115 } 3116 3117 surfaceID = object_heap_allocate(&driver_data->surface_heap); 3118 obj_surface = SURFACE(surfaceID); 3119 if (NULL == obj_surface) { 3120 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3121 DEBUG_FAILURE; 3122 return vaStatus; 3123 } 3124 MEMSET_OBJECT(obj_surface, struct object_surface_s); 3125 3126 width = v4l2_fmt->fmt.pix.width; 3127 height = v4l2_fmt->fmt.pix.height; 3128 3129 buf_stride = width; /* ? */ 3130 buf_offset = v4l2_buf->m.offset; 3131 size = v4l2_buf->length; 3132 3133 psb__information_message("Create Surface from V4L2 buffer: %dx%d, stride=%d, buffer offset=0x%08x, size=%d\n", 3134 width, height, buf_stride, buf_offset, size); 3135 3136 obj_surface->surface_id = surfaceID; 3137 *surface = surfaceID; 3138 obj_surface->context_id = -1; 3139 obj_surface->width = width; 3140 obj_surface->height = height; 3141 obj_surface->subpictures = NULL; 3142 obj_surface->subpic_count = 0; 3143 obj_surface->derived_imgcnt = 0; 3144 obj_surface->display_timestamp = 0; 3145 3146 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 3147 if (NULL == psb_surface) { 3148 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3149 obj_surface->surface_id = VA_INVALID_SURFACE; 3150 3151 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3152 3153 DEBUG_FAILURE; 3154 3155 return vaStatus; 3156 } 3157 3158 /* current assume it is NV12 */ 3159 if (IS_MRST(driver_data)) 3160 vaStatus = psb_surface_create_camera(driver_data, width, height, buf_stride, size, psb_surface, 1, buf_offset); 3161 else { 3162 if (V4L2_MEMORY_USERPTR == v4l2_buf->memory) 3163 user_ptr = (unsigned long *)(v4l2_buf->m.userptr); 3164 else { 3165 user_ptr = mmap(NULL /* start anywhere */ , 3166 v4l2_buf->length, 3167 PROT_READ , 3168 MAP_SHARED /* recommended */ , 3169 v4l2_fd, v4l2_buf->m.offset); 3170 } 3171 3172 if (NULL != user_ptr && MAP_FAILED != user_ptr) 3173 vaStatus = psb_surface_create_camera_from_ub(driver_data, width, height, 3174 buf_stride, size, psb_surface, 1, buf_offset, user_ptr); 3175 else { 3176 DEBUG_FAILURE; 3177 vaStatus = VA_STATUS_ERROR_UNKNOWN; 3178 } 3179 } 3180 3181 if (VA_STATUS_SUCCESS != vaStatus) { 3182 free(psb_surface); 3183 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3184 obj_surface->surface_id = VA_INVALID_SURFACE; 3185 3186 DEBUG_FAILURE; 3187 3188 return vaStatus; 3189 } 3190 3191 memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info)); 3192 psb_surface->extra_info[4] = VA_FOURCC_NV12; /* temp treat is as IYUV */ 3193 3194 obj_surface->psb_surface = psb_surface; 3195 3196 /* Error recovery */ 3197 if (VA_STATUS_SUCCESS != vaStatus) { 3198 object_surface_p obj_surface = SURFACE(*surface); 3199 psb__destroy_surface(driver_data, obj_surface); 3200 *surface = VA_INVALID_SURFACE; 3201 } 3202 3203 return vaStatus; 3204} 3205 3206 3207VAStatus psb_CreateSurfacesForUserPtr( 3208 VADriverContextP ctx, 3209 int Width, 3210 int Height, 3211 int format, 3212 int num_surfaces, 3213 VASurfaceID *surface_list, /* out */ 3214 unsigned size, /* total buffer size need to be allocated */ 3215 unsigned int fourcc, /* expected fourcc */ 3216 unsigned int luma_stride, /* luma stride, could be width aligned with a special value */ 3217 unsigned int chroma_u_stride, /* chroma stride */ 3218 unsigned int chroma_v_stride, 3219 unsigned int luma_offset, /* could be 0 */ 3220 unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */ 3221 unsigned int chroma_v_offset 3222) 3223{ 3224 INIT_DRIVER_DATA 3225 VAStatus vaStatus = VA_STATUS_SUCCESS; 3226 int i, height_origin; 3227 unsigned long buffer_stride; 3228 3229 /* silient compiler warning */ 3230 unsigned int width = (unsigned int)Width; 3231 unsigned int height = (unsigned int)Height; 3232 3233 psb__information_message("Create surface: width %d, height %d, format 0x%08x" 3234 "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x" 3235 "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d" 3236 "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n", 3237 width, height, format, 3238 num_surfaces, size, fourcc, 3239 luma_stride, chroma_u_stride, chroma_v_stride, 3240 luma_offset, chroma_u_offset, chroma_v_offset); 3241 3242 if (num_surfaces <= 0) { 3243 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 3244 DEBUG_FAILURE; 3245 return vaStatus; 3246 } 3247 3248 if (NULL == surface_list) { 3249 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 3250 DEBUG_FAILURE; 3251 return vaStatus; 3252 } 3253 3254 /* We only support one format */ 3255 if ((VA_RT_FORMAT_YUV420 != format) 3256 && (VA_RT_FORMAT_YUV422 != format)) { 3257 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 3258 DEBUG_FAILURE; 3259 return vaStatus; 3260 } 3261 3262 /* We only support NV12/YV12 */ 3263 if (((VA_RT_FORMAT_YUV420 == format) && (fourcc != VA_FOURCC_NV12)) || 3264 ((VA_RT_FORMAT_YUV422 == format) && (fourcc != VA_FOURCC_YV16))) { 3265 psb__error_message("Only support NV12/YV16 format\n"); 3266 return VA_STATUS_ERROR_UNKNOWN; 3267 } 3268 3269 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 3270 if (VA_STATUS_SUCCESS != vaStatus) { 3271 DEBUG_FAILURE; 3272 return vaStatus; 3273 } 3274 3275 if ((size < width * height * 1.5) || 3276 (luma_stride < width) || 3277 (chroma_u_stride * 2 < width) || 3278 (chroma_v_stride * 2 < width) || 3279 (chroma_u_offset < luma_offset + width * height) || 3280 (chroma_v_offset < luma_offset + width * height)) { 3281 3282 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 3283 DEBUG_FAILURE; 3284 return vaStatus; 3285 } 3286 3287 height_origin = height; 3288 3289 for (i = 0; i < num_surfaces; i++) { 3290 int surfaceID; 3291 object_surface_p obj_surface; 3292 psb_surface_p psb_surface; 3293 3294 surfaceID = object_heap_allocate(&driver_data->surface_heap); 3295 obj_surface = SURFACE(surfaceID); 3296 if (NULL == obj_surface) { 3297 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3298 DEBUG_FAILURE; 3299 break; 3300 } 3301 MEMSET_OBJECT(obj_surface, struct object_surface_s); 3302 3303 obj_surface->surface_id = surfaceID; 3304 surface_list[i] = surfaceID; 3305 obj_surface->context_id = -1; 3306 obj_surface->width = width; 3307 obj_surface->height = height; 3308 obj_surface->width_r = width; 3309 obj_surface->height_r = height; 3310 obj_surface->height_origin = height_origin; 3311 3312 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 3313 if (NULL == psb_surface) { 3314 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3315 obj_surface->surface_id = VA_INVALID_SURFACE; 3316 3317 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3318 3319 DEBUG_FAILURE; 3320 break; 3321 } 3322 3323 switch (format) { 3324 case VA_RT_FORMAT_YUV422: 3325 fourcc = VA_FOURCC_YV16; 3326 break; 3327 case VA_RT_FORMAT_YUV420: 3328 default: 3329 fourcc = VA_FOURCC_NV12; 3330 break; 3331 } 3332 3333 vaStatus = psb_surface_create_for_userptr(driver_data, width, height, 3334 size, 3335 fourcc, 3336 luma_stride, 3337 chroma_u_stride, 3338 chroma_v_stride, 3339 luma_offset, 3340 chroma_u_offset, 3341 chroma_v_offset, 3342 psb_surface 3343 ); 3344 3345 if (VA_STATUS_SUCCESS != vaStatus) { 3346 free(psb_surface); 3347 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3348 obj_surface->surface_id = VA_INVALID_SURFACE; 3349 3350 DEBUG_FAILURE; 3351 break; 3352 } 3353 buffer_stride = psb_surface->stride; 3354 /* by default, surface fourcc is NV12 */ 3355 memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info)); 3356 psb_surface->extra_info[4] = fourcc; 3357 3358 obj_surface->psb_surface = psb_surface; 3359 } 3360 3361 /* Error recovery */ 3362 if (VA_STATUS_SUCCESS != vaStatus) { 3363 /* surface_list[i-1] was the last successful allocation */ 3364 for (; i--;) { 3365 object_surface_p obj_surface = SURFACE(surface_list[i]); 3366 psb__destroy_surface(driver_data, obj_surface); 3367 surface_list[i] = VA_INVALID_SURFACE; 3368 } 3369 } 3370 3371 3372 return vaStatus; 3373} 3374 3375VAStatus psb_CreateSurfaceFromKbuf( 3376 VADriverContextP ctx, 3377 int _width, 3378 int _height, 3379 int format, 3380 VASurfaceID *surface, /* out */ 3381 unsigned int kbuf_handle, /* kernel buffer handle*/ 3382 unsigned size, /* kernel buffer size */ 3383 unsigned int kBuf_fourcc, /* expected fourcc */ 3384 unsigned int luma_stride, /* luma stride, could be width aligned with a special value */ 3385 unsigned int chroma_u_stride, /* chroma stride */ 3386 unsigned int chroma_v_stride, 3387 unsigned int luma_offset, /* could be 0 */ 3388 unsigned int chroma_u_offset, /* UV offset from the beginning of the memory */ 3389 unsigned int chroma_v_offset 3390) 3391{ 3392 INIT_DRIVER_DATA 3393 VAStatus vaStatus = VA_STATUS_SUCCESS; 3394 int i ; 3395 unsigned long buffer_stride; 3396 3397 /* silient compiler warning */ 3398 unsigned int width = (unsigned int)_width; 3399 unsigned int height = (unsigned int)_height; 3400 3401 psb__information_message("Create surface: width %d, height %d, format 0x%08x" 3402 "\n\t\t\t\t\tnum_surface %d, buffer size %d, fourcc 0x%08x" 3403 "\n\t\t\t\t\tluma_stride %d, chroma u stride %d, chroma v stride %d" 3404 "\n\t\t\t\t\tluma_offset %d, chroma u offset %d, chroma v offset %d\n", 3405 width, height, format, 3406 size, kBuf_fourcc, 3407 luma_stride, chroma_u_stride, chroma_v_stride, 3408 luma_offset, chroma_u_offset, chroma_v_offset); 3409 3410 if (NULL == surface) { 3411 vaStatus = VA_STATUS_ERROR_INVALID_SURFACE; 3412 DEBUG_FAILURE; 3413 return vaStatus; 3414 } 3415 3416 /* We only support one format */ 3417 if ((VA_RT_FORMAT_YUV420 != format) 3418 && (VA_RT_FORMAT_YUV422 != format)) { 3419 vaStatus = VA_STATUS_ERROR_UNSUPPORTED_RT_FORMAT; 3420 DEBUG_FAILURE; 3421 return vaStatus; 3422 } 3423 3424 /* We only support NV12/YV12 */ 3425 3426 if (((VA_RT_FORMAT_YUV420 == format) && (kBuf_fourcc != VA_FOURCC_NV12)) || 3427 ((VA_RT_FORMAT_YUV422 == format) && (kBuf_fourcc != VA_FOURCC_YV16))) { 3428 psb__error_message("Only support NV12/YV16 format\n"); 3429 return VA_STATUS_ERROR_UNKNOWN; 3430 } 3431 3432 vaStatus = psb__checkSurfaceDimensions(driver_data, width, height); 3433 if (VA_STATUS_SUCCESS != vaStatus) { 3434 DEBUG_FAILURE; 3435 return vaStatus; 3436 } 3437 3438 if ((size < width * height * 1.5) || 3439 (luma_stride < width) || 3440 (chroma_u_stride * 2 < width) || 3441 (chroma_v_stride * 2 < width) || 3442 (chroma_u_offset < luma_offset + width * height) || 3443 (chroma_v_offset < luma_offset + width * height)) { 3444 3445 vaStatus = VA_STATUS_ERROR_INVALID_PARAMETER; 3446 DEBUG_FAILURE; 3447 return vaStatus; 3448 } 3449 3450 int surfaceID; 3451 object_surface_p obj_surface; 3452 psb_surface_p psb_surface; 3453 3454 surfaceID = object_heap_allocate(&driver_data->surface_heap); 3455 obj_surface = SURFACE(surfaceID); 3456 if (NULL == obj_surface) { 3457 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3458 DEBUG_FAILURE; 3459 } 3460 MEMSET_OBJECT(obj_surface, struct object_surface_s); 3461 3462 obj_surface->surface_id = surfaceID; 3463 *surface = surfaceID; 3464 obj_surface->context_id = -1; 3465 obj_surface->width = width; 3466 obj_surface->height = height; 3467 obj_surface->width_r = width; 3468 obj_surface->height_r = height; 3469 obj_surface->height_origin = height; 3470 3471 psb_surface = (psb_surface_p) calloc(1, sizeof(struct psb_surface_s)); 3472 if (NULL == psb_surface) { 3473 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3474 obj_surface->surface_id = VA_INVALID_SURFACE; 3475 3476 vaStatus = VA_STATUS_ERROR_ALLOCATION_FAILED; 3477 3478 DEBUG_FAILURE; 3479 } 3480 3481 vaStatus = psb_surface_create_from_kbuf(driver_data, width, height, 3482 size, 3483 kBuf_fourcc, 3484 kbuf_handle, 3485 luma_stride, 3486 chroma_u_stride, 3487 chroma_v_stride, 3488 luma_offset, 3489 chroma_u_offset, 3490 chroma_v_offset, 3491 psb_surface); 3492 3493 if (VA_STATUS_SUCCESS != vaStatus) { 3494 free(psb_surface); 3495 object_heap_free(&driver_data->surface_heap, (object_base_p) obj_surface); 3496 obj_surface->surface_id = VA_INVALID_SURFACE; 3497 3498 DEBUG_FAILURE; 3499 } 3500 buffer_stride = psb_surface->stride; 3501 /* by default, surface fourcc is NV12 */ 3502 memset(psb_surface->extra_info, 0, sizeof(psb_surface->extra_info)); 3503 psb_surface->extra_info[4] = kBuf_fourcc; 3504 obj_surface->psb_surface = psb_surface; 3505 3506 /* Error recovery */ 3507 if (VA_STATUS_SUCCESS != vaStatus) { 3508 object_surface_p obj_surface = SURFACE(surfaceID); 3509 psb__destroy_surface(driver_data, obj_surface); 3510 *surface = VA_INVALID_SURFACE; 3511 } 3512 3513 return vaStatus; 3514} 3515 3516 3517VAStatus psb_PutSurfaceBuf( 3518 VADriverContextP ctx, 3519 VASurfaceID surface, 3520 unsigned char* data, 3521 int* data_len, 3522 short srcx, 3523 short srcy, 3524 unsigned short srcw, 3525 unsigned short srch, 3526 short destx, 3527 short desty, 3528 unsigned short destw, 3529 unsigned short desth, 3530 VARectangle *cliprects, /* client supplied clip list */ 3531 unsigned int number_cliprects, /* number of clip rects in the clip list */ 3532 unsigned int flags /* de-interlacing flags */ 3533) 3534{ 3535 INIT_DRIVER_DATA; 3536 object_surface_p obj_surface = SURFACE(surface); 3537 psb_surface_p psb_surface; 3538 3539 obj_surface = SURFACE(surface); 3540 psb_surface = obj_surface->psb_surface; 3541 3542 psb_putsurface_textureblit(ctx, data, surface, srcx, srcy, srcw, srch, destx, desty, destw, desth, 1, /* check subpicture */ 3543 obj_surface->width, obj_surface->height, 3544 psb_surface->stride, psb_surface->buf.drm_buf, 3545 psb_surface->buf.pl_flags, 1 /* wrap dst */); 3546 3547 return VA_STATUS_SUCCESS; 3548} 3549 3550 3551int LOCK_HARDWARE(psb_driver_data_p driver_data) 3552{ 3553 char ret = 0; 3554 3555 if (driver_data->dri2 || driver_data->dri_dummy) 3556 return 0; 3557 3558 pthread_mutex_lock(&driver_data->drm_mutex); 3559 DRM_CAS(driver_data->drm_lock, driver_data->drm_context, 3560 (DRM_LOCK_HELD | driver_data->drm_context), ret); 3561 if (ret) { 3562 ret = drmGetLock(driver_data->drm_fd, driver_data->drm_context, 0); 3563 /* driver_data->contended_lock=1; */ 3564 } 3565 3566 return ret; 3567} 3568 3569int UNLOCK_HARDWARE(psb_driver_data_p driver_data) 3570{ 3571 /* driver_data->contended_lock=0; */ 3572 if (driver_data->dri2 || driver_data->dri_dummy) 3573 return 0; 3574 3575 DRM_UNLOCK(driver_data->drm_fd, driver_data->drm_lock, driver_data->drm_context); 3576 pthread_mutex_unlock(&driver_data->drm_mutex); 3577 3578 return 0; 3579} 3580 3581 3582static void psb__deinitDRM(VADriverContextP ctx) 3583{ 3584 INIT_DRIVER_DATA 3585 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 3586 3587 if (driver_data->main_pool) { 3588 driver_data->main_pool->takeDown(driver_data->main_pool); 3589 driver_data->main_pool = NULL; 3590 } 3591 if (driver_data->fence_mgr) { 3592 wsbmFenceMgrTTMTakedown(driver_data->fence_mgr); 3593 driver_data->fence_mgr = NULL; 3594 } 3595 3596 if (wsbmIsInitialized()) 3597 wsbmTakedown(); 3598 3599 close(driver_data->drm_fd); 3600 driver_data->drm_fd = dri_state->fd = -1; 3601} 3602 3603 3604static VAStatus psb__initDRI(VADriverContextP ctx) 3605{ 3606 INIT_DRIVER_DATA 3607 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 3608 3609 assert(dri_state); 3610 assert(dri_state->driConnectedFlag == VA_DRI2 || 3611 dri_state->driConnectedFlag == VA_DUMMY); 3612 3613 driver_data->drm_fd = dri_state->fd; 3614 driver_data->dri_dummy = (dri_state->driConnectedFlag == VA_DUMMY); 3615 driver_data->dri2 = (dri_state->driConnectedFlag == VA_DRI2); 3616 driver_data->ws_priv = NULL; 3617 driver_data->bus_id = NULL; 3618 3619 return VA_STATUS_SUCCESS; 3620} 3621 3622 3623static VAStatus psb__initTTM(VADriverContextP ctx) 3624{ 3625 INIT_DRIVER_DATA 3626 3627 const char drm_ext[] = "psb_ttm_placement_alphadrop"; 3628 union drm_psb_extension_arg arg; 3629 struct _WsbmBufferPool *pool; 3630 int ret; 3631 const char exec_ext[] = "psb_ttm_execbuf_alphadrop"; 3632 union drm_psb_extension_arg exec_arg; 3633 const char lncvideo_getparam_ext[] = "lnc_video_getparam"; 3634 union drm_psb_extension_arg lncvideo_getparam_arg; 3635 3636 /* init wsbm */ 3637 ret = wsbmInit(wsbmNullThreadFuncs(), psbVNodeFuncs()); 3638 if (ret) { 3639 psb__error_message("failed initializing libwsbm.\n"); 3640 return VA_STATUS_ERROR_UNKNOWN; 3641 } 3642 3643 strncpy(arg.extension, drm_ext, sizeof(arg.extension)); 3644 /* FIXME: should check dri enabled? 3645 * it seems not init dri here at all 3646 */ 3647 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, 3648 &arg, sizeof(arg)); 3649 if (ret != 0 || !arg.rep.exists) { 3650 psb__error_message("failed to detect DRM extension \"%s\".\n", 3651 drm_ext); 3652 driver_data->main_pool = NULL; 3653 return VA_STATUS_ERROR_UNKNOWN; 3654 } else { 3655 pool = wsbmTTMPoolInit(driver_data->drm_fd, 3656 arg.rep.driver_ioctl_offset); 3657 if (pool == NULL) { 3658 psb__error_message("failed to get ttm pool\n"); 3659 return VA_STATUS_ERROR_UNKNOWN; 3660 } 3661 driver_data->main_pool = pool; 3662 } 3663 3664 strncpy(exec_arg.extension, exec_ext, sizeof(exec_arg.extension)); 3665 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &exec_arg, 3666 sizeof(exec_arg)); 3667 if (ret != 0 || !exec_arg.rep.exists) { 3668 psb__error_message("failed to detect DRM extension \"%s\".\n", 3669 exec_ext); 3670 return FALSE; 3671 } 3672 driver_data->execIoctlOffset = exec_arg.rep.driver_ioctl_offset; 3673 3674 strncpy(lncvideo_getparam_arg.extension, lncvideo_getparam_ext, sizeof(lncvideo_getparam_arg.extension)); 3675 ret = drmCommandWriteRead(driver_data->drm_fd, DRM_PSB_EXTENSION, &lncvideo_getparam_arg, 3676 sizeof(lncvideo_getparam_arg)); 3677 if (ret != 0 || !lncvideo_getparam_arg.rep.exists) { 3678 psb__error_message("failed to detect DRM extension \"%s\".\n", 3679 lncvideo_getparam_ext); 3680 /* return FALSE; */ /* not reture FALSE, so it still can run */ 3681 } 3682 driver_data->getParamIoctlOffset = lncvideo_getparam_arg.rep.driver_ioctl_offset; 3683 return VA_STATUS_SUCCESS; 3684} 3685 3686static VAStatus psb__initDRM(VADriverContextP ctx) 3687{ 3688 VAStatus vaStatus; 3689 3690 vaStatus = psb__initDRI(ctx); 3691 3692 if (vaStatus == VA_STATUS_SUCCESS) 3693 return psb__initTTM(ctx); 3694 else 3695 return vaStatus; 3696} 3697 3698VAStatus psb_Terminate(VADriverContextP ctx) 3699{ 3700 INIT_DRIVER_DATA 3701 object_subpic_p obj_subpic; 3702 object_image_p obj_image; 3703 object_buffer_p obj_buffer; 3704 object_surface_p obj_surface; 3705 object_context_p obj_context; 3706 object_config_p obj_config; 3707 object_heap_iterator iter; 3708 3709 psb__information_message("vaTerminate: begin to tear down\n"); 3710 3711 if (driver_data->bcd_registered != 0) 3712 if (VA_STATUS_SUCCESS != psb_release_video_bcd(ctx)) 3713 return VA_STATUS_ERROR_UNKNOWN; 3714 3715 /* Clean up left over contexts */ 3716 obj_context = (object_context_p) object_heap_first(&driver_data->context_heap, &iter); 3717 while (obj_context) { 3718 psb__information_message("vaTerminate: contextID %08x still allocated, destroying\n", obj_context->base.id); 3719 psb__destroy_context(driver_data, obj_context); 3720 obj_context = (object_context_p) object_heap_next(&driver_data->context_heap, &iter); 3721 } 3722 object_heap_destroy(&driver_data->context_heap); 3723 3724 /* Clean up SubpicIDs */ 3725 obj_subpic = (object_subpic_p) object_heap_first(&driver_data->subpic_heap, &iter); 3726 while (obj_subpic) { 3727 psb__information_message("vaTerminate: subpictureID %08x still allocated, destroying\n", obj_subpic->base.id); 3728 psb__destroy_subpicture(driver_data, obj_subpic); 3729 obj_subpic = (object_subpic_p) object_heap_next(&driver_data->subpic_heap, &iter); 3730 } 3731 object_heap_destroy(&driver_data->subpic_heap); 3732 3733 /* Clean up ImageIDs */ 3734 obj_image = (object_image_p) object_heap_first(&driver_data->image_heap, &iter); 3735 while (obj_image) { 3736 psb__information_message("vaTerminate: imageID %08x still allocated, destroying\n", obj_image->base.id); 3737 psb__destroy_image(driver_data, obj_image); 3738 obj_image = (object_image_p) object_heap_next(&driver_data->image_heap, &iter); 3739 } 3740 object_heap_destroy(&driver_data->image_heap); 3741 3742 /* Clean up left over buffers */ 3743 obj_buffer = (object_buffer_p) object_heap_first(&driver_data->buffer_heap, &iter); 3744 while (obj_buffer) { 3745 psb__information_message("vaTerminate: bufferID %08x still allocated, destroying\n", obj_buffer->base.id); 3746 psb__destroy_buffer(driver_data, obj_buffer); 3747 obj_buffer = (object_buffer_p) object_heap_next(&driver_data->buffer_heap, &iter); 3748 } 3749 object_heap_destroy(&driver_data->buffer_heap); 3750 3751 /* Clean up left over surfaces */ 3752 3753 /* Free PVR2D buffer wrapped from the surfaces */ 3754 psb_free_surface_pvr2dbuf(driver_data); 3755 obj_surface = (object_surface_p) object_heap_first(&driver_data->surface_heap, &iter); 3756 while (obj_surface) { 3757 psb__information_message("vaTerminate: surfaceID %08x still allocated, destroying\n", obj_surface->base.id); 3758 psb__destroy_surface(driver_data, obj_surface); 3759 obj_surface = (object_surface_p) object_heap_next(&driver_data->surface_heap, &iter); 3760 } 3761 object_heap_destroy(&driver_data->surface_heap); 3762 3763 /* Clean up configIDs */ 3764 obj_config = (object_config_p) object_heap_first(&driver_data->config_heap, &iter); 3765 while (obj_config) { 3766 object_heap_free(&driver_data->config_heap, (object_base_p) obj_config); 3767 obj_config = (object_config_p) object_heap_next(&driver_data->config_heap, &iter); 3768 } 3769 object_heap_destroy(&driver_data->config_heap); 3770 3771 if (driver_data->camera_bo) { 3772 psb__information_message("vaTerminate: clearup camera global BO\n"); 3773 3774 psb_buffer_destroy((psb_buffer_p)driver_data->camera_bo); 3775 free(driver_data->camera_bo); 3776 driver_data->camera_bo = NULL; 3777 } 3778 3779 if (driver_data->rar_bo) { 3780 psb__information_message("vaTerminate: clearup RAR global BO\n"); 3781 3782 psb_buffer_destroy((psb_buffer_p)driver_data->rar_bo); 3783 free(driver_data->rar_bo); 3784 driver_data->rar_bo = NULL; 3785 } 3786 3787 if (driver_data->ws_priv) { 3788 psb__information_message("vaTerminate: tear down output portion\n"); 3789 3790 psb_deinitOutput(ctx); 3791 driver_data->ws_priv = NULL; 3792 } 3793 3794 psb__information_message("vaTerminate: de-initialized DRM\n"); 3795 3796 psb__deinitDRM(ctx); 3797 3798 if (driver_data->msvdx_decode_status) 3799 free(driver_data->msvdx_decode_status); 3800 3801 if (driver_data->surface_mb_error) 3802 free(driver_data->surface_mb_error); 3803 3804 if (driver_data->bcd_buffer_surfaces) 3805 free(driver_data->bcd_buffer_surfaces); 3806 3807 free(ctx->pDriverData); 3808 free(ctx->vtable_egl); 3809 free(ctx->vtable_tpi); 3810 3811 ctx->pDriverData = NULL; 3812 psb__information_message("vaTerminate: goodbye\n\n"); 3813 3814 psb__close_log(); 3815 3816 return VA_STATUS_SUCCESS; 3817} 3818 3819EXPORT VAStatus __vaDriverInit_0_31(VADriverContextP ctx) 3820{ 3821 psb_driver_data_p driver_data; 3822 struct VADriverVTableTPI *tpi; 3823 struct VADriverVTableEGL *va_egl; 3824 int result; 3825 3826#ifdef DEBUG_TRACE 3827 /* make gdb always stop here */ 3828 signal(SIGUSR1, SIG_IGN); 3829 kill(getpid(), SIGUSR1); 3830#endif 3831 3832 psb__open_log(); 3833 3834 psb__information_message("vaInitilize: start the journey\n"); 3835 3836 ctx->version_major = 0; 3837 ctx->version_minor = 31; 3838 3839 ctx->max_profiles = PSB_MAX_PROFILES; 3840 ctx->max_entrypoints = PSB_MAX_ENTRYPOINTS; 3841 ctx->max_attributes = PSB_MAX_CONFIG_ATTRIBUTES; 3842 ctx->max_image_formats = PSB_MAX_IMAGE_FORMATS; 3843 ctx->max_subpic_formats = PSB_MAX_SUBPIC_FORMATS; 3844 ctx->max_display_attributes = PSB_MAX_DISPLAY_ATTRIBUTES; 3845 3846 ctx->vtable->vaTerminate = psb_Terminate; 3847 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints; 3848 ctx->vtable->vaTerminate = psb_Terminate; 3849 ctx->vtable->vaQueryConfigProfiles = psb_QueryConfigProfiles; 3850 ctx->vtable->vaQueryConfigEntrypoints = psb_QueryConfigEntrypoints; 3851 ctx->vtable->vaQueryConfigAttributes = psb_QueryConfigAttributes; 3852 ctx->vtable->vaCreateConfig = psb_CreateConfig; 3853 ctx->vtable->vaDestroyConfig = psb_DestroyConfig; 3854 ctx->vtable->vaGetConfigAttributes = psb_GetConfigAttributes; 3855 ctx->vtable->vaCreateSurfaces = psb_CreateSurfaces; 3856 ctx->vtable->vaDestroySurfaces = psb_DestroySurfaces; 3857 ctx->vtable->vaCreateContext = psb_CreateContext; 3858 ctx->vtable->vaDestroyContext = psb_DestroyContext; 3859 ctx->vtable->vaCreateBuffer = psb_CreateBuffer; 3860 ctx->vtable->vaBufferSetNumElements = psb_BufferSetNumElements; 3861 ctx->vtable->vaMapBuffer = psb_MapBuffer; 3862 ctx->vtable->vaUnmapBuffer = psb_UnmapBuffer; 3863 ctx->vtable->vaDestroyBuffer = psb_DestroyBuffer; 3864 ctx->vtable->vaBeginPicture = psb_BeginPicture; 3865 ctx->vtable->vaRenderPicture = psb_RenderPicture; 3866 ctx->vtable->vaEndPicture = psb_EndPicture; 3867 ctx->vtable->vaSyncSurface = psb_SyncSurface; 3868 ctx->vtable->vaQuerySurfaceStatus = psb_QuerySurfaceStatus; 3869 ctx->vtable->vaQuerySurfaceError = psb_QuerySurfaceError; 3870 ctx->vtable->vaPutSurface = psb_PutSurface; 3871 ctx->vtable->vaQueryImageFormats = psb_QueryImageFormats; 3872 ctx->vtable->vaCreateImage = psb_CreateImage; 3873 ctx->vtable->vaDeriveImage = psb_DeriveImage; 3874 ctx->vtable->vaDestroyImage = psb_DestroyImage; 3875 ctx->vtable->vaSetImagePalette = psb_SetImagePalette; 3876 ctx->vtable->vaGetImage = psb_GetImage; 3877 ctx->vtable->vaPutImage = psb_PutImage; 3878 ctx->vtable->vaQuerySubpictureFormats = psb_QuerySubpictureFormats; 3879 ctx->vtable->vaCreateSubpicture = psb_CreateSubpicture; 3880 ctx->vtable->vaDestroySubpicture = psb_DestroySubpicture; 3881 ctx->vtable->vaSetSubpictureImage = psb_SetSubpictureImage; 3882 ctx->vtable->vaSetSubpictureChromakey = psb_SetSubpictureChromakey; 3883 ctx->vtable->vaSetSubpictureGlobalAlpha = psb_SetSubpictureGlobalAlpha; 3884 ctx->vtable->vaAssociateSubpicture = psb_AssociateSubpicture; 3885 ctx->vtable->vaDeassociateSubpicture = psb_DeassociateSubpicture; 3886 ctx->vtable->vaQueryDisplayAttributes = psb_QueryDisplayAttributes; 3887 ctx->vtable->vaGetDisplayAttributes = psb_GetDisplayAttributes; 3888 ctx->vtable->vaSetDisplayAttributes = psb_SetDisplayAttributes; 3889 ctx->vtable->vaBufferInfo = psb_BufferInfo; 3890 ctx->vtable->vaLockSurface = psb_LockSurface; 3891 ctx->vtable->vaUnlockSurface = psb_UnlockSurface; 3892 ctx->vtable_tpi = calloc(1, sizeof(struct VADriverVTableTPI)); 3893 if (NULL == ctx->vtable_tpi) 3894 return VA_STATUS_ERROR_ALLOCATION_FAILED; 3895 3896 tpi = (struct VADriverVTableTPI *)ctx->vtable_tpi; 3897 tpi->vaCreateSurfaceFromCIFrame = psb_CreateSurfaceFromCIFrame; 3898 tpi->vaCreateSurfaceFromV4L2Buf = psb_CreateSurfaceFromV4L2Buf; 3899 tpi->vaCreateSurfacesForUserPtr = psb_CreateSurfacesForUserPtr; 3900 tpi->vaCreateSurfaceFromKBuf = psb_CreateSurfaceFromKbuf; 3901 tpi->vaPutSurfaceBuf = psb_PutSurfaceBuf; 3902 3903 ctx->vtable_egl = calloc(1, sizeof(struct VADriverVTableEGL)); 3904 if (NULL == ctx->vtable_egl) 3905 return VA_STATUS_ERROR_ALLOCATION_FAILED; 3906 3907 va_egl = (struct VADriverVTableEGL *)ctx->vtable_egl; 3908 va_egl->vaGetEGLClientBufferFromSurface = psb_GetEGLClientBufferFromSurface; 3909 3910 driver_data = (psb_driver_data_p) calloc(1, sizeof(*driver_data)); 3911 ctx->pDriverData = (unsigned char *) driver_data; 3912 if (NULL == driver_data) { 3913 if (ctx->vtable_tpi) 3914 free(ctx->vtable_tpi); 3915 if (ctx->vtable_egl) 3916 free(ctx->vtable_egl); 3917 return VA_STATUS_ERROR_ALLOCATION_FAILED; 3918 } 3919 3920 if (VA_STATUS_SUCCESS != psb__initDRM(ctx)) { 3921 free(ctx->pDriverData); 3922 ctx->pDriverData = NULL; 3923 return VA_STATUS_ERROR_UNKNOWN; 3924 } 3925 3926 pthread_mutex_init(&driver_data->drm_mutex, NULL); 3927 3928 /* 3929 * To read PBO.MSR.CCF Mode and Status Register C-Spec -p112 3930 */ 3931#define PCI_PORT5_REG80_VIDEO_SD_DISABLE 0x0008 3932#define PCI_PORT5_REG80_VIDEO_HD_DISABLE 0x0010 3933 3934#if 0 3935 struct drm_psb_hw_info hw_info; 3936 do { 3937 result = drmCommandRead(driver_data->drm_fd, DRM_PSB_HW_INFO, &hw_info, sizeof(hw_info)); 3938 } while (result == EAGAIN); 3939 3940 if (result != 0) { 3941 psb__deinitDRM(ctx); 3942 free(ctx->pDriverData); 3943 ctx->pDriverData = NULL; 3944 return VA_STATUS_ERROR_UNKNOWN; 3945 } 3946 3947 driver_data->video_sd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_SD_DISABLE); 3948 driver_data->video_hd_disabled = !!(hw_info.caps & PCI_PORT5_REG80_VIDEO_HD_DISABLE); 3949 psb__information_message("hw_info: rev_id = %08x capabilities = %08x\n", hw_info.rev_id, hw_info.caps); 3950 psb__information_message("hw_info: video_sd_disable=%d,video_hd_disable=%d\n", 3951 driver_data->video_sd_disabled, driver_data->video_hd_disabled); 3952 if (driver_data->video_sd_disabled != 0) { 3953 psb__error_message("MRST: hw_info shows video_sd_disable is true,fix it manually\n"); 3954 driver_data->video_sd_disabled = 0; 3955 } 3956 if (driver_data->video_hd_disabled != 0) { 3957 psb__error_message("MRST: hw_info shows video_hd_disable is true,fix it manually\n"); 3958 driver_data->video_hd_disabled = 0; 3959 } 3960#endif 3961 3962 if (0 != psb_get_device_info(ctx)) { 3963 psb__error_message("ERROR: failed to get video device info\n"); 3964 driver_data->encode_supported = 1; 3965 driver_data->decode_supported = 1; 3966 driver_data->hd_encode_supported = 1; 3967 driver_data->hd_decode_supported = 1; 3968 } 3969 3970 psb_init_surface_pvr2dbuf(driver_data); 3971 3972 struct dri_state *dri_state = (struct dri_state *)ctx->dri_state; 3973 if (dri_state->driConnectedFlag == VA_DRI1 || 3974 dri_state->driConnectedFlag == VA_DRI2 || 3975 dri_state->driConnectedFlag == VA_DUMMY) { 3976 if (VA_STATUS_SUCCESS != psb_initOutput(ctx)) { 3977 psb__deinitDRM(ctx); 3978 free(ctx->pDriverData); 3979 ctx->pDriverData = NULL; 3980 return VA_STATUS_ERROR_UNKNOWN; 3981 } 3982 } 3983 3984 driver_data->msvdx_context_base = (((unsigned int) getpid()) & 0xffff) << 16; 3985#ifdef PSBVIDEO_MFLD 3986 if (IS_MFLD(driver_data)) { 3987 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &pnw_H263ES_vtable; 3988 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &pnw_H264ES_vtable; 3989 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &pnw_H264ES_vtable; 3990 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; 3991 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &pnw_MPEG4ES_vtable; 3992 driver_data->profile2Format[VAProfileJPEGBaseline][VAEntrypointEncPicture] = &pnw_JPEG_vtable; 3993 3994 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &pnw_MPEG2_vtable; 3995 3996 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3997 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &pnw_MPEG4_vtable; 3998 3999 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &pnw_H264_vtable; 4000 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &pnw_H264_vtable; 4001 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &pnw_H264_vtable; 4002 4003 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &pnw_VC1_vtable; 4004 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &pnw_VC1_vtable; 4005 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &pnw_VC1_vtable; 4006 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &pnw_H264_vtable; 4007 } 4008#endif 4009#ifdef PSBVIDEO_MRST 4010 if (IS_MRST(driver_data)) { 4011 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointVLD] = &psb_MPEG2_vtable; 4012 driver_data->profile2Format[VAProfileMPEG2Main][VAEntrypointMoComp] = &psb_MPEG2MC_vtable; 4013 4014 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointVLD] = &psb_MPEG4_vtable; 4015 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointVLD] = &psb_MPEG4_vtable; 4016 4017 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointVLD] = &psb_H264_vtable; 4018 driver_data->profile2Format[VAProfileH264Main][VAEntrypointVLD] = &psb_H264_vtable; 4019 driver_data->profile2Format[VAProfileH264High][VAEntrypointVLD] = &psb_H264_vtable; 4020 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &psb_H264_vtable; 4021 4022 driver_data->profile2Format[VAProfileVC1Simple][VAEntrypointVLD] = &psb_VC1_vtable; 4023 driver_data->profile2Format[VAProfileVC1Main][VAEntrypointVLD] = &psb_VC1_vtable; 4024 driver_data->profile2Format[VAProfileVC1Advanced][VAEntrypointVLD] = &psb_VC1_vtable; 4025 driver_data->profile2Format[VAProfileH264ConstrainedBaseline][VAEntrypointVLD] = &psb_H264_vtable; 4026 4027 if(driver_data->encode_supported) { 4028 4029 driver_data->profile2Format[VAProfileH263Baseline][VAEntrypointEncSlice] = &lnc_H263ES_vtable; 4030 driver_data->profile2Format[VAProfileH264Baseline][VAEntrypointEncSlice] = &lnc_H264ES_vtable; 4031 driver_data->profile2Format[VAProfileH264Main][VAEntrypointEncSlice] = &lnc_H264ES_vtable; 4032 driver_data->profile2Format[VAProfileMPEG4Simple][VAEntrypointEncSlice] = &lnc_MPEG4ES_vtable; 4033 driver_data->profile2Format[VAProfileMPEG4AdvancedSimple][VAEntrypointEncSlice] = &lnc_MPEG4ES_vtable; 4034 } 4035} 4036#endif 4037 result = object_heap_init(&driver_data->config_heap, sizeof(struct object_config_s), CONFIG_ID_OFFSET); 4038 ASSERT(result == 0); 4039 4040 result = object_heap_init(&driver_data->context_heap, sizeof(struct object_context_s), CONTEXT_ID_OFFSET); 4041 ASSERT(result == 0); 4042 4043 result = object_heap_init(&driver_data->surface_heap, sizeof(struct object_surface_s), SURFACE_ID_OFFSET); 4044 ASSERT(result == 0); 4045 4046 result = object_heap_init(&driver_data->buffer_heap, sizeof(struct object_buffer_s), BUFFER_ID_OFFSET); 4047 ASSERT(result == 0); 4048 4049 result = object_heap_init(&driver_data->image_heap, sizeof(struct object_image_s), IMAGE_ID_OFFSET); 4050 ASSERT(result == 0); 4051 4052 result = object_heap_init(&driver_data->subpic_heap, sizeof(struct object_subpic_s), SUBPIC_ID_OFFSET); 4053 ASSERT(result == 0); 4054 4055 driver_data->cur_displaying_surface = VA_INVALID_SURFACE; 4056 driver_data->last_displaying_surface = VA_INVALID_SURFACE; 4057 4058 driver_data->clear_color = 0; 4059 driver_data->blend_color = 0; 4060 driver_data->blend_mode = 0; 4061 driver_data->overlay_auto_paint_color_key = 0; 4062 4063 if (IS_MFLD(driver_data)) 4064 ctx->str_vendor = PSB_STR_VENDOR_MFLD; 4065 else 4066 ctx->str_vendor = PSB_STR_VENDOR_MRST; 4067 4068 4069 driver_data->msvdx_decode_status = calloc(1, sizeof(drm_psb_msvdx_decode_status_t)); 4070 if (NULL == driver_data->msvdx_decode_status) { 4071 return VA_STATUS_ERROR_ALLOCATION_FAILED; 4072 } 4073 driver_data->surface_mb_error = calloc(MAX_MB_ERRORS, sizeof(VASurfaceDecodeMBErrors)); 4074 if (NULL == driver_data->surface_mb_error) { 4075 return VA_STATUS_ERROR_ALLOCATION_FAILED; 4076 } 4077 4078 psb__information_message("vaInitilize: succeeded!\n\n"); 4079 4080#ifdef ANDROID 4081 gralloc_init(); 4082#endif 4083 return VA_STATUS_SUCCESS; 4084} 4085 4086 4087EXPORT VAStatus __vaDriverInit_0_32(VADriverContextP ctx) 4088{ 4089 return __vaDriverInit_0_31(ctx); 4090} 4091 4092 4093 4094static int psb_get_device_info(VADriverContextP ctx) 4095{ 4096 INIT_DRIVER_DATA; 4097 struct drm_lnc_video_getparam_arg arg; 4098 unsigned long device_info; 4099 int ret = 0; 4100 unsigned long video_capability; 4101 unsigned long pci_device; 4102 4103 driver_data->dev_id = 0x4100; /* by default MRST */ 4104 4105 arg.key = LNC_VIDEO_DEVICE_INFO; 4106 arg.value = (uint64_t)((unsigned long) & device_info); 4107 ret = drmCommandWriteRead(driver_data->drm_fd, driver_data->getParamIoctlOffset, 4108 &arg, sizeof(arg)); 4109 if (ret != 0) { 4110 psb__information_message("failed to get video device info\n"); 4111 return ret; 4112 } 4113 4114 pci_device = (device_info >> 16) & 0xffff; 4115 video_capability = device_info & 0xffff; 4116 4117 driver_data->dev_id = pci_device; 4118 psb__information_message("Retrieve Device ID 0x%04x\n", driver_data->dev_id); 4119 4120 if ((IS_MRST(driver_data) && (pci_device != 0x4101)) || 4121 IS_MFLD(driver_data)) 4122 driver_data->encode_supported = 1; 4123 else /* 0x4101 or other device hasn't encode support */ 4124 driver_data->encode_supported = 0; 4125 4126 if (IS_MRST(driver_data)) { 4127 driver_data->decode_supported = !(video_capability & 0x2); 4128 driver_data->hd_decode_supported = !(video_capability & 0x3); 4129 driver_data->hd_encode_supported = !(video_capability & 0x4); 4130 4131 psb__information_message("video capability: decode %s, HD decode %s\n", 4132 driver_data->decode_supported ? "support" : "not support", 4133 driver_data->hd_decode_supported ? "support" : "not support"); 4134 4135 psb__information_message("video capability: encode %s, HD encode %s\n", 4136 driver_data->encode_supported ? "support" : "not support", 4137 driver_data->hd_encode_supported ? "support" : "not support"); 4138 4139 } else { 4140 driver_data->decode_supported = 1; 4141 driver_data->hd_decode_supported = 1; 4142 driver_data->hd_encode_supported = 1; 4143 } 4144 4145 return ret; 4146} 4147