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 50extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch); 51 52 53/**************************************************************************** 54* Typedefs 55****************************************************************************/ 56 57typedef 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 83typedef void ((*vp8blit_func)(unsigned char *, int, YUV_BUFFER_CONFIG *)); 84 85/* define an x_image structure based on the core x_image struct */ 86typedef 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****************************************************************************/ 127static 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****************************************************************************/ 148void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter); 149 150static int onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *bd_tag); 151static int onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag); 152 153static 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*/ 169void 170convert_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 189int 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 ****************************************************************************/ 608static 609int 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*/ 670static 671int 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*/ 693static int 694onyx_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*/ 711static int 712onyx_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*/ 729static 730int 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*/ 753static 754int 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*/ 789static 790DXV_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 828static 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*/ 856static 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*/ 897int 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*/ 913int 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 ****************************************************************************/ 938void 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*/ 985static int 986onyx_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*/ 1003static int 1004onyx_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*/ 1043int 1044vpx_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