Removing dr[16] from VP8D_COMP
[aom.git] / vp8 / decoder / onyxd_if.c
blobaa3ef81b38168340dccd85182e846427355005af
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 <stdio.h>
25 #include <assert.h>
27 #include "vp8/common/quant_common.h"
28 #include "vpx_scale/vpxscale.h"
29 #include "vp8/common/systemdependent.h"
30 #include "vpx_ports/vpx_timer.h"
31 #include "detokenize.h"
32 #if ARCH_ARM
33 #include "vpx_ports/arm.h"
34 #endif
36 extern void vp8_init_loop_filter(VP8_COMMON *cm);
37 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
38 static int get_free_fb(VP8_COMMON *cm);
39 static void ref_cnt_fb(int *buf, int *idx, int new_idx);
41 #if CONFIG_DEBUG
42 void vp8_recon_write_yuv_frame(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;
47 do {
48 fwrite(src, s->y_width, 1, yuv_file);
49 src += s->y_stride;
50 } while (--h);
52 src = s->u_buffer;
53 h = s->uv_height;
55 do {
56 fwrite(src, s->uv_width, 1, yuv_file);
57 src += s->uv_stride;
58 } while (--h);
60 src = s->v_buffer;
61 h = s->uv_height;
63 do {
64 fwrite(src, s->uv_width, 1, yuv_file);
65 src += s->uv_stride;
66 } while (--h);
68 fclose(yuv_file);
70 #endif
71 #define WRITE_RECON_BUFFER 0
72 #if WRITE_RECON_BUFFER
73 void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) {
75 // write the frame
76 FILE *yframe;
77 int i;
78 char filename[255];
80 sprintf(filename, "dx\\y%04d.raw", this_frame);
81 yframe = fopen(filename, "wb");
83 for (i = 0; i < frame->y_height; i++)
84 fwrite(frame->y_buffer + i * frame->y_stride,
85 frame->y_width, 1, yframe);
87 fclose(yframe);
88 sprintf(filename, "dx\\u%04d.raw", this_frame);
89 yframe = fopen(filename, "wb");
91 for (i = 0; i < frame->uv_height; i++)
92 fwrite(frame->u_buffer + i * frame->uv_stride,
93 frame->uv_width, 1, yframe);
95 fclose(yframe);
96 sprintf(filename, "dx\\v%04d.raw", this_frame);
97 yframe = fopen(filename, "wb");
99 for (i = 0; i < frame->uv_height; i++)
100 fwrite(frame->v_buffer + i * frame->uv_stride,
101 frame->uv_width, 1, yframe);
103 fclose(yframe);
105 #endif
107 void vp8dx_initialize() {
108 static int init_done = 0;
110 if (!init_done) {
111 vp8_initialize_common();
112 vp8_init_quant_tables();
113 vp8_scale_machine_specific_config();
114 init_done = 1;
118 VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf) {
119 VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
121 if (!pbi)
122 return NULL;
124 vpx_memset(pbi, 0, sizeof(VP8D_COMP));
126 if (setjmp(pbi->common.error.jmp)) {
127 pbi->common.error.setjmp = 0;
128 vp8dx_remove_decompressor(pbi);
129 return 0;
132 pbi->common.error.setjmp = 1;
133 vp8dx_initialize();
135 vp8_create_common(&pbi->common);
136 vp8_dmachine_specific_config(pbi);
138 pbi->common.current_video_frame = 0;
139 pbi->ready_for_new_data = 1;
141 /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
142 * unnecessary calling of vp8cx_init_de_quantizer() for every frame.
144 vp8cx_init_de_quantizer(pbi);
146 vp8_loop_filter_init(&pbi->common);
148 pbi->common.error.setjmp = 0;
150 pbi->decoded_key_frame = 0;
152 pbi->interleaved_decoding = CONFIG_NEWBESTREFMV || CONFIG_SUPERBLOCKS;
154 return (VP8D_PTR) pbi;
157 void vp8dx_remove_decompressor(VP8D_PTR ptr) {
158 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
160 if (!pbi)
161 return;
163 // Delete sementation map
164 if (pbi->common.last_frame_seg_map != 0)
165 vpx_free(pbi->common.last_frame_seg_map);
167 vp8_remove_common(&pbi->common);
168 vpx_free(pbi->mbc);
169 vpx_free(pbi);
173 vpx_codec_err_t vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) {
174 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
175 VP8_COMMON *cm = &pbi->common;
176 int ref_fb_idx;
178 if (ref_frame_flag == VP8_LAST_FLAG)
179 ref_fb_idx = cm->lst_fb_idx;
180 else if (ref_frame_flag == VP8_GOLD_FLAG)
181 ref_fb_idx = cm->gld_fb_idx;
182 else if (ref_frame_flag == VP8_ALT_FLAG)
183 ref_fb_idx = cm->alt_fb_idx;
184 else {
185 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
186 "Invalid reference frame");
187 return pbi->common.error.error_code;
190 if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
191 cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
192 cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
193 cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) {
194 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
195 "Incorrect buffer dimensions");
196 } else
197 vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
199 return pbi->common.error.error_code;
203 vpx_codec_err_t vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd) {
204 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
205 VP8_COMMON *cm = &pbi->common;
206 int *ref_fb_ptr = NULL;
207 int free_fb;
209 if (ref_frame_flag == VP8_LAST_FLAG)
210 ref_fb_ptr = &cm->lst_fb_idx;
211 else if (ref_frame_flag == VP8_GOLD_FLAG)
212 ref_fb_ptr = &cm->gld_fb_idx;
213 else if (ref_frame_flag == VP8_ALT_FLAG)
214 ref_fb_ptr = &cm->alt_fb_idx;
215 else {
216 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
217 "Invalid reference frame");
218 return pbi->common.error.error_code;
221 if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
222 cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
223 cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
224 cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) {
225 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
226 "Incorrect buffer dimensions");
227 } else {
228 /* Find an empty frame buffer. */
229 free_fb = get_free_fb(cm);
230 /* Decrease fb_idx_ref_cnt since it will be increased again in
231 * ref_cnt_fb() below. */
232 cm->fb_idx_ref_cnt[free_fb]--;
234 /* Manage the reference counters and copy image. */
235 ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
236 vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
239 return pbi->common.error.error_code;
242 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
243 #if HAVE_ARMV7
244 extern void vp8_push_neon(int64_t *store);
245 extern void vp8_pop_neon(int64_t *store);
246 #endif
248 static int get_free_fb(VP8_COMMON *cm) {
249 int i;
250 for (i = 0; i < NUM_YV12_BUFFERS; i++)
251 if (cm->fb_idx_ref_cnt[i] == 0)
252 break;
254 assert(i < NUM_YV12_BUFFERS);
255 cm->fb_idx_ref_cnt[i] = 1;
256 return i;
259 static void ref_cnt_fb(int *buf, int *idx, int new_idx) {
260 if (buf[*idx] > 0)
261 buf[*idx]--;
263 *idx = new_idx;
265 buf[new_idx]++;
268 /* If any buffer copy / swapping is signalled it should be done here. */
269 static int swap_frame_buffers(VP8_COMMON *cm) {
270 int err = 0;
272 /* The alternate reference frame or golden frame can be updated
273 * using the new, last, or golden/alt ref frame. If it
274 * is updated using the newly decoded frame it is a refresh.
275 * An update using the last or golden/alt ref frame is a copy.
277 if (cm->copy_buffer_to_arf) {
278 int new_fb = 0;
280 if (cm->copy_buffer_to_arf == 1)
281 new_fb = cm->lst_fb_idx;
282 else if (cm->copy_buffer_to_arf == 2)
283 new_fb = cm->gld_fb_idx;
284 else
285 err = -1;
287 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
290 if (cm->copy_buffer_to_gf) {
291 int new_fb = 0;
293 if (cm->copy_buffer_to_gf == 1)
294 new_fb = cm->lst_fb_idx;
295 else if (cm->copy_buffer_to_gf == 2)
296 new_fb = cm->alt_fb_idx;
297 else
298 err = -1;
300 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
303 if (cm->refresh_golden_frame)
304 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
306 if (cm->refresh_alt_ref_frame)
307 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
309 if (cm->refresh_last_frame) {
310 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
312 cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
313 } else
314 cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
316 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
318 return err;
322 static void vp8_print_yuv_rec_mb(VP8_COMMON *cm, int mb_row, int mb_col)
324 YV12_BUFFER_CONFIG *s = cm->frame_to_show;
325 unsigned char *src = s->y_buffer;
326 int i, j;
328 printf("After loop filter\n");
329 for (i=0;i<16;i++) {
330 for (j=0;j<16;j++)
331 printf("%3d ", src[(mb_row*16+i)*s->y_stride + mb_col*16+j]);
332 printf("\n");
337 int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, int64_t time_stamp) {
338 #if HAVE_ARMV7
339 int64_t dx_store_reg[8];
340 #endif
341 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
342 VP8_COMMON *cm = &pbi->common;
343 int retcode = 0;
345 /*if(pbi->ready_for_new_data == 0)
346 return -1;*/
348 if (ptr == 0) {
349 return -1;
352 pbi->common.error.error_code = VPX_CODEC_OK;
354 pbi->Source = source;
355 pbi->source_sz = size;
357 if (pbi->source_sz == 0) {
358 /* This is used to signal that we are missing frames.
359 * We do not know if the missing frame(s) was supposed to update
360 * any of the reference buffers, but we act conservative and
361 * mark only the last buffer as corrupted.
363 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
366 #if HAVE_ARMV7
367 #if CONFIG_RUNTIME_CPU_DETECT
368 if (cm->rtcd.flags & HAS_NEON)
369 #endif
371 vp8_push_neon(dx_store_reg);
373 #endif
375 cm->new_fb_idx = get_free_fb(cm);
377 if (setjmp(pbi->common.error.jmp)) {
378 #if HAVE_ARMV7
379 #if CONFIG_RUNTIME_CPU_DETECT
380 if (cm->rtcd.flags & HAS_NEON)
381 #endif
383 vp8_pop_neon(dx_store_reg);
385 #endif
386 pbi->common.error.setjmp = 0;
388 /* We do not know if the missing frame(s) was supposed to update
389 * any of the reference buffers, but we act conservative and
390 * mark only the last buffer as corrupted.
392 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
394 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
395 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
396 return -1;
399 pbi->common.error.setjmp = 1;
401 retcode = vp8_decode_frame(pbi);
403 if (retcode < 0) {
404 #if HAVE_ARMV7
405 #if CONFIG_RUNTIME_CPU_DETECT
406 if (cm->rtcd.flags & HAS_NEON)
407 #endif
409 vp8_pop_neon(dx_store_reg);
411 #endif
412 pbi->common.error.error_code = VPX_CODEC_ERROR;
413 pbi->common.error.setjmp = 0;
414 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
415 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
416 return retcode;
420 if (swap_frame_buffers(cm)) {
421 #if HAVE_ARMV7
422 #if CONFIG_RUNTIME_CPU_DETECT
423 if (cm->rtcd.flags & HAS_NEON)
424 #endif
426 vp8_pop_neon(dx_store_reg);
428 #endif
429 pbi->common.error.error_code = VPX_CODEC_ERROR;
430 pbi->common.error.setjmp = 0;
431 return -1;
434 #if WRITE_RECON_BUFFER
435 if (cm->show_frame)
436 write_dx_frame_to_file(cm->frame_to_show,
437 cm->current_video_frame);
438 else
439 write_dx_frame_to_file(cm->frame_to_show,
440 cm->current_video_frame + 1000);
441 #endif
443 if (cm->filter_level) {
444 /* Apply the loop filter if appropriate. */
445 vp8_loop_filter_frame(cm, &pbi->mb);
447 vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
450 #if CONFIG_DEBUG
451 if (cm->show_frame)
452 vp8_recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
453 #endif
455 vp8_clear_system_state();
457 if (cm->show_frame) {
458 vpx_memcpy(cm->prev_mip, cm->mip,
459 (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
460 } else {
461 vpx_memset(cm->prev_mip, 0,
462 (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
465 /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/
467 if (cm->show_frame)
468 cm->current_video_frame++;
470 pbi->ready_for_new_data = 0;
471 pbi->last_time_stamp = time_stamp;
472 pbi->source_sz = 0;
474 #if HAVE_ARMV7
475 #if CONFIG_RUNTIME_CPU_DETECT
476 if (cm->rtcd.flags & HAS_NEON)
477 #endif
479 vp8_pop_neon(dx_store_reg);
481 #endif
482 pbi->common.error.setjmp = 0;
483 return retcode;
485 int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags) {
486 int ret = -1;
487 VP8D_COMP *pbi = (VP8D_COMP *) ptr;
489 if (pbi->ready_for_new_data == 1)
490 return ret;
492 /* ie no raw frame to show!!! */
493 if (pbi->common.show_frame == 0)
494 return ret;
496 pbi->ready_for_new_data = 1;
497 *time_stamp = pbi->last_time_stamp;
498 *time_end_stamp = 0;
500 sd->clrtype = pbi->common.clr_type;
501 #if CONFIG_POSTPROC
502 ret = vp8_post_proc_frame(&pbi->common, sd, flags);
503 #else
505 if (pbi->common.frame_to_show) {
506 *sd = *pbi->common.frame_to_show;
507 sd->y_width = pbi->common.Width;
508 sd->y_height = pbi->common.Height;
509 sd->uv_height = pbi->common.Height / 2;
510 ret = 0;
511 } else {
512 ret = -1;
515 #endif /*!CONFIG_POSTPROC*/
516 vp8_clear_system_state();
517 return ret;