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 "vp8/common/loopfilter.h"
21 #include "vp8/common/swapyv12buffer.h"
22 #include "vp8/common/threading.h"
23 #include "decoderthreading.h"
24 #include <stdio.h>
25 #include <assert.h>
26 
27 #include "vp8/common/quant_common.h"
28 #include "./vpx_scale_rtcd.h"
29 #include "vpx_scale/vpx_scale.h"
30 #include "vp8/common/systemdependent.h"
31 #include "vpx_ports/vpx_timer.h"
32 #include "detokenize.h"
33 #if CONFIG_ERROR_CONCEALMENT
34 #include "error_concealment.h"
35 #endif
36 #if ARCH_ARM
37 #include "vpx_ports/arm.h"
38 #endif
39 
40 extern void vp8_init_loop_filter(VP8_COMMON *cm);
41 extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
42 static int get_free_fb (VP8_COMMON *cm);
43 static void ref_cnt_fb (int *buf, int *idx, int new_idx);
44 
remove_decompressor(VP8D_COMP * pbi)45 static void remove_decompressor(VP8D_COMP *pbi)
46 {
47 #if CONFIG_ERROR_CONCEALMENT
48     vp8_de_alloc_overlap_lists(pbi);
49 #endif
50     vp8_remove_common(&pbi->common);
51     vpx_free(pbi);
52 }
53 
create_decompressor(VP8D_CONFIG * oxcf)54 static struct VP8D_COMP * create_decompressor(VP8D_CONFIG *oxcf)
55 {
56     VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
57     (void)oxcf;
58     if (!pbi)
59         return NULL;
60 
61     vpx_memset(pbi, 0, sizeof(VP8D_COMP));
62 
63     if (setjmp(pbi->common.error.jmp))
64     {
65         pbi->common.error.setjmp = 0;
66         remove_decompressor(pbi);
67         return 0;
68     }
69 
70     pbi->common.error.setjmp = 1;
71 
72     vp8_create_common(&pbi->common);
73 
74     pbi->common.current_video_frame = 0;
75     pbi->ready_for_new_data = 1;
76 
77     /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
78      *  unnecessary calling of vp8cx_init_de_quantizer() for every frame.
79      */
80     vp8cx_init_de_quantizer(pbi);
81 
82     vp8_loop_filter_init(&pbi->common);
83 
84     pbi->common.error.setjmp = 0;
85 
86 #if CONFIG_ERROR_CONCEALMENT
87     pbi->ec_enabled = oxcf->error_concealment;
88     pbi->overlaps = NULL;
89 #else
90     pbi->ec_enabled = 0;
91 #endif
92     /* Error concealment is activated after a key frame has been
93      * decoded without errors when error concealment is enabled.
94      */
95     pbi->ec_active = 0;
96 
97     pbi->decoded_key_frame = 0;
98 
99     /* Independent partitions is activated when a frame updates the
100      * token probability table to have equal probabilities over the
101      * PREV_COEF context.
102      */
103     pbi->independent_partitions = 0;
104 
105     vp8_setup_block_dptrs(&pbi->mb);
106 
107     return pbi;
108 }
109 
vp8dx_get_reference(VP8D_COMP * pbi,enum vpx_ref_frame_type ref_frame_flag,YV12_BUFFER_CONFIG * sd)110 vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
111 {
112     VP8_COMMON *cm = &pbi->common;
113     int ref_fb_idx;
114 
115     if (ref_frame_flag == VP8_LAST_FRAME)
116         ref_fb_idx = cm->lst_fb_idx;
117     else if (ref_frame_flag == VP8_GOLD_FRAME)
118         ref_fb_idx = cm->gld_fb_idx;
119     else if (ref_frame_flag == VP8_ALTR_FRAME)
120         ref_fb_idx = cm->alt_fb_idx;
121     else{
122         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
123             "Invalid reference frame");
124         return pbi->common.error.error_code;
125     }
126 
127     if(cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
128         cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
129         cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
130         cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){
131         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
132             "Incorrect buffer dimensions");
133     }
134     else
135         vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
136 
137     return pbi->common.error.error_code;
138 }
139 
140 
vp8dx_set_reference(VP8D_COMP * pbi,enum vpx_ref_frame_type ref_frame_flag,YV12_BUFFER_CONFIG * sd)141 vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi, enum vpx_ref_frame_type ref_frame_flag, YV12_BUFFER_CONFIG *sd)
142 {
143     VP8_COMMON *cm = &pbi->common;
144     int *ref_fb_ptr = NULL;
145     int free_fb;
146 
147     if (ref_frame_flag == VP8_LAST_FRAME)
148         ref_fb_ptr = &cm->lst_fb_idx;
149     else if (ref_frame_flag == VP8_GOLD_FRAME)
150         ref_fb_ptr = &cm->gld_fb_idx;
151     else if (ref_frame_flag == VP8_ALTR_FRAME)
152         ref_fb_ptr = &cm->alt_fb_idx;
153     else{
154         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
155             "Invalid reference frame");
156         return pbi->common.error.error_code;
157     }
158 
159     if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
160         cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
161         cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
162         cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){
163         vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
164             "Incorrect buffer dimensions");
165     }
166     else{
167         /* Find an empty frame buffer. */
168         free_fb = get_free_fb(cm);
169         /* Decrease fb_idx_ref_cnt since it will be increased again in
170          * ref_cnt_fb() below. */
171         cm->fb_idx_ref_cnt[free_fb]--;
172 
173         /* Manage the reference counters and copy image. */
174         ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
175         vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
176     }
177 
178    return pbi->common.error.error_code;
179 }
180 
181 /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
182 #if HAVE_NEON
183 extern void vp8_push_neon(int64_t *store);
184 extern void vp8_pop_neon(int64_t *store);
185 #endif
186 
get_free_fb(VP8_COMMON * cm)187 static int get_free_fb (VP8_COMMON *cm)
188 {
189     int i;
190     for (i = 0; i < NUM_YV12_BUFFERS; i++)
191         if (cm->fb_idx_ref_cnt[i] == 0)
192             break;
193 
194     assert(i < NUM_YV12_BUFFERS);
195     cm->fb_idx_ref_cnt[i] = 1;
196     return i;
197 }
198 
ref_cnt_fb(int * buf,int * idx,int new_idx)199 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
200 {
201     if (buf[*idx] > 0)
202         buf[*idx]--;
203 
204     *idx = new_idx;
205 
206     buf[new_idx]++;
207 }
208 
209 /* If any buffer copy / swapping is signalled it should be done here. */
swap_frame_buffers(VP8_COMMON * cm)210 static int swap_frame_buffers (VP8_COMMON *cm)
211 {
212     int err = 0;
213 
214     /* The alternate reference frame or golden frame can be updated
215      *  using the new, last, or golden/alt ref frame.  If it
216      *  is updated using the newly decoded frame it is a refresh.
217      *  An update using the last or golden/alt ref frame is a copy.
218      */
219     if (cm->copy_buffer_to_arf)
220     {
221         int new_fb = 0;
222 
223         if (cm->copy_buffer_to_arf == 1)
224             new_fb = cm->lst_fb_idx;
225         else if (cm->copy_buffer_to_arf == 2)
226             new_fb = cm->gld_fb_idx;
227         else
228             err = -1;
229 
230         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
231     }
232 
233     if (cm->copy_buffer_to_gf)
234     {
235         int new_fb = 0;
236 
237         if (cm->copy_buffer_to_gf == 1)
238             new_fb = cm->lst_fb_idx;
239         else if (cm->copy_buffer_to_gf == 2)
240             new_fb = cm->alt_fb_idx;
241         else
242             err = -1;
243 
244         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
245     }
246 
247     if (cm->refresh_golden_frame)
248         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
249 
250     if (cm->refresh_alt_ref_frame)
251         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
252 
253     if (cm->refresh_last_frame)
254     {
255         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
256 
257         cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
258     }
259     else
260         cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
261 
262     cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
263 
264     return err;
265 }
266 
check_fragments_for_errors(VP8D_COMP * pbi)267 int check_fragments_for_errors(VP8D_COMP *pbi)
268 {
269     if (!pbi->ec_active &&
270         pbi->fragments.count <= 1 && pbi->fragments.sizes[0] == 0)
271     {
272         VP8_COMMON *cm = &pbi->common;
273 
274         /* If error concealment is disabled we won't signal missing frames
275          * to the decoder.
276          */
277         if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1)
278         {
279             /* The last reference shares buffer with another reference
280              * buffer. Move it to its own buffer before setting it as
281              * corrupt, otherwise we will make multiple buffers corrupt.
282              */
283             const int prev_idx = cm->lst_fb_idx;
284             cm->fb_idx_ref_cnt[prev_idx]--;
285             cm->lst_fb_idx = get_free_fb(cm);
286             vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx],
287                                     &cm->yv12_fb[cm->lst_fb_idx]);
288         }
289         /* This is used to signal that we are missing frames.
290          * We do not know if the missing frame(s) was supposed to update
291          * any of the reference buffers, but we act conservative and
292          * mark only the last buffer as corrupted.
293          */
294         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
295 
296         /* Signal that we have no frame to show. */
297         cm->show_frame = 0;
298 
299         /* Nothing more to do. */
300         return 0;
301     }
302 
303     return 1;
304 }
305 
vp8dx_receive_compressed_data(VP8D_COMP * pbi,size_t size,const uint8_t * source,int64_t time_stamp)306 int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
307                                   const uint8_t *source,
308                                   int64_t time_stamp)
309 {
310 #if HAVE_NEON
311     int64_t dx_store_reg[8];
312 #endif
313     VP8_COMMON *cm = &pbi->common;
314     volatile int retcode;
315 
316     (void) size;
317     (void) source;
318     pbi->common.error.error_code = VPX_CODEC_OK;
319 
320     retcode = check_fragments_for_errors(pbi);
321     if(retcode <= 0)
322         return retcode;
323 
324 #if HAVE_NEON
325 #if CONFIG_RUNTIME_CPU_DETECT
326     if (cm->cpu_caps & HAS_NEON)
327 #endif
328     {
329         vp8_push_neon(dx_store_reg);
330     }
331 #endif
332 
333     cm->new_fb_idx = get_free_fb (cm);
334 
335     /* setup reference frames for vp8_decode_frame */
336     pbi->dec_fb_ref[INTRA_FRAME]  = &cm->yv12_fb[cm->new_fb_idx];
337     pbi->dec_fb_ref[LAST_FRAME]   = &cm->yv12_fb[cm->lst_fb_idx];
338     pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
339     pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];
340 
341     if (setjmp(pbi->common.error.jmp))
342     {
343        /* We do not know if the missing frame(s) was supposed to update
344         * any of the reference buffers, but we act conservative and
345         * mark only the last buffer as corrupted.
346         */
347         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
348 
349         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
350           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
351 
352         goto decode_exit;
353     }
354 
355     pbi->common.error.setjmp = 1;
356 
357     retcode = vp8_decode_frame(pbi);
358 
359     if (retcode < 0)
360     {
361         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
362           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
363 
364         pbi->common.error.error_code = VPX_CODEC_ERROR;
365         goto decode_exit;
366     }
367 
368     if (swap_frame_buffers (cm))
369     {
370         pbi->common.error.error_code = VPX_CODEC_ERROR;
371         goto decode_exit;
372     }
373 
374     vp8_clear_system_state();
375 
376     if (cm->show_frame)
377     {
378         cm->current_video_frame++;
379         cm->show_frame_mi = cm->mi;
380     }
381 
382     #if CONFIG_ERROR_CONCEALMENT
383     /* swap the mode infos to storage for future error concealment */
384     if (pbi->ec_enabled && pbi->common.prev_mi)
385     {
386         MODE_INFO* tmp = pbi->common.prev_mi;
387         int row, col;
388         pbi->common.prev_mi = pbi->common.mi;
389         pbi->common.mi = tmp;
390 
391         /* Propagate the segment_ids to the next frame */
392         for (row = 0; row < pbi->common.mb_rows; ++row)
393         {
394             for (col = 0; col < pbi->common.mb_cols; ++col)
395             {
396                 const int i = row*pbi->common.mode_info_stride + col;
397                 pbi->common.mi[i].mbmi.segment_id =
398                         pbi->common.prev_mi[i].mbmi.segment_id;
399             }
400         }
401     }
402 #endif
403 
404     pbi->ready_for_new_data = 0;
405     pbi->last_time_stamp = time_stamp;
406 
407 decode_exit:
408 #if HAVE_NEON
409 #if CONFIG_RUNTIME_CPU_DETECT
410     if (cm->cpu_caps & HAS_NEON)
411 #endif
412     {
413         vp8_pop_neon(dx_store_reg);
414     }
415 #endif
416 
417     pbi->common.error.setjmp = 0;
418     return retcode;
419 }
vp8dx_get_raw_frame(VP8D_COMP * pbi,YV12_BUFFER_CONFIG * sd,int64_t * time_stamp,int64_t * time_end_stamp,vp8_ppflags_t * flags)420 int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags)
421 {
422     int ret = -1;
423 
424     if (pbi->ready_for_new_data == 1)
425         return ret;
426 
427     /* ie no raw frame to show!!! */
428     if (pbi->common.show_frame == 0)
429         return ret;
430 
431     pbi->ready_for_new_data = 1;
432     *time_stamp = pbi->last_time_stamp;
433     *time_end_stamp = 0;
434 
435 #if CONFIG_POSTPROC
436     ret = vp8_post_proc_frame(&pbi->common, sd, flags);
437 #else
438 
439     if (pbi->common.frame_to_show)
440     {
441         *sd = *pbi->common.frame_to_show;
442         sd->y_width = pbi->common.Width;
443         sd->y_height = pbi->common.Height;
444         sd->uv_height = pbi->common.Height / 2;
445         ret = 0;
446     }
447     else
448     {
449         ret = -1;
450     }
451 
452 #endif /*!CONFIG_POSTPROC*/
453     vp8_clear_system_state();
454     return ret;
455 }
456 
457 
458 /* This function as written isn't decoder specific, but the encoder has
459  * much faster ways of computing this, so it's ok for it to live in a
460  * decode specific file.
461  */
vp8dx_references_buffer(VP8_COMMON * oci,int ref_frame)462 int vp8dx_references_buffer( VP8_COMMON *oci, int ref_frame )
463 {
464     const MODE_INFO *mi = oci->mi;
465     int mb_row, mb_col;
466 
467     for (mb_row = 0; mb_row < oci->mb_rows; mb_row++)
468     {
469         for (mb_col = 0; mb_col < oci->mb_cols; mb_col++,mi++)
470         {
471             if( mi->mbmi.ref_frame == ref_frame)
472               return 1;
473         }
474         mi++;
475     }
476     return 0;
477 
478 }
479 
vp8_create_decoder_instances(struct frame_buffers * fb,VP8D_CONFIG * oxcf)480 int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf)
481 {
482     if(!fb->use_frame_threads)
483     {
484         /* decoder instance for single thread mode */
485         fb->pbi[0] = create_decompressor(oxcf);
486         if(!fb->pbi[0])
487             return VPX_CODEC_ERROR;
488 
489 #if CONFIG_MULTITHREAD
490         /* enable row-based threading only when use_frame_threads
491          * is disabled */
492         fb->pbi[0]->max_threads = oxcf->max_threads;
493         vp8_decoder_create_threads(fb->pbi[0]);
494 #endif
495     }
496     else
497     {
498         /* TODO : create frame threads and decoder instances for each
499          * thread here */
500     }
501 
502     return VPX_CODEC_OK;
503 }
504 
vp8_remove_decoder_instances(struct frame_buffers * fb)505 int vp8_remove_decoder_instances(struct frame_buffers *fb)
506 {
507     if(!fb->use_frame_threads)
508     {
509         VP8D_COMP *pbi = fb->pbi[0];
510 
511         if (!pbi)
512             return VPX_CODEC_ERROR;
513 #if CONFIG_MULTITHREAD
514         if (pbi->b_multithreaded_rd)
515             vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
516         vp8_decoder_remove_threads(pbi);
517 #endif
518 
519         /* decoder instance for single thread mode */
520         remove_decompressor(pbi);
521     }
522     else
523     {
524         /* TODO : remove frame threads and decoder instances for each
525          * thread here */
526     }
527 
528     return VPX_CODEC_OK;
529 }
530