Fix relative include paths
[libvpx.git] / vp8 / decoder / onyxd_if.c
blob4ac419a9eef77e9b3b8ad3a3bbce88dbaa1d3396
1 /*
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved.
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 */
12 #include "vp8/common/onyxc_int.h"
13 #if CONFIG_POSTPROC
14 #include "vp8/common/postproc.h"
15 #endif
16 #include "vp8/common/onyxd.h"
17 #include "onyxd_int.h"
18 #include "vpx_mem/vpx_mem.h"
19 #include "vp8/common/alloccommon.h"
20 #include "vpx_scale/yv12extend.h"
21 #include "vp8/common/loopfilter.h"
22 #include "vp8/common/swapyv12buffer.h"
23 #include "vp8/common/g_common.h"
24 #include "vp8/common/threading.h"
25 #include "decoderthreading.h"
26 #include <stdio.h>
28 #include "vp8/common/quant_common.h"
29 #include "vpx_scale/vpxscale.h"
30 #include "vp8/common/systemdependent.h"
31 #include "vpx_ports/vpx_timer.h"
32 #include "detokenize.h"
33 #if ARCH_ARM
34 #include "vpx_ports/arm.h"
35 #endif
37 extern void vp8_init_loop_filter(VP8_COMMON *cm);
38 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
40 #if CONFIG_DEBUG
41 void vp8_recon_write_yuv_frame(unsigned char *name, YV12_BUFFER_CONFIG *s)
43 FILE *yuv_file = fopen((char *)name, "ab");
44 unsigned char *src = s->y_buffer;
45 int h = s->y_height;
49 fwrite(src, s->y_width, 1, yuv_file);
50 src += s->y_stride;
52 while (--h);
54 src = s->u_buffer;
55 h = s->uv_height;
59 fwrite(src, s->uv_width, 1, yuv_file);
60 src += s->uv_stride;
62 while (--h);
64 src = s->v_buffer;
65 h = s->uv_height;
69 fwrite(src, s->uv_width, 1, yuv_file);
70 src += s->uv_stride;
72 while (--h);
74 fclose(yuv_file);
76 #endif
78 void vp8dx_initialize()
80 static int init_done = 0;
82 if (!init_done)
84 vp8_initialize_common();
85 vp8_scale_machine_specific_config();
86 init_done = 1;
91 VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
93 VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
95 if (!pbi)
96 return NULL;
98 vpx_memset(pbi, 0, sizeof(VP8D_COMP));
100 if (setjmp(pbi->common.error.jmp))
102 pbi->common.error.setjmp = 0;
103 vp8dx_remove_decompressor(pbi);
104 return 0;
107 pbi->common.error.setjmp = 1;
108 vp8dx_initialize();
110 vp8_create_common(&pbi->common);
111 vp8_dmachine_specific_config(pbi);
113 pbi->common.current_video_frame = 0;
114 pbi->ready_for_new_data = 1;
116 pbi->CPUFreq = 0; /*vp8_get_processor_freq();*/
117 #if CONFIG_MULTITHREAD
118 pbi->max_threads = oxcf->max_threads;
119 vp8_decoder_create_threads(pbi);
120 #endif
122 /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
123 * unnecessary calling of vp8cx_init_de_quantizer() for every frame.
125 vp8cx_init_de_quantizer(pbi);
128 VP8_COMMON *cm = &pbi->common;
130 vp8_init_loop_filter(cm);
131 cm->last_frame_type = KEY_FRAME;
132 cm->last_filter_type = cm->filter_type;
133 cm->last_sharpness_level = cm->sharpness_level;
136 #if CONFIG_ARM_ASM_DETOK
137 vp8_init_detokenizer(pbi);
138 #endif
139 pbi->common.error.setjmp = 0;
140 return (VP8D_PTR) pbi;
144 void vp8dx_remove_decompressor(VP8D_PTR ptr)
146 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
148 if (!pbi)
149 return;
151 #if CONFIG_MULTITHREAD
152 if (pbi->b_multithreaded_rd)
153 vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
154 vp8_decoder_remove_threads(pbi);
155 #endif
156 vp8_remove_common(&pbi->common);
157 vpx_free(pbi);
161 void vp8dx_set_setting(VP8D_PTR comp, VP8D_SETTING oxst, int x)
163 VP8D_COMP *pbi = (VP8D_COMP *) comp;
165 (void) pbi;
166 (void) x;
168 switch (oxst)
170 case VP8D_OK:
171 break;
175 int vp8dx_get_setting(VP8D_PTR comp, VP8D_SETTING oxst)
177 VP8D_COMP *pbi = (VP8D_COMP *) comp;
179 (void) pbi;
181 switch (oxst)
183 case VP8D_OK:
184 break;
187 return -1;
190 int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
192 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
193 VP8_COMMON *cm = &pbi->common;
194 int ref_fb_idx;
196 if (ref_frame_flag == VP8_LAST_FLAG)
197 ref_fb_idx = cm->lst_fb_idx;
198 else if (ref_frame_flag == VP8_GOLD_FLAG)
199 ref_fb_idx = cm->gld_fb_idx;
200 else if (ref_frame_flag == VP8_ALT_FLAG)
201 ref_fb_idx = cm->alt_fb_idx;
202 else
203 return -1;
205 vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
207 return 0;
209 int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
211 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
212 VP8_COMMON *cm = &pbi->common;
213 int ref_fb_idx;
215 if (ref_frame_flag == VP8_LAST_FLAG)
216 ref_fb_idx = cm->lst_fb_idx;
217 else if (ref_frame_flag == VP8_GOLD_FLAG)
218 ref_fb_idx = cm->gld_fb_idx;
219 else if (ref_frame_flag == VP8_ALT_FLAG)
220 ref_fb_idx = cm->alt_fb_idx;
221 else
222 return -1;
224 vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[ref_fb_idx]);
226 return 0;
229 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
230 #if HAVE_ARMV7
231 extern void vp8_push_neon(INT64 *store);
232 extern void vp8_pop_neon(INT64 *store);
233 #endif
235 static int get_free_fb (VP8_COMMON *cm)
237 int i;
238 for (i = 0; i < NUM_YV12_BUFFERS; i++)
239 if (cm->fb_idx_ref_cnt[i] == 0)
240 break;
242 cm->fb_idx_ref_cnt[i] = 1;
243 return i;
246 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
248 if (buf[*idx] > 0)
249 buf[*idx]--;
251 *idx = new_idx;
253 buf[new_idx]++;
256 /* If any buffer copy / swapping is signalled it should be done here. */
257 static int swap_frame_buffers (VP8_COMMON *cm)
259 int err = 0;
261 /* The alternate reference frame or golden frame can be updated
262 * using the new, last, or golden/alt ref frame. If it
263 * is updated using the newly decoded frame it is a refresh.
264 * An update using the last or golden/alt ref frame is a copy.
266 if (cm->copy_buffer_to_arf)
268 int new_fb = 0;
270 if (cm->copy_buffer_to_arf == 1)
271 new_fb = cm->lst_fb_idx;
272 else if (cm->copy_buffer_to_arf == 2)
273 new_fb = cm->gld_fb_idx;
274 else
275 err = -1;
277 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
280 if (cm->copy_buffer_to_gf)
282 int new_fb = 0;
284 if (cm->copy_buffer_to_gf == 1)
285 new_fb = cm->lst_fb_idx;
286 else if (cm->copy_buffer_to_gf == 2)
287 new_fb = cm->alt_fb_idx;
288 else
289 err = -1;
291 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
294 if (cm->refresh_golden_frame)
295 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
297 if (cm->refresh_alt_ref_frame)
298 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
300 if (cm->refresh_last_frame)
302 ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
304 cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
306 else
307 cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
309 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
311 return err;
314 int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
316 #if HAVE_ARMV7
317 INT64 dx_store_reg[8];
318 #endif
319 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
320 VP8_COMMON *cm = &pbi->common;
321 int retcode = 0;
322 struct vpx_usec_timer timer;
324 /*if(pbi->ready_for_new_data == 0)
325 return -1;*/
327 if (ptr == 0)
329 return -1;
332 pbi->common.error.error_code = VPX_CODEC_OK;
334 if (size == 0)
336 /* This is used to signal that we are missing frames.
337 * We do not know if the missing frame(s) was supposed to update
338 * any of the reference buffers, but we act conservative and
339 * mark only the last buffer as corrupted.
341 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
343 /* Signal that we have no frame to show. */
344 cm->show_frame = 0;
346 /* Nothing more to do. */
347 return 0;
351 #if HAVE_ARMV7
352 #if CONFIG_RUNTIME_CPU_DETECT
353 if (cm->rtcd.flags & HAS_NEON)
354 #endif
356 vp8_push_neon(dx_store_reg);
358 #endif
360 cm->new_fb_idx = get_free_fb (cm);
362 if (setjmp(pbi->common.error.jmp))
364 #if HAVE_ARMV7
365 #if CONFIG_RUNTIME_CPU_DETECT
366 if (cm->rtcd.flags & HAS_NEON)
367 #endif
369 vp8_pop_neon(dx_store_reg);
371 #endif
372 pbi->common.error.setjmp = 0;
374 /* We do not know if the missing frame(s) was supposed to update
375 * any of the reference buffers, but we act conservative and
376 * mark only the last buffer as corrupted.
378 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
380 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
381 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
382 return -1;
385 pbi->common.error.setjmp = 1;
387 vpx_usec_timer_start(&timer);
389 /*cm->current_video_frame++;*/
390 pbi->Source = source;
391 pbi->source_sz = size;
393 retcode = vp8_decode_frame(pbi);
395 if (retcode < 0)
397 #if HAVE_ARMV7
398 #if CONFIG_RUNTIME_CPU_DETECT
399 if (cm->rtcd.flags & HAS_NEON)
400 #endif
402 vp8_pop_neon(dx_store_reg);
404 #endif
405 pbi->common.error.error_code = VPX_CODEC_ERROR;
406 pbi->common.error.setjmp = 0;
407 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
408 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
409 return retcode;
412 #if CONFIG_MULTITHREAD
413 if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
415 if (swap_frame_buffers (cm))
417 #if HAVE_ARMV7
418 #if CONFIG_RUNTIME_CPU_DETECT
419 if (cm->rtcd.flags & HAS_NEON)
420 #endif
422 vp8_pop_neon(dx_store_reg);
424 #endif
425 pbi->common.error.error_code = VPX_CODEC_ERROR;
426 pbi->common.error.setjmp = 0;
427 return -1;
429 } else
430 #endif
432 if (swap_frame_buffers (cm))
434 #if HAVE_ARMV7
435 #if CONFIG_RUNTIME_CPU_DETECT
436 if (cm->rtcd.flags & HAS_NEON)
437 #endif
439 vp8_pop_neon(dx_store_reg);
441 #endif
442 pbi->common.error.error_code = VPX_CODEC_ERROR;
443 pbi->common.error.setjmp = 0;
444 return -1;
447 if(pbi->common.filter_level)
449 struct vpx_usec_timer lpftimer;
450 vpx_usec_timer_start(&lpftimer);
451 /* Apply the loop filter if appropriate. */
453 vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
455 vpx_usec_timer_mark(&lpftimer);
456 pbi->time_loop_filtering += vpx_usec_timer_elapsed(&lpftimer);
458 cm->last_frame_type = cm->frame_type;
459 cm->last_filter_type = cm->filter_type;
460 cm->last_sharpness_level = cm->sharpness_level;
462 vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
465 #if 0
466 /* DEBUG code */
467 /*vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);*/
468 if (cm->current_video_frame <= 5)
469 write_dx_frame_to_file(cm->frame_to_show, cm->current_video_frame);
470 #endif
472 vp8_clear_system_state();
474 vpx_usec_timer_mark(&timer);
475 pbi->decode_microseconds = vpx_usec_timer_elapsed(&timer);
477 pbi->time_decoding += pbi->decode_microseconds;
479 /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/
481 if (cm->show_frame)
482 cm->current_video_frame++;
484 pbi->ready_for_new_data = 0;
485 pbi->last_time_stamp = time_stamp;
487 #if 0
489 int i;
490 INT64 earliest_time = pbi->dr[0].time_stamp;
491 INT64 latest_time = pbi->dr[0].time_stamp;
492 INT64 time_diff = 0;
493 int bytes = 0;
495 pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
496 pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
498 for (i = 0; i < 16; i++)
501 bytes += pbi->dr[i].size;
503 if (pbi->dr[i].time_stamp < earliest_time)
504 earliest_time = pbi->dr[i].time_stamp;
506 if (pbi->dr[i].time_stamp > latest_time)
507 latest_time = pbi->dr[i].time_stamp;
510 time_diff = latest_time - earliest_time;
512 if (time_diff > 0)
514 pbi->common.bitrate = 80000.00 * bytes / time_diff ;
515 pbi->common.framerate = 160000000.00 / time_diff ;
519 #endif
521 #if HAVE_ARMV7
522 #if CONFIG_RUNTIME_CPU_DETECT
523 if (cm->rtcd.flags & HAS_NEON)
524 #endif
526 vp8_pop_neon(dx_store_reg);
528 #endif
529 pbi->common.error.setjmp = 0;
530 return retcode;
532 int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags)
534 int ret = -1;
535 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
537 if (pbi->ready_for_new_data == 1)
538 return ret;
540 /* ie no raw frame to show!!! */
541 if (pbi->common.show_frame == 0)
542 return ret;
544 pbi->ready_for_new_data = 1;
545 *time_stamp = pbi->last_time_stamp;
546 *time_end_stamp = 0;
548 sd->clrtype = pbi->common.clr_type;
549 #if CONFIG_POSTPROC
550 ret = vp8_post_proc_frame(&pbi->common, sd, flags);
551 #else
553 if (pbi->common.frame_to_show)
555 *sd = *pbi->common.frame_to_show;
556 sd->y_width = pbi->common.Width;
557 sd->y_height = pbi->common.Height;
558 sd->uv_height = pbi->common.Height / 2;
559 ret = 0;
561 else
563 ret = -1;
566 #endif /*!CONFIG_POSTPROC*/
567 vp8_clear_system_state();
568 return ret;