Merge "Reduce overshoot in 1 pass rate control"
[profile/ivi/libvpx.git] / vp8 / decoder / onyxd_if.c
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 #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>
27 #include <assert.h>
28
29 #include "vp8/common/quant_common.h"
30 #include "vpx_scale/vpxscale.h"
31 #include "vp8/common/systemdependent.h"
32 #include "vpx_ports/vpx_timer.h"
33 #include "detokenize.h"
34 #if CONFIG_ERROR_CONCEALMENT
35 #include "error_concealment.h"
36 #endif
37 #if ARCH_ARM
38 #include "vpx_ports/arm.h"
39 #endif
40
41 extern void vp8_init_loop_filter(VP8_COMMON *cm);
42 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
43 static int get_free_fb (VP8_COMMON *cm);
44 static void ref_cnt_fb (int *buf, int *idx, int new_idx);
45
46
47 void vp8dx_initialize()
48 {
49     static int init_done = 0;
50
51     if (!init_done)
52     {
53         vp8_initialize_common();
54         vp8_scale_machine_specific_config();
55         init_done = 1;
56     }
57 }
58
59
60 VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
61 {
62     VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
63
64     if (!pbi)
65         return NULL;
66
67     vpx_memset(pbi, 0, sizeof(VP8D_COMP));
68
69     if (setjmp(pbi->common.error.jmp))
70     {
71         pbi->common.error.setjmp = 0;
72         vp8dx_remove_decompressor(pbi);
73         return 0;
74     }
75
76     pbi->common.error.setjmp = 1;
77     vp8dx_initialize();
78
79     vp8_create_common(&pbi->common);
80     vp8_dmachine_specific_config(pbi);
81
82     pbi->common.current_video_frame = 0;
83     pbi->ready_for_new_data = 1;
84
85 #if CONFIG_MULTITHREAD
86     pbi->max_threads = oxcf->max_threads;
87     vp8_decoder_create_threads(pbi);
88 #endif
89
90     /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
91      *  unnecessary calling of vp8cx_init_de_quantizer() for every frame.
92      */
93     vp8cx_init_de_quantizer(pbi);
94
95     {
96         VP8_COMMON *cm = &pbi->common;
97
98         vp8_init_loop_filter(cm);
99         cm->last_frame_type = KEY_FRAME;
100         cm->last_filter_type = cm->filter_type;
101         cm->last_sharpness_level = cm->sharpness_level;
102     }
103
104     pbi->common.error.setjmp = 0;
105
106 #if CONFIG_ERROR_CONCEALMENT
107     pbi->ec_enabled = oxcf->error_concealment;
108 #else
109     pbi->ec_enabled = 0;
110 #endif
111
112     return (VP8D_PTR) pbi;
113 }
114
115
116 void vp8dx_remove_decompressor(VP8D_PTR ptr)
117 {
118     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
119
120     if (!pbi)
121         return;
122
123 #if CONFIG_MULTITHREAD
124     if (pbi->b_multithreaded_rd)
125         vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
126     vp8_decoder_remove_threads(pbi);
127 #endif
128 #if CONFIG_ERROR_CONCEALMENT
129     vp8_de_alloc_overlap_lists(pbi);
130 #endif
131     vp8_remove_common(&pbi->common);
132     vpx_free(pbi);
133 }
134
135
136 int vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
137 {
138     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
139     VP8_COMMON *cm = &pbi->common;
140     int ref_fb_idx;
141
142     if (ref_frame_flag == VP8_LAST_FLAG)
143         ref_fb_idx = cm->lst_fb_idx;
144     else if (ref_frame_flag == VP8_GOLD_FLAG)
145         ref_fb_idx = cm->gld_fb_idx;
146     else if (ref_frame_flag == VP8_ALT_FLAG)
147         ref_fb_idx = cm->alt_fb_idx;
148     else
149         return -1;
150
151     vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
152
153     return 0;
154 }
155
156
157 int vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
158 {
159     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
160     VP8_COMMON *cm = &pbi->common;
161     int *ref_fb_ptr = NULL;
162     int free_fb;
163
164     if (ref_frame_flag == VP8_LAST_FLAG)
165         ref_fb_ptr = &cm->lst_fb_idx;
166     else if (ref_frame_flag == VP8_GOLD_FLAG)
167         ref_fb_ptr = &cm->gld_fb_idx;
168     else if (ref_frame_flag == VP8_ALT_FLAG)
169         ref_fb_ptr = &cm->alt_fb_idx;
170     else
171         return -1;
172
173     /* Find an empty frame buffer. */
174     free_fb = get_free_fb(cm);
175     /* Decrease fb_idx_ref_cnt since it will be increased again in
176      * ref_cnt_fb() below. */
177     cm->fb_idx_ref_cnt[free_fb]--;
178
179     /* Manage the reference counters and copy image. */
180     ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
181     vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
182
183     return 0;
184 }
185
186 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
187 #if HAVE_ARMV7
188 extern void vp8_push_neon(INT64 *store);
189 extern void vp8_pop_neon(INT64 *store);
190 #endif
191
192 static int get_free_fb (VP8_COMMON *cm)
193 {
194     int i;
195     for (i = 0; i < NUM_YV12_BUFFERS; i++)
196         if (cm->fb_idx_ref_cnt[i] == 0)
197             break;
198
199     assert(i < NUM_YV12_BUFFERS);
200     cm->fb_idx_ref_cnt[i] = 1;
201     return i;
202 }
203
204 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
205 {
206     if (buf[*idx] > 0)
207         buf[*idx]--;
208
209     *idx = new_idx;
210
211     buf[new_idx]++;
212 }
213
214 /* If any buffer copy / swapping is signalled it should be done here. */
215 static int swap_frame_buffers (VP8_COMMON *cm)
216 {
217     int err = 0;
218
219     /* The alternate reference frame or golden frame can be updated
220      *  using the new, last, or golden/alt ref frame.  If it
221      *  is updated using the newly decoded frame it is a refresh.
222      *  An update using the last or golden/alt ref frame is a copy.
223      */
224     if (cm->copy_buffer_to_arf)
225     {
226         int new_fb = 0;
227
228         if (cm->copy_buffer_to_arf == 1)
229             new_fb = cm->lst_fb_idx;
230         else if (cm->copy_buffer_to_arf == 2)
231             new_fb = cm->gld_fb_idx;
232         else
233             err = -1;
234
235         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
236     }
237
238     if (cm->copy_buffer_to_gf)
239     {
240         int new_fb = 0;
241
242         if (cm->copy_buffer_to_gf == 1)
243             new_fb = cm->lst_fb_idx;
244         else if (cm->copy_buffer_to_gf == 2)
245             new_fb = cm->alt_fb_idx;
246         else
247             err = -1;
248
249         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
250     }
251
252     if (cm->refresh_golden_frame)
253         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
254
255     if (cm->refresh_alt_ref_frame)
256         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
257
258     if (cm->refresh_last_frame)
259     {
260         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
261
262         cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
263     }
264     else
265         cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
266
267     cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
268
269     return err;
270 }
271
272 int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
273 {
274 #if HAVE_ARMV7
275     INT64 dx_store_reg[8];
276 #endif
277     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
278     VP8_COMMON *cm = &pbi->common;
279     int retcode = 0;
280
281     /*if(pbi->ready_for_new_data == 0)
282         return -1;*/
283
284     if (ptr == 0)
285     {
286         return -1;
287     }
288
289     pbi->common.error.error_code = VPX_CODEC_OK;
290
291     if (size == 0)
292     {
293        /* This is used to signal that we are missing frames.
294         * We do not know if the missing frame(s) was supposed to update
295         * any of the reference buffers, but we act conservative and
296         * mark only the last buffer as corrupted.
297         */
298         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
299
300         /* If error concealment is disabled we won't signal missing frames to
301          * the decoder.
302          */
303         if (!pbi->ec_enabled)
304         {
305             /* Signal that we have no frame to show. */
306             cm->show_frame = 0;
307
308             /* Nothing more to do. */
309             return 0;
310         }
311     }
312
313
314 #if HAVE_ARMV7
315 #if CONFIG_RUNTIME_CPU_DETECT
316     if (cm->rtcd.flags & HAS_NEON)
317 #endif
318     {
319         vp8_push_neon(dx_store_reg);
320     }
321 #endif
322
323     cm->new_fb_idx = get_free_fb (cm);
324
325     if (setjmp(pbi->common.error.jmp))
326     {
327 #if HAVE_ARMV7
328 #if CONFIG_RUNTIME_CPU_DETECT
329         if (cm->rtcd.flags & HAS_NEON)
330 #endif
331         {
332             vp8_pop_neon(dx_store_reg);
333         }
334 #endif
335         pbi->common.error.setjmp = 0;
336
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.
340         */
341         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
342
343         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
344           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
345         return -1;
346     }
347
348     pbi->common.error.setjmp = 1;
349
350     /*cm->current_video_frame++;*/
351     pbi->Source = source;
352     pbi->source_sz = size;
353
354     retcode = vp8_decode_frame(pbi);
355
356     if (retcode < 0)
357     {
358 #if HAVE_ARMV7
359 #if CONFIG_RUNTIME_CPU_DETECT
360         if (cm->rtcd.flags & HAS_NEON)
361 #endif
362         {
363             vp8_pop_neon(dx_store_reg);
364         }
365 #endif
366         pbi->common.error.error_code = VPX_CODEC_ERROR;
367         pbi->common.error.setjmp = 0;
368         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
369           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
370         return retcode;
371     }
372
373 #if CONFIG_MULTITHREAD
374     if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
375     {
376         if (swap_frame_buffers (cm))
377         {
378 #if HAVE_ARMV7
379 #if CONFIG_RUNTIME_CPU_DETECT
380             if (cm->rtcd.flags & HAS_NEON)
381 #endif
382             {
383                 vp8_pop_neon(dx_store_reg);
384             }
385 #endif
386             pbi->common.error.error_code = VPX_CODEC_ERROR;
387             pbi->common.error.setjmp = 0;
388             return -1;
389         }
390     } else
391 #endif
392     {
393         if (swap_frame_buffers (cm))
394         {
395 #if HAVE_ARMV7
396 #if CONFIG_RUNTIME_CPU_DETECT
397             if (cm->rtcd.flags & HAS_NEON)
398 #endif
399             {
400                 vp8_pop_neon(dx_store_reg);
401             }
402 #endif
403             pbi->common.error.error_code = VPX_CODEC_ERROR;
404             pbi->common.error.setjmp = 0;
405             return -1;
406         }
407
408         if(pbi->common.filter_level)
409         {
410             /* Apply the loop filter if appropriate. */
411             vp8_loop_filter_frame(cm, &pbi->mb, cm->filter_level);
412
413             cm->last_frame_type = cm->frame_type;
414             cm->last_filter_type = cm->filter_type;
415             cm->last_sharpness_level = cm->sharpness_level;
416         }
417         vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
418     }
419
420
421     vp8_clear_system_state();
422
423 #if CONFIG_ERROR_CONCEALMENT
424     /* swap the mode infos to storage for future error concealment */
425     if (pbi->ec_enabled && pbi->common.prev_mi)
426     {
427         const MODE_INFO* tmp = pbi->common.prev_mi;
428         int row, col;
429         pbi->common.prev_mi = pbi->common.mi;
430         pbi->common.mi = tmp;
431
432         /* Propagate the segment_ids to the next frame */
433         for (row = 0; row < pbi->common.mb_rows; ++row)
434         {
435             for (col = 0; col < pbi->common.mb_cols; ++col)
436             {
437                 const int i = row*pbi->common.mode_info_stride + col;
438                 pbi->common.mi[i].mbmi.segment_id =
439                         pbi->common.prev_mi[i].mbmi.segment_id;
440             }
441         }
442     }
443 #endif
444
445     /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/
446
447     if (cm->show_frame)
448         cm->current_video_frame++;
449
450     pbi->ready_for_new_data = 0;
451     pbi->last_time_stamp = time_stamp;
452
453 #if 0
454     {
455         int i;
456         INT64 earliest_time = pbi->dr[0].time_stamp;
457         INT64 latest_time = pbi->dr[0].time_stamp;
458         INT64 time_diff = 0;
459         int bytes = 0;
460
461         pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
462         pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
463
464         for (i = 0; i < 16; i++)
465         {
466
467             bytes += pbi->dr[i].size;
468
469             if (pbi->dr[i].time_stamp < earliest_time)
470                 earliest_time = pbi->dr[i].time_stamp;
471
472             if (pbi->dr[i].time_stamp > latest_time)
473                 latest_time = pbi->dr[i].time_stamp;
474         }
475
476         time_diff = latest_time - earliest_time;
477
478         if (time_diff > 0)
479         {
480             pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
481             pbi->common.framerate = 160000000.00 / time_diff ;
482         }
483
484     }
485 #endif
486
487 #if HAVE_ARMV7
488 #if CONFIG_RUNTIME_CPU_DETECT
489     if (cm->rtcd.flags & HAS_NEON)
490 #endif
491     {
492         vp8_pop_neon(dx_store_reg);
493     }
494 #endif
495     pbi->common.error.setjmp = 0;
496     return retcode;
497 }
498 int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags)
499 {
500     int ret = -1;
501     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
502
503     if (pbi->ready_for_new_data == 1)
504         return ret;
505
506     /* ie no raw frame to show!!! */
507     if (pbi->common.show_frame == 0)
508         return ret;
509
510     pbi->ready_for_new_data = 1;
511     *time_stamp = pbi->last_time_stamp;
512     *time_end_stamp = 0;
513
514     sd->clrtype = pbi->common.clr_type;
515 #if CONFIG_POSTPROC
516     ret = vp8_post_proc_frame(&pbi->common, sd, flags);
517 #else
518
519     if (pbi->common.frame_to_show)
520     {
521         *sd = *pbi->common.frame_to_show;
522         sd->y_width = pbi->common.Width;
523         sd->y_height = pbi->common.Height;
524         sd->uv_height = pbi->common.Height / 2;
525         ret = 0;
526     }
527     else
528     {
529         ret = -1;
530     }
531
532 #endif /*!CONFIG_POSTPROC*/
533     vp8_clear_system_state();
534     return ret;
535 }