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