/media/libvpx/vp8/decoder/onyxd_if.c

http://github.com/zpao/v8monkey · C · 597 lines · 442 code · 101 blank · 54 comment · 96 complexity · 4fb63de99f41f7c9d0ed1bd1a2843170 MD5 · raw file

  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. #include "vp8/common/onyxc_int.h"
  11. #if CONFIG_POSTPROC
  12. #include "vp8/common/postproc.h"
  13. #endif
  14. #include "vp8/common/onyxd.h"
  15. #include "onyxd_int.h"
  16. #include "vpx_mem/vpx_mem.h"
  17. #include "vp8/common/alloccommon.h"
  18. #include "vpx_scale/yv12extend.h"
  19. #include "vp8/common/loopfilter.h"
  20. #include "vp8/common/swapyv12buffer.h"
  21. #include "vp8/common/g_common.h"
  22. #include "vp8/common/threading.h"
  23. #include "decoderthreading.h"
  24. #include <stdio.h>
  25. #include <assert.h>
  26. #include "vp8/common/quant_common.h"
  27. #include "vpx_scale/vpxscale.h"
  28. #include "vp8/common/systemdependent.h"
  29. #include "vpx_ports/vpx_timer.h"
  30. #include "detokenize.h"
  31. #if CONFIG_ERROR_CONCEALMENT
  32. #include "error_concealment.h"
  33. #endif
  34. #if ARCH_ARM
  35. #include "vpx_ports/arm.h"
  36. #endif
  37. extern void vp8_init_loop_filter(VP8_COMMON *cm);
  38. extern void vp8cx_init_de_quantizer(VP8D_COMP *pbi);
  39. static int get_free_fb (VP8_COMMON *cm);
  40. static void ref_cnt_fb (int *buf, int *idx, int new_idx);
  41. void vp8dx_initialize()
  42. {
  43. static int init_done = 0;
  44. if (!init_done)
  45. {
  46. vp8_initialize_common();
  47. vp8_scale_machine_specific_config();
  48. init_done = 1;
  49. }
  50. }
  51. VP8D_PTR vp8dx_create_decompressor(VP8D_CONFIG *oxcf)
  52. {
  53. VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
  54. if (!pbi)
  55. return NULL;
  56. vpx_memset(pbi, 0, sizeof(VP8D_COMP));
  57. if (setjmp(pbi->common.error.jmp))
  58. {
  59. pbi->common.error.setjmp = 0;
  60. vp8dx_remove_decompressor(pbi);
  61. return 0;
  62. }
  63. pbi->common.error.setjmp = 1;
  64. vp8dx_initialize();
  65. vp8_create_common(&pbi->common);
  66. vp8_dmachine_specific_config(pbi);
  67. pbi->common.current_video_frame = 0;
  68. pbi->ready_for_new_data = 1;
  69. #if CONFIG_MULTITHREAD
  70. pbi->max_threads = oxcf->max_threads;
  71. vp8_decoder_create_threads(pbi);
  72. #endif
  73. /* vp8cx_init_de_quantizer() is first called here. Add check in frame_init_dequantizer() to avoid
  74. * unnecessary calling of vp8cx_init_de_quantizer() for every frame.
  75. */
  76. vp8cx_init_de_quantizer(pbi);
  77. vp8_loop_filter_init(&pbi->common);
  78. pbi->common.error.setjmp = 0;
  79. #if CONFIG_ERROR_CONCEALMENT
  80. pbi->ec_enabled = oxcf->error_concealment;
  81. #else
  82. pbi->ec_enabled = 0;
  83. #endif
  84. /* Error concealment is activated after a key frame has been
  85. * decoded without errors when error concealment is enabled.
  86. */
  87. pbi->ec_active = 0;
  88. pbi->decoded_key_frame = 0;
  89. pbi->input_partition = oxcf->input_partition;
  90. /* Independent partitions is activated when a frame updates the
  91. * token probability table to have equal probabilities over the
  92. * PREV_COEF context.
  93. */
  94. pbi->independent_partitions = 0;
  95. return (VP8D_PTR) pbi;
  96. }
  97. void vp8dx_remove_decompressor(VP8D_PTR ptr)
  98. {
  99. VP8D_COMP *pbi = (VP8D_COMP *) ptr;
  100. if (!pbi)
  101. return;
  102. #if CONFIG_MULTITHREAD
  103. if (pbi->b_multithreaded_rd)
  104. vp8mt_de_alloc_temp_buffers(pbi, pbi->common.mb_rows);
  105. vp8_decoder_remove_threads(pbi);
  106. #endif
  107. #if CONFIG_ERROR_CONCEALMENT
  108. vp8_de_alloc_overlap_lists(pbi);
  109. #endif
  110. vp8_remove_common(&pbi->common);
  111. vpx_free(pbi->mbc);
  112. vpx_free(pbi);
  113. }
  114. vpx_codec_err_t vp8dx_get_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
  115. {
  116. VP8D_COMP *pbi = (VP8D_COMP *) ptr;
  117. VP8_COMMON *cm = &pbi->common;
  118. int ref_fb_idx;
  119. if (ref_frame_flag == VP8_LAST_FLAG)
  120. ref_fb_idx = cm->lst_fb_idx;
  121. else if (ref_frame_flag == VP8_GOLD_FLAG)
  122. ref_fb_idx = cm->gld_fb_idx;
  123. else if (ref_frame_flag == VP8_ALT_FLAG)
  124. ref_fb_idx = cm->alt_fb_idx;
  125. else{
  126. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  127. "Invalid reference frame");
  128. return pbi->common.error.error_code;
  129. }
  130. if(cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
  131. cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
  132. cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
  133. cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width){
  134. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  135. "Incorrect buffer dimensions");
  136. }
  137. else
  138. vp8_yv12_copy_frame_ptr(&cm->yv12_fb[ref_fb_idx], sd);
  139. return pbi->common.error.error_code;
  140. }
  141. vpx_codec_err_t vp8dx_set_reference(VP8D_PTR ptr, VP8_REFFRAME ref_frame_flag, YV12_BUFFER_CONFIG *sd)
  142. {
  143. VP8D_COMP *pbi = (VP8D_COMP *) ptr;
  144. VP8_COMMON *cm = &pbi->common;
  145. int *ref_fb_ptr = NULL;
  146. int free_fb;
  147. if (ref_frame_flag == VP8_LAST_FLAG)
  148. ref_fb_ptr = &cm->lst_fb_idx;
  149. else if (ref_frame_flag == VP8_GOLD_FLAG)
  150. ref_fb_ptr = &cm->gld_fb_idx;
  151. else if (ref_frame_flag == VP8_ALT_FLAG)
  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. if(cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
  159. cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
  160. cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
  161. cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width){
  162. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  163. "Incorrect buffer dimensions");
  164. }
  165. else{
  166. /* Find an empty frame buffer. */
  167. free_fb = get_free_fb(cm);
  168. /* Decrease fb_idx_ref_cnt since it will be increased again in
  169. * ref_cnt_fb() below. */
  170. cm->fb_idx_ref_cnt[free_fb]--;
  171. /* Manage the reference counters and copy image. */
  172. ref_cnt_fb (cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
  173. vp8_yv12_copy_frame_ptr(sd, &cm->yv12_fb[*ref_fb_ptr]);
  174. }
  175. return pbi->common.error.error_code;
  176. }
  177. /*For ARM NEON, d8-d15 are callee-saved registers, and need to be saved by us.*/
  178. #if HAVE_ARMV7
  179. extern void vp8_push_neon(int64_t *store);
  180. extern void vp8_pop_neon(int64_t *store);
  181. #endif
  182. static int get_free_fb (VP8_COMMON *cm)
  183. {
  184. int i;
  185. for (i = 0; i < NUM_YV12_BUFFERS; i++)
  186. if (cm->fb_idx_ref_cnt[i] == 0)
  187. break;
  188. assert(i < NUM_YV12_BUFFERS);
  189. cm->fb_idx_ref_cnt[i] = 1;
  190. return i;
  191. }
  192. static void ref_cnt_fb (int *buf, int *idx, int new_idx)
  193. {
  194. if (buf[*idx] > 0)
  195. buf[*idx]--;
  196. *idx = new_idx;
  197. buf[new_idx]++;
  198. }
  199. /* If any buffer copy / swapping is signalled it should be done here. */
  200. static int swap_frame_buffers (VP8_COMMON *cm)
  201. {
  202. int err = 0;
  203. /* The alternate reference frame or golden frame can be updated
  204. * using the new, last, or golden/alt ref frame. If it
  205. * is updated using the newly decoded frame it is a refresh.
  206. * An update using the last or golden/alt ref frame is a copy.
  207. */
  208. if (cm->copy_buffer_to_arf)
  209. {
  210. int new_fb = 0;
  211. if (cm->copy_buffer_to_arf == 1)
  212. new_fb = cm->lst_fb_idx;
  213. else if (cm->copy_buffer_to_arf == 2)
  214. new_fb = cm->gld_fb_idx;
  215. else
  216. err = -1;
  217. ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
  218. }
  219. if (cm->copy_buffer_to_gf)
  220. {
  221. int new_fb = 0;
  222. if (cm->copy_buffer_to_gf == 1)
  223. new_fb = cm->lst_fb_idx;
  224. else if (cm->copy_buffer_to_gf == 2)
  225. new_fb = cm->alt_fb_idx;
  226. else
  227. err = -1;
  228. ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
  229. }
  230. if (cm->refresh_golden_frame)
  231. ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
  232. if (cm->refresh_alt_ref_frame)
  233. ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
  234. if (cm->refresh_last_frame)
  235. {
  236. ref_cnt_fb (cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
  237. cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
  238. }
  239. else
  240. cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
  241. cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
  242. return err;
  243. }
  244. int vp8dx_receive_compressed_data(VP8D_PTR ptr, unsigned long size, const unsigned char *source, int64_t time_stamp)
  245. {
  246. #if HAVE_ARMV7
  247. int64_t dx_store_reg[8];
  248. #endif
  249. VP8D_COMP *pbi = (VP8D_COMP *) ptr;
  250. VP8_COMMON *cm = &pbi->common;
  251. int retcode = 0;
  252. /*if(pbi->ready_for_new_data == 0)
  253. return -1;*/
  254. if (ptr == 0)
  255. {
  256. return -1;
  257. }
  258. pbi->common.error.error_code = VPX_CODEC_OK;
  259. if (pbi->input_partition && !(source == NULL && size == 0))
  260. {
  261. /* Store a pointer to this partition and return. We haven't
  262. * received the complete frame yet, so we will wait with decoding.
  263. */
  264. pbi->partitions[pbi->num_partitions] = source;
  265. pbi->partition_sizes[pbi->num_partitions] = size;
  266. pbi->source_sz += size;
  267. pbi->num_partitions++;
  268. if (pbi->num_partitions > (1<<pbi->common.multi_token_partition) + 1)
  269. pbi->common.multi_token_partition++;
  270. if (pbi->common.multi_token_partition > EIGHT_PARTITION)
  271. {
  272. pbi->common.error.error_code = VPX_CODEC_UNSUP_BITSTREAM;
  273. pbi->common.error.setjmp = 0;
  274. return -1;
  275. }
  276. return 0;
  277. }
  278. else
  279. {
  280. if (!pbi->input_partition)
  281. {
  282. pbi->Source = source;
  283. pbi->source_sz = size;
  284. }
  285. if (pbi->source_sz == 0)
  286. {
  287. /* This is used to signal that we are missing frames.
  288. * We do not know if the missing frame(s) was supposed to update
  289. * any of the reference buffers, but we act conservative and
  290. * mark only the last buffer as corrupted.
  291. */
  292. cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
  293. /* If error concealment is disabled we won't signal missing frames to
  294. * the decoder.
  295. */
  296. if (!pbi->ec_active)
  297. {
  298. /* Signal that we have no frame to show. */
  299. cm->show_frame = 0;
  300. pbi->num_partitions = 0;
  301. if (pbi->input_partition)
  302. pbi->common.multi_token_partition = 0;
  303. /* Nothing more to do. */
  304. return 0;
  305. }
  306. }
  307. #if HAVE_ARMV7
  308. #if CONFIG_RUNTIME_CPU_DETECT
  309. if (cm->rtcd.flags & HAS_NEON)
  310. #endif
  311. {
  312. vp8_push_neon(dx_store_reg);
  313. }
  314. #endif
  315. cm->new_fb_idx = get_free_fb (cm);
  316. if (setjmp(pbi->common.error.jmp))
  317. {
  318. #if HAVE_ARMV7
  319. #if CONFIG_RUNTIME_CPU_DETECT
  320. if (cm->rtcd.flags & HAS_NEON)
  321. #endif
  322. {
  323. vp8_pop_neon(dx_store_reg);
  324. }
  325. #endif
  326. pbi->common.error.setjmp = 0;
  327. pbi->num_partitions = 0;
  328. if (pbi->input_partition)
  329. pbi->common.multi_token_partition = 0;
  330. /* We do not know if the missing frame(s) was supposed to update
  331. * any of the reference buffers, but we act conservative and
  332. * mark only the last buffer as corrupted.
  333. */
  334. cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
  335. if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
  336. cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
  337. return -1;
  338. }
  339. pbi->common.error.setjmp = 1;
  340. }
  341. retcode = vp8_decode_frame(pbi);
  342. if (retcode < 0)
  343. {
  344. #if HAVE_ARMV7
  345. #if CONFIG_RUNTIME_CPU_DETECT
  346. if (cm->rtcd.flags & HAS_NEON)
  347. #endif
  348. {
  349. vp8_pop_neon(dx_store_reg);
  350. }
  351. #endif
  352. pbi->common.error.error_code = VPX_CODEC_ERROR;
  353. pbi->common.error.setjmp = 0;
  354. if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0)
  355. cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
  356. return retcode;
  357. }
  358. #if CONFIG_MULTITHREAD
  359. if (pbi->b_multithreaded_rd && cm->multi_token_partition != ONE_PARTITION)
  360. {
  361. if (swap_frame_buffers (cm))
  362. {
  363. #if HAVE_ARMV7
  364. #if CONFIG_RUNTIME_CPU_DETECT
  365. if (cm->rtcd.flags & HAS_NEON)
  366. #endif
  367. {
  368. vp8_pop_neon(dx_store_reg);
  369. }
  370. #endif
  371. pbi->common.error.error_code = VPX_CODEC_ERROR;
  372. pbi->common.error.setjmp = 0;
  373. return -1;
  374. }
  375. } else
  376. #endif
  377. {
  378. if (swap_frame_buffers (cm))
  379. {
  380. #if HAVE_ARMV7
  381. #if CONFIG_RUNTIME_CPU_DETECT
  382. if (cm->rtcd.flags & HAS_NEON)
  383. #endif
  384. {
  385. vp8_pop_neon(dx_store_reg);
  386. }
  387. #endif
  388. pbi->common.error.error_code = VPX_CODEC_ERROR;
  389. pbi->common.error.setjmp = 0;
  390. return -1;
  391. }
  392. if(cm->filter_level)
  393. {
  394. /* Apply the loop filter if appropriate. */
  395. vp8_loop_filter_frame(cm, &pbi->mb);
  396. }
  397. vp8_yv12_extend_frame_borders_ptr(cm->frame_to_show);
  398. }
  399. vp8_clear_system_state();
  400. #if CONFIG_ERROR_CONCEALMENT
  401. /* swap the mode infos to storage for future error concealment */
  402. if (pbi->ec_enabled && pbi->common.prev_mi)
  403. {
  404. const MODE_INFO* tmp = pbi->common.prev_mi;
  405. int row, col;
  406. pbi->common.prev_mi = pbi->common.mi;
  407. pbi->common.mi = tmp;
  408. /* Propagate the segment_ids to the next frame */
  409. for (row = 0; row < pbi->common.mb_rows; ++row)
  410. {
  411. for (col = 0; col < pbi->common.mb_cols; ++col)
  412. {
  413. const int i = row*pbi->common.mode_info_stride + col;
  414. pbi->common.mi[i].mbmi.segment_id =
  415. pbi->common.prev_mi[i].mbmi.segment_id;
  416. }
  417. }
  418. }
  419. #endif
  420. /*vp8_print_modes_and_motion_vectors( cm->mi, cm->mb_rows,cm->mb_cols, cm->current_video_frame);*/
  421. if (cm->show_frame)
  422. cm->current_video_frame++;
  423. pbi->ready_for_new_data = 0;
  424. pbi->last_time_stamp = time_stamp;
  425. pbi->num_partitions = 0;
  426. if (pbi->input_partition)
  427. pbi->common.multi_token_partition = 0;
  428. pbi->source_sz = 0;
  429. #if 0
  430. {
  431. int i;
  432. int64_t earliest_time = pbi->dr[0].time_stamp;
  433. int64_t latest_time = pbi->dr[0].time_stamp;
  434. int64_t time_diff = 0;
  435. int bytes = 0;
  436. pbi->dr[pbi->common.current_video_frame&0xf].size = pbi->bc.pos + pbi->bc2.pos + 4;;
  437. pbi->dr[pbi->common.current_video_frame&0xf].time_stamp = time_stamp;
  438. for (i = 0; i < 16; i++)
  439. {
  440. bytes += pbi->dr[i].size;
  441. if (pbi->dr[i].time_stamp < earliest_time)
  442. earliest_time = pbi->dr[i].time_stamp;
  443. if (pbi->dr[i].time_stamp > latest_time)
  444. latest_time = pbi->dr[i].time_stamp;
  445. }
  446. time_diff = latest_time - earliest_time;
  447. if (time_diff > 0)
  448. {
  449. pbi->common.bitrate = 80000.00 * bytes / time_diff ;
  450. pbi->common.framerate = 160000000.00 / time_diff ;
  451. }
  452. }
  453. #endif
  454. #if HAVE_ARMV7
  455. #if CONFIG_RUNTIME_CPU_DETECT
  456. if (cm->rtcd.flags & HAS_NEON)
  457. #endif
  458. {
  459. vp8_pop_neon(dx_store_reg);
  460. }
  461. #endif
  462. pbi->common.error.setjmp = 0;
  463. return retcode;
  464. }
  465. int vp8dx_get_raw_frame(VP8D_PTR ptr, YV12_BUFFER_CONFIG *sd, int64_t *time_stamp, int64_t *time_end_stamp, vp8_ppflags_t *flags)
  466. {
  467. int ret = -1;
  468. VP8D_COMP *pbi = (VP8D_COMP *) ptr;
  469. if (pbi->ready_for_new_data == 1)
  470. return ret;
  471. /* ie no raw frame to show!!! */
  472. if (pbi->common.show_frame == 0)
  473. return ret;
  474. pbi->ready_for_new_data = 1;
  475. *time_stamp = pbi->last_time_stamp;
  476. *time_end_stamp = 0;
  477. sd->clrtype = pbi->common.clr_type;
  478. #if CONFIG_POSTPROC
  479. ret = vp8_post_proc_frame(&pbi->common, sd, flags);
  480. #else
  481. if (pbi->common.frame_to_show)
  482. {
  483. *sd = *pbi->common.frame_to_show;
  484. sd->y_width = pbi->common.Width;
  485. sd->y_height = pbi->common.Height;
  486. sd->uv_height = pbi->common.Height / 2;
  487. ret = 0;
  488. }
  489. else
  490. {
  491. ret = -1;
  492. }
  493. #endif /*!CONFIG_POSTPROC*/
  494. vp8_clear_system_state();
  495. return ret;
  496. }