| /* |
| * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| |
| /**************************************************************************** |
| * |
| * Module Title : onyxdxv.c |
| * |
| * Description : VP80 interface to DXV. |
| * |
| ***************************************************************************** |
| */ |
| /**************************************************************************** |
| * Header Files |
| ****************************************************************************/ |
| #include <math.h> // For Abs() |
| #include "pragmas.h" |
| |
| #include "vpxdxv.h" |
| #include "vpxdxv_plugin.h" |
| |
| #include "onyxd_int.h" |
| #include "onyx.h" |
| #include "codec_common_interface.h" |
| #include "vpx_scale/vpxscale.h" |
| #include "vpx_mem/vpx_mem.h" |
| #include "postproc.h" |
| #include "vpxblit.h" |
| #include "g_common.h" |
| #include "vpx_scale/yv12extend.h" |
| |
| #include <limits.h> |
| #include <stdio.h> |
| #include "scale_mode.h" |
| #include "onyx_pb_interface.h" |
| |
| /**************************************************************************** |
| * Macros |
| ****************************************************************************/ |
| |
| #define VP8_FOURCC DXL_MKFOURCC( 'V', 'P', '8', '0') |
| |
| extern void vp8_blit_text(const char *msg, unsigned char *address, const int pitch); |
| |
| |
| /**************************************************************************** |
| * Typedefs |
| ****************************************************************************/ |
| |
| typedef struct // YUV buffer configuration structure |
| { |
| int y_width; |
| int y_height; |
| int y_stride; |
| |
| int uv_width; |
| int uv_height; |
| int uv_stride; |
| |
| char *y_buffer; |
| char *u_buffer; |
| char *v_buffer; |
| |
| char *uv_start; |
| int uv_dst_area; |
| int uv_used_area; |
| |
| unsigned char *y_ptr_scrn; |
| unsigned char *u_ptr_scrn; |
| unsigned char *v_ptr_scrn; |
| |
| |
| } DXV_YUV_BUFFER_CONFIG; |
| |
| |
| typedef void ((*vp8blit_func)(unsigned char *, int, YUV_BUFFER_CONFIG *)); |
| |
| /* define an x_image structure based on the core x_image struct */ |
| typedef struct t_ximage_codec |
| { |
| DXV_YUV_BUFFER_CONFIG frame_buffer; |
| VP8D_COMP *my_pbi; |
| VP8_COMMON *common; |
| int owned; |
| int decompressed_once; |
| |
| int sizeof_pixel; |
| vp8blit_func blitter; |
| |
| unsigned int ppl_tag; |
| unsigned int bd_tag; |
| unsigned int *supported_output_format_list; |
| |
| int cpu_free; |
| int postproc; |
| int add_noise; |
| int deinterlace; |
| |
| int post_proc2time; |
| int post_proc4time; |
| |
| int hs; |
| int hr; |
| int vs; |
| int vr; |
| YV12_BUFFER_CONFIG this_buffer; |
| YV12_BUFFER_CONFIG scaled_buffer; |
| YV12_BUFFER_CONFIG *passed_in_buffer; |
| |
| int avgq; |
| int ppcount; |
| |
| |
| } VP8_XIMAGE, *VP8_XIMAGE_HANDLE; |
| |
| |
| /**************************************************************************** |
| * Modul Statics |
| ****************************************************************************/ |
| static unsigned int g_vp8_preferred_output_format_list[] = |
| { |
| VPXDXV_YUY2, |
| VPXDXV_UYVY, |
| VPXDXV_RGB8888, |
| VPXDXV_RGB888, |
| VPXDXV_RGB555, |
| VPXDXV_RGB565, |
| VPXDXV_YV12, |
| VPXDXV_I420, |
| |
| // VPXDXV_YV12, |
| // VPXDXV_YUY2, |
| // VPXDXV_RGB565, |
| // VPXDXV_UYVY, |
| 0 |
| }; |
| |
| /**************************************************************************** |
| * Forward declarationss |
| ****************************************************************************/ |
| void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter); |
| |
| static int onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *bd_tag); |
| static int onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag); |
| |
| static int vpx_get_size_of_pixel(unsigned int bd); |
| |
| /**************************************************************************** |
| * Imports |
| ****************************************************************************/ |
| |
| #define __Clamp255(x) (unsigned char) ( (x) < 0 ? 0 : ( (x) <= 255 ? (x) : 255 ) ) |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| void |
| convert_yv12_buffer_types(YV12_BUFFER_CONFIG *source, DXV_YUV_BUFFER_CONFIG *dest) |
| { |
| dest->y_buffer = (char *)source->y_buffer; |
| dest->u_buffer = (char *)source->u_buffer; |
| dest->v_buffer = (char *)source->v_buffer; |
| dest->y_width = source->y_width; |
| dest->y_height = source->y_height; |
| dest->y_stride = source->y_stride; |
| dest->uv_width = source->uv_width; |
| dest->uv_height = source->uv_height; |
| dest->uv_stride = source->uv_stride; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| |
| |
| int onyx_blit |
| ( |
| XIMAGE_HANDLE src, |
| VSCREEN_HANDLE v_screen, |
| DXV_YUV_BUFFER_CONFIG *frame_buffer, |
| int x, |
| int y |
| ) |
| { |
| VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| VP8D_COMP *pbi; |
| VP8_COMMON *common = tab->common; |
| pbi = tab->my_pbi; |
| |
| if (v_screen) /* if there is a v_screen, blit to it */ |
| { |
| unsigned char *ptr_scrn; |
| int this_pitch, vs_height, vs_width; |
| unsigned int start_tick, stop_tick; |
| |
| vpxdxv_get_vscreen_attributes(v_screen, (void **)&ptr_scrn, &vs_width, &vs_height, &this_pitch); |
| |
| if (ptr_scrn) |
| { |
| int w, h; |
| |
| int p_size; |
| int view_x, view_y, view_w; |
| int hs, hr, vs, vr; |
| int neww, newh; |
| int cw, ch; |
| int microseconds_available = (int)(1000000 / 30); |
| |
| microseconds_available = microseconds_available * tab->cpu_free / 100; |
| |
| if (pbi) |
| { |
| microseconds_available -= pbi->decode_microseconds; |
| |
| if (tab->cpu_free == 0) |
| microseconds_available = INT_MAX; |
| |
| if (tab->post_proc2time == 0) |
| tab->post_proc2time = pbi->decode_microseconds * 1 / 2; |
| |
| if (tab->post_proc4time == 0) |
| tab->post_proc4time = pbi->decode_microseconds; |
| } |
| |
| |
| if (tab->ppcount == 0) |
| { |
| tab->post_proc2time = 0; |
| tab->post_proc4time = 0; |
| tab->ppcount = 64; |
| } |
| else |
| { |
| tab->ppcount --; |
| } |
| |
| vpxdxv_get_vscreen_view(v_screen, &view_x, &view_y, &view_w, NULL); |
| |
| Scale2Ratio(common->horiz_scale, &hr, &hs); |
| Scale2Ratio(common->vert_scale, &vr, &vs); |
| |
| if (tab->postproc && tab->passed_in_buffer == 0) |
| { |
| int show_text = 0; |
| |
| unsigned char message[512]; |
| |
| int pp = tab->postproc; |
| int q = (tab->avgq + 4) / 8; |
| int noise = 0; |
| |
| vp8_clear_system_state(); |
| |
| if (pp >= 1000) |
| { |
| pp -= 1000; |
| noise = pp / 100; |
| pp = pp - noise * 100; |
| } |
| |
| if (pp >= 300) |
| { |
| pp -= 300; |
| show_text = 3; |
| } |
| else if (pp >= 200) |
| { |
| pp -= 200; |
| show_text = 2; |
| } |
| else if (pp >= 100) |
| { |
| pp -= 100; |
| show_text = 1; |
| } |
| |
| if (pbi && (pbi->mb.segmentation_enabled & SEGMENT_PF) && tab->deinterlace) |
| { |
| de_interlace(common->frame_to_show->y_buffer, common->post_proc_buffer.y_buffer, |
| common->post_proc_buffer.y_width, common->post_proc_buffer.y_height, |
| common->post_proc_buffer.y_stride); |
| |
| de_interlace(common->frame_to_show->u_buffer, common->post_proc_buffer.u_buffer, |
| common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height, |
| common->post_proc_buffer.uv_stride); |
| de_interlace(common->frame_to_show->v_buffer, common->post_proc_buffer.v_buffer, |
| common->post_proc_buffer.uv_width, common->post_proc_buffer.uv_height, |
| common->post_proc_buffer.uv_stride); |
| } |
| else |
| { |
| if (pp >= 10 && pp <= 20) |
| { |
| q = q + (pp - 15) * 10; |
| |
| if (q < 0) |
| q = 0; |
| } |
| |
| start_tick = vp8_get_high_res_timer_tick(); |
| |
| if (pp > 3 && tab->post_proc4time < microseconds_available) |
| { |
| vp8_deblock_and_de_macro_block(common->frame_to_show, &common->post_proc_buffer, q, 1, 0); |
| |
| stop_tick = vp8_get_high_res_timer_tick(); |
| |
| if (pbi) |
| tab->post_proc4time = vp8_get_time_in_micro_sec(start_tick, stop_tick); |
| } |
| |
| else if (pp > 0 && tab->post_proc2time < microseconds_available) |
| { |
| vp8_deblock(common->frame_to_show, &common->post_proc_buffer, q , 1, 0); |
| stop_tick = vp8_get_high_res_timer_tick(); |
| |
| if (pbi) |
| tab->post_proc2time = vp8_get_time_in_micro_sec(start_tick, stop_tick); |
| } |
| else |
| { |
| vp8_yv12_copy_frame(common->frame_to_show, &common->post_proc_buffer); |
| } |
| |
| } |
| |
| vp8_clear_system_state(); |
| |
| if (tab->add_noise == 1) |
| { |
| |
| vp8_plane_add_noise(common->post_proc_buffer.y_buffer, |
| common->post_proc_buffer.y_width, common->post_proc_buffer.y_height, |
| common->post_proc_buffer.y_stride, 63 - q, noise); |
| } |
| |
| |
| if (show_text == 1) |
| { |
| #ifdef PACKET_TESTING |
| { |
| VP8_HEADER *oh2 = (VP8_HEADER *) pbi->Source; |
| sprintf(message, "%8d %d%d%d%d%d size:%d\n", |
| oh2->frame_number , |
| oh2->update_gold , |
| oh2->update_last , |
| oh2->uses_gold , |
| oh2->uses_last , |
| oh2->type, |
| vpxdxv_get_ximage_csize(src)); |
| } |
| #else |
| sprintf(message, "F:%1ldG:%1ldQ:%3ldF:%3ld,%3ldP:%d_s:%6ld,N:%d,", |
| (common->frame_type == KEY_FRAME), |
| common->refresh_golden_frame, |
| common->base_qindex, |
| common->filter_level, |
| q, |
| tab->postproc, |
| vpxdxv_get_ximage_csize(src), noise); |
| #endif |
| |
| vp8_blit_text(message, common->post_proc_buffer.y_buffer, common->post_proc_buffer.y_stride); |
| |
| } |
| else if (show_text == 2) |
| { |
| int i, j; |
| unsigned char *y_ptr; |
| YV12_BUFFER_CONFIG *post = &common->post_proc_buffer; |
| int mb_rows = post->y_height >> 4; |
| int mb_cols = post->y_width >> 4; |
| int mb_index = 0; |
| MODE_INFO *mi = common->mi; |
| |
| y_ptr = post->y_buffer + 4 * post->y_stride + 4; |
| |
| // vp8_filter each macro block |
| for (i = 0; i < mb_rows; i++) |
| { |
| for (j = 0; j < mb_cols; j++) |
| { |
| char zz[4]; |
| |
| if (pp == 4) |
| sprintf(zz, "%c", mi[mb_index].mbmi.mode + 'a'); |
| else |
| sprintf(zz, "%c", mi[mb_index].mbmi.ref_frame + 'a'); |
| |
| vp8_blit_text(zz, y_ptr, post->y_stride); |
| mb_index ++; |
| y_ptr += 16; |
| } |
| |
| mb_index ++; //border |
| y_ptr += post->y_stride * 16 - post->y_width; |
| |
| } |
| } |
| else if (show_text == 3) |
| { |
| int i, j; |
| unsigned char *y_ptr; |
| YV12_BUFFER_CONFIG *post = &common->post_proc_buffer; |
| int mb_rows = post->y_height >> 4; |
| int mb_cols = post->y_width >> 4; |
| int mb_index = 0; |
| MODE_INFO *mi = common->mi; |
| |
| y_ptr = post->y_buffer + 4 * post->y_stride + 4; |
| |
| // vp8_filter each macro block |
| for (i = 0; i < mb_rows; i++) |
| { |
| for (j = 0; j < mb_cols; j++) |
| { |
| char zz[4]; |
| |
| if (j == 0) |
| sprintf(zz, "%c", '0' + i % 10); |
| else |
| sprintf(zz, "%c", '0' + j % 10); |
| |
| vp8_blit_text(zz, y_ptr, post->y_stride); |
| mb_index ++; |
| y_ptr += 16; |
| } |
| |
| y_ptr += post->y_stride * 16 - post->y_width; |
| |
| } |
| } |
| |
| vpx_memcpy(&tab->this_buffer, &common->post_proc_buffer, sizeof(YV12_BUFFER_CONFIG)); |
| } |
| else |
| { |
| vpx_memcpy(&tab->this_buffer, common->frame_to_show, sizeof(YV12_BUFFER_CONFIG)); |
| } |
| |
| |
| /* get a frame pointer to the scaled and postprocessed reconstructed buffer */ |
| if (tab->passed_in_buffer == 0) |
| { |
| if (common->horiz_scale != NORMAL || common->vert_scale != NORMAL) |
| { |
| neww = hs * tab->this_buffer.y_width / hr; |
| newh = vs * tab->this_buffer.y_height / vr; |
| |
| neww += neww & 1; |
| |
| if (tab->hs != hs || tab->hr != hr || tab->vs != vs || tab->vr != vr) |
| { |
| vp8_yv12_alloc_frame_buffer(&tab->scaled_buffer, neww, newh , 8); |
| } |
| |
| vp8_yv12_scale_or_center(&tab->this_buffer, |
| &tab->scaled_buffer, |
| neww, newh, SCALE_TO_FIT, hs, hr, vs, vr); |
| |
| convert_yv12_buffer_types(&tab->scaled_buffer, frame_buffer); |
| |
| cw = hs * common->Width / hr; |
| ch = vs * common->Height / vr; |
| |
| } |
| else |
| { |
| convert_yv12_buffer_types(&tab->this_buffer, frame_buffer); |
| |
| cw = common->Width; |
| ch = common->Height; |
| } |
| } |
| else |
| { |
| convert_yv12_buffer_types(tab->passed_in_buffer, frame_buffer); |
| cw = common->Width; |
| ch = common->Height; |
| tab->passed_in_buffer = 0; |
| } |
| |
| frame_buffer->y_width = cw; |
| frame_buffer->y_height = ch; |
| frame_buffer->uv_width = cw / 2; |
| frame_buffer->uv_height = ch / 2; |
| |
| p_size = vpx_get_size_of_pixel(tab->bd_tag); |
| |
| /* remember to offset if requested */ |
| y += view_y; |
| x += view_x ; |
| |
| /* for planar destinations */ |
| w = view_w; |
| h = vs_height; |
| |
| if (w < frame_buffer->y_width) |
| { |
| frame_buffer->y_width = w; |
| frame_buffer->uv_width = (w + 1) / 2; |
| } |
| |
| if (h < frame_buffer->y_height) |
| { |
| frame_buffer->y_height = h; |
| frame_buffer->uv_height = (h + 1) / 2; |
| } |
| |
| if (frame_buffer->y_width < view_w) |
| x += (view_w - frame_buffer->y_width) / 2; |
| |
| if (x & 1) |
| x -= 1; |
| |
| if (frame_buffer->y_height < vs_height) |
| y += (vs_height - frame_buffer->y_height) / 2; |
| |
| |
| ptr_scrn += (x * p_size) + (y * this_pitch); |
| |
| frame_buffer->y_stride *= -1; |
| frame_buffer->uv_stride *= -1; |
| |
| if (tab->bd_tag == VPXDXV_YV12 || tab->bd_tag == VPXDXV_I420) |
| { |
| if (this_pitch < 0) |
| { |
| frame_buffer->uv_start = (char *)(ptr_scrn + abs(this_pitch) + abs(this_pitch) * h / 4 + this_pitch / 2); |
| frame_buffer->uv_dst_area = abs((this_pitch * h) / 4); |
| frame_buffer->uv_used_area = 0; |
| } |
| else |
| { |
| frame_buffer->uv_start = (char *)(ptr_scrn + (this_pitch * h)); |
| frame_buffer->uv_dst_area = (((this_pitch + 1) / 2) * ((h + 1) / 2)); |
| frame_buffer->uv_used_area = (((this_pitch + 1) / 2) * frame_buffer->uv_height); |
| } |
| } |
| |
| if ((pbi->mb.segmentation_enabled & SEGMENT_PF) && (tab->bd_tag != VPXDXV_YV12 && tab->bd_tag != VPXDXV_I420)) |
| { |
| int ypitch = frame_buffer->y_stride; |
| int uvpitch = frame_buffer->uv_stride; |
| |
| frame_buffer->y_stride <<= 1; |
| frame_buffer->y_height >>= 1; |
| frame_buffer->uv_stride <<= 1; |
| frame_buffer->uv_height >>= 1; |
| |
| ptr_scrn += this_pitch; |
| frame_buffer->y_buffer -= ypitch; |
| frame_buffer->u_buffer -= uvpitch; |
| frame_buffer->v_buffer -= uvpitch; |
| tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer)); |
| |
| ptr_scrn -= this_pitch; |
| frame_buffer->y_buffer += ypitch; |
| frame_buffer->u_buffer += uvpitch; |
| frame_buffer->v_buffer += uvpitch; |
| tab->blitter(ptr_scrn, 2 * this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer)); |
| |
| } |
| else |
| { |
| /* blit the screen */ |
| tab->blitter(ptr_scrn, this_pitch, (YUV_BUFFER_CONFIG *)(&tab->frame_buffer)); |
| vpx_log("Decoder: Frame shown \n"); |
| } |
| |
| } |
| else |
| vpx_log("Decoder: Frame not shown scrn pointer 0\n"); |
| } |
| else |
| vpx_log("Decoder: Frame not shown vscreen 0\n"); |
| |
| return DXV_OK; |
| } |
| /**************************************************************************** |
| * |
| * ROUTINE : onyx_decompress |
| * |
| * INPUTS : None |
| * |
| * OUTPUTS : None |
| * |
| * RETURNS : None. |
| * |
| * FUNCTION : |
| * |
| * SPECIAL NOTES : |
| * |
| ****************************************************************************/ |
| static |
| int onyx_decompress(XIMAGE_HANDLE src, VSCREEN_HANDLE v_screen) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| unsigned char *c_addr; |
| unsigned int c_size; |
| int w, h, x, y; |
| int vp8_rv; |
| |
| c_addr = vpxdxv_get_ximage_cdata_addr(src); |
| c_size = vpxdxv_get_ximage_csize(src); |
| vpxdxv_get_ximage_xywh(src, &x, &y, &w, &h); |
| |
| // if we have a compressed frame decompress it ( otherwise we'll just redo |
| // the scaling and postprocessing from the last frame ) |
| if (c_addr) |
| { |
| if (c_size != 0) |
| { |
| int flags; |
| int ret_val; |
| |
| int f; |
| |
| // decode the frame |
| ret_val = vp8d_decompress_frame((VP8D_PTR) this_algorithm_base->my_pbi, |
| c_size, |
| (char *) c_addr, |
| &this_algorithm_base->this_buffer, |
| &flags); |
| |
| |
| f = this_algorithm_base->my_pbi->common.filter_level * 10 / 6; |
| |
| if (this_algorithm_base->my_pbi->common.frame_type == KEY_FRAME) |
| this_algorithm_base->avgq = 8 * f; |
| else |
| this_algorithm_base->avgq = this_algorithm_base->avgq * 7 / 8 + f; |
| |
| |
| |
| if (ret_val != 0) |
| { |
| if (ret_val == -1) |
| return DXV_VERSION_CONFLICT; |
| else |
| return DXV_BAD_DATA; |
| } |
| |
| } |
| } |
| |
| |
| vp8_rv = onyx_blit(src, v_screen, &this_algorithm_base->frame_buffer, x, y); |
| |
| |
| return vp8_rv; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static |
| int vp8_ximagedestroy(XIMAGE_HANDLE src) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| if (this_algorithm_base) |
| { |
| |
| vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer); |
| |
| /* safety check in case stopdecode was not called */ |
| if (this_algorithm_base->owned) |
| vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi)); |
| |
| duck_free(this_algorithm_base); |
| } |
| |
| return DXV_OK; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static int |
| onyx_get_post_proc(XIMAGE_HANDLE src, unsigned int *ppl) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| if (this_algorithm_base) |
| { |
| *ppl = this_algorithm_base->ppl_tag; |
| |
| return DXV_OK; |
| } |
| |
| return DXV_NULL_BASE; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static int |
| onyx_set_post_proc(XIMAGE_HANDLE src, unsigned int ppl) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| if (this_algorithm_base) |
| { |
| this_algorithm_base->ppl_tag = ppl; |
| |
| return DXV_OK; |
| } |
| |
| return DXV_NULL_BASE; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static |
| int vp8_ximagestop_decode(XIMAGE_HANDLE src) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| if (this_algorithm_base) |
| { |
| |
| vp8_yv12_de_alloc_frame_buffer(&this_algorithm_base->scaled_buffer); |
| |
| if (this_algorithm_base->owned) |
| vp8dx_remove_decompressor((VP8D_PTR)(this_algorithm_base->my_pbi)); |
| |
| this_algorithm_base->owned = 0; |
| } |
| |
| return DXV_OK; |
| } |
| |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static |
| int vp8_ximagestart_decode |
| ( |
| XIMAGE_HANDLE src |
| ) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| XIMAGE_INFO_PTR xinfo = vpxdxv_get_ximage_info(src); |
| VP8D_CONFIG ocf; |
| |
| if (xinfo) |
| { |
| ocf.Width = xinfo->width; |
| ocf.Height = xinfo->height; |
| } |
| |
| if (this_algorithm_base->common == 0) |
| { |
| this_algorithm_base->my_pbi = (VP8D_COMP *) vp8dx_create_decompressor(&ocf); |
| this_algorithm_base->owned = 1; |
| this_algorithm_base->common = &this_algorithm_base->my_pbi->common; |
| this_algorithm_base->avgq = 0; |
| |
| } |
| |
| this_algorithm_base->passed_in_buffer = 0; |
| this_algorithm_base->post_proc2time = 0; |
| this_algorithm_base->post_proc4time = 0; |
| this_algorithm_base->ppcount = 64; |
| |
| return DXV_OK; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static |
| DXV_HANDLE vp8_ximagecreate(XIMAGE_HANDLE src) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base; |
| |
| /* create a new algorithm base container */ |
| this_algorithm_base = (VP8_XIMAGE_HANDLE)duck_calloc(1, sizeof(VP8_XIMAGE), DMEM_GENERAL); |
| |
| if (this_algorithm_base == NULL) |
| return NULL; |
| |
| vp8_scale_machine_specific_config(); |
| |
| vpxdxv_register_ximage_start_decode(src, vp8_ximagestart_decode); |
| |
| vpxdxv_register_ximage_stop_decode(src, vp8_ximagestop_decode); |
| |
| vpxdxv_register_ximage_destroy(src, vp8_ximagedestroy); |
| |
| vpxdxv_register_ximage_dx(src, onyx_decompress); |
| |
| vpxdxv_register_ximage_set_parameter(src, onyx_set_parameter); |
| |
| vpxdxv_register_ximage_output_format_func(src, |
| onyx_get_output_format, |
| onyx_set_output_format); |
| |
| vpxdxv_register_ximage_post_proc_level_func(src, |
| onyx_get_post_proc, |
| onyx_set_post_proc); |
| |
| return (DXV_HANDLE)this_algorithm_base; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| |
| static int store_output_list(unsigned int supported, int count, |
| unsigned int *outlist) |
| { |
| int i = 0, j = 0, |
| ret = DXV_OK; |
| |
| while (i < count) |
| { |
| while (supported && !(supported & 0x01)) |
| { |
| supported >>= 1; |
| ++j; |
| } |
| |
| *(outlist + i) = g_vp8_preferred_output_format_list[j]; |
| ++i; |
| ++j; |
| supported >>= 1; |
| } |
| |
| |
| return ret; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static int onyx_get_output_list(XIMAGE_INFO_PTR xinfo, unsigned int *outlist, |
| unsigned int *size) |
| { |
| int i, |
| ret = DXV_INVALID_REQUEST; |
| unsigned int supported = 0, |
| count = 0; |
| (void)xinfo; |
| |
| if (size) |
| { |
| for (i = 0; i < sizeof(g_vp8_preferred_output_format_list) / sizeof(unsigned int) && i < 32; ++i) |
| { |
| if (vpx_get_blitter(g_vp8_preferred_output_format_list[i]) != (void *)0xffffffff) |
| { |
| supported |= (1 << i); |
| ++count; |
| } |
| } |
| |
| if (outlist) |
| { |
| if (count && ((count + 1) == (*size / sizeof(int)))) |
| ret = store_output_list(supported, count, outlist); |
| else |
| *outlist = 0; |
| } |
| else |
| { |
| *size = (count + 1) * sizeof(int); |
| ret = DXV_OK; |
| } |
| } |
| |
| return ret; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| int onyx_init(void) |
| { |
| int vp8_rv; |
| |
| /* register VPX blitters based on cpu */ |
| vpx_set_blit(); |
| |
| vp8_rv = vpxdxv_register_ximage(vp8_ximagecreate, onyx_get_output_list, VP8_FOURCC); |
| return vp8_rv; |
| |
| return DXV_OK; |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| int onyx_exit(void) |
| { |
| |
| vpxdxv_un_register_ximage(VP8_FOURCC); |
| |
| return DXV_OK; |
| } |
| /**************************************************************************** |
| * |
| * ROUTINE : onyx_set_parameter |
| * |
| * INPUTS : XIMAGE_HANDLE src : |
| * int Command : |
| * unsigned long Parameter : |
| * |
| * OUTPUTS : None. |
| * |
| * RETURNS : void |
| * |
| * FUNCTION : |
| * |
| * |
| * SPECIAL NOTES : None. |
| * |
| ****************************************************************************/ |
| void onyx_set_parameter(XIMAGE_HANDLE src, int Command, unsigned int Parameter) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| switch (Command) |
| { |
| case PBC_SET_CPUFREE: |
| this_algorithm_base->cpu_free = Parameter; |
| break; |
| case PBC_SET_POSTPROC: |
| this_algorithm_base->postproc = Parameter; |
| break; |
| |
| case PBC_SET_BLITBUFF: |
| this_algorithm_base->passed_in_buffer = (YV12_BUFFER_CONFIG *) Parameter; |
| break; |
| |
| case PBC_SET_REFERENCEFRAME: |
| { |
| VP8_XIMAGE_HANDLE tab = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| VP8D_COMP *pbi; |
| pbi = tab->my_pbi; |
| vp8_yv12_copy_frame((YV12_BUFFER_CONFIG *) Parameter, &pbi->common.last_frame); |
| } |
| break; |
| |
| case PBC_SET_COMMON: |
| |
| if (Parameter) |
| { |
| this_algorithm_base->common = (VP8_COMMON *)Parameter; |
| } |
| |
| break; |
| case PBC_SET_ADDNOISE: |
| this_algorithm_base->add_noise = Parameter; |
| break; |
| case PBC_SET_DEINTERLACEMODE: |
| this_algorithm_base->deinterlace = Parameter; |
| break; |
| |
| } |
| } |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static int |
| onyx_get_output_format(XIMAGE_HANDLE src, unsigned int *format_tag) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| |
| if (this_algorithm_base) |
| { |
| *format_tag = this_algorithm_base->bd_tag; |
| return DXV_OK; |
| } |
| |
| return DXV_NULL_BASE; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| static int |
| onyx_set_output_format(XIMAGE_HANDLE src, unsigned int bd_tag) |
| { |
| VP8_XIMAGE_HANDLE this_algorithm_base = (VP8_XIMAGE_HANDLE)vpxdxv_get_algorithm_base_ptr(src); |
| int i; |
| unsigned int bd_tag_found; |
| |
| if (this_algorithm_base) |
| { |
| i = 0; |
| bd_tag_found = 0; |
| |
| while (g_vp8_preferred_output_format_list[i] != 0) |
| { |
| if (g_vp8_preferred_output_format_list[i] == bd_tag) |
| { |
| bd_tag_found = 1; |
| break; |
| } |
| |
| i++; |
| } |
| |
| if (bd_tag_found) |
| { |
| this_algorithm_base->blitter = (vp8blit_func)vpx_get_blitter(bd_tag); |
| this_algorithm_base->bd_tag = bd_tag; |
| return DXV_OK; |
| } |
| |
| return DXV_INVALID_BLIT; |
| } |
| |
| return DXV_NULL_BASE; |
| } |
| |
| /* |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| */ |
| int |
| vpx_get_size_of_pixel(unsigned int bd) |
| { |
| int vp8_rv; |
| |
| switch (bd) |
| { |
| case VPXDXV_YV12: |
| case VPXDXV_I420: |
| vp8_rv = 1; |
| break; |
| |
| #ifdef _ENABLE_SPLIT_PIXEL_ |
| case VPXDXV_SPLIT565: |
| #endif |
| case VPXDXV_RGB555: |
| case VPXDXV_RGB565: |
| case VPXDXV_YUY2: |
| case VPXDXV_UYVY: |
| case VPXDXV_YVYU: |
| vp8_rv = 2; |
| break; |
| |
| case VPXDXV_RGB888: |
| vp8_rv = 3; |
| break; |
| |
| case VPXDXV_RGB8888: |
| vp8_rv = 4; |
| break; |
| |
| default: |
| vp8_rv = -1; |
| break; |
| } |
| |
| return vp8_rv; |
| } |