fix sharpness bug and clean up
[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     vp8_loop_filter_init(&pbi->common);
96
97     pbi->common.error.setjmp = 0;
98
99 #if CONFIG_ERROR_CONCEALMENT
100     pbi->ec_enabled = oxcf->error_concealment;
101 #else
102     pbi->ec_enabled = 0;
103 #endif
104
105     pbi->input_partition = oxcf->input_partition;
106
107     return (VP8D_PTR) pbi;
108 }
109
110
111 void vp8dx_remove_decompressor(VP8D_PTR ptr)
112 {
113     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
114
115     if (!pbi)
116         return;
117
118 #if CONFIG_MULTITHREAD
119     if (pbi->b_multithreaded_rd)
120         vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
121     vp8_decoder_remove_threads(pbi);
122 #endif
123 #if CONFIG_ERROR_CONCEALMENT
124     vp8_de_alloc_overlap_lists(pbi);
125 #endif
126     vp8_remove_common(&pbi->common);
127     vpx_free(pbi->mbc);
128     vpx_free(pbi);
129 }
130
131
132 vpx_codec_err_t vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
133 {
134     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
135     VP8_COMMON *cm = &pbi->common;
136     int ref_fb_idx;
137
138     if (ref_frame_flag == VP8_LAST_FLAG)
139         ref_fb_idx = cm->lst_fb_idx;
140     else if (ref_frame_flag == VP8_GOLD_FLAG)
141         ref_fb_idx = cm->gld_fb_idx;
142     else if (ref_frame_flag == VP8_ALT_FLAG)
143         ref_fb_idx = cm->alt_fb_idx;
144     else{
145         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
146             "Invalid reference frame");
147         return pbi->common.error.error_code;
148     }
149
150     if(cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
151         cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
152         cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
153         cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){
154         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
155             "Incorrect buffer dimensions");
156     }
157     else
158         vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
159
160     return pbi->common.error.error_code;
161 }
162
163
164 vpx_codec_err_t vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
165 {
166     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
167     VP8_COMMON *cm = &pbi->common;
168     int *ref_fb_ptr = NULL;
169     int free_fb;
170
171     if (ref_frame_flag == VP8_LAST_FLAG)
172         ref_fb_ptr = &cm->lst_fb_idx;
173     else if (ref_frame_flag == VP8_GOLD_FLAG)
174         ref_fb_ptr = &cm->gld_fb_idx;
175     else if (ref_frame_flag == VP8_ALT_FLAG)
176         ref_fb_ptr = &cm->alt_fb_idx;
177     else{
178         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
179             "Invalid reference frame");
180         return pbi->common.error.error_code;
181     }
182
183     if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
184         cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
185         cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
186         cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){
187         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
188             "Incorrect buffer dimensions");
189     }
190     else{
191         /* Find an empty frame buffer. */
192         free_fb = get_free_fb(cm);
193         /* Decrease fb_idx_ref_cnt since it will be increased again in
194          * ref_cnt_fb() below. */
195         cm->fb_idx_ref_cnt[free_fb]--;
196
197         /* Manage the reference counters and copy image. */
198         ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
199         vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
200     }
201
202    return pbi->common.error.error_code;
203 }
204
205 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
206 #if HAVE_ARMV7
207 extern void vp8_push_neon(INT64 *store);
208 extern void vp8_pop_neon(INT64 *store);
209 #endif
210
211 static int get_free_fb (VP8_COMMON *cm)
212 {
213     int i;
214     for (i = 0; i < NUM_YV12_BUFFERS; i++)
215         if (cm->fb_idx_ref_cnt[i] == 0)
216             break;
217
218     assert(i < NUM_YV12_BUFFERS);
219     cm->fb_idx_ref_cnt[i] = 1;
220     return i;
221 }
222
223 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
224 {
225     if (buf[*idx] > 0)
226         buf[*idx]--;
227
228     *idx = new_idx;
229
230     buf[new_idx]++;
231 }
232
233 /* If any buffer copy / swapping is signalled it should be done here. */
234 static int swap_frame_buffers (VP8_COMMON *cm)
235 {
236     int err = 0;
237
238     /* The alternate reference frame or golden frame can be updated
239      *  using the new, last, or golden/alt ref frame.  If it
240      *  is updated using the newly decoded frame it is a refresh.
241      *  An update using the last or golden/alt ref frame is a copy.
242      */
243     if (cm->copy_buffer_to_arf)
244     {
245         int new_fb = 0;
246
247         if (cm->copy_buffer_to_arf == 1)
248             new_fb = cm->lst_fb_idx;
249         else if (cm->copy_buffer_to_arf == 2)
250             new_fb = cm->gld_fb_idx;
251         else
252             err = -1;
253
254         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
255     }
256
257     if (cm->copy_buffer_to_gf)
258     {
259         int new_fb = 0;
260
261         if (cm->copy_buffer_to_gf == 1)
262             new_fb = cm->lst_fb_idx;
263         else if (cm->copy_buffer_to_gf == 2)
264             new_fb = cm->alt_fb_idx;
265         else
266             err = -1;
267
268         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
269     }
270
271     if (cm->refresh_golden_frame)
272         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
273
274     if (cm->refresh_alt_ref_frame)
275         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
276
277     if (cm->refresh_last_frame)
278     {
279         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
280
281         cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
282     }
283     else
284         cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
285
286     cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
287
288     return err;
289 }
290
291 int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, INT64 time_stamp)
292 {
293 #if HAVE_ARMV7
294     INT64 dx_store_reg[8];
295 #endif
296     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
297     VP8_COMMON *cm = &pbi->common;
298     int retcode = 0;
299
300     /*if(pbi->ready_for_new_data == 0)
301         return -1;*/
302
303     if (ptr == 0)
304     {
305         return -1;
306     }
307
308     pbi->common.error.error_code = VPX_CODEC_OK;
309
310     if (pbi->input_partition && !(source == NULL && size == 0))
311     {
312         /* Store a pointer to this partition and return. We haven't
313          * received the complete frame yet, so we will wait with decoding.
314          */
315         pbi->partitions[pbi->num_partitions] = source;
316         pbi->partition_sizes[pbi->num_partitions] = size;
317         pbi->source_sz += size;
318         pbi->num_partitions++;
319         if (pbi->num_partitions > (1<<pbi->common.multi_token_partition) + 1)
320             pbi->common.multi_token_partition++;
321         if (pbi->common.multi_token_partition > EIGHT_PARTITION)
322         {
323             pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM;
324             pbi->common.error.setjmp = 0;
325             return -1;
326         }
327         return 0;
328     }
329     else
330     {
331         if (!pbi->input_partition)
332         {
333             pbi->Source = source;
334             pbi->source_sz = size;
335         }
336
337         if (pbi->source_sz == 0)
338         {
339            /* This is used to signal that we are missing frames.
340             * We do not know if the missing frame(s) was supposed to update
341             * any of the reference buffers, but we act conservative and
342             * mark only the last buffer as corrupted.
343             */
344             cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
345
346             /* If error concealment is disabled we won't signal missing frames to
347              * the decoder.
348              */
349             if (!pbi->ec_enabled)
350             {
351                 /* Signal that we have no frame to show. */
352                 cm->show_frame = 0;
353
354                 /* Nothing more to do. */
355                 return 0;
356             }
357         }
358
359 #if HAVE_ARMV7
360 #if CONFIG_RUNTIME_CPU_DETECT
361         if (cm->rtcd.flags & HAS_NEON)
362 #endif
363         {
364             vp8_push_neon(dx_store_reg);
365         }
366 #endif
367
368         cm->new_fb_idx = get_free_fb (cm);
369
370         if (setjmp(pbi->common.error.jmp))
371         {
372 #if HAVE_ARMV7
373 #if CONFIG_RUNTIME_CPU_DETECT
374             if (cm->rtcd.flags & HAS_NEON)
375 #endif
376             {
377                 vp8_pop_neon(dx_store_reg);
378             }
379 #endif
380             pbi->common.error.setjmp = 0;
381
382            /* We do not know if the missing frame(s) was supposed to update
383             * any of the reference buffers, but we act conservative and
384             * mark only the last buffer as corrupted.
385             */
386             cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
387
388             if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
389               cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
390             return -1;
391         }
392
393         pbi->common.error.setjmp = 1;
394     }
395
396     retcode = vp8_decode_frame(pbi);
397
398     if (retcode < 0)
399     {
400 #if HAVE_ARMV7
401 #if CONFIG_RUNTIME_CPU_DETECT
402         if (cm->rtcd.flags & HAS_NEON)
403 #endif
404         {
405             vp8_pop_neon(dx_store_reg);
406         }
407 #endif
408         pbi->common.error.error_code = VPX_CODEC_ERROR;
409         pbi->common.error.setjmp = 0;
410         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
411           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
412         return retcode;
413     }
414
415 #if CONFIG_MULTITHREAD
416     if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
417     {
418         if (swap_frame_buffers (cm))
419         {
420 #if HAVE_ARMV7
421 #if CONFIG_RUNTIME_CPU_DETECT
422             if (cm->rtcd.flags & HAS_NEON)
423 #endif
424             {
425                 vp8_pop_neon(dx_store_reg);
426             }
427 #endif
428             pbi->common.error.error_code = VPX_CODEC_ERROR;
429             pbi->common.error.setjmp = 0;
430             return -1;
431         }
432     } else
433 #endif
434     {
435         if (swap_frame_buffers (cm))
436         {
437 #if HAVE_ARMV7
438 #if CONFIG_RUNTIME_CPU_DETECT
439             if (cm->rtcd.flags & HAS_NEON)
440 #endif
441             {
442                 vp8_pop_neon(dx_store_reg);
443             }
444 #endif
445             pbi->common.error.error_code = VPX_CODEC_ERROR;
446             pbi->common.error.setjmp = 0;
447             return -1;
448         }
449
450         if(cm->filter_level)
451         {
452             /* Apply the loop filter if appropriate. */
453             vp8_loop_filter_frame(cm, &pbi->mb);
454         }
455         vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
456     }
457
458
459     vp8_clear_system_state();
460
461 #if CONFIG_ERROR_CONCEALMENT
462     /* swap the mode infos to storage for future error concealment */
463     if (pbi->ec_enabled && pbi->common.prev_mi)
464     {
465         const MODE_INFO* tmp = pbi->common.prev_mi;
466         int row, col;
467         pbi->common.prev_mi = pbi->common.mi;
468         pbi->common.mi = tmp;
469
470         /* Propagate the segment_ids to the next frame */
471         for (row = 0; row < pbi->common.mb_rows; ++row)
472         {
473             for (col = 0; col < pbi->common.mb_cols; ++col)
474             {
475                 const int i = row*pbi->common.mode_info_stride + col;
476                 pbi->common.mi[i].mbmi.segment_id =
477                         pbi->common.prev_mi[i].mbmi.segment_id;
478             }
479         }
480     }
481 #endif
482
483     /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/
484
485     if (cm->show_frame)
486         cm->current_video_frame++;
487
488     pbi->ready_for_new_data = 0;
489     pbi->last_time_stamp = time_stamp;
490     pbi->num_partitions = 0;
491     if (pbi->input_partition)
492         pbi->common.multi_token_partition = 0;
493     pbi->source_sz = 0;
494
495 #if 0
496     {
497         int i;
498         INT64 earliest_time = pbi->dr[0].time_stamp;
499         INT64 latest_time = pbi->dr[0].time_stamp;
500         INT64 time_diff = 0;
501         int bytes = 0;
502
503         pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
504         pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
505
506         for (i = 0; i < 16; i++)
507         {
508
509             bytes += pbi->dr[i].size;
510
511             if (pbi->dr[i].time_stamp < earliest_time)
512                 earliest_time = pbi->dr[i].time_stamp;
513
514             if (pbi->dr[i].time_stamp > latest_time)
515                 latest_time = pbi->dr[i].time_stamp;
516         }
517
518         time_diff = latest_time - earliest_time;
519
520         if (time_diff > 0)
521         {
522             pbi->common.bitrate = 80000.00 * bytes / time_diff  ;
523             pbi->common.framerate = 160000000.00 / time_diff ;
524         }
525
526     }
527 #endif
528
529 #if HAVE_ARMV7
530 #if CONFIG_RUNTIME_CPU_DETECT
531     if (cm->rtcd.flags & HAS_NEON)
532 #endif
533     {
534         vp8_pop_neon(dx_store_reg);
535     }
536 #endif
537     pbi->common.error.setjmp = 0;
538     return retcode;
539 }
540 int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, INT64 *time_stamp, INT64 *time_end_stamp, vp8_ppflags_t *flags)
541 {
542     int ret = -1;
543     VP8D_COMP *pbi = (VP8D_COMP *) ptr;
544
545     if (pbi->ready_for_new_data == 1)
546         return ret;
547
548     /* ie no raw frame to show!!! */
549     if (pbi->common.show_frame == 0)
550         return ret;
551
552     pbi->ready_for_new_data = 1;
553     *time_stamp = pbi->last_time_stamp;
554     *time_end_stamp = 0;
555
556     sd->clrtype = pbi->common.clr_type;
557 #if CONFIG_POSTPROC
558     ret = vp8_post_proc_frame(&pbi->common, sd, flags);
559 #else
560
561     if (pbi->common.frame_to_show)
562     {
563         *sd = *pbi->common.frame_to_show;
564         sd->y_width = pbi->common.Width;
565         sd->y_height = pbi->common.Height;
566         sd->uv_height = pbi->common.Height / 2;
567         ret = 0;
568     }
569     else
570     {
571         ret = -1;
572     }
573
574 #endif /*!CONFIG_POSTPROC*/
575     vp8_clear_system_state();
576     return ret;
577 }