vp9_dx_iface.c 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730
  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 <stdlib.h>
  11. #include <string.h>
  12. #include "./vpx_config.h"
  13. #include "./vpx_version.h"
  14. #include "vpx/internal/vpx_codec_internal.h"
  15. #include "vpx/vp8dx.h"
  16. #include "vpx/vpx_decoder.h"
  17. #include "vpx_dsp/bitreader_buffer.h"
  18. #include "vpx_dsp/vpx_dsp_common.h"
  19. #include "vpx_util/vpx_thread.h"
  20. #include "vp9/common/vp9_alloccommon.h"
  21. #include "vp9/common/vp9_frame_buffers.h"
  22. #include "vp9/decoder/vp9_decodeframe.h"
  23. #include "vp9/vp9_dx_iface.h"
  24. #include "vp9/vp9_iface_common.h"
  25. #define VP9_CAP_POSTPROC (CONFIG_VP9_POSTPROC ? VPX_CODEC_CAP_POSTPROC : 0)
  26. static vpx_codec_err_t decoder_init(vpx_codec_ctx_t *ctx,
  27. vpx_codec_priv_enc_mr_cfg_t *data) {
  28. // This function only allocates space for the vpx_codec_alg_priv_t
  29. // structure. More memory may be required at the time the stream
  30. // information becomes known.
  31. (void)data;
  32. if (!ctx->priv) {
  33. vpx_codec_alg_priv_t *const priv =
  34. (vpx_codec_alg_priv_t *)vpx_calloc(1, sizeof(*priv));
  35. if (priv == NULL) return VPX_CODEC_MEM_ERROR;
  36. ctx->priv = (vpx_codec_priv_t *)priv;
  37. ctx->priv->init_flags = ctx->init_flags;
  38. priv->si.sz = sizeof(priv->si);
  39. priv->flushed = 0;
  40. if (ctx->config.dec) {
  41. priv->cfg = *ctx->config.dec;
  42. ctx->config.dec = &priv->cfg;
  43. }
  44. }
  45. return VPX_CODEC_OK;
  46. }
  47. static vpx_codec_err_t decoder_destroy(vpx_codec_alg_priv_t *ctx) {
  48. if (ctx->pbi != NULL) {
  49. vp9_decoder_remove(ctx->pbi);
  50. }
  51. if (ctx->buffer_pool) {
  52. vp9_free_ref_frame_buffers(ctx->buffer_pool);
  53. vp9_free_internal_frame_buffers(&ctx->buffer_pool->int_frame_buffers);
  54. }
  55. vpx_free(ctx->buffer_pool);
  56. vpx_free(ctx);
  57. return VPX_CODEC_OK;
  58. }
  59. static int parse_bitdepth_colorspace_sampling(BITSTREAM_PROFILE profile,
  60. struct vpx_read_bit_buffer *rb) {
  61. vpx_color_space_t color_space;
  62. if (profile >= PROFILE_2) rb->bit_offset += 1; // Bit-depth 10 or 12.
  63. color_space = (vpx_color_space_t)vpx_rb_read_literal(rb, 3);
  64. if (color_space != VPX_CS_SRGB) {
  65. rb->bit_offset += 1; // [16,235] (including xvycc) vs [0,255] range.
  66. if (profile == PROFILE_1 || profile == PROFILE_3) {
  67. rb->bit_offset += 2; // subsampling x/y.
  68. rb->bit_offset += 1; // unused.
  69. }
  70. } else {
  71. if (profile == PROFILE_1 || profile == PROFILE_3) {
  72. rb->bit_offset += 1; // unused
  73. } else {
  74. // RGB is only available in version 1.
  75. return 0;
  76. }
  77. }
  78. return 1;
  79. }
  80. static vpx_codec_err_t decoder_peek_si_internal(
  81. const uint8_t *data, unsigned int data_sz, vpx_codec_stream_info_t *si,
  82. int *is_intra_only, vpx_decrypt_cb decrypt_cb, void *decrypt_state) {
  83. int intra_only_flag = 0;
  84. uint8_t clear_buffer[11];
  85. if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM;
  86. si->is_kf = 0;
  87. si->w = si->h = 0;
  88. if (decrypt_cb) {
  89. data_sz = VPXMIN(sizeof(clear_buffer), data_sz);
  90. decrypt_cb(decrypt_state, data, clear_buffer, data_sz);
  91. data = clear_buffer;
  92. }
  93. // A maximum of 6 bits are needed to read the frame marker, profile and
  94. // show_existing_frame.
  95. if (data_sz < 1) return VPX_CODEC_UNSUP_BITSTREAM;
  96. {
  97. int show_frame;
  98. int error_resilient;
  99. struct vpx_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
  100. const int frame_marker = vpx_rb_read_literal(&rb, 2);
  101. const BITSTREAM_PROFILE profile = vp9_read_profile(&rb);
  102. if (frame_marker != VP9_FRAME_MARKER) return VPX_CODEC_UNSUP_BITSTREAM;
  103. if (profile >= MAX_PROFILES) return VPX_CODEC_UNSUP_BITSTREAM;
  104. if (vpx_rb_read_bit(&rb)) { // show an existing frame
  105. // If profile is > 2 and show_existing_frame is true, then at least 1 more
  106. // byte (6+3=9 bits) is needed.
  107. if (profile > 2 && data_sz < 2) return VPX_CODEC_UNSUP_BITSTREAM;
  108. vpx_rb_read_literal(&rb, 3); // Frame buffer to show.
  109. return VPX_CODEC_OK;
  110. }
  111. // For the rest of the function, a maximum of 9 more bytes are needed
  112. // (computed by taking the maximum possible bits needed in each case). Note
  113. // that this has to be updated if we read any more bits in this function.
  114. if (data_sz < 10) return VPX_CODEC_UNSUP_BITSTREAM;
  115. si->is_kf = !vpx_rb_read_bit(&rb);
  116. show_frame = vpx_rb_read_bit(&rb);
  117. error_resilient = vpx_rb_read_bit(&rb);
  118. if (si->is_kf) {
  119. if (!vp9_read_sync_code(&rb)) return VPX_CODEC_UNSUP_BITSTREAM;
  120. if (!parse_bitdepth_colorspace_sampling(profile, &rb))
  121. return VPX_CODEC_UNSUP_BITSTREAM;
  122. vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h);
  123. } else {
  124. intra_only_flag = show_frame ? 0 : vpx_rb_read_bit(&rb);
  125. rb.bit_offset += error_resilient ? 0 : 2; // reset_frame_context
  126. if (intra_only_flag) {
  127. if (!vp9_read_sync_code(&rb)) return VPX_CODEC_UNSUP_BITSTREAM;
  128. if (profile > PROFILE_0) {
  129. if (!parse_bitdepth_colorspace_sampling(profile, &rb))
  130. return VPX_CODEC_UNSUP_BITSTREAM;
  131. // The colorspace info may cause vp9_read_frame_size() to need 11
  132. // bytes.
  133. if (data_sz < 11) return VPX_CODEC_UNSUP_BITSTREAM;
  134. }
  135. rb.bit_offset += REF_FRAMES; // refresh_frame_flags
  136. vp9_read_frame_size(&rb, (int *)&si->w, (int *)&si->h);
  137. }
  138. }
  139. }
  140. if (is_intra_only != NULL) *is_intra_only = intra_only_flag;
  141. return VPX_CODEC_OK;
  142. }
  143. static vpx_codec_err_t decoder_peek_si(const uint8_t *data,
  144. unsigned int data_sz,
  145. vpx_codec_stream_info_t *si) {
  146. return decoder_peek_si_internal(data, data_sz, si, NULL, NULL, NULL);
  147. }
  148. static vpx_codec_err_t decoder_get_si(vpx_codec_alg_priv_t *ctx,
  149. vpx_codec_stream_info_t *si) {
  150. const size_t sz = (si->sz >= sizeof(vp9_stream_info_t))
  151. ? sizeof(vp9_stream_info_t)
  152. : sizeof(vpx_codec_stream_info_t);
  153. memcpy(si, &ctx->si, sz);
  154. si->sz = (unsigned int)sz;
  155. return VPX_CODEC_OK;
  156. }
  157. static void set_error_detail(vpx_codec_alg_priv_t *ctx,
  158. const char *const error) {
  159. ctx->base.err_detail = error;
  160. }
  161. static vpx_codec_err_t update_error_state(
  162. vpx_codec_alg_priv_t *ctx, const struct vpx_internal_error_info *error) {
  163. if (error->error_code)
  164. set_error_detail(ctx, error->has_detail ? error->detail : NULL);
  165. return error->error_code;
  166. }
  167. static void init_buffer_callbacks(vpx_codec_alg_priv_t *ctx) {
  168. VP9_COMMON *const cm = &ctx->pbi->common;
  169. BufferPool *const pool = cm->buffer_pool;
  170. cm->new_fb_idx = INVALID_IDX;
  171. cm->byte_alignment = ctx->byte_alignment;
  172. cm->skip_loop_filter = ctx->skip_loop_filter;
  173. if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
  174. pool->get_fb_cb = ctx->get_ext_fb_cb;
  175. pool->release_fb_cb = ctx->release_ext_fb_cb;
  176. pool->cb_priv = ctx->ext_priv;
  177. } else {
  178. pool->get_fb_cb = vp9_get_frame_buffer;
  179. pool->release_fb_cb = vp9_release_frame_buffer;
  180. if (vp9_alloc_internal_frame_buffers(&pool->int_frame_buffers))
  181. vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
  182. "Failed to initialize internal frame buffers");
  183. pool->cb_priv = &pool->int_frame_buffers;
  184. }
  185. }
  186. static void set_default_ppflags(vp8_postproc_cfg_t *cfg) {
  187. cfg->post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
  188. cfg->deblocking_level = 4;
  189. cfg->noise_level = 0;
  190. }
  191. static void set_ppflags(const vpx_codec_alg_priv_t *ctx, vp9_ppflags_t *flags) {
  192. flags->post_proc_flag = ctx->postproc_cfg.post_proc_flag;
  193. flags->deblocking_level = ctx->postproc_cfg.deblocking_level;
  194. flags->noise_level = ctx->postproc_cfg.noise_level;
  195. }
  196. #undef ERROR
  197. #define ERROR(str) \
  198. do { \
  199. ctx->base.err_detail = str; \
  200. return VPX_CODEC_INVALID_PARAM; \
  201. } while (0)
  202. #define RANGE_CHECK(p, memb, lo, hi) \
  203. do { \
  204. if (!(((p)->memb == (lo) || (p)->memb > (lo)) && (p)->memb <= (hi))) \
  205. ERROR(#memb " out of range [" #lo ".." #hi "]"); \
  206. } while (0)
  207. static vpx_codec_err_t init_decoder(vpx_codec_alg_priv_t *ctx) {
  208. ctx->last_show_frame = -1;
  209. ctx->need_resync = 1;
  210. ctx->flushed = 0;
  211. ctx->buffer_pool = (BufferPool *)vpx_calloc(1, sizeof(BufferPool));
  212. if (ctx->buffer_pool == NULL) return VPX_CODEC_MEM_ERROR;
  213. ctx->pbi = vp9_decoder_create(ctx->buffer_pool);
  214. if (ctx->pbi == NULL) {
  215. set_error_detail(ctx, "Failed to allocate decoder");
  216. return VPX_CODEC_MEM_ERROR;
  217. }
  218. ctx->pbi->max_threads = ctx->cfg.threads;
  219. ctx->pbi->inv_tile_order = ctx->invert_tile_order;
  220. RANGE_CHECK(ctx, row_mt, 0, 1);
  221. ctx->pbi->row_mt = ctx->row_mt;
  222. RANGE_CHECK(ctx, lpf_opt, 0, 1);
  223. ctx->pbi->lpf_mt_opt = ctx->lpf_opt;
  224. // If postprocessing was enabled by the application and a
  225. // configuration has not been provided, default it.
  226. if (!ctx->postproc_cfg_set && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC))
  227. set_default_ppflags(&ctx->postproc_cfg);
  228. init_buffer_callbacks(ctx);
  229. return VPX_CODEC_OK;
  230. }
  231. static INLINE void check_resync(vpx_codec_alg_priv_t *const ctx,
  232. const VP9Decoder *const pbi) {
  233. // Clear resync flag if the decoder got a key frame or intra only frame.
  234. if (ctx->need_resync == 1 && pbi->need_resync == 0 &&
  235. (pbi->common.intra_only || pbi->common.frame_type == KEY_FRAME))
  236. ctx->need_resync = 0;
  237. }
  238. static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
  239. const uint8_t **data, unsigned int data_sz,
  240. void *user_priv, int64_t deadline) {
  241. (void)deadline;
  242. // Determine the stream parameters. Note that we rely on peek_si to
  243. // validate that we have a buffer that does not wrap around the top
  244. // of the heap.
  245. if (!ctx->si.h) {
  246. int is_intra_only = 0;
  247. const vpx_codec_err_t res =
  248. decoder_peek_si_internal(*data, data_sz, &ctx->si, &is_intra_only,
  249. ctx->decrypt_cb, ctx->decrypt_state);
  250. if (res != VPX_CODEC_OK) return res;
  251. if (!ctx->si.is_kf && !is_intra_only) return VPX_CODEC_ERROR;
  252. }
  253. ctx->user_priv = user_priv;
  254. // Set these even if already initialized. The caller may have changed the
  255. // decrypt config between frames.
  256. ctx->pbi->decrypt_cb = ctx->decrypt_cb;
  257. ctx->pbi->decrypt_state = ctx->decrypt_state;
  258. if (vp9_receive_compressed_data(ctx->pbi, data_sz, data)) {
  259. ctx->pbi->cur_buf->buf.corrupted = 1;
  260. ctx->pbi->need_resync = 1;
  261. ctx->need_resync = 1;
  262. return update_error_state(ctx, &ctx->pbi->common.error);
  263. }
  264. check_resync(ctx, ctx->pbi);
  265. return VPX_CODEC_OK;
  266. }
  267. static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx,
  268. const uint8_t *data, unsigned int data_sz,
  269. void *user_priv, long deadline) {
  270. const uint8_t *data_start = data;
  271. const uint8_t *const data_end = data + data_sz;
  272. vpx_codec_err_t res;
  273. uint32_t frame_sizes[8];
  274. int frame_count;
  275. if (data == NULL && data_sz == 0) {
  276. ctx->flushed = 1;
  277. return VPX_CODEC_OK;
  278. }
  279. // Reset flushed when receiving a valid frame.
  280. ctx->flushed = 0;
  281. // Initialize the decoder on the first frame.
  282. if (ctx->pbi == NULL) {
  283. const vpx_codec_err_t res = init_decoder(ctx);
  284. if (res != VPX_CODEC_OK) return res;
  285. }
  286. res = vp9_parse_superframe_index(data, data_sz, frame_sizes, &frame_count,
  287. ctx->decrypt_cb, ctx->decrypt_state);
  288. if (res != VPX_CODEC_OK) return res;
  289. if (ctx->svc_decoding && ctx->svc_spatial_layer < frame_count - 1)
  290. frame_count = ctx->svc_spatial_layer + 1;
  291. // Decode in serial mode.
  292. if (frame_count > 0) {
  293. int i;
  294. for (i = 0; i < frame_count; ++i) {
  295. const uint8_t *data_start_copy = data_start;
  296. const uint32_t frame_size = frame_sizes[i];
  297. vpx_codec_err_t res;
  298. if (data_start < data || frame_size > (uint32_t)(data_end - data_start)) {
  299. set_error_detail(ctx, "Invalid frame size in index");
  300. return VPX_CODEC_CORRUPT_FRAME;
  301. }
  302. res = decode_one(ctx, &data_start_copy, frame_size, user_priv, deadline);
  303. if (res != VPX_CODEC_OK) return res;
  304. data_start += frame_size;
  305. }
  306. } else {
  307. while (data_start < data_end) {
  308. const uint32_t frame_size = (uint32_t)(data_end - data_start);
  309. const vpx_codec_err_t res =
  310. decode_one(ctx, &data_start, frame_size, user_priv, deadline);
  311. if (res != VPX_CODEC_OK) return res;
  312. // Account for suboptimal termination by the encoder.
  313. while (data_start < data_end) {
  314. const uint8_t marker =
  315. read_marker(ctx->decrypt_cb, ctx->decrypt_state, data_start);
  316. if (marker) break;
  317. ++data_start;
  318. }
  319. }
  320. }
  321. return res;
  322. }
  323. static vpx_image_t *decoder_get_frame(vpx_codec_alg_priv_t *ctx,
  324. vpx_codec_iter_t *iter) {
  325. vpx_image_t *img = NULL;
  326. // Legacy parameter carried over from VP8. Has no effect for VP9 since we
  327. // always return only 1 frame per decode call.
  328. (void)iter;
  329. if (ctx->pbi != NULL) {
  330. YV12_BUFFER_CONFIG sd;
  331. vp9_ppflags_t flags = { 0, 0, 0 };
  332. if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) set_ppflags(ctx, &flags);
  333. if (vp9_get_raw_frame(ctx->pbi, &sd, &flags) == 0) {
  334. VP9_COMMON *const cm = &ctx->pbi->common;
  335. RefCntBuffer *const frame_bufs = cm->buffer_pool->frame_bufs;
  336. ctx->last_show_frame = ctx->pbi->common.new_fb_idx;
  337. if (ctx->need_resync) return NULL;
  338. yuvconfig2image(&ctx->img, &sd, ctx->user_priv);
  339. ctx->img.fb_priv = frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
  340. img = &ctx->img;
  341. return img;
  342. }
  343. }
  344. return NULL;
  345. }
  346. static vpx_codec_err_t decoder_set_fb_fn(
  347. vpx_codec_alg_priv_t *ctx, vpx_get_frame_buffer_cb_fn_t cb_get,
  348. vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
  349. if (cb_get == NULL || cb_release == NULL) {
  350. return VPX_CODEC_INVALID_PARAM;
  351. } else if (ctx->pbi == NULL) {
  352. // If the decoder has already been initialized, do not accept changes to
  353. // the frame buffer functions.
  354. ctx->get_ext_fb_cb = cb_get;
  355. ctx->release_ext_fb_cb = cb_release;
  356. ctx->ext_priv = cb_priv;
  357. return VPX_CODEC_OK;
  358. }
  359. return VPX_CODEC_ERROR;
  360. }
  361. static vpx_codec_err_t ctrl_set_reference(vpx_codec_alg_priv_t *ctx,
  362. va_list args) {
  363. vpx_ref_frame_t *const data = va_arg(args, vpx_ref_frame_t *);
  364. if (data) {
  365. vpx_ref_frame_t *const frame = (vpx_ref_frame_t *)data;
  366. YV12_BUFFER_CONFIG sd;
  367. image2yuvconfig(&frame->img, &sd);
  368. return vp9_set_reference_dec(
  369. &ctx->pbi->common, ref_frame_to_vp9_reframe(frame->frame_type), &sd);
  370. } else {
  371. return VPX_CODEC_INVALID_PARAM;
  372. }
  373. }
  374. static vpx_codec_err_t ctrl_copy_reference(vpx_codec_alg_priv_t *ctx,
  375. va_list args) {
  376. vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
  377. if (data) {
  378. vpx_ref_frame_t *frame = (vpx_ref_frame_t *)data;
  379. YV12_BUFFER_CONFIG sd;
  380. image2yuvconfig(&frame->img, &sd);
  381. return vp9_copy_reference_dec(ctx->pbi, (VP9_REFFRAME)frame->frame_type,
  382. &sd);
  383. } else {
  384. return VPX_CODEC_INVALID_PARAM;
  385. }
  386. }
  387. static vpx_codec_err_t ctrl_get_reference(vpx_codec_alg_priv_t *ctx,
  388. va_list args) {
  389. vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
  390. if (data) {
  391. const int fb_idx = ctx->pbi->common.cur_show_frame_fb_idx;
  392. YV12_BUFFER_CONFIG *fb = get_buf_frame(&ctx->pbi->common, fb_idx);
  393. if (fb == NULL) return VPX_CODEC_ERROR;
  394. yuvconfig2image(&data->img, fb, NULL);
  395. return VPX_CODEC_OK;
  396. } else {
  397. return VPX_CODEC_INVALID_PARAM;
  398. }
  399. }
  400. static vpx_codec_err_t ctrl_set_postproc(vpx_codec_alg_priv_t *ctx,
  401. va_list args) {
  402. #if CONFIG_VP9_POSTPROC
  403. vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
  404. if (data) {
  405. ctx->postproc_cfg_set = 1;
  406. ctx->postproc_cfg = *((vp8_postproc_cfg_t *)data);
  407. return VPX_CODEC_OK;
  408. } else {
  409. return VPX_CODEC_INVALID_PARAM;
  410. }
  411. #else
  412. (void)ctx;
  413. (void)args;
  414. return VPX_CODEC_INCAPABLE;
  415. #endif
  416. }
  417. static vpx_codec_err_t ctrl_get_quantizer(vpx_codec_alg_priv_t *ctx,
  418. va_list args) {
  419. int *const arg = va_arg(args, int *);
  420. if (arg == NULL || ctx->pbi == NULL) return VPX_CODEC_INVALID_PARAM;
  421. *arg = ctx->pbi->common.base_qindex;
  422. return VPX_CODEC_OK;
  423. }
  424. static vpx_codec_err_t ctrl_get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
  425. va_list args) {
  426. int *const update_info = va_arg(args, int *);
  427. if (update_info) {
  428. if (ctx->pbi != NULL) {
  429. *update_info = ctx->pbi->refresh_frame_flags;
  430. return VPX_CODEC_OK;
  431. } else {
  432. return VPX_CODEC_ERROR;
  433. }
  434. }
  435. return VPX_CODEC_INVALID_PARAM;
  436. }
  437. static vpx_codec_err_t ctrl_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
  438. va_list args) {
  439. int *corrupted = va_arg(args, int *);
  440. if (corrupted) {
  441. if (ctx->pbi != NULL) {
  442. RefCntBuffer *const frame_bufs = ctx->pbi->common.buffer_pool->frame_bufs;
  443. if (ctx->pbi->common.frame_to_show == NULL) return VPX_CODEC_ERROR;
  444. if (ctx->last_show_frame >= 0)
  445. *corrupted = frame_bufs[ctx->last_show_frame].buf.corrupted;
  446. return VPX_CODEC_OK;
  447. } else {
  448. return VPX_CODEC_ERROR;
  449. }
  450. }
  451. return VPX_CODEC_INVALID_PARAM;
  452. }
  453. static vpx_codec_err_t ctrl_get_frame_size(vpx_codec_alg_priv_t *ctx,
  454. va_list args) {
  455. int *const frame_size = va_arg(args, int *);
  456. if (frame_size) {
  457. if (ctx->pbi != NULL) {
  458. const VP9_COMMON *const cm = &ctx->pbi->common;
  459. frame_size[0] = cm->width;
  460. frame_size[1] = cm->height;
  461. return VPX_CODEC_OK;
  462. } else {
  463. return VPX_CODEC_ERROR;
  464. }
  465. }
  466. return VPX_CODEC_INVALID_PARAM;
  467. }
  468. static vpx_codec_err_t ctrl_get_render_size(vpx_codec_alg_priv_t *ctx,
  469. va_list args) {
  470. int *const render_size = va_arg(args, int *);
  471. if (render_size) {
  472. if (ctx->pbi != NULL) {
  473. const VP9_COMMON *const cm = &ctx->pbi->common;
  474. render_size[0] = cm->render_width;
  475. render_size[1] = cm->render_height;
  476. return VPX_CODEC_OK;
  477. } else {
  478. return VPX_CODEC_ERROR;
  479. }
  480. }
  481. return VPX_CODEC_INVALID_PARAM;
  482. }
  483. static vpx_codec_err_t ctrl_get_bit_depth(vpx_codec_alg_priv_t *ctx,
  484. va_list args) {
  485. unsigned int *const bit_depth = va_arg(args, unsigned int *);
  486. if (bit_depth) {
  487. if (ctx->pbi != NULL) {
  488. const VP9_COMMON *const cm = &ctx->pbi->common;
  489. *bit_depth = cm->bit_depth;
  490. return VPX_CODEC_OK;
  491. } else {
  492. return VPX_CODEC_ERROR;
  493. }
  494. }
  495. return VPX_CODEC_INVALID_PARAM;
  496. }
  497. static vpx_codec_err_t ctrl_set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
  498. va_list args) {
  499. ctx->invert_tile_order = va_arg(args, int);
  500. return VPX_CODEC_OK;
  501. }
  502. static vpx_codec_err_t ctrl_set_decryptor(vpx_codec_alg_priv_t *ctx,
  503. va_list args) {
  504. vpx_decrypt_init *init = va_arg(args, vpx_decrypt_init *);
  505. ctx->decrypt_cb = init ? init->decrypt_cb : NULL;
  506. ctx->decrypt_state = init ? init->decrypt_state : NULL;
  507. return VPX_CODEC_OK;
  508. }
  509. static vpx_codec_err_t ctrl_set_byte_alignment(vpx_codec_alg_priv_t *ctx,
  510. va_list args) {
  511. const int legacy_byte_alignment = 0;
  512. const int min_byte_alignment = 32;
  513. const int max_byte_alignment = 1024;
  514. const int byte_alignment = va_arg(args, int);
  515. if (byte_alignment != legacy_byte_alignment &&
  516. (byte_alignment < min_byte_alignment ||
  517. byte_alignment > max_byte_alignment ||
  518. (byte_alignment & (byte_alignment - 1)) != 0))
  519. return VPX_CODEC_INVALID_PARAM;
  520. ctx->byte_alignment = byte_alignment;
  521. if (ctx->pbi != NULL) {
  522. ctx->pbi->common.byte_alignment = byte_alignment;
  523. }
  524. return VPX_CODEC_OK;
  525. }
  526. static vpx_codec_err_t ctrl_set_skip_loop_filter(vpx_codec_alg_priv_t *ctx,
  527. va_list args) {
  528. ctx->skip_loop_filter = va_arg(args, int);
  529. if (ctx->pbi != NULL) {
  530. ctx->pbi->common.skip_loop_filter = ctx->skip_loop_filter;
  531. }
  532. return VPX_CODEC_OK;
  533. }
  534. static vpx_codec_err_t ctrl_set_spatial_layer_svc(vpx_codec_alg_priv_t *ctx,
  535. va_list args) {
  536. ctx->svc_decoding = 1;
  537. ctx->svc_spatial_layer = va_arg(args, int);
  538. if (ctx->svc_spatial_layer < 0)
  539. return VPX_CODEC_INVALID_PARAM;
  540. else
  541. return VPX_CODEC_OK;
  542. }
  543. static vpx_codec_err_t ctrl_set_row_mt(vpx_codec_alg_priv_t *ctx,
  544. va_list args) {
  545. ctx->row_mt = va_arg(args, int);
  546. return VPX_CODEC_OK;
  547. }
  548. static vpx_codec_err_t ctrl_enable_lpf_opt(vpx_codec_alg_priv_t *ctx,
  549. va_list args) {
  550. ctx->lpf_opt = va_arg(args, int);
  551. return VPX_CODEC_OK;
  552. }
  553. static vpx_codec_ctrl_fn_map_t decoder_ctrl_maps[] = {
  554. { VP8_COPY_REFERENCE, ctrl_copy_reference },
  555. // Setters
  556. { VP8_SET_REFERENCE, ctrl_set_reference },
  557. { VP8_SET_POSTPROC, ctrl_set_postproc },
  558. { VP9_INVERT_TILE_DECODE_ORDER, ctrl_set_invert_tile_order },
  559. { VPXD_SET_DECRYPTOR, ctrl_set_decryptor },
  560. { VP9_SET_BYTE_ALIGNMENT, ctrl_set_byte_alignment },
  561. { VP9_SET_SKIP_LOOP_FILTER, ctrl_set_skip_loop_filter },
  562. { VP9_DECODE_SVC_SPATIAL_LAYER, ctrl_set_spatial_layer_svc },
  563. { VP9D_SET_ROW_MT, ctrl_set_row_mt },
  564. { VP9D_SET_LOOP_FILTER_OPT, ctrl_enable_lpf_opt },
  565. // Getters
  566. { VPXD_GET_LAST_QUANTIZER, ctrl_get_quantizer },
  567. { VP8D_GET_LAST_REF_UPDATES, ctrl_get_last_ref_updates },
  568. { VP8D_GET_FRAME_CORRUPTED, ctrl_get_frame_corrupted },
  569. { VP9_GET_REFERENCE, ctrl_get_reference },
  570. { VP9D_GET_DISPLAY_SIZE, ctrl_get_render_size },
  571. { VP9D_GET_BIT_DEPTH, ctrl_get_bit_depth },
  572. { VP9D_GET_FRAME_SIZE, ctrl_get_frame_size },
  573. { -1, NULL },
  574. };
  575. #ifndef VERSION_STRING
  576. #define VERSION_STRING
  577. #endif
  578. CODEC_INTERFACE(vpx_codec_vp9_dx) = {
  579. "WebM Project VP9 Decoder" VERSION_STRING,
  580. VPX_CODEC_INTERNAL_ABI_VERSION,
  581. #if CONFIG_VP9_HIGHBITDEPTH
  582. VPX_CODEC_CAP_HIGHBITDEPTH |
  583. #endif
  584. VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
  585. VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER, // vpx_codec_caps_t
  586. decoder_init, // vpx_codec_init_fn_t
  587. decoder_destroy, // vpx_codec_destroy_fn_t
  588. decoder_ctrl_maps, // vpx_codec_ctrl_fn_map_t
  589. {
  590. // NOLINT
  591. decoder_peek_si, // vpx_codec_peek_si_fn_t
  592. decoder_get_si, // vpx_codec_get_si_fn_t
  593. decoder_decode, // vpx_codec_decode_fn_t
  594. decoder_get_frame, // vpx_codec_frame_get_fn_t
  595. decoder_set_fb_fn, // vpx_codec_set_fb_fn_t
  596. },
  597. {
  598. // NOLINT
  599. 0,
  600. NULL, // vpx_codec_enc_cfg_map_t
  601. NULL, // vpx_codec_encode_fn_t
  602. NULL, // vpx_codec_get_cx_data_fn_t
  603. NULL, // vpx_codec_enc_config_set_fn_t
  604. NULL, // vpx_codec_get_global_headers_fn_t
  605. NULL, // vpx_codec_get_preview_frame_fn_t
  606. NULL // vpx_codec_enc_mr_get_mem_loc_fn_t
  607. }
  608. };