Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(117)

Side by Side Diff: source/libvpx/vp9/decoder/vp9_onyxd_if.c

Issue 11555023: libvpx: Add VP9 decoder. (Closed) Base URL: svn://chrome-svn/chrome/trunk/deps/third_party/libvpx/
Patch Set: Created 8 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
Property Changes:
Added: svn:eol-style
+ LF
OLDNEW
(Empty)
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 "vp9/common/vp9_onyxc_int.h"
13 #if CONFIG_POSTPROC
14 #include "vp9/common/vp9_postproc.h"
15 #endif
16 #include "vp9/common/vp9_onyxd.h"
17 #include "vp9/decoder/vp9_onyxd_int.h"
18 #include "vpx_mem/vpx_mem.h"
19 #include "vp9/common/vp9_alloccommon.h"
20 #include "vp9/common/vp9_loopfilter.h"
21 #include "vp9/common/vp9_swapyv12buffer.h"
22 #include <stdio.h>
23 #include <assert.h>
24
25 #include "vp9/common/vp9_quant_common.h"
26 #include "vpx_scale/vpxscale.h"
27 #include "vp9/common/vp9_systemdependent.h"
28 #include "vpx_ports/vpx_timer.h"
29 #include "vp9/decoder/vp9_decodframe.h"
30 #include "vp9/decoder/vp9_detokenize.h"
31 #include "./vpx_scale_rtcd.h"
32
33 static int get_free_fb(VP9_COMMON *cm);
34 static void ref_cnt_fb(int *buf, int *idx, int new_idx);
35
36 #define WRITE_RECON_BUFFER 0
37 #if WRITE_RECON_BUFFER == 1
38 static void recon_write_yuv_frame(char *name, YV12_BUFFER_CONFIG *s) {
39 FILE *yuv_file = fopen((char *)name, "ab");
40 unsigned char *src = s->y_buffer;
41 int h = s->y_height;
42
43 do {
44 fwrite(src, s->y_width, 1, yuv_file);
45 src += s->y_stride;
46 } while (--h);
47
48 src = s->u_buffer;
49 h = s->uv_height;
50
51 do {
52 fwrite(src, s->uv_width, 1, yuv_file);
53 src += s->uv_stride;
54 } while (--h);
55
56 src = s->v_buffer;
57 h = s->uv_height;
58
59 do {
60 fwrite(src, s->uv_width, 1, yuv_file);
61 src += s->uv_stride;
62 } while (--h);
63
64 fclose(yuv_file);
65 }
66 #endif
67 #if WRITE_RECON_BUFFER == 2
68 void write_dx_frame_to_file(YV12_BUFFER_CONFIG *frame, int this_frame) {
69
70 // write the frame
71 FILE *yframe;
72 int i;
73 char filename[255];
74
75 sprintf(filename, "dx\\y%04d.raw", this_frame);
76 yframe = fopen(filename, "wb");
77
78 for (i = 0; i < frame->y_height; i++)
79 fwrite(frame->y_buffer + i * frame->y_stride,
80 frame->y_width, 1, yframe);
81
82 fclose(yframe);
83 sprintf(filename, "dx\\u%04d.raw", this_frame);
84 yframe = fopen(filename, "wb");
85
86 for (i = 0; i < frame->uv_height; i++)
87 fwrite(frame->u_buffer + i * frame->uv_stride,
88 frame->uv_width, 1, yframe);
89
90 fclose(yframe);
91 sprintf(filename, "dx\\v%04d.raw", this_frame);
92 yframe = fopen(filename, "wb");
93
94 for (i = 0; i < frame->uv_height; i++)
95 fwrite(frame->v_buffer + i * frame->uv_stride,
96 frame->uv_width, 1, yframe);
97
98 fclose(yframe);
99 }
100 #endif
101
102 void vp9_initialize_dec(void) {
103 static int init_done = 0;
104
105 if (!init_done) {
106 vp9_initialize_common();
107 vp9_init_quant_tables();
108 init_done = 1;
109 }
110 }
111
112 VP9D_PTR vp9_create_decompressor(VP9D_CONFIG *oxcf) {
113 VP9D_COMP *pbi = vpx_memalign(32, sizeof(VP9D_COMP));
114
115 if (!pbi)
116 return NULL;
117
118 vpx_memset(pbi, 0, sizeof(VP9D_COMP));
119
120 if (setjmp(pbi->common.error.jmp)) {
121 pbi->common.error.setjmp = 0;
122 vp9_remove_decompressor(pbi);
123 return 0;
124 }
125
126 pbi->common.error.setjmp = 1;
127 vp9_initialize_dec();
128
129 vp9_create_common(&pbi->common);
130
131 pbi->common.current_video_frame = 0;
132 pbi->ready_for_new_data = 1;
133
134 /* vp9_init_de_quantizer() is first called here. Add check in
135 * frame_init_dequantizer() to avoid unnecessary calling of
136 * vp9_init_de_quantizer() for every frame.
137 */
138 vp9_init_de_quantizer(pbi);
139
140 vp9_loop_filter_init(&pbi->common);
141
142 pbi->common.error.setjmp = 0;
143
144 pbi->decoded_key_frame = 0;
145
146 return (VP9D_PTR) pbi;
147 }
148
149 void vp9_remove_decompressor(VP9D_PTR ptr) {
150 VP9D_COMP *pbi = (VP9D_COMP *) ptr;
151
152 if (!pbi)
153 return;
154
155 // Delete sementation map
156 if (pbi->common.last_frame_seg_map != 0)
157 vpx_free(pbi->common.last_frame_seg_map);
158
159 vp9_remove_common(&pbi->common);
160 vpx_free(pbi->mbc);
161 vpx_free(pbi);
162 }
163
164
165 vpx_codec_err_t vp9_get_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
166 YV12_BUFFER_CONFIG *sd) {
167 VP9D_COMP *pbi = (VP9D_COMP *) ptr;
168 VP9_COMMON *cm = &pbi->common;
169 int ref_fb_idx;
170
171 if (ref_frame_flag == VP9_LAST_FLAG)
172 ref_fb_idx = cm->lst_fb_idx;
173 else if (ref_frame_flag == VP9_GOLD_FLAG)
174 ref_fb_idx = cm->gld_fb_idx;
175 else if (ref_frame_flag == VP9_ALT_FLAG)
176 ref_fb_idx = 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_idx].y_height != sd->y_height ||
184 cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
185 cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
186 cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) {
187 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
188 "Incorrect buffer dimensions");
189 } else
190 vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
191
192 return pbi->common.error.error_code;
193 }
194
195
196 vpx_codec_err_t vp9_set_reference_dec(VP9D_PTR ptr, VP9_REFFRAME ref_frame_flag,
197 YV12_BUFFER_CONFIG *sd) {
198 VP9D_COMP *pbi = (VP9D_COMP *) ptr;
199 VP9_COMMON *cm = &pbi->common;
200 int *ref_fb_ptr = NULL;
201 int free_fb;
202
203 if (ref_frame_flag == VP9_LAST_FLAG)
204 ref_fb_ptr = &cm->lst_fb_idx;
205 else if (ref_frame_flag == VP9_GOLD_FLAG)
206 ref_fb_ptr = &cm->gld_fb_idx;
207 else if (ref_frame_flag == VP9_ALT_FLAG)
208 ref_fb_ptr = &cm->alt_fb_idx;
209 else {
210 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
211 "Invalid reference frame");
212 return pbi->common.error.error_code;
213 }
214
215 if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
216 cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
217 cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
218 cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) {
219 vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
220 "Incorrect buffer dimensions");
221 } else {
222 /* Find an empty frame buffer. */
223 free_fb = get_free_fb(cm);
224 /* Decrease fb_idx_ref_cnt since it will be increased again in
225 * ref_cnt_fb() below. */
226 cm->fb_idx_ref_cnt[free_fb]--;
227
228 /* Manage the reference counters and copy image. */
229 ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
230 vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
231 }
232
233 return pbi->common.error.error_code;
234 }
235
236
237 static int get_free_fb(VP9_COMMON *cm) {
238 int i;
239 for (i = 0; i < NUM_YV12_BUFFERS; i++)
240 if (cm->fb_idx_ref_cnt[i] == 0)
241 break;
242
243 assert(i < NUM_YV12_BUFFERS);
244 cm->fb_idx_ref_cnt[i] = 1;
245 return i;
246 }
247
248 static void ref_cnt_fb(int *buf, int *idx, int new_idx) {
249 if (buf[*idx] > 0)
250 buf[*idx]--;
251
252 *idx = new_idx;
253
254 buf[new_idx]++;
255 }
256
257 /* If any buffer copy / swapping is signalled it should be done here. */
258 static int swap_frame_buffers(VP9_COMMON *cm) {
259 int err = 0;
260
261 /* The alternate reference frame or golden frame can be updated
262 * using the new, last, or golden/alt ref frame. If it
263 * is updated using the newly decoded frame it is a refresh.
264 * An update using the last or golden/alt ref frame is a copy.
265 */
266 if (cm->copy_buffer_to_arf) {
267 int new_fb = 0;
268
269 if (cm->copy_buffer_to_arf == 1)
270 new_fb = cm->lst_fb_idx;
271 else if (cm->copy_buffer_to_arf == 2)
272 new_fb = cm->gld_fb_idx;
273 else
274 err = -1;
275
276 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
277 }
278
279 if (cm->copy_buffer_to_gf) {
280 int new_fb = 0;
281
282 if (cm->copy_buffer_to_gf == 1)
283 new_fb = cm->lst_fb_idx;
284 else if (cm->copy_buffer_to_gf == 2)
285 new_fb = cm->alt_fb_idx;
286 else
287 err = -1;
288
289 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
290 }
291
292 if (cm->refresh_golden_frame)
293 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
294
295 if (cm->refresh_alt_ref_frame)
296 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
297
298 if (cm->refresh_last_frame) {
299 ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
300
301 cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
302 } else
303 cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
304
305 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
306
307 return err;
308 }
309
310 int vp9_receive_compressed_data(VP9D_PTR ptr, unsigned long size,
311 const unsigned char **psource,
312 int64_t time_stamp) {
313 VP9D_COMP *pbi = (VP9D_COMP *) ptr;
314 VP9_COMMON *cm = &pbi->common;
315 const unsigned char *source = *psource;
316 int retcode = 0;
317
318 /*if(pbi->ready_for_new_data == 0)
319 return -1;*/
320
321 if (ptr == 0) {
322 return -1;
323 }
324
325 pbi->common.error.error_code = VPX_CODEC_OK;
326
327 pbi->Source = source;
328 pbi->source_sz = size;
329
330 if (pbi->source_sz == 0) {
331 /* This is used to signal that we are missing frames.
332 * We do not know if the missing frame(s) was supposed to update
333 * any of the reference buffers, but we act conservative and
334 * mark only the last buffer as corrupted.
335 */
336 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
337 }
338
339 cm->new_fb_idx = get_free_fb(cm);
340
341 if (setjmp(pbi->common.error.jmp)) {
342 pbi->common.error.setjmp = 0;
343
344 /* We do not know if the missing frame(s) was supposed to update
345 * any of the reference buffers, but we act conservative and
346 * mark only the last buffer as corrupted.
347 */
348 cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
349
350 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
351 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
352 return -1;
353 }
354
355 pbi->common.error.setjmp = 1;
356
357 retcode = vp9_decode_frame(pbi, psource);
358
359 if (retcode < 0) {
360 pbi->common.error.error_code = VPX_CODEC_ERROR;
361 pbi->common.error.setjmp = 0;
362 if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
363 cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
364 return retcode;
365 }
366
367 {
368 if (swap_frame_buffers(cm)) {
369 pbi->common.error.error_code = VPX_CODEC_ERROR;
370 pbi->common.error.setjmp = 0;
371 return -1;
372 }
373
374 #if WRITE_RECON_BUFFER == 2
375 if (cm->show_frame)
376 write_dx_frame_to_file(cm->frame_to_show,
377 cm->current_video_frame);
378 else
379 write_dx_frame_to_file(cm->frame_to_show,
380 cm->current_video_frame + 1000);
381 #endif
382
383 if (cm->filter_level) {
384 /* Apply the loop filter if appropriate. */
385 vp9_loop_filter_frame(cm, &pbi->mb);
386 }
387 vp8_yv12_extend_frame_borders(cm->frame_to_show);
388 }
389
390 #if WRITE_RECON_BUFFER == 1
391 if (cm->show_frame)
392 recon_write_yuv_frame("recon.yuv", cm->frame_to_show);
393 #endif
394
395 vp9_clear_system_state();
396
397 if (cm->show_frame) {
398 vpx_memcpy(cm->prev_mip, cm->mip,
399 (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
400 } else {
401 vpx_memset(cm->prev_mip, 0,
402 (cm->mb_cols + 1) * (cm->mb_rows + 1)* sizeof(MODE_INFO));
403 }
404
405 /*vp9_print_modes_and_motion_vectors(cm->mi, cm->mb_rows,cm->mb_cols,
406 cm->current_video_frame);*/
407
408 if (cm->show_frame)
409 cm->current_video_frame++;
410
411 pbi->ready_for_new_data = 0;
412 pbi->last_time_stamp = time_stamp;
413 pbi->source_sz = 0;
414
415 pbi->common.error.setjmp = 0;
416 return retcode;
417 }
418
419 int vp9_get_raw_frame(VP9D_PTR ptr, YV12_BUFFER_CONFIG *sd,
420 int64_t *time_stamp, int64_t *time_end_stamp,
421 vp9_ppflags_t *flags) {
422 int ret = -1;
423 VP9D_COMP *pbi = (VP9D_COMP *) ptr;
424
425 if (pbi->ready_for_new_data == 1)
426 return ret;
427
428 /* ie no raw frame to show!!! */
429 if (pbi->common.show_frame == 0)
430 return ret;
431
432 pbi->ready_for_new_data = 1;
433 *time_stamp = pbi->last_time_stamp;
434 *time_end_stamp = 0;
435
436 sd->clrtype = pbi->common.clr_type;
437 #if CONFIG_POSTPROC
438 ret = vp9_post_proc_frame(&pbi->common, sd, flags);
439 #else
440
441 if (pbi->common.frame_to_show) {
442 *sd = *pbi->common.frame_to_show;
443 sd->y_width = pbi->common.Width;
444 sd->y_height = pbi->common.Height;
445 sd->uv_height = pbi->common.Height / 2;
446 ret = 0;
447 } else {
448 ret = -1;
449 }
450
451 #endif /*!CONFIG_POSTPROC*/
452 vp9_clear_system_state();
453 return ret;
454 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698