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 
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 
get_free_fb(VP8_COMMON * cm)181 static int get_free_fb (VP8_COMMON *cm)
182 {
183     int i;
184     for (i = 0; i < NUM_YV12_BUFFERS; i++)
185         if (cm->fb_idx_ref_cnt[i] == 0)
186             break;
187 
188     assert(i < NUM_YV12_BUFFERS);
189     cm->fb_idx_ref_cnt[i] = 1;
190     return i;
191 }
192 
ref_cnt_fb(int * buf,int * idx,int new_idx)193 static void ref_cnt_fb (int *buf, int *idx, int new_idx)
194 {
195     if (buf[*idx] > 0)
196         buf[*idx]--;
197 
198     *idx = new_idx;
199 
200     buf[new_idx]++;
201 }
202 
203 /* If any buffer copy / swapping is signalled it should be done here. */
swap_frame_buffers(VP8_COMMON * cm)204 static int swap_frame_buffers (VP8_COMMON *cm)
205 {
206     int err = 0;
207 
208     /* The alternate reference frame or golden frame can be updated
209      *  using the new, last, or golden/alt ref frame.  If it
210      *  is updated using the newly decoded frame it is a refresh.
211      *  An update using the last or golden/alt ref frame is a copy.
212      */
213     if (cm->copy_buffer_to_arf)
214     {
215         int new_fb = 0;
216 
217         if (cm->copy_buffer_to_arf == 1)
218             new_fb = cm->lst_fb_idx;
219         else if (cm->copy_buffer_to_arf == 2)
220             new_fb = cm->gld_fb_idx;
221         else
222             err = -1;
223 
224         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
225     }
226 
227     if (cm->copy_buffer_to_gf)
228     {
229         int new_fb = 0;
230 
231         if (cm->copy_buffer_to_gf == 1)
232             new_fb = cm->lst_fb_idx;
233         else if (cm->copy_buffer_to_gf == 2)
234             new_fb = cm->alt_fb_idx;
235         else
236             err = -1;
237 
238         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
239     }
240 
241     if (cm->refresh_golden_frame)
242         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
243 
244     if (cm->refresh_alt_ref_frame)
245         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
246 
247     if (cm->refresh_last_frame)
248     {
249         ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
250 
251         cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
252     }
253     else
254         cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
255 
256     cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
257 
258     return err;
259 }
260 
check_fragments_for_errors(VP8D_COMP * pbi)261 int check_fragments_for_errors(VP8D_COMP *pbi)
262 {
263     if (!pbi->ec_active &&
264         pbi->fragments.count <= 1 && pbi->fragments.sizes[0] == 0)
265     {
266         VP8_COMMON *cm = &pbi->common;
267 
268         /* If error concealment is disabled we won't signal missing frames
269          * to the decoder.
270          */
271         if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1)
272         {
273             /* The last reference shares buffer with another reference
274              * buffer. Move it to its own buffer before setting it as
275              * corrupt, otherwise we will make multiple buffers corrupt.
276              */
277             const int prev_idx = cm->lst_fb_idx;
278             cm->fb_idx_ref_cnt[prev_idx]--;
279             cm->lst_fb_idx = get_free_fb(cm);
280             vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx],
281                                     &cm->yv12_fb[cm->lst_fb_idx]);
282         }
283         /* This is used to signal that we are missing frames.
284          * We do not know if the missing frame(s) was supposed to update
285          * any of the reference buffers, but we act conservative and
286          * mark only the last buffer as corrupted.
287          */
288         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
289 
290         /* Signal that we have no frame to show. */
291         cm->show_frame = 0;
292 
293         /* Nothing more to do. */
294         return 0;
295     }
296 
297     return 1;
298 }
299 
vp8dx_receive_compressed_data(VP8D_COMP * pbi,size_t size,const uint8_t * source,int64_t time_stamp)300 int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
301                                   const uint8_t *source,
302                                   int64_t time_stamp)
303 {
304     VP8_COMMON *cm = &pbi->common;
305     int retcode = -1;
306 
307     pbi->common.error.error_code = VPX_CODEC_OK;
308 
309     retcode = check_fragments_for_errors(pbi);
310     if(retcode <= 0)
311         return retcode;
312 
313     cm->new_fb_idx = get_free_fb (cm);
314 
315     /* setup reference frames for vp8_decode_frame */
316     pbi->dec_fb_ref[INTRA_FRAME]  = &cm->yv12_fb[cm->new_fb_idx];
317     pbi->dec_fb_ref[LAST_FRAME]   = &cm->yv12_fb[cm->lst_fb_idx];
318     pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
319     pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];
320 
321     if (setjmp(pbi->common.error.jmp))
322     {
323        /* We do not know if the missing frame(s) was supposed to update
324         * any of the reference buffers, but we act conservative and
325         * mark only the last buffer as corrupted.
326         */
327         cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
328 
329         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
330           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
331 
332         goto decode_exit;
333     }
334 
335     pbi->common.error.setjmp = 1;
336 
337     retcode = vp8_decode_frame(pbi);
338 
339     if (retcode < 0)
340     {
341         if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
342           cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
343 
344         pbi->common.error.error_code = VPX_CODEC_ERROR;
345         goto decode_exit;
346     }
347 
348     if (swap_frame_buffers (cm))
349     {
350         pbi->common.error.error_code = VPX_CODEC_ERROR;
351         goto decode_exit;
352     }
353 
354     vp8_clear_system_state();
355 
356     if (cm->show_frame)
357     {
358         cm->current_video_frame++;
359         cm->show_frame_mi = cm->mi;
360     }
361 
362     #if CONFIG_ERROR_CONCEALMENT
363     /* swap the mode infos to storage for future error concealment */
364     if (pbi->ec_enabled && pbi->common.prev_mi)
365     {
366         MODE_INFO* tmp = pbi->common.prev_mi;
367         int row, col;
368         pbi->common.prev_mi = pbi->common.mi;
369         pbi->common.mi = tmp;
370 
371         /* Propagate the segment_ids to the next frame */
372         for (row = 0; row < pbi->common.mb_rows; ++row)
373         {
374             for (col = 0; col < pbi->common.mb_cols; ++col)
375             {
376                 const int i = row*pbi->common.mode_info_stride + col;
377                 pbi->common.mi[i].mbmi.segment_id =
378                         pbi->common.prev_mi[i].mbmi.segment_id;
379             }
380         }
381     }
382 #endif
383 
384     pbi->ready_for_new_data = 0;
385     pbi->last_time_stamp = time_stamp;
386 
387 decode_exit:
388     pbi->common.error.setjmp = 0;
389     vp8_clear_system_state();
390     return retcode;
391 }
vp8dx_get_raw_frame(VP8D_COMP * pbi,YV12_BUFFER_CONFIG * sd,int64_t * time_stamp,int64_t * time_end_stamp,vp8_ppflags_t * flags)392 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)
393 {
394     int ret = -1;
395 
396     if (pbi->ready_for_new_data == 1)
397         return ret;
398 
399     /* ie no raw frame to show!!! */
400     if (pbi->common.show_frame == 0)
401         return ret;
402 
403     pbi->ready_for_new_data = 1;
404     *time_stamp = pbi->last_time_stamp;
405     *time_end_stamp = 0;
406 
407 #if CONFIG_POSTPROC
408     ret = vp8_post_proc_frame(&pbi->common, sd, flags);
409 #else
410 
411     if (pbi->common.frame_to_show)
412     {
413         *sd = *pbi->common.frame_to_show;
414         sd->y_width = pbi->common.Width;
415         sd->y_height = pbi->common.Height;
416         sd->uv_height = pbi->common.Height / 2;
417         ret = 0;
418     }
419     else
420     {
421         ret = -1;
422     }
423 
424 #endif /*!CONFIG_POSTPROC*/
425     vp8_clear_system_state();
426     return ret;
427 }
428 
429 
430 /* This function as written isn't decoder specific, but the encoder has
431  * much faster ways of computing this, so it's ok for it to live in a
432  * decode specific file.
433  */
vp8dx_references_buffer(VP8_COMMON * oci,int ref_frame)434 int vp8dx_references_buffer( VP8_COMMON *oci, int ref_frame )
435 {
436     const MODE_INFO *mi = oci->mi;
437     int mb_row, mb_col;
438 
439     for (mb_row = 0; mb_row < oci->mb_rows; mb_row++)
440     {
441         for (mb_col = 0; mb_col < oci->mb_cols; mb_col++,mi++)
442         {
443             if( mi->mbmi.ref_frame == ref_frame)
444               return 1;
445         }
446         mi++;
447     }
448     return 0;
449 
450 }
451 
vp8_create_decoder_instances(struct frame_buffers * fb,VP8D_CONFIG * oxcf)452 int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf)
453 {
454     if(!fb->use_frame_threads)
455     {
456         /* decoder instance for single thread mode */
457         fb->pbi[0] = create_decompressor(oxcf);
458         if(!fb->pbi[0])
459             return VPX_CODEC_ERROR;
460 
461 #if CONFIG_MULTITHREAD
462         /* enable row-based threading only when use_frame_threads
463          * is disabled */
464         fb->pbi[0]->max_threads = oxcf->max_threads;
465         vp8_decoder_create_threads(fb->pbi[0]);
466 #endif
467     }
468     else
469     {
470         /* TODO : create frame threads and decoder instances for each
471          * thread here */
472     }
473 
474     return VPX_CODEC_OK;
475 }
476 
vp8_remove_decoder_instances(struct frame_buffers * fb)477 int vp8_remove_decoder_instances(struct frame_buffers *fb)
478 {
479     if(!fb->use_frame_threads)
480     {
481         VP8D_COMP *pbi = fb->pbi[0];
482 
483         if (!pbi)
484             return VPX_CODEC_ERROR;
485 #if CONFIG_MULTITHREAD
486         if (pbi->b_multithreaded_rd)
487             vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
488         vp8_decoder_remove_threads(pbi);
489 #endif
490 
491         /* decoder instance for single thread mode */
492         remove_decompressor(pbi);
493     }
494     else
495     {
496         /* TODO : remove frame threads and decoder instances for each
497          * thread here */
498     }
499 
500     return VPX_CODEC_OK;
501 }
502