Home | History | Annotate | Download | only in x86
      1 /*
      2  *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
      3  *
      4  *  Use of this source code is governed by a BSD-style license
      5  *  that can be found in the LICENSE file in the root of the source
      6  *  tree. An additional intellectual property rights grant can be found
      7  *  in the file PATENTS.  All contributing project authors may
      8  *  be found in the AUTHORS file in the root of the source tree.
      9  */
     10 
     11 
     12 /****************************************************************************
     13 *
     14 *   Module Title :     onyxdxv.c
     15 *
     16 *   Description  :     VP80 interface to DXV.
     17 *
     18 *****************************************************************************
     19 */
     20 /****************************************************************************
     21 *  Header Files
     22 ****************************************************************************/
     23 #include <math.h>   // For Abs()
     24 #include "pragmas.h"
     25 
     26 #include "vpxdxv.h"
     27 #include "vpxdxv_plugin.h"
     28 
     29 #include "onyxd_int.h"
     30 #include "onyx.h"
     31 #include "codec_common_interface.h"
     32 #include "vpx_scale/vpxscale.h"
     33 #include "vpx_mem/vpx_mem.h"
     34 #include "postproc.h"
     35 #include "vpxblit.h"
     36 #include "g_common.h"
     37 #include "vpx_scale/yv12extend.h"
     38 
     39 #include <limits.h>
     40 #include <stdio.h>
     41 #include "scale_mode.h"
     42 #include "onyx_pb_interface.h"
     43 
     44 /****************************************************************************
     45 *  Macros
     46 ****************************************************************************/
     47 
     48 #define VP8_FOURCC DXL_MKFOURCC( 'V', 'P', '8', '0')
     49 
     50 extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch);
     51 
     52 
     53 /****************************************************************************
     54 *  Typedefs
     55 ****************************************************************************/
     56 
     57 typedef struct  // YUV buffer configuration structure
     58 {
     59     int   y_width;
     60     int   y_height;
     61     int   y_stride;
     62 
     63     int   uv_width;
     64     int   uv_height;
     65     int   uv_stride;
     66 
     67     char *y_buffer;
     68     char *u_buffer;
     69     char *v_buffer;
     70 
     71     char *uv_start;
     72     int   uv_dst_area;
     73     int   uv_used_area;
     74 
     75     unsigned char *y_ptr_scrn;
     76     unsigned char *u_ptr_scrn;
     77     unsigned char *v_ptr_scrn;
     78 
     79 
     80 } DXV_YUV_BUFFER_CONFIG;
     81 
     82 
     83 typedef void ((*vp8blit_func)(unsigned char *, int, YUV_BUFFER_CONFIG *));
     84 
     85 /* define an x_image structure based on the core x_image struct */
     86 typedef struct t_ximage_codec
     87 {
     88     DXV_YUV_BUFFER_CONFIG frame_buffer;
     89     VP8D_COMP *my_pbi;
     90     VP8_COMMON *common;
     91     int owned;
     92     int decompressed_once;
     93 
     94     int sizeof_pixel;
     95     vp8blit_func blitter;
     96 
     97     unsigned int ppl_tag;
     98     unsigned int bd_tag;
     99     unsigned int *supported_output_format_list;
    100 
    101     int cpu_free;
    102     int postproc;
    103     int add_noise;
    104     int deinterlace;
    105 
    106     int post_proc2time;
    107     int post_proc4time;
    108 
    109     int hs;
    110     int hr;
    111     int vs;
    112     int vr;
    113     YV12_BUFFER_CONFIG this_buffer;
    114     YV12_BUFFER_CONFIG scaled_buffer;
    115     YV12_BUFFER_CONFIG *passed_in_buffer;
    116 
    117     int avgq;
    118     int ppcount;
    119 
    120 
    121 } VP8_XIMAGE, *VP8_XIMAGE_HANDLE;
    122 
    123 
    124 /****************************************************************************
    125 *  Modul Statics
    126 ****************************************************************************/
    127 static unsigned int g_vp8_preferred_output_format_list[] =
    128 {
    129     VPXDXV_YUY2,
    130     VPXDXV_UYVY,
    131     VPXDXV_RGB8888,
    132     VPXDXV_RGB888,
    133     VPXDXV_RGB555,
    134     VPXDXV_RGB565,
    135     VPXDXV_YV12,
    136     VPXDXV_I420,
    137 
    138 //    VPXDXV_YV12,
    139 //    VPXDXV_YUY2,
    140 //    VPXDXV_RGB565,
    141 //    VPXDXV_UYVY,
    142     0
    143 };
    144 
    145 /****************************************************************************
    146 *  Forward declarationss
    147 ****************************************************************************/
    148 void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter);
    149 
    150 static int onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *bd_tag);
    151 static int onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag);
    152 
    153 static int vpx_get_size_of_pixel(unsigned int bd);
    154 
    155 /****************************************************************************
    156 *  Imports
    157 ****************************************************************************/
    158 
    159 #define __Clamp255(x)   (unsigned char) ( (x) < 0 ? 0 : ( (x) <= 255 ? (x) : 255 ) )
    160 
    161 /*
    162 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    163 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    164 */
    165 /*
    166 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    167 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    168 */
    169 void
    170 convert_yv12_buffer_types(YV12_BUFFER_CONFIG *source, DXV_YUV_BUFFER_CONFIG *dest)
    171 {
    172     dest->y_buffer = (char *)source->y_buffer;
    173     dest->u_buffer = (char *)source->u_buffer;
    174     dest->v_buffer = (char *)source->v_buffer;
    175     dest->y_width  = source->y_width;
    176     dest->y_height = source->y_height;
    177     dest->y_stride = source->y_stride;
    178     dest->uv_width  = source->uv_width;
    179     dest->uv_height = source->uv_height;
    180     dest->uv_stride = source->uv_stride;
    181 }
    182 
    183 /*
    184 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    185 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    186 */
    187 
    188 
    189 int onyx_blit
    190 (
    191     XIMAGE_HANDLE src,
    192     VSCREEN_HANDLE v_screen,
    193     DXV_YUV_BUFFER_CONFIG *frame_buffer,
    194     int x,
    195     int y
    196 )
    197 {
    198     VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    199     VP8D_COMP *pbi;
    200     VP8_COMMON *common = tab->common;
    201     pbi = tab->my_pbi;
    202 
    203     if (v_screen) /* if there is a v_screen, blit to it */
    204     {
    205         unsigned char *ptr_scrn;
    206         int this_pitch, vs_height, vs_width;
    207         unsigned int start_tick, stop_tick;
    208 
    209         vpxdxv_get_vscreen_attributes(v_screen, (void **)&ptr_scrn,  &vs_width, &vs_height, &this_pitch);
    210 
    211         if (ptr_scrn)
    212         {
    213             int w, h;
    214 
    215             int p_size;
    216             int view_x, view_y, view_w;
    217             int hs, hr, vs, vr;
    218             int neww, newh;
    219             int cw, ch;
    220             int microseconds_available = (int)(1000000 / 30);
    221 
    222             microseconds_available = microseconds_available * tab->cpu_free / 100;
    223 
    224             if (pbi)
    225             {
    226                 microseconds_available -= pbi->decode_microseconds;
    227 
    228                 if (tab->cpu_free == 0)
    229                     microseconds_available = INT_MAX;
    230 
    231                 if (tab->post_proc2time == 0)
    232                     tab->post_proc2time = pbi->decode_microseconds * 1 / 2;
    233 
    234                 if (tab->post_proc4time == 0)
    235                     tab->post_proc4time = pbi->decode_microseconds;
    236             }
    237 
    238 
    239             if (tab->ppcount == 0)
    240             {
    241                 tab->post_proc2time = 0;
    242                 tab->post_proc4time = 0;
    243                 tab->ppcount = 64;
    244             }
    245             else
    246             {
    247                 tab->ppcount --;
    248             }
    249 
    250             vpxdxv_get_vscreen_view(v_screen, &view_x, &view_y, &view_w, NULL);
    251 
    252             Scale2Ratio(common->horiz_scale, &hr, &hs);
    253             Scale2Ratio(common->vert_scale, &vr, &vs);
    254 
    255             if (tab->postproc && tab->passed_in_buffer == 0)
    256             {
    257                 int show_text = 0;
    258 
    259                 unsigned char message[512];
    260 
    261                 int pp = tab->postproc;
    262                 int q = (tab->avgq + 4) / 8;
    263                 int noise = 0;
    264 
    265                 vp8_clear_system_state();
    266 
    267                 if (pp >= 1000)
    268                 {
    269                     pp -= 1000;
    270                     noise = pp / 100;
    271                     pp = pp - noise * 100;
    272                 }
    273 
    274                 if (pp >= 300)
    275                 {
    276                     pp -= 300;
    277                     show_text = 3;
    278                 }
    279                 else if (pp >= 200)
    280                 {
    281                     pp -= 200;
    282                     show_text = 2;
    283                 }
    284                 else if (pp >= 100)
    285                 {
    286                     pp -= 100;
    287                     show_text = 1;
    288                 }
    289 
    290                 if (pbi && (pbi->mb.segmentation_enabled & SEGMENT_PF) && tab->deinterlace)
    291                 {
    292                     de_interlace(common->frame_to_show->y_buffer, common->post_proc_buffer.y_buffer,
    293                                  common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
    294                                  common->post_proc_buffer.y_stride);
    295 
    296                     de_interlace(common->frame_to_show->u_buffer, common->post_proc_buffer.u_buffer,
    297                                  common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
    298                                  common->post_proc_buffer.uv_stride);
    299                     de_interlace(common->frame_to_show->v_buffer, common->post_proc_buffer.v_buffer,
    300                                  common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height,
    301                                  common->post_proc_buffer.uv_stride);
    302                 }
    303                 else
    304                 {
    305                     if (pp >= 10 && pp <= 20)
    306                     {
    307                         q = q + (pp - 15) * 10;
    308 
    309                         if (q < 0)
    310                             q = 0;
    311                     }
    312 
    313                     start_tick = vp8_get_high_res_timer_tick();
    314 
    315                     if (pp > 3 && tab->post_proc4time < microseconds_available)
    316                     {
    317                         vp8_deblock_and_de_macro_block(common->frame_to_show, &common->post_proc_buffer, q, 1, 0);
    318 
    319                         stop_tick = vp8_get_high_res_timer_tick();
    320 
    321                         if (pbi)
    322                             tab->post_proc4time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
    323                     }
    324 
    325                     else if (pp > 0 && tab->post_proc2time < microseconds_available)
    326                     {
    327                         vp8_deblock(common->frame_to_show, &common->post_proc_buffer, q , 1,  0);
    328                         stop_tick = vp8_get_high_res_timer_tick();
    329 
    330                         if (pbi)
    331                             tab->post_proc2time = vp8_get_time_in_micro_sec(start_tick, stop_tick);
    332                     }
    333                     else
    334                     {
    335                         vp8_yv12_copy_frame(common->frame_to_show, &common->post_proc_buffer);
    336                     }
    337 
    338                 }
    339 
    340                 vp8_clear_system_state();
    341 
    342                 if (tab->add_noise == 1)
    343                 {
    344 
    345                     vp8_plane_add_noise(common->post_proc_buffer.y_buffer,
    346                                         common->post_proc_buffer.y_width, common->post_proc_buffer.y_height,
    347                                         common->post_proc_buffer.y_stride, 63 - q, noise);
    348                 }
    349 
    350 
    351                 if (show_text == 1)
    352                 {
    353 #ifdef PACKET_TESTING
    354                     {
    355                         VP8_HEADER *oh2 = (VP8_HEADER *) pbi->Source;
    356                         sprintf(message, "%8d %d%d%d%d%d size:%d\n",
    357                         oh2->frame_number ,
    358                         oh2->update_gold  ,
    359                         oh2->update_last  ,
    360                         oh2->uses_gold    ,
    361                         oh2->uses_last    ,
    362                         oh2->type,
    363                         vpxdxv_get_ximage_csize(src));
    364                     }
    365 #else
    366                     sprintf(message, "F:%1ldG:%1ldQ:%3ldF:%3ld,%3ldP:%d_s:%6ld,N:%d,",
    367                             (common->frame_type == KEY_FRAME),
    368                             common->refresh_golden_frame,
    369                             common->base_qindex,
    370                             common->filter_level,
    371                             q,
    372                             tab->postproc,
    373                             vpxdxv_get_ximage_csize(src), noise);
    374 #endif
    375 
    376                     vp8_blit_text(message, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_stride);
    377 
    378                 }
    379                 else if (show_text == 2)
    380                 {
    381                     int i, j;
    382                     unsigned char *y_ptr;
    383                     YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
    384                     int mb_rows = post->y_height >> 4;
    385                     int mb_cols = post->y_width  >> 4;
    386                     int mb_index = 0;
    387                     MODE_INFO *mi = common->mi;
    388 
    389                     y_ptr = post->y_buffer + 4 * post->y_stride + 4;
    390 
    391                     // vp8_filter each macro block
    392                     for (i = 0; i < mb_rows; i++)
    393                     {
    394                         for (j = 0; j < mb_cols; j++)
    395                         {
    396                             char zz[4];
    397 
    398                             if (pp == 4)
    399                                 sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a');
    400                             else
    401                                 sprintf(zz, "%c", mi[mb_index].mbmi.ref_frame + 'a');
    402 
    403                             vp8_blit_text(zz, y_ptr, post->y_stride);
    404                             mb_index ++;
    405                             y_ptr += 16;
    406                         }
    407 
    408                         mb_index ++; //border
    409                         y_ptr += post->y_stride  * 16 - post->y_width;
    410 
    411                     }
    412                 }
    413                 else if (show_text == 3)
    414                 {
    415                     int i, j;
    416                     unsigned char *y_ptr;
    417                     YV12_BUFFER_CONFIG *post = &common->post_proc_buffer;
    418                     int mb_rows = post->y_height >> 4;
    419                     int mb_cols = post->y_width  >> 4;
    420                     int mb_index = 0;
    421                     MODE_INFO *mi = common->mi;
    422 
    423                     y_ptr = post->y_buffer + 4 * post->y_stride + 4;
    424 
    425                     // vp8_filter each macro block
    426                     for (i = 0; i < mb_rows; i++)
    427                     {
    428                         for (j = 0; j < mb_cols; j++)
    429                         {
    430                             char zz[4];
    431 
    432                             if (j == 0)
    433                                 sprintf(zz, "%c", '0' + i % 10);
    434                             else
    435                                 sprintf(zz, "%c", '0' + j % 10);
    436 
    437                             vp8_blit_text(zz, y_ptr, post->y_stride);
    438                             mb_index ++;
    439                             y_ptr += 16;
    440                         }
    441 
    442                         y_ptr += post->y_stride  * 16 - post->y_width;
    443 
    444                     }
    445                 }
    446 
    447                 vpx_memcpy(&tab->this_buffer, &common->post_proc_buffer, sizeof(YV12_BUFFER_CONFIG));
    448             }
    449             else
    450             {
    451                 vpx_memcpy(&tab->this_buffer, common->frame_to_show, sizeof(YV12_BUFFER_CONFIG));
    452             }
    453 
    454 
    455             /* get a frame pointer to the scaled and postprocessed reconstructed buffer */
    456             if (tab->passed_in_buffer == 0)
    457             {
    458                 if (common->horiz_scale != NORMAL || common->vert_scale != NORMAL)
    459                 {
    460                     neww = hs * tab->this_buffer.y_width / hr;
    461                     newh = vs * tab->this_buffer.y_height / vr;
    462 
    463                     neww += neww & 1;
    464 
    465                     if (tab->hs != hs || tab->hr != hr || tab->vs != vs || tab->vr != vr)
    466                     {
    467                         vp8_yv12_alloc_frame_buffer(&tab->scaled_buffer, neww, newh , 8);
    468                     }
    469 
    470                     vp8_yv12_scale_or_center(&tab->this_buffer,
    471                                              &tab->scaled_buffer,
    472                                              neww, newh, SCALE_TO_FIT, hs, hr, vs, vr);
    473 
    474                     convert_yv12_buffer_types(&tab->scaled_buffer, frame_buffer);
    475 
    476                     cw = hs * common->Width / hr;
    477                     ch = vs * common->Height / vr;
    478 
    479                 }
    480                 else
    481                 {
    482                     convert_yv12_buffer_types(&tab->this_buffer, frame_buffer);
    483 
    484                     cw = common->Width;
    485                     ch = common->Height;
    486                 }
    487             }
    488             else
    489             {
    490                 convert_yv12_buffer_types(tab->passed_in_buffer, frame_buffer);
    491                 cw = common->Width;
    492                 ch = common->Height;
    493                 tab->passed_in_buffer = 0;
    494             }
    495 
    496             frame_buffer->y_width = cw;
    497             frame_buffer->y_height = ch;
    498             frame_buffer->uv_width = cw / 2;
    499             frame_buffer->uv_height = ch / 2;
    500 
    501             p_size = vpx_get_size_of_pixel(tab->bd_tag);
    502 
    503             /* remember to offset if requested */
    504             y += view_y;
    505             x += view_x ;
    506 
    507             /* for planar destinations */
    508             w = view_w;
    509             h = vs_height;
    510 
    511             if (w < frame_buffer->y_width)
    512             {
    513                 frame_buffer->y_width = w;
    514                 frame_buffer->uv_width = (w + 1) / 2;
    515             }
    516 
    517             if (h < frame_buffer->y_height)
    518             {
    519                 frame_buffer->y_height = h;
    520                 frame_buffer->uv_height = (h + 1) / 2;
    521             }
    522 
    523             if (frame_buffer->y_width < view_w)
    524                 x += (view_w - frame_buffer->y_width) / 2;
    525 
    526             if (x & 1)
    527                 x -= 1;
    528 
    529             if (frame_buffer->y_height < vs_height)
    530                 y += (vs_height - frame_buffer->y_height) / 2;
    531 
    532 
    533             ptr_scrn += (x * p_size) + (y * this_pitch);
    534 
    535             frame_buffer->y_stride *= -1;
    536             frame_buffer->uv_stride *= -1;
    537 
    538             if (tab->bd_tag == VPXDXV_YV12 || tab->bd_tag == VPXDXV_I420)
    539             {
    540                 if (this_pitch < 0)
    541                 {
    542                     frame_buffer->uv_start = (char *)(ptr_scrn + abs(this_pitch) + abs(this_pitch) * h / 4 + this_pitch / 2);
    543                     frame_buffer->uv_dst_area = abs((this_pitch * h) / 4);
    544                     frame_buffer->uv_used_area = 0;
    545                 }
    546                 else
    547                 {
    548                     frame_buffer->uv_start = (char *)(ptr_scrn + (this_pitch * h));
    549                     frame_buffer->uv_dst_area = (((this_pitch + 1) / 2) * ((h + 1) / 2));
    550                     frame_buffer->uv_used_area = (((this_pitch + 1) / 2) * frame_buffer->uv_height);
    551                 }
    552             }
    553 
    554             if ((pbi->mb.segmentation_enabled & SEGMENT_PF) && (tab->bd_tag != VPXDXV_YV12 && tab->bd_tag != VPXDXV_I420))
    555             {
    556                 int ypitch = frame_buffer->y_stride;
    557                 int uvpitch = frame_buffer->uv_stride;
    558 
    559                 frame_buffer->y_stride <<= 1;
    560                 frame_buffer->y_height >>= 1;
    561                 frame_buffer->uv_stride <<= 1;
    562                 frame_buffer->uv_height >>= 1;
    563 
    564                 ptr_scrn += this_pitch;
    565                 frame_buffer->y_buffer -= ypitch;
    566                 frame_buffer->u_buffer -= uvpitch;
    567                 frame_buffer->v_buffer -= uvpitch;
    568                 tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
    569 
    570                 ptr_scrn -= this_pitch;
    571                 frame_buffer->y_buffer += ypitch;
    572                 frame_buffer->u_buffer += uvpitch;
    573                 frame_buffer->v_buffer += uvpitch;
    574                 tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
    575 
    576             }
    577             else
    578             {
    579                 /* blit the screen */
    580                 tab->blitter(ptr_scrn, this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer));
    581                 vpx_log("Decoder: Frame shown \n");
    582             }
    583 
    584         }
    585         else
    586             vpx_log("Decoder: Frame not shown scrn pointer 0\n");
    587     }
    588     else
    589         vpx_log("Decoder: Frame not shown vscreen 0\n");
    590 
    591     return DXV_OK;
    592 }
    593 /****************************************************************************
    594  *
    595  *  ROUTINE       :     onyx_decompress
    596  *
    597  *  INPUTS        :     None
    598  *
    599  *  OUTPUTS       :     None
    600  *
    601  *  RETURNS       :     None.
    602  *
    603  *  FUNCTION      :
    604  *
    605  *  SPECIAL NOTES :
    606  *
    607  ****************************************************************************/
    608 static
    609 int onyx_decompress(XIMAGE_HANDLE src, VSCREEN_HANDLE v_screen)
    610 {
    611     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    612     unsigned char *c_addr;
    613     unsigned int c_size;
    614     int w, h, x, y;
    615     int vp8_rv;
    616 
    617     c_addr = vpxdxv_get_ximage_cdata_addr(src);
    618     c_size = vpxdxv_get_ximage_csize(src);
    619     vpxdxv_get_ximage_xywh(src, &x, &y, &w, &h);
    620 
    621     // if we have a compressed frame decompress it ( otherwise we'll just redo
    622     // the scaling and postprocessing from the last frame )
    623     if (c_addr)
    624     {
    625         if (c_size != 0)
    626         {
    627             int flags;
    628             int ret_val;
    629 
    630             int f;
    631 
    632             // decode the frame
    633             ret_val = vp8d_decompress_frame((VP8D_PTR) this_algorithm_base->my_pbi,
    634                                             c_size,
    635                                             (char *) c_addr,
    636                                             &this_algorithm_base->this_buffer,
    637                                             &flags);
    638 
    639 
    640             f = this_algorithm_base->my_pbi->common.filter_level * 10 / 6;
    641 
    642             if (this_algorithm_base->my_pbi->common.frame_type == KEY_FRAME)
    643                 this_algorithm_base->avgq = 8 * f;
    644             else
    645                 this_algorithm_base->avgq = this_algorithm_base->avgq * 7 / 8 + f;
    646 
    647 
    648 
    649             if (ret_val != 0)
    650             {
    651                 if (ret_val == -1)
    652                     return DXV_VERSION_CONFLICT;
    653                 else
    654                     return DXV_BAD_DATA;
    655             }
    656 
    657         }
    658     }
    659 
    660 
    661     vp8_rv = onyx_blit(src, v_screen, &this_algorithm_base->frame_buffer, x, y);
    662 
    663 
    664     return vp8_rv;
    665 }
    666 /*
    667 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    668 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    669 */
    670 static
    671 int vp8_ximagedestroy(XIMAGE_HANDLE src)
    672 {
    673     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    674 
    675     if (this_algorithm_base)
    676     {
    677 
    678         vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer);
    679 
    680         /* safety check in case stopdecode was not called */
    681         if (this_algorithm_base->owned)
    682             vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi));
    683 
    684         duck_free(this_algorithm_base);
    685     }
    686 
    687     return DXV_OK;
    688 }
    689 /*
    690 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    691 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    692 */
    693 static int
    694 onyx_get_post_proc(XIMAGE_HANDLE src, unsigned int *ppl)
    695 {
    696     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    697 
    698     if (this_algorithm_base)
    699     {
    700         *ppl = this_algorithm_base->ppl_tag;
    701 
    702         return DXV_OK;
    703     }
    704 
    705     return DXV_NULL_BASE;
    706 }
    707 /*
    708 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    709 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    710 */
    711 static int
    712 onyx_set_post_proc(XIMAGE_HANDLE src, unsigned int ppl)
    713 {
    714     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    715 
    716     if (this_algorithm_base)
    717     {
    718         this_algorithm_base->ppl_tag = ppl;
    719 
    720         return DXV_OK;
    721     }
    722 
    723     return DXV_NULL_BASE;
    724 }
    725 /*
    726 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    727 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    728 */
    729 static
    730 int vp8_ximagestop_decode(XIMAGE_HANDLE src)
    731 {
    732     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    733 
    734     if (this_algorithm_base)
    735     {
    736 
    737         vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer);
    738 
    739         if (this_algorithm_base->owned)
    740             vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi));
    741 
    742         this_algorithm_base->owned = 0;
    743     }
    744 
    745     return DXV_OK;
    746 }
    747 
    748 
    749 /*
    750 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    751 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    752 */
    753 static
    754 int vp8_ximagestart_decode
    755 (
    756     XIMAGE_HANDLE src
    757 )
    758 {
    759     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    760     XIMAGE_INFO_PTR xinfo = vpxdxv_get_ximage_info(src);
    761     VP8D_CONFIG ocf;
    762 
    763     if (xinfo)
    764     {
    765         ocf.Width = xinfo->width;
    766         ocf.Height = xinfo->height;
    767     }
    768 
    769     if (this_algorithm_base->common == 0)
    770     {
    771         this_algorithm_base->my_pbi = (VP8D_COMP *) vp8dx_create_decompressor(&ocf);
    772         this_algorithm_base->owned = 1;
    773         this_algorithm_base->common = &this_algorithm_base->my_pbi->common;
    774         this_algorithm_base->avgq = 0;
    775 
    776     }
    777 
    778     this_algorithm_base->passed_in_buffer = 0;
    779     this_algorithm_base->post_proc2time = 0;
    780     this_algorithm_base->post_proc4time = 0;
    781     this_algorithm_base->ppcount = 64;
    782 
    783     return DXV_OK;
    784 }
    785 /*
    786 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    787 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    788 */
    789 static
    790 DXV_HANDLE vp8_ximagecreate(XIMAGE_HANDLE src)
    791 {
    792     VP8_XIMAGE_HANDLE this_algorithm_base;
    793 
    794     /* create a new algorithm base container */
    795     this_algorithm_base = (VP8_XIMAGE_HANDLE)duck_calloc(1, sizeof(VP8_XIMAGE), DMEM_GENERAL);
    796 
    797     if (this_algorithm_base == NULL)
    798         return NULL;
    799 
    800     vp8_scale_machine_specific_config();
    801 
    802     vpxdxv_register_ximage_start_decode(src, vp8_ximagestart_decode);
    803 
    804     vpxdxv_register_ximage_stop_decode(src, vp8_ximagestop_decode);
    805 
    806     vpxdxv_register_ximage_destroy(src, vp8_ximagedestroy);
    807 
    808     vpxdxv_register_ximage_dx(src, onyx_decompress);
    809 
    810     vpxdxv_register_ximage_set_parameter(src, onyx_set_parameter);
    811 
    812     vpxdxv_register_ximage_output_format_func(src,
    813             onyx_get_output_format,
    814             onyx_set_output_format);
    815 
    816     vpxdxv_register_ximage_post_proc_level_func(src,
    817             onyx_get_post_proc,
    818             onyx_set_post_proc);
    819 
    820     return (DXV_HANDLE)this_algorithm_base;
    821 }
    822 
    823 /*
    824 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    825 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    826 */
    827 
    828 static int store_output_list(unsigned int supported, int count,
    829                              unsigned int *outlist)
    830 {
    831     int i = 0, j = 0,
    832         ret = DXV_OK;
    833 
    834     while (i < count)
    835     {
    836         while (supported && !(supported & 0x01))
    837         {
    838             supported >>= 1;
    839             ++j;
    840         }
    841 
    842         *(outlist + i) = g_vp8_preferred_output_format_list[j];
    843         ++i;
    844         ++j;
    845         supported >>= 1;
    846     }
    847 
    848 
    849     return ret;
    850 }
    851 
    852 /*
    853 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    854 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    855 */
    856 static int onyx_get_output_list(XIMAGE_INFO_PTR xinfo, unsigned int *outlist,
    857                                 unsigned int *size)
    858 {
    859     int i,
    860         ret = DXV_INVALID_REQUEST;
    861     unsigned int supported = 0,
    862                  count = 0;
    863     (void)xinfo;
    864 
    865     if (size)
    866     {
    867         for (i = 0; i < sizeof(g_vp8_preferred_output_format_list) / sizeof(unsigned int) && i < 32; ++i)
    868         {
    869             if (vpx_get_blitter(g_vp8_preferred_output_format_list[i]) != (void *)0xffffffff)
    870             {
    871                 supported |= (1 << i);
    872                 ++count;
    873             }
    874         }
    875 
    876         if (outlist)
    877         {
    878             if (count && ((count + 1) == (*size / sizeof(int))))
    879                 ret = store_output_list(supported, count, outlist);
    880             else
    881                 *outlist = 0;
    882         }
    883         else
    884         {
    885             *size = (count + 1) * sizeof(int);
    886             ret = DXV_OK;
    887         }
    888     }
    889 
    890     return ret;
    891 }
    892 
    893 /*
    894 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    895 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    896 */
    897 int onyx_init(void)
    898 {
    899     int vp8_rv;
    900 
    901     /* register VPX blitters based on cpu */
    902     vpx_set_blit();
    903 
    904     vp8_rv = vpxdxv_register_ximage(vp8_ximagecreate, onyx_get_output_list, VP8_FOURCC);
    905     return vp8_rv;
    906 
    907     return DXV_OK;
    908 }
    909 /*
    910 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    911 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    912 */
    913 int onyx_exit(void)
    914 {
    915 
    916     vpxdxv_un_register_ximage(VP8_FOURCC);
    917 
    918     return DXV_OK;
    919 }
    920 /****************************************************************************
    921  *
    922  *  ROUTINE       :  onyx_set_parameter
    923  *
    924  *  INPUTS        :  XIMAGE_HANDLE src   :
    925  *                   int Command             :
    926  *                   unsigned long Parameter :
    927  *
    928  *  OUTPUTS       :  None.
    929  *
    930  *  RETURNS       :  void
    931  *
    932  *  FUNCTION      :
    933  *
    934  *
    935  *  SPECIAL NOTES :  None.
    936  *
    937  ****************************************************************************/
    938 void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter)
    939 {
    940     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    941 
    942     switch (Command)
    943     {
    944     case PBC_SET_CPUFREE:
    945         this_algorithm_base->cpu_free  = Parameter;
    946         break;
    947     case PBC_SET_POSTPROC:
    948         this_algorithm_base->postproc = Parameter;
    949         break;
    950 
    951     case PBC_SET_BLITBUFF:
    952         this_algorithm_base->passed_in_buffer = (YV12_BUFFER_CONFIG *) Parameter;
    953         break;
    954 
    955     case PBC_SET_REFERENCEFRAME:
    956     {
    957         VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    958         VP8D_COMP *pbi;
    959         pbi = tab->my_pbi;
    960         vp8_yv12_copy_frame((YV12_BUFFER_CONFIG *) Parameter, &pbi->common.last_frame);
    961     }
    962     break;
    963 
    964     case PBC_SET_COMMON:
    965 
    966         if (Parameter)
    967         {
    968             this_algorithm_base->common = (VP8_COMMON *)Parameter;
    969         }
    970 
    971         break;
    972     case PBC_SET_ADDNOISE:
    973         this_algorithm_base->add_noise = Parameter;
    974         break;
    975     case PBC_SET_DEINTERLACEMODE:
    976         this_algorithm_base->deinterlace = Parameter;
    977         break;
    978 
    979     }
    980 }
    981 /*
    982 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    983 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    984 */
    985 static int
    986 onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *format_tag)
    987 {
    988     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
    989 
    990     if (this_algorithm_base)
    991     {
    992         *format_tag = this_algorithm_base->bd_tag;
    993         return DXV_OK;
    994     }
    995 
    996     return DXV_NULL_BASE;
    997 }
    998 
    999 /*
   1000 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1001 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1002 */
   1003 static int
   1004 onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag)
   1005 {
   1006     VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src);
   1007     int i;
   1008     unsigned int bd_tag_found;
   1009 
   1010     if (this_algorithm_base)
   1011     {
   1012         i = 0;
   1013         bd_tag_found = 0;
   1014 
   1015         while (g_vp8_preferred_output_format_list[i] != 0)
   1016         {
   1017             if (g_vp8_preferred_output_format_list[i] == bd_tag)
   1018             {
   1019                 bd_tag_found = 1;
   1020                 break;
   1021             }
   1022 
   1023             i++;
   1024         }
   1025 
   1026         if (bd_tag_found)
   1027         {
   1028             this_algorithm_base->blitter = (vp8blit_func)vpx_get_blitter(bd_tag);
   1029             this_algorithm_base->bd_tag = bd_tag;
   1030             return DXV_OK;
   1031         }
   1032 
   1033         return DXV_INVALID_BLIT;
   1034     }
   1035 
   1036     return DXV_NULL_BASE;
   1037 }
   1038 
   1039 /*
   1040 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1041 //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   1042 */
   1043 int
   1044 vpx_get_size_of_pixel(unsigned int bd)
   1045 {
   1046     int vp8_rv;
   1047 
   1048     switch (bd)
   1049     {
   1050     case VPXDXV_YV12:
   1051     case VPXDXV_I420:
   1052         vp8_rv = 1;
   1053         break;
   1054 
   1055 #ifdef _ENABLE_SPLIT_PIXEL_
   1056     case VPXDXV_SPLIT565:
   1057 #endif
   1058     case VPXDXV_RGB555:
   1059     case VPXDXV_RGB565:
   1060     case VPXDXV_YUY2:
   1061     case VPXDXV_UYVY:
   1062     case VPXDXV_YVYU:
   1063         vp8_rv = 2;
   1064         break;
   1065 
   1066     case VPXDXV_RGB888:
   1067         vp8_rv = 3;
   1068         break;
   1069 
   1070     case VPXDXV_RGB8888:
   1071         vp8_rv = 4;
   1072         break;
   1073 
   1074     default:
   1075         vp8_rv = -1;
   1076         break;
   1077     }
   1078 
   1079     return vp8_rv;
   1080 }
   1081