2
0

onyxd_if.c 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467
  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 "vp8/common/common.h"
  19. #include "vp8/common/loopfilter.h"
  20. #include "vp8/common/swapyv12buffer.h"
  21. #include "vp8/common/threading.h"
  22. #include "decoderthreading.h"
  23. #include <stdio.h>
  24. #include <assert.h>
  25. #include "vp8/common/quant_common.h"
  26. #include "vp8/common/reconintra.h"
  27. #include "./vpx_dsp_rtcd.h"
  28. #include "./vpx_scale_rtcd.h"
  29. #include "vpx_scale/vpx_scale.h"
  30. #include "vp8/common/systemdependent.h"
  31. #include "vpx_ports/system_state.h"
  32. #include "vpx_ports/vpx_once.h"
  33. #include "vpx_ports/vpx_timer.h"
  34. #include "detokenize.h"
  35. #if CONFIG_ERROR_CONCEALMENT
  36. #include "error_concealment.h"
  37. #endif
  38. #if ARCH_ARM
  39. #include "vpx_ports/arm.h"
  40. #endif
  41. extern void vp8_init_loop_filter(VP8_COMMON *cm);
  42. static int get_free_fb(VP8_COMMON *cm);
  43. static void ref_cnt_fb(int *buf, int *idx, int new_idx);
  44. static void initialize_dec(void) {
  45. static volatile int init_done = 0;
  46. if (!init_done) {
  47. vpx_dsp_rtcd();
  48. vp8_init_intra_predictors();
  49. init_done = 1;
  50. }
  51. }
  52. static void remove_decompressor(VP8D_COMP *pbi) {
  53. #if CONFIG_ERROR_CONCEALMENT
  54. vp8_de_alloc_overlap_lists(pbi);
  55. #endif
  56. vp8_remove_common(&pbi->common);
  57. vpx_free(pbi);
  58. }
  59. static struct VP8D_COMP *create_decompressor(VP8D_CONFIG *oxcf) {
  60. VP8D_COMP *pbi = vpx_memalign(32, sizeof(VP8D_COMP));
  61. if (!pbi) return NULL;
  62. memset(pbi, 0, sizeof(VP8D_COMP));
  63. if (setjmp(pbi->common.error.jmp)) {
  64. pbi->common.error.setjmp = 0;
  65. remove_decompressor(pbi);
  66. return 0;
  67. }
  68. pbi->common.error.setjmp = 1;
  69. vp8_create_common(&pbi->common);
  70. pbi->common.current_video_frame = 0;
  71. pbi->ready_for_new_data = 1;
  72. /* vp8cx_init_de_quantizer() is first called here. Add check in
  73. * 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. pbi->overlaps = NULL;
  82. #else
  83. (void)oxcf;
  84. pbi->ec_enabled = 0;
  85. #endif
  86. /* Error concealment is activated after a key frame has been
  87. * decoded without errors when error concealment is enabled.
  88. */
  89. pbi->ec_active = 0;
  90. pbi->decoded_key_frame = 0;
  91. /* Independent partitions is activated when a frame updates the
  92. * token probability table to have equal probabilities over the
  93. * PREV_COEF context.
  94. */
  95. pbi->independent_partitions = 0;
  96. vp8_setup_block_dptrs(&pbi->mb);
  97. once(initialize_dec);
  98. return pbi;
  99. }
  100. vpx_codec_err_t vp8dx_get_reference(VP8D_COMP *pbi,
  101. enum vpx_ref_frame_type ref_frame_flag,
  102. YV12_BUFFER_CONFIG *sd) {
  103. VP8_COMMON *cm = &pbi->common;
  104. int ref_fb_idx;
  105. if (ref_frame_flag == VP8_LAST_FRAME) {
  106. ref_fb_idx = cm->lst_fb_idx;
  107. } else if (ref_frame_flag == VP8_GOLD_FRAME) {
  108. ref_fb_idx = cm->gld_fb_idx;
  109. } else if (ref_frame_flag == VP8_ALTR_FRAME) {
  110. ref_fb_idx = cm->alt_fb_idx;
  111. } else {
  112. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  113. "Invalid reference frame");
  114. return pbi->common.error.error_code;
  115. }
  116. if (cm->yv12_fb[ref_fb_idx].y_height != sd->y_height ||
  117. cm->yv12_fb[ref_fb_idx].y_width != sd->y_width ||
  118. cm->yv12_fb[ref_fb_idx].uv_height != sd->uv_height ||
  119. cm->yv12_fb[ref_fb_idx].uv_width != sd->uv_width) {
  120. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  121. "Incorrect buffer dimensions");
  122. } else
  123. vp8_yv12_copy_frame(&cm->yv12_fb[ref_fb_idx], sd);
  124. return pbi->common.error.error_code;
  125. }
  126. vpx_codec_err_t vp8dx_set_reference(VP8D_COMP *pbi,
  127. enum vpx_ref_frame_type ref_frame_flag,
  128. YV12_BUFFER_CONFIG *sd) {
  129. VP8_COMMON *cm = &pbi->common;
  130. int *ref_fb_ptr = NULL;
  131. int free_fb;
  132. if (ref_frame_flag == VP8_LAST_FRAME) {
  133. ref_fb_ptr = &cm->lst_fb_idx;
  134. } else if (ref_frame_flag == VP8_GOLD_FRAME) {
  135. ref_fb_ptr = &cm->gld_fb_idx;
  136. } else if (ref_frame_flag == VP8_ALTR_FRAME) {
  137. ref_fb_ptr = &cm->alt_fb_idx;
  138. } else {
  139. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  140. "Invalid reference frame");
  141. return pbi->common.error.error_code;
  142. }
  143. if (cm->yv12_fb[*ref_fb_ptr].y_height != sd->y_height ||
  144. cm->yv12_fb[*ref_fb_ptr].y_width != sd->y_width ||
  145. cm->yv12_fb[*ref_fb_ptr].uv_height != sd->uv_height ||
  146. cm->yv12_fb[*ref_fb_ptr].uv_width != sd->uv_width) {
  147. vpx_internal_error(&pbi->common.error, VPX_CODEC_ERROR,
  148. "Incorrect buffer dimensions");
  149. } else {
  150. /* Find an empty frame buffer. */
  151. free_fb = get_free_fb(cm);
  152. /* Decrease fb_idx_ref_cnt since it will be increased again in
  153. * ref_cnt_fb() below. */
  154. cm->fb_idx_ref_cnt[free_fb]--;
  155. /* Manage the reference counters and copy image. */
  156. ref_cnt_fb(cm->fb_idx_ref_cnt, ref_fb_ptr, free_fb);
  157. vp8_yv12_copy_frame(sd, &cm->yv12_fb[*ref_fb_ptr]);
  158. }
  159. return pbi->common.error.error_code;
  160. }
  161. static int get_free_fb(VP8_COMMON *cm) {
  162. int i;
  163. for (i = 0; i < NUM_YV12_BUFFERS; ++i) {
  164. if (cm->fb_idx_ref_cnt[i] == 0) break;
  165. }
  166. assert(i < NUM_YV12_BUFFERS);
  167. cm->fb_idx_ref_cnt[i] = 1;
  168. return i;
  169. }
  170. static void ref_cnt_fb(int *buf, int *idx, int new_idx) {
  171. if (buf[*idx] > 0) buf[*idx]--;
  172. *idx = new_idx;
  173. buf[new_idx]++;
  174. }
  175. /* If any buffer copy / swapping is signalled it should be done here. */
  176. static int swap_frame_buffers(VP8_COMMON *cm) {
  177. int err = 0;
  178. /* The alternate reference frame or golden frame can be updated
  179. * using the new, last, or golden/alt ref frame. If it
  180. * is updated using the newly decoded frame it is a refresh.
  181. * An update using the last or golden/alt ref frame is a copy.
  182. */
  183. if (cm->copy_buffer_to_arf) {
  184. int new_fb = 0;
  185. if (cm->copy_buffer_to_arf == 1) {
  186. new_fb = cm->lst_fb_idx;
  187. } else if (cm->copy_buffer_to_arf == 2) {
  188. new_fb = cm->gld_fb_idx;
  189. } else {
  190. err = -1;
  191. }
  192. ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, new_fb);
  193. }
  194. if (cm->copy_buffer_to_gf) {
  195. int new_fb = 0;
  196. if (cm->copy_buffer_to_gf == 1) {
  197. new_fb = cm->lst_fb_idx;
  198. } else if (cm->copy_buffer_to_gf == 2) {
  199. new_fb = cm->alt_fb_idx;
  200. } else {
  201. err = -1;
  202. }
  203. ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, new_fb);
  204. }
  205. if (cm->refresh_golden_frame) {
  206. ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->gld_fb_idx, cm->new_fb_idx);
  207. }
  208. if (cm->refresh_alt_ref_frame) {
  209. ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->alt_fb_idx, cm->new_fb_idx);
  210. }
  211. if (cm->refresh_last_frame) {
  212. ref_cnt_fb(cm->fb_idx_ref_cnt, &cm->lst_fb_idx, cm->new_fb_idx);
  213. cm->frame_to_show = &cm->yv12_fb[cm->lst_fb_idx];
  214. } else {
  215. cm->frame_to_show = &cm->yv12_fb[cm->new_fb_idx];
  216. }
  217. cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
  218. return err;
  219. }
  220. static int check_fragments_for_errors(VP8D_COMP *pbi) {
  221. if (!pbi->ec_active && pbi->fragments.count <= 1 &&
  222. pbi->fragments.sizes[0] == 0) {
  223. VP8_COMMON *cm = &pbi->common;
  224. /* If error concealment is disabled we won't signal missing frames
  225. * to the decoder.
  226. */
  227. if (cm->fb_idx_ref_cnt[cm->lst_fb_idx] > 1) {
  228. /* The last reference shares buffer with another reference
  229. * buffer. Move it to its own buffer before setting it as
  230. * corrupt, otherwise we will make multiple buffers corrupt.
  231. */
  232. const int prev_idx = cm->lst_fb_idx;
  233. cm->fb_idx_ref_cnt[prev_idx]--;
  234. cm->lst_fb_idx = get_free_fb(cm);
  235. vp8_yv12_copy_frame(&cm->yv12_fb[prev_idx], &cm->yv12_fb[cm->lst_fb_idx]);
  236. }
  237. /* This is used to signal that we are missing frames.
  238. * We do not know if the missing frame(s) was supposed to update
  239. * any of the reference buffers, but we act conservative and
  240. * mark only the last buffer as corrupted.
  241. */
  242. cm->yv12_fb[cm->lst_fb_idx].corrupted = 1;
  243. /* Signal that we have no frame to show. */
  244. cm->show_frame = 0;
  245. /* Nothing more to do. */
  246. return 0;
  247. }
  248. return 1;
  249. }
  250. int vp8dx_receive_compressed_data(VP8D_COMP *pbi, size_t size,
  251. const uint8_t *source, int64_t time_stamp) {
  252. VP8_COMMON *cm = &pbi->common;
  253. int retcode = -1;
  254. (void)size;
  255. (void)source;
  256. pbi->common.error.error_code = VPX_CODEC_OK;
  257. retcode = check_fragments_for_errors(pbi);
  258. if (retcode <= 0) return retcode;
  259. cm->new_fb_idx = get_free_fb(cm);
  260. /* setup reference frames for vp8_decode_frame */
  261. pbi->dec_fb_ref[INTRA_FRAME] = &cm->yv12_fb[cm->new_fb_idx];
  262. pbi->dec_fb_ref[LAST_FRAME] = &cm->yv12_fb[cm->lst_fb_idx];
  263. pbi->dec_fb_ref[GOLDEN_FRAME] = &cm->yv12_fb[cm->gld_fb_idx];
  264. pbi->dec_fb_ref[ALTREF_FRAME] = &cm->yv12_fb[cm->alt_fb_idx];
  265. retcode = vp8_decode_frame(pbi);
  266. if (retcode < 0) {
  267. if (cm->fb_idx_ref_cnt[cm->new_fb_idx] > 0) {
  268. cm->fb_idx_ref_cnt[cm->new_fb_idx]--;
  269. }
  270. pbi->common.error.error_code = VPX_CODEC_ERROR;
  271. // Propagate the error info.
  272. if (pbi->mb.error_info.error_code != 0) {
  273. pbi->common.error.error_code = pbi->mb.error_info.error_code;
  274. memcpy(pbi->common.error.detail, pbi->mb.error_info.detail,
  275. sizeof(pbi->mb.error_info.detail));
  276. }
  277. goto decode_exit;
  278. }
  279. if (swap_frame_buffers(cm)) {
  280. pbi->common.error.error_code = VPX_CODEC_ERROR;
  281. goto decode_exit;
  282. }
  283. vpx_clear_system_state();
  284. if (cm->show_frame) {
  285. cm->current_video_frame++;
  286. cm->show_frame_mi = cm->mi;
  287. }
  288. #if CONFIG_ERROR_CONCEALMENT
  289. /* swap the mode infos to storage for future error concealment */
  290. if (pbi->ec_enabled && pbi->common.prev_mi) {
  291. MODE_INFO *tmp = pbi->common.prev_mi;
  292. int row, col;
  293. pbi->common.prev_mi = pbi->common.mi;
  294. pbi->common.mi = tmp;
  295. /* Propagate the segment_ids to the next frame */
  296. for (row = 0; row < pbi->common.mb_rows; ++row) {
  297. for (col = 0; col < pbi->common.mb_cols; ++col) {
  298. const int i = row * pbi->common.mode_info_stride + col;
  299. pbi->common.mi[i].mbmi.segment_id =
  300. pbi->common.prev_mi[i].mbmi.segment_id;
  301. }
  302. }
  303. }
  304. #endif
  305. pbi->ready_for_new_data = 0;
  306. pbi->last_time_stamp = time_stamp;
  307. decode_exit:
  308. vpx_clear_system_state();
  309. return retcode;
  310. }
  311. int vp8dx_get_raw_frame(VP8D_COMP *pbi, YV12_BUFFER_CONFIG *sd,
  312. int64_t *time_stamp, int64_t *time_end_stamp,
  313. vp8_ppflags_t *flags) {
  314. int ret = -1;
  315. if (pbi->ready_for_new_data == 1) return ret;
  316. /* ie no raw frame to show!!! */
  317. if (pbi->common.show_frame == 0) return ret;
  318. pbi->ready_for_new_data = 1;
  319. *time_stamp = pbi->last_time_stamp;
  320. *time_end_stamp = 0;
  321. #if CONFIG_POSTPROC
  322. ret = vp8_post_proc_frame(&pbi->common, sd, flags);
  323. #else
  324. (void)flags;
  325. if (pbi->common.frame_to_show) {
  326. *sd = *pbi->common.frame_to_show;
  327. sd->y_width = pbi->common.Width;
  328. sd->y_height = pbi->common.Height;
  329. sd->uv_height = pbi->common.Height / 2;
  330. ret = 0;
  331. } else {
  332. ret = -1;
  333. }
  334. #endif /*!CONFIG_POSTPROC*/
  335. vpx_clear_system_state();
  336. return ret;
  337. }
  338. /* This function as written isn't decoder specific, but the encoder has
  339. * much faster ways of computing this, so it's ok for it to live in a
  340. * decode specific file.
  341. */
  342. int vp8dx_references_buffer(VP8_COMMON *oci, int ref_frame) {
  343. const MODE_INFO *mi = oci->mi;
  344. int mb_row, mb_col;
  345. for (mb_row = 0; mb_row < oci->mb_rows; ++mb_row) {
  346. for (mb_col = 0; mb_col < oci->mb_cols; mb_col++, mi++) {
  347. if (mi->mbmi.ref_frame == ref_frame) return 1;
  348. }
  349. mi++;
  350. }
  351. return 0;
  352. }
  353. int vp8_create_decoder_instances(struct frame_buffers *fb, VP8D_CONFIG *oxcf) {
  354. /* decoder instance for single thread mode */
  355. fb->pbi[0] = create_decompressor(oxcf);
  356. if (!fb->pbi[0]) return VPX_CODEC_ERROR;
  357. #if CONFIG_MULTITHREAD
  358. if (setjmp(fb->pbi[0]->common.error.jmp)) {
  359. vp8_remove_decoder_instances(fb);
  360. vp8_zero(fb->pbi);
  361. vpx_clear_system_state();
  362. return VPX_CODEC_ERROR;
  363. }
  364. fb->pbi[0]->common.error.setjmp = 1;
  365. fb->pbi[0]->max_threads = oxcf->max_threads;
  366. vp8_decoder_create_threads(fb->pbi[0]);
  367. fb->pbi[0]->common.error.setjmp = 0;
  368. #endif
  369. return VPX_CODEC_OK;
  370. }
  371. int vp8_remove_decoder_instances(struct frame_buffers *fb) {
  372. VP8D_COMP *pbi = fb->pbi[0];
  373. if (!pbi) return VPX_CODEC_ERROR;
  374. #if CONFIG_MULTITHREAD
  375. vp8_decoder_remove_threads(pbi);
  376. #endif
  377. /* decoder instance for single thread mode */
  378. remove_decompressor(pbi);
  379. return VPX_CODEC_OK;
  380. }
  381. int vp8dx_get_quantizer(const VP8D_COMP *pbi) {
  382. return pbi->common.base_qindex;
  383. }