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