OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. | 2 * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 * | 3 * |
4 * Use of this source code is governed by a BSD-style license | 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 | 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 | 6 * tree. An additional intellectual property rights grant can be found |
7 * in the file PATENTS. All contributing project authors may | 7 * in the file PATENTS. All contributing project authors may |
8 * be found in the AUTHORS file in the root of the source tree. | 8 * be found in the AUTHORS file in the root of the source tree. |
9 */ | 9 */ |
10 | 10 |
(...skipping 14 matching lines...) Expand all Loading... |
25 #include "vp9/vp9_iface_common.h" | 25 #include "vp9/vp9_iface_common.h" |
26 | 26 |
27 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) | 27 #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0) |
28 | 28 |
29 typedef vpx_codec_stream_info_t vp9_stream_info_t; | 29 typedef vpx_codec_stream_info_t vp9_stream_info_t; |
30 | 30 |
31 struct vpx_codec_alg_priv { | 31 struct vpx_codec_alg_priv { |
32 vpx_codec_priv_t base; | 32 vpx_codec_priv_t base; |
33 vpx_codec_dec_cfg_t cfg; | 33 vpx_codec_dec_cfg_t cfg; |
34 vp9_stream_info_t si; | 34 vp9_stream_info_t si; |
35 struct VP9Decoder *pbi; | |
36 int postproc_cfg_set; | 35 int postproc_cfg_set; |
37 vp8_postproc_cfg_t postproc_cfg; | 36 vp8_postproc_cfg_t postproc_cfg; |
38 vpx_decrypt_cb decrypt_cb; | 37 vpx_decrypt_cb decrypt_cb; |
39 void *decrypt_state; | 38 void *decrypt_state; |
40 vpx_image_t img; | 39 vpx_image_t img; |
41 int invert_tile_order; | 40 int invert_tile_order; |
42 int frame_parallel_decode; // frame-based threading. | 41 int frame_parallel_decode; // frame-based threading. |
43 int last_show_frame; // Index of last output frame. | 42 int last_show_frame; // Index of last output frame. |
44 | 43 |
| 44 VP9Worker *frame_workers; |
| 45 int num_frame_workers; |
| 46 int next_submit_thread_id; |
| 47 int next_output_thread_id; |
| 48 |
45 // External frame buffer info to save for VP9 common. | 49 // External frame buffer info to save for VP9 common. |
46 void *ext_priv; // Private data associated with the external frame buffers. | 50 void *ext_priv; // Private data associated with the external frame buffers. |
47 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; | 51 vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb; |
48 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; | 52 vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb; |
49 }; | 53 }; |
50 | 54 |
51 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, | 55 static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx, |
52 vpx_codec_priv_enc_mr_cfg_t *data) { | 56 vpx_codec_priv_enc_mr_cfg_t *data) { |
53 // This function only allocates space for the vpx_codec_alg_priv_t | 57 // This function only allocates space for the vpx_codec_alg_priv_t |
54 // structure. More memory may be required at the time the stream | 58 // structure. More memory may be required at the time the stream |
(...skipping 23 matching lines...) Expand all Loading... |
78 // Update the reference to the config structure to an internal copy. | 82 // Update the reference to the config structure to an internal copy. |
79 ctx->priv->alg_priv->cfg = *ctx->config.dec; | 83 ctx->priv->alg_priv->cfg = *ctx->config.dec; |
80 ctx->config.dec = &ctx->priv->alg_priv->cfg; | 84 ctx->config.dec = &ctx->priv->alg_priv->cfg; |
81 } | 85 } |
82 } | 86 } |
83 | 87 |
84 return VPX_CODEC_OK; | 88 return VPX_CODEC_OK; |
85 } | 89 } |
86 | 90 |
87 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { | 91 static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) { |
88 if (ctx->pbi) { | 92 if (ctx->frame_workers != NULL) { |
89 vp9_decoder_remove(ctx->pbi); | 93 int i; |
90 ctx->pbi = NULL; | 94 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 95 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 96 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 97 vp9_decoder_remove(worker_data->pbi); |
| 98 vpx_free(worker_data); |
| 99 } |
91 } | 100 } |
92 | 101 |
| 102 vpx_free(ctx->frame_workers); |
93 vpx_free(ctx); | 103 vpx_free(ctx); |
94 | 104 |
95 return VPX_CODEC_OK; | 105 return VPX_CODEC_OK; |
96 } | 106 } |
97 | 107 |
98 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, | 108 static vpx_codec_err_t decoder_peek_si_internal(const uint8_t *data, |
99 unsigned int data_sz, | 109 unsigned int data_sz, |
100 vpx_codec_stream_info_t *si, | 110 vpx_codec_stream_info_t *si, |
101 vpx_decrypt_cb decrypt_cb, | 111 vpx_decrypt_cb decrypt_cb, |
102 void *decrypt_state) { | 112 void *decrypt_state) { |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
180 vpx_codec_stream_info_t *si) { | 190 vpx_codec_stream_info_t *si) { |
181 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) | 191 const size_t sz = (si->sz >= sizeof(vp9_stream_info_t)) |
182 ? sizeof(vp9_stream_info_t) | 192 ? sizeof(vp9_stream_info_t) |
183 : sizeof(vpx_codec_stream_info_t); | 193 : sizeof(vpx_codec_stream_info_t); |
184 memcpy(si, &ctx->si, sz); | 194 memcpy(si, &ctx->si, sz); |
185 si->sz = (unsigned int)sz; | 195 si->sz = (unsigned int)sz; |
186 | 196 |
187 return VPX_CODEC_OK; | 197 return VPX_CODEC_OK; |
188 } | 198 } |
189 | 199 |
| 200 static void set_error_detail(vpx_codec_alg_priv_t *ctx, |
| 201 const char *const error) { |
| 202 ctx->base.err_detail = error; |
| 203 } |
| 204 |
190 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, | 205 static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx, |
191 const struct vpx_internal_error_info *error) { | 206 const struct vpx_internal_error_info *error) { |
192 if (error->error_code) | 207 if (error->error_code) |
193 ctx->base.err_detail = error->has_detail ? error->detail : NULL; | 208 set_error_detail(ctx, error->has_detail ? error->detail : NULL); |
194 | 209 |
195 return error->error_code; | 210 return error->error_code; |
196 } | 211 } |
197 | 212 |
198 static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) { | 213 static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) { |
199 VP9_COMMON *const cm = &ctx->pbi->common; | 214 int i; |
200 | 215 |
201 cm->new_fb_idx = -1; | 216 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 217 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 218 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 219 VP9_COMMON *const cm = &worker_data->pbi->common; |
202 | 220 |
203 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { | 221 cm->new_fb_idx = -1; |
204 cm->get_fb_cb = ctx->get_ext_fb_cb; | 222 if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) { |
205 cm->release_fb_cb = ctx->release_ext_fb_cb; | 223 cm->get_fb_cb = ctx->get_ext_fb_cb; |
206 cm->cb_priv = ctx->ext_priv; | 224 cm->release_fb_cb = ctx->release_ext_fb_cb; |
207 } else { | 225 cm->cb_priv = ctx->ext_priv; |
208 cm->get_fb_cb = vp9_get_frame_buffer; | 226 } else { |
209 cm->release_fb_cb = vp9_release_frame_buffer; | 227 cm->get_fb_cb = vp9_get_frame_buffer; |
| 228 cm->release_fb_cb = vp9_release_frame_buffer; |
210 | 229 |
211 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers)) | 230 if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers)) |
212 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, | 231 vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR, |
213 "Failed to initialize internal frame buffers"); | 232 "Failed to initialize internal frame buffers"); |
214 | 233 |
215 cm->cb_priv = &cm->int_frame_buffers; | 234 cm->cb_priv = &cm->int_frame_buffers; |
| 235 } |
216 } | 236 } |
217 } | 237 } |
218 | 238 |
219 static void set_default_ppflags(vp8_postproc_cfg_t *cfg) { | 239 static void set_default_ppflags(vp8_postproc_cfg_t *cfg) { |
220 cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; | 240 cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK; |
221 cfg->deblocking_level = 4; | 241 cfg->deblocking_level = 4; |
222 cfg->noise_level = 0; | 242 cfg->noise_level = 0; |
223 } | 243 } |
224 | 244 |
225 static void set_ppflags(const vpx_codec_alg_priv_t *ctx, | 245 static void set_ppflags(const vpx_codec_alg_priv_t *ctx, |
226 vp9_ppflags_t *flags) { | 246 vp9_ppflags_t *flags) { |
227 flags->post_proc_flag = | 247 flags->post_proc_flag = |
228 ctx->postproc_cfg.post_proc_flag; | 248 ctx->postproc_cfg.post_proc_flag; |
229 | 249 |
230 flags->deblocking_level = ctx->postproc_cfg.deblocking_level; | 250 flags->deblocking_level = ctx->postproc_cfg.deblocking_level; |
231 flags->noise_level = ctx->postproc_cfg.noise_level; | 251 flags->noise_level = ctx->postproc_cfg.noise_level; |
232 } | 252 } |
233 | 253 |
234 static void init_decoder(vpx_codec_alg_priv_t *ctx) { | 254 static int frame_worker_hook(void *arg1, void *arg2) { |
235 ctx->pbi = vp9_decoder_create(); | 255 FrameWorkerData *const worker_data = (FrameWorkerData *)arg1; |
236 if (ctx->pbi == NULL) | 256 const uint8_t *data = worker_data->data; |
237 return; | 257 (void)arg2; |
| 258 worker_data->result = vp9_receive_compressed_data(worker_data->pbi, |
| 259 worker_data->data_size, |
| 260 &data); |
| 261 worker_data->data_end = data; |
| 262 return !worker_data->result; |
| 263 } |
238 | 264 |
239 ctx->pbi->max_threads = ctx->cfg.threads; | 265 static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) { |
240 ctx->pbi->inv_tile_order = ctx->invert_tile_order; | 266 int i; |
241 ctx->pbi->frame_parallel_decode = ctx->frame_parallel_decode; | 267 |
242 ctx->last_show_frame = -1; | 268 ctx->last_show_frame = -1; |
| 269 ctx->next_submit_thread_id = 0; |
| 270 ctx->next_output_thread_id = 0; |
| 271 ctx->num_frame_workers = |
| 272 (ctx->frame_parallel_decode == 1) ? ctx->cfg.threads: 1; |
| 273 |
| 274 ctx->frame_workers = (VP9Worker *) |
| 275 vpx_malloc(ctx->num_frame_workers * sizeof(*ctx->frame_workers)); |
| 276 if (ctx->frame_workers == NULL) { |
| 277 set_error_detail(ctx, "Failed to allocate frame_workers"); |
| 278 return VPX_CODEC_MEM_ERROR; |
| 279 } |
| 280 |
| 281 for (i = 0; i < ctx->num_frame_workers; ++i) { |
| 282 VP9Worker *const worker = &ctx->frame_workers[i]; |
| 283 FrameWorkerData *worker_data = NULL; |
| 284 vp9_worker_init(worker); |
| 285 worker->data1 = vpx_memalign(32, sizeof(FrameWorkerData)); |
| 286 if (worker->data1 == NULL) { |
| 287 set_error_detail(ctx, "Failed to allocate worker_data"); |
| 288 return VPX_CODEC_MEM_ERROR; |
| 289 } |
| 290 worker_data = (FrameWorkerData *)worker->data1; |
| 291 worker_data->pbi = vp9_decoder_create(); |
| 292 if (worker_data->pbi == NULL) { |
| 293 set_error_detail(ctx, "Failed to allocate worker_data"); |
| 294 return VPX_CODEC_MEM_ERROR; |
| 295 } |
| 296 |
| 297 // If decoding in serial mode, FrameWorker thread could create tile worker |
| 298 // thread or loopfilter thread. |
| 299 worker_data->pbi->max_threads = |
| 300 (ctx->frame_parallel_decode == 0) ? ctx->cfg.threads : 0; |
| 301 |
| 302 worker_data->pbi->inv_tile_order = ctx->invert_tile_order; |
| 303 worker_data->pbi->frame_parallel_decode = ctx->frame_parallel_decode; |
| 304 worker->hook = (VP9WorkerHook)frame_worker_hook; |
| 305 } |
243 | 306 |
244 // If postprocessing was enabled by the application and a | 307 // If postprocessing was enabled by the application and a |
245 // configuration has not been provided, default it. | 308 // configuration has not been provided, default it. |
246 if (!ctx->postproc_cfg_set && | 309 if (!ctx->postproc_cfg_set && |
247 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) | 310 (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) |
248 set_default_ppflags(&ctx->postproc_cfg); | 311 set_default_ppflags(&ctx->postproc_cfg); |
249 | 312 |
250 init_buffer_callbacks(ctx); | 313 init_buffer_callbacks(ctx); |
| 314 |
| 315 return VPX_CODEC_OK; |
251 } | 316 } |
252 | 317 |
253 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, | 318 static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx, |
254 const uint8_t **data, unsigned int data_sz, | 319 const uint8_t **data, unsigned int data_sz, |
255 void *user_priv, int64_t deadline) { | 320 void *user_priv, int64_t deadline) { |
256 vp9_ppflags_t flags = {0}; | 321 vp9_ppflags_t flags = {0}; |
257 VP9_COMMON *cm = NULL; | |
258 | |
259 (void)deadline; | 322 (void)deadline; |
260 | 323 |
261 // Determine the stream parameters. Note that we rely on peek_si to | 324 // Determine the stream parameters. Note that we rely on peek_si to |
262 // validate that we have a buffer that does not wrap around the top | 325 // validate that we have a buffer that does not wrap around the top |
263 // of the heap. | 326 // of the heap. |
264 if (!ctx->si.h) { | 327 if (!ctx->si.h) { |
265 const vpx_codec_err_t res = | 328 const vpx_codec_err_t res = |
266 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, | 329 decoder_peek_si_internal(*data, data_sz, &ctx->si, ctx->decrypt_cb, |
267 ctx->decrypt_state); | 330 ctx->decrypt_state); |
268 if (res != VPX_CODEC_OK) | 331 if (res != VPX_CODEC_OK) |
269 return res; | 332 return res; |
270 | 333 |
271 if (!ctx->si.is_kf) | 334 if (!ctx->si.is_kf) |
272 return VPX_CODEC_ERROR; | 335 return VPX_CODEC_ERROR; |
273 } | 336 } |
274 | 337 |
275 // Initialize the decoder instance on the first frame | 338 // Initialize the decoder workers on the first frame |
276 if (ctx->pbi == NULL) { | 339 if (ctx->frame_workers == NULL) { |
277 init_decoder(ctx); | 340 const vpx_codec_err_t res = init_decoder(ctx); |
278 if (ctx->pbi == NULL) | 341 if (res != VPX_CODEC_OK) |
279 return VPX_CODEC_ERROR; | 342 return res; |
280 } | 343 } |
281 | 344 |
282 // Set these even if already initialized. The caller may have changed the | 345 if (!ctx->frame_parallel_decode) { |
283 // decrypt config between frames. | 346 VP9Worker *const worker = ctx->frame_workers; |
284 ctx->pbi->decrypt_cb = ctx->decrypt_cb; | 347 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
285 ctx->pbi->decrypt_state = ctx->decrypt_state; | 348 worker_data->data = *data; |
| 349 worker_data->data_size = data_sz; |
286 | 350 |
287 cm = &ctx->pbi->common; | 351 // Set these even if already initialized. The caller may have changed the |
| 352 // decrypt config between frames. |
| 353 worker_data->pbi->decrypt_cb = ctx->decrypt_cb; |
| 354 worker_data->pbi->decrypt_state = ctx->decrypt_state; |
288 | 355 |
289 if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) | 356 vp9_worker_execute(worker); |
290 return update_error_state(ctx, &cm->error); | 357 if (worker->had_error) |
| 358 return update_error_state(ctx, &worker_data->pbi->common.error); |
| 359 |
| 360 // Update data pointer after decode. |
| 361 *data = worker_data->data_end; |
| 362 } else { |
| 363 // TODO(hkuang): Implement frame parallel decode. |
| 364 return VPX_CODEC_INCAPABLE; |
| 365 } |
291 | 366 |
292 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) | 367 if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) |
293 set_ppflags(ctx, &flags); | 368 set_ppflags(ctx, &flags); |
294 | 369 |
295 return VPX_CODEC_OK; | 370 return VPX_CODEC_OK; |
296 } | 371 } |
297 | 372 |
298 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, | 373 static INLINE uint8_t read_marker(vpx_decrypt_cb decrypt_cb, |
299 void *decrypt_state, | 374 void *decrypt_state, |
300 const uint8_t *data) { | 375 const uint8_t *data) { |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
374 // in the superframe. | 449 // in the superframe. |
375 if (frame_count > 0) { | 450 if (frame_count > 0) { |
376 int i; | 451 int i; |
377 | 452 |
378 for (i = 0; i < frame_count; ++i) { | 453 for (i = 0; i < frame_count; ++i) { |
379 const uint8_t *data_start_copy = data_start; | 454 const uint8_t *data_start_copy = data_start; |
380 const uint32_t frame_size = frame_sizes[i]; | 455 const uint32_t frame_size = frame_sizes[i]; |
381 vpx_codec_err_t res; | 456 vpx_codec_err_t res; |
382 if (data_start < data | 457 if (data_start < data |
383 || frame_size > (uint32_t) (data_end - data_start)) { | 458 || frame_size > (uint32_t) (data_end - data_start)) { |
384 ctx->base.err_detail = "Invalid frame size in index"; | 459 set_error_detail(ctx, "Invalid frame size in index"); |
385 return VPX_CODEC_CORRUPT_FRAME; | 460 return VPX_CODEC_CORRUPT_FRAME; |
386 } | 461 } |
387 | 462 |
388 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, | 463 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
389 deadline); | 464 deadline); |
390 if (res != VPX_CODEC_OK) | 465 if (res != VPX_CODEC_OK) |
391 return res; | 466 return res; |
392 | 467 |
393 data_start += frame_size; | 468 data_start += frame_size; |
394 } | 469 } |
395 } else { | 470 } else { |
396 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); | 471 res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); |
397 if (res != VPX_CODEC_OK) | 472 if (res != VPX_CODEC_OK) |
398 return res; | 473 return res; |
399 | 474 |
400 // Extra data detected after the frame. | 475 // Extra data detected after the frame. |
401 if (data_start < data_end - 1) { | 476 if (data_start < data_end - 1) { |
402 ctx->base.err_detail = "Fail to decode frame in parallel mode"; | 477 set_error_detail(ctx, "Fail to decode frame in parallel mode"); |
403 return VPX_CODEC_INCAPABLE; | 478 return VPX_CODEC_INCAPABLE; |
404 } | 479 } |
405 } | 480 } |
406 } else { | 481 } else { |
407 // Decode in serial mode. | 482 // Decode in serial mode. |
408 if (frame_count > 0) { | 483 if (frame_count > 0) { |
409 int i; | 484 int i; |
410 | 485 |
411 for (i = 0; i < frame_count; ++i) { | 486 for (i = 0; i < frame_count; ++i) { |
412 const uint8_t *data_start_copy = data_start; | 487 const uint8_t *data_start_copy = data_start; |
413 const uint32_t frame_size = frame_sizes[i]; | 488 const uint32_t frame_size = frame_sizes[i]; |
414 vpx_codec_err_t res; | 489 vpx_codec_err_t res; |
415 if (data_start < data | 490 if (data_start < data |
416 || frame_size > (uint32_t) (data_end - data_start)) { | 491 || frame_size > (uint32_t) (data_end - data_start)) { |
417 ctx->base.err_detail = "Invalid frame size in index"; | 492 set_error_detail(ctx, "Invalid frame size in index"); |
418 return VPX_CODEC_CORRUPT_FRAME; | 493 return VPX_CODEC_CORRUPT_FRAME; |
419 } | 494 } |
420 | 495 |
421 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, | 496 res = decode_one(ctx, &data_start_copy, frame_size, user_priv, |
422 deadline); | 497 deadline); |
423 if (res != VPX_CODEC_OK) | 498 if (res != VPX_CODEC_OK) |
424 return res; | 499 return res; |
425 | 500 |
426 data_start += frame_size; | 501 data_start += frame_size; |
427 } | 502 } |
(...skipping 19 matching lines...) Expand all Loading... |
447 | 522 |
448 return VPX_CODEC_OK; | 523 return VPX_CODEC_OK; |
449 } | 524 } |
450 | 525 |
451 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, | 526 static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx, |
452 vpx_codec_iter_t *iter) { | 527 vpx_codec_iter_t *iter) { |
453 vpx_image_t *img = NULL; | 528 vpx_image_t *img = NULL; |
454 | 529 |
455 // iter acts as a flip flop, so an image is only returned on the first | 530 // iter acts as a flip flop, so an image is only returned on the first |
456 // call to get_frame. | 531 // call to get_frame. |
457 if (*iter == NULL && ctx->pbi != NULL) { | 532 if (*iter == NULL && ctx->frame_workers != NULL) { |
458 YV12_BUFFER_CONFIG sd; | 533 YV12_BUFFER_CONFIG sd; |
459 vp9_ppflags_t flags = {0, 0, 0}; | 534 vp9_ppflags_t flags = {0, 0, 0}; |
460 | 535 |
461 if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) { | 536 VP9Worker *const worker = &ctx->frame_workers[ctx->next_output_thread_id]; |
462 VP9_COMMON *cm = &ctx->pbi->common; | 537 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 538 if (vp9_get_raw_frame(worker_data->pbi, &sd, &flags) == 0) { |
| 539 VP9_COMMON *const cm = &worker_data->pbi->common; |
463 yuvconfig2image(&ctx->img, &sd, NULL); | 540 yuvconfig2image(&ctx->img, &sd, NULL); |
464 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; | 541 ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv; |
465 img = &ctx->img; | 542 img = &ctx->img; |
466 *iter = img; | 543 *iter = img; |
467 // Decrease reference count of last output frame in frame parallel mode. | 544 // Decrease reference count of last output frame in frame parallel mode. |
468 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { | 545 if (ctx->frame_parallel_decode && ctx->last_show_frame >= 0) { |
469 --cm->frame_bufs[ctx->last_show_frame].ref_count; | 546 --cm->frame_bufs[ctx->last_show_frame].ref_count; |
470 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { | 547 if (cm->frame_bufs[ctx->last_show_frame].ref_count == 0) { |
471 cm->release_fb_cb(cm->cb_priv, | 548 cm->release_fb_cb(cm->cb_priv, |
472 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); | 549 &cm->frame_bufs[ctx->last_show_frame].raw_frame_buffer); |
473 } | 550 } |
474 } | 551 } |
475 ctx->last_show_frame = ctx->pbi->common.new_fb_idx; | 552 ctx->last_show_frame = worker_data->pbi->common.new_fb_idx; |
476 } | 553 } |
477 } | 554 } |
478 | 555 |
479 return img; | 556 return img; |
480 } | 557 } |
481 | 558 |
482 static vpx_codec_err_t decoder_set_fb_fn( | 559 static vpx_codec_err_t decoder_set_fb_fn( |
483 vpx_codec_alg_priv_t *ctx, | 560 vpx_codec_alg_priv_t *ctx, |
484 vpx_get_frame_buffer_cb_fn_t cb_get, | 561 vpx_get_frame_buffer_cb_fn_t cb_get, |
485 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { | 562 vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) { |
486 if (cb_get == NULL || cb_release == NULL) { | 563 if (cb_get == NULL || cb_release == NULL) { |
487 return VPX_CODEC_INVALID_PARAM; | 564 return VPX_CODEC_INVALID_PARAM; |
488 } else if (ctx->pbi == NULL) { | 565 } else if (ctx->frame_workers == NULL) { |
489 // If the decoder has already been initialized, do not accept changes to | 566 // If the decoder has already been initialized, do not accept changes to |
490 // the frame buffer functions. | 567 // the frame buffer functions. |
491 ctx->get_ext_fb_cb = cb_get; | 568 ctx->get_ext_fb_cb = cb_get; |
492 ctx->release_ext_fb_cb = cb_release; | 569 ctx->release_ext_fb_cb = cb_release; |
493 ctx->ext_priv = cb_priv; | 570 ctx->ext_priv = cb_priv; |
494 return VPX_CODEC_OK; | 571 return VPX_CODEC_OK; |
495 } | 572 } |
496 | 573 |
497 return VPX_CODEC_ERROR; | 574 return VPX_CODEC_ERROR; |
498 } | 575 } |
499 | 576 |
500 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, | 577 static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx, |
501 va_list args) { | 578 va_list args) { |
502 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); | 579 vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *); |
503 | 580 |
| 581 // Only support this function in serial decode. |
| 582 if (ctx->frame_parallel_decode) { |
| 583 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 584 return VPX_CODEC_INCAPABLE; |
| 585 } |
| 586 |
504 if (data) { | 587 if (data) { |
505 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; | 588 vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data; |
506 YV12_BUFFER_CONFIG sd; | 589 YV12_BUFFER_CONFIG sd; |
507 | 590 VP9Worker *const worker = ctx->frame_workers; |
| 591 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
508 image2yuvconfig(&frame->img, &sd); | 592 image2yuvconfig(&frame->img, &sd); |
509 return vp9_set_reference_dec(&ctx->pbi->common, | 593 return vp9_set_reference_dec(&worker_data->pbi->common, |
510 (VP9_REFFRAME)frame->frame_type, &sd); | 594 (VP9_REFFRAME)frame->frame_type, &sd); |
511 } else { | 595 } else { |
512 return VPX_CODEC_INVALID_PARAM; | 596 return VPX_CODEC_INVALID_PARAM; |
513 } | 597 } |
514 } | 598 } |
515 | 599 |
516 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, | 600 static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx, |
517 va_list args) { | 601 va_list args) { |
518 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); | 602 vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *); |
519 | 603 |
| 604 // Only support this function in serial decode. |
| 605 if (ctx->frame_parallel_decode) { |
| 606 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 607 return VPX_CODEC_INCAPABLE; |
| 608 } |
| 609 |
520 if (data) { | 610 if (data) { |
521 vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data; | 611 vpx_ref_frame_t *frame = (vpx_ref_frame_t *) data; |
522 YV12_BUFFER_CONFIG sd; | 612 YV12_BUFFER_CONFIG sd; |
523 | 613 VP9Worker *const worker = ctx->frame_workers; |
| 614 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
524 image2yuvconfig(&frame->img, &sd); | 615 image2yuvconfig(&frame->img, &sd); |
525 | 616 return vp9_copy_reference_dec(worker_data->pbi, |
526 return vp9_copy_reference_dec(ctx->pbi, | |
527 (VP9_REFFRAME)frame->frame_type, &sd); | 617 (VP9_REFFRAME)frame->frame_type, &sd); |
528 } else { | 618 } else { |
529 return VPX_CODEC_INVALID_PARAM; | 619 return VPX_CODEC_INVALID_PARAM; |
530 } | 620 } |
531 } | 621 } |
532 | 622 |
533 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, | 623 static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx, |
534 va_list args) { | 624 va_list args) { |
535 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); | 625 vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *); |
536 | 626 |
| 627 // Only support this function in serial decode. |
| 628 if (ctx->frame_parallel_decode) { |
| 629 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 630 return VPX_CODEC_INCAPABLE; |
| 631 } |
| 632 |
537 if (data) { | 633 if (data) { |
538 YV12_BUFFER_CONFIG* fb; | 634 YV12_BUFFER_CONFIG* fb; |
539 | 635 VP9Worker *const worker = ctx->frame_workers; |
540 vp9_get_reference_dec(ctx->pbi, data->idx, &fb); | 636 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 637 vp9_get_reference_dec(worker_data->pbi, data->idx, &fb); |
541 yuvconfig2image(&data->img, fb, NULL); | 638 yuvconfig2image(&data->img, fb, NULL); |
542 return VPX_CODEC_OK; | 639 return VPX_CODEC_OK; |
543 } else { | 640 } else { |
544 return VPX_CODEC_INVALID_PARAM; | 641 return VPX_CODEC_INVALID_PARAM; |
545 } | 642 } |
546 } | 643 } |
547 | 644 |
548 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, | 645 static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx, |
549 va_list args) { | 646 va_list args) { |
550 #if CONFIG_VP9_POSTPROC | 647 #if CONFIG_VP9_POSTPROC |
(...skipping 17 matching lines...) Expand all Loading... |
568 va_list args) { | 665 va_list args) { |
569 (void)ctx; | 666 (void)ctx; |
570 (void)args; | 667 (void)args; |
571 return VPX_CODEC_INCAPABLE; | 668 return VPX_CODEC_INCAPABLE; |
572 } | 669 } |
573 | 670 |
574 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, | 671 static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx, |
575 va_list args) { | 672 va_list args) { |
576 int *const update_info = va_arg(args, int *); | 673 int *const update_info = va_arg(args, int *); |
577 | 674 |
| 675 // Only support this function in serial decode. |
| 676 if (ctx->frame_parallel_decode) { |
| 677 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 678 return VPX_CODEC_INCAPABLE; |
| 679 } |
| 680 |
578 if (update_info) { | 681 if (update_info) { |
579 if (ctx->pbi) | 682 if (ctx->frame_workers) { |
580 *update_info = ctx->pbi->refresh_frame_flags; | 683 VP9Worker *const worker = ctx->frame_workers; |
581 else | 684 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 685 *update_info = worker_data->pbi->refresh_frame_flags; |
| 686 } else { |
582 return VPX_CODEC_ERROR; | 687 return VPX_CODEC_ERROR; |
| 688 } |
583 return VPX_CODEC_OK; | 689 return VPX_CODEC_OK; |
584 } else { | 690 } else { |
585 return VPX_CODEC_INVALID_PARAM; | 691 return VPX_CODEC_INVALID_PARAM; |
586 } | 692 } |
587 } | 693 } |
588 | 694 |
589 | 695 |
590 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, | 696 static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx, |
591 va_list args) { | 697 va_list args) { |
592 int *corrupted = va_arg(args, int *); | 698 int *corrupted = va_arg(args, int *); |
593 | 699 |
| 700 // Only support this function in serial decode. |
| 701 if (ctx->frame_parallel_decode) { |
| 702 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 703 return VPX_CODEC_INCAPABLE; |
| 704 } |
| 705 |
594 if (corrupted) { | 706 if (corrupted) { |
595 if (ctx->pbi) | 707 if (ctx->frame_workers) { |
596 *corrupted = ctx->pbi->common.frame_to_show->corrupted; | 708 VP9Worker *const worker = ctx->frame_workers; |
597 else | 709 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 710 *corrupted = worker_data->pbi->common.frame_to_show->corrupted; |
| 711 } else { |
598 return VPX_CODEC_ERROR; | 712 return VPX_CODEC_ERROR; |
| 713 } |
599 return VPX_CODEC_OK; | 714 return VPX_CODEC_OK; |
600 } else { | 715 } else { |
601 return VPX_CODEC_INVALID_PARAM; | 716 return VPX_CODEC_INVALID_PARAM; |
602 } | 717 } |
603 } | 718 } |
604 | 719 |
605 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, | 720 static vpx_codec_err_t ctrl_get_display_size(vpx_codec_alg_priv_t *ctx, |
606 va_list args) { | 721 va_list args) { |
607 int *const display_size = va_arg(args, int *); | 722 int *const display_size = va_arg(args, int *); |
608 | 723 |
| 724 // Only support this function in serial decode. |
| 725 if (ctx->frame_parallel_decode) { |
| 726 set_error_detail(ctx, "Not supported in frame parallel decode"); |
| 727 return VPX_CODEC_INCAPABLE; |
| 728 } |
| 729 |
609 if (display_size) { | 730 if (display_size) { |
610 if (ctx->pbi) { | 731 if (ctx->frame_workers) { |
611 const VP9_COMMON *const cm = &ctx->pbi->common; | 732 VP9Worker *const worker = ctx->frame_workers; |
| 733 FrameWorkerData *const worker_data = (FrameWorkerData *)worker->data1; |
| 734 const VP9_COMMON *const cm = &worker_data->pbi->common; |
612 display_size[0] = cm->display_width; | 735 display_size[0] = cm->display_width; |
613 display_size[1] = cm->display_height; | 736 display_size[1] = cm->display_height; |
614 } else { | 737 } else { |
615 return VPX_CODEC_ERROR; | 738 return VPX_CODEC_ERROR; |
616 } | 739 } |
617 return VPX_CODEC_OK; | 740 return VPX_CODEC_OK; |
618 } else { | 741 } else { |
619 return VPX_CODEC_INVALID_PARAM; | 742 return VPX_CODEC_INVALID_PARAM; |
620 } | 743 } |
621 } | 744 } |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
679 { // NOLINT | 802 { // NOLINT |
680 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t | 803 NOT_IMPLEMENTED, // vpx_codec_enc_cfg_map_t |
681 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t | 804 NOT_IMPLEMENTED, // vpx_codec_encode_fn_t |
682 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t | 805 NOT_IMPLEMENTED, // vpx_codec_get_cx_data_fn_t |
683 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t | 806 NOT_IMPLEMENTED, // vpx_codec_enc_config_set_fn_t |
684 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t | 807 NOT_IMPLEMENTED, // vpx_codec_get_global_headers_fn_t |
685 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t | 808 NOT_IMPLEMENTED, // vpx_codec_get_preview_frame_fn_t |
686 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t | 809 NOT_IMPLEMENTED // vpx_codec_enc_mr_get_mem_loc_fn_t |
687 } | 810 } |
688 }; | 811 }; |
OLD | NEW |