Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / third_party / libvpx / source / libvpx / vp9 / vp9_dx_iface.c
index 5dacab4..ad568c5 100644 (file)
@@ -15,6 +15,7 @@
 #include "vpx/vp8dx.h"
 #include "vpx/internal/vpx_codec_internal.h"
 #include "./vpx_version.h"
+#include "vp9/common/vp9_frame_buffers.h"
 #include "vp9/decoder/vp9_onyxd.h"
 #include "vp9/decoder/vp9_onyxd_int.h"
 #include "vp9/decoder/vp9_read_bit_buffer.h"
@@ -25,7 +26,7 @@ typedef vpx_codec_stream_info_t  vp9_stream_info_t;
 
 /* Structures for handling memory allocations */
 typedef enum {
-  VP9_SEG_ALG_PRIV     = 256,
+  VP9_SEG_ALG_PRIV = 256,
   VP9_SEG_MAX
 } mem_seg_id_t;
 #define NELEMENTS(x) ((int)(sizeof(x)/sizeof(x[0])))
@@ -59,6 +60,11 @@ struct vpx_codec_alg_priv {
   int                     img_setup;
   int                     img_avail;
   int                     invert_tile_order;
+
+  // External frame buffer info to save for VP9 common.
+  void *ext_priv;  // Private data associated with the external frame buffers.
+  vpx_get_frame_buffer_cb_fn_t get_ext_fb_cb;
+  vpx_release_frame_buffer_cb_fn_t release_ext_fb_cb;
 };
 
 static unsigned long priv_sz(const vpx_codec_dec_cfg_t *si,
@@ -100,12 +106,11 @@ static void vp9_finalize_mmaps(vpx_codec_alg_priv_t *ctx) {
 
 static vpx_codec_err_t vp9_init(vpx_codec_ctx_t *ctx,
                                 vpx_codec_priv_enc_mr_cfg_t *data) {
-  vpx_codec_err_t        res = VPX_CODEC_OK;
+  vpx_codec_err_t res = VPX_CODEC_OK;
 
-  /* This function only allocates space for the vpx_codec_alg_priv_t
-   * structure. More memory may be required at the time the stream
-   * information becomes known.
-   */
+  // This function only allocates space for the vpx_codec_alg_priv_t
+  // structure. More memory may be required at the time the stream
+  // information becomes known.
   if (!ctx->priv) {
     vpx_codec_mmap_t mmap;
 
@@ -115,12 +120,10 @@ static vpx_codec_err_t vp9_init(vpx_codec_ctx_t *ctx,
     mmap.flags = vp9_mem_req_segs[0].flags;
 
     res = vpx_mmap_alloc(&mmap);
-
     if (!res) {
       vp9_init_ctx(ctx, &mmap);
 
       ctx->priv->alg_priv->defer_alloc = 1;
-      /*post processing level initialized to do nothing */
     }
   }
 
@@ -140,8 +143,7 @@ static vpx_codec_err_t vp9_destroy(vpx_codec_alg_priv_t *ctx) {
   return VPX_CODEC_OK;
 }
 
-static vpx_codec_err_t vp9_peek_si(const uint8_t         *data,
-                                   unsigned int           data_sz,
+static vpx_codec_err_t vp9_peek_si(const uint8_t *data, unsigned int data_sz,
                                    vpx_codec_stream_info_t *si) {
   if (data_sz <= 8) return VPX_CODEC_UNSUP_BITSTREAM;
   if (data + data_sz <= data) return VPX_CODEC_INVALID_PARAM;
@@ -152,8 +154,11 @@ static vpx_codec_err_t vp9_peek_si(const uint8_t         *data,
   {
     struct vp9_read_bit_buffer rb = { data, data + data_sz, 0, NULL, NULL };
     const int frame_marker = vp9_rb_read_literal(&rb, 2);
-    const int version = vp9_rb_read_bit(&rb) | (vp9_rb_read_bit(&rb) << 1);
-    if (frame_marker != 0x2) return VPX_CODEC_UNSUP_BITSTREAM;
+    const int version = vp9_rb_read_bit(&rb);
+    (void) vp9_rb_read_bit(&rb);  // unused version bit
+
+    if (frame_marker != VP9_FRAME_MARKER)
+      return VPX_CODEC_UNSUP_BITSTREAM;
 #if CONFIG_NON420
     if (version > 1) return VPX_CODEC_UNSUP_BITSTREAM;
 #else
@@ -205,38 +210,27 @@ static vpx_codec_err_t vp9_peek_si(const uint8_t         *data,
 
 static vpx_codec_err_t vp9_get_si(vpx_codec_alg_priv_t    *ctx,
                                   vpx_codec_stream_info_t *si) {
-  unsigned int sz;
-
-  if (si->sz >= sizeof(vp9_stream_info_t))
-    sz = sizeof(vp9_stream_info_t);
-  else
-    sz = sizeof(vpx_codec_stream_info_t);
-
+  const size_t sz = (si->sz >= sizeof(vp9_stream_info_t))
+                       ? sizeof(vp9_stream_info_t)
+                       : sizeof(vpx_codec_stream_info_t);
   memcpy(si, &ctx->si, sz);
-  si->sz = sz;
+  si->sz = (unsigned int)sz;
 
   return VPX_CODEC_OK;
 }
 
 
-static vpx_codec_err_t
-update_error_state(vpx_codec_alg_priv_t                 *ctx,
-                   const struct vpx_internal_error_info *error) {
-  vpx_codec_err_t res;
+static vpx_codec_err_t update_error_state(vpx_codec_alg_priv_t *ctx,
+                           const struct vpx_internal_error_info *error) {
+  if (error->error_code)
+    ctx->base.err_detail = error->has_detail ? error->detail : NULL;
 
-  if ((res = error->error_code))
-    ctx->base.err_detail = error->has_detail
-                           ? error->detail
-                           : NULL;
-
-  return res;
+  return error->error_code;
 }
 
-static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
-                                  const uint8_t        **data,
-                                  unsigned int           data_sz,
-                                  void                  *user_priv,
-                                  long                   deadline) {
+static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t *ctx,
+                                  const uint8_t **data, unsigned int data_sz,
+                                  void *user_priv, int64_t deadline) {
   vpx_codec_err_t res = VPX_CODEC_OK;
 
   ctx->img_avail = 0;
@@ -296,21 +290,40 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
       oxcf.inv_tile_order = ctx->invert_tile_order;
       optr = vp9_create_decompressor(&oxcf);
 
-      /* If postprocessing was enabled by the application and a
-       * configuration has not been provided, default it.
-       */
-      if (!ctx->postproc_cfg_set
-          && (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
-        ctx->postproc_cfg.post_proc_flag =
-          VP8_DEBLOCK | VP8_DEMACROBLOCK;
+      // If postprocessing was enabled by the application and a
+      // configuration has not been provided, default it.
+      if (!ctx->postproc_cfg_set &&
+          (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC)) {
+        ctx->postproc_cfg.post_proc_flag = VP8_DEBLOCK | VP8_DEMACROBLOCK;
         ctx->postproc_cfg.deblocking_level = 4;
         ctx->postproc_cfg.noise_level = 0;
       }
 
-      if (!optr)
+      if (!optr) {
         res = VPX_CODEC_ERROR;
-      else
+      } else {
+        VP9D_COMP *const pbi = (VP9D_COMP*)optr;
+        VP9_COMMON *const cm = &pbi->common;
+
+        // Set index to not initialized.
+        cm->new_fb_idx = -1;
+
+        if (ctx->get_ext_fb_cb != NULL && ctx->release_ext_fb_cb != NULL) {
+          cm->get_fb_cb = ctx->get_ext_fb_cb;
+          cm->release_fb_cb = ctx->release_ext_fb_cb;
+          cm->cb_priv = ctx->ext_priv;
+        } else {
+          cm->get_fb_cb = vp9_get_frame_buffer;
+          cm->release_fb_cb = vp9_release_frame_buffer;
+
+          if (vp9_alloc_internal_frame_buffers(&cm->int_frame_buffers))
+            vpx_internal_error(&cm->error, VPX_CODEC_MEM_ERROR,
+                               "Failed to initialize internal frame buffers");
+          cm->cb_priv = &cm->int_frame_buffers;
+        }
+
         ctx->pbi = optr;
+      }
     }
 
     ctx->decoder_init = 1;
@@ -324,36 +337,35 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
     if (ctx->base.init_flags & VPX_CODEC_USE_POSTPROC) {
       flags.post_proc_flag =
 #if CONFIG_POSTPROC_VISUALIZER
-          ((ctx->dbg_color_ref_frame_flag != 0) ?
-              VP9D_DEBUG_CLR_FRM_REF_BLKS : 0)
-          | ((ctx->dbg_color_mb_modes_flag != 0) ?
-              VP9D_DEBUG_CLR_BLK_MODES : 0)
-          | ((ctx->dbg_color_b_modes_flag != 0) ?
-              VP9D_DEBUG_CLR_BLK_MODES : 0)
-          | ((ctx->dbg_display_mv_flag != 0) ?
-              VP9D_DEBUG_DRAW_MV : 0)
-          |
+          (ctx->dbg_color_ref_frame_flag ? VP9D_DEBUG_CLR_FRM_REF_BLKS : 0) |
+          (ctx->dbg_color_mb_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
+          (ctx->dbg_color_b_modes_flag ? VP9D_DEBUG_CLR_BLK_MODES : 0) |
+          (ctx->dbg_display_mv_flag ? VP9D_DEBUG_DRAW_MV : 0) |
 #endif
           ctx->postproc_cfg.post_proc_flag;
 
-      flags.deblocking_level      = ctx->postproc_cfg.deblocking_level;
-      flags.noise_level           = ctx->postproc_cfg.noise_level;
+      flags.deblocking_level = ctx->postproc_cfg.deblocking_level;
+      flags.noise_level = ctx->postproc_cfg.noise_level;
 #if CONFIG_POSTPROC_VISUALIZER
       flags.display_ref_frame_flag = ctx->dbg_color_ref_frame_flag;
       flags.display_mb_modes_flag = ctx->dbg_color_mb_modes_flag;
-      flags.display_b_modes_flag  = ctx->dbg_color_b_modes_flag;
-      flags.display_mv_flag       = ctx->dbg_display_mv_flag;
+      flags.display_b_modes_flag = ctx->dbg_color_b_modes_flag;
+      flags.display_mv_flag = ctx->dbg_display_mv_flag;
 #endif
     }
 
     if (vp9_receive_compressed_data(ctx->pbi, data_sz, data, deadline)) {
-      VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+      VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
       res = update_error_state(ctx, &pbi->common.error);
     }
 
     if (!res && 0 == vp9_get_raw_frame(ctx->pbi, &sd, &time_stamp,
                                        &time_end_stamp, &flags)) {
+      VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi;
+      VP9_COMMON *const cm = &pbi->common;
       yuvconfig2image(&ctx->img, &sd, user_priv);
+
+      ctx->img.fb_priv = cm->frame_bufs[cm->new_fb_idx].raw_frame_buffer.priv;
       ctx->img_avail = 1;
     }
   }
@@ -361,10 +373,8 @@ static vpx_codec_err_t decode_one(vpx_codec_alg_priv_t  *ctx,
   return res;
 }
 
-static void parse_superframe_index(const uint8_t *data,
-                                   size_t         data_sz,
-                                   uint32_t       sizes[8],
-                                   int           *count) {
+static void parse_superframe_index(const uint8_t *data, size_t data_sz,
+                                   uint32_t sizes[8], int *count) {
   uint8_t marker;
 
   assert(data_sz);
@@ -475,11 +485,29 @@ static vpx_image_t *vp9_get_frame(vpx_codec_alg_priv_t  *ctx,
   return img;
 }
 
-static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t      *ctx,
-                                        vpx_codec_mmap_t           *mmap,
-                                        vpx_codec_iter_t           *iter) {
-  vpx_codec_err_t     res;
-  const mem_req_t  *seg_iter = *iter;
+static vpx_codec_err_t vp9_set_fb_fn(
+    vpx_codec_alg_priv_t *ctx,
+    vpx_get_frame_buffer_cb_fn_t cb_get,
+    vpx_release_frame_buffer_cb_fn_t cb_release, void *cb_priv) {
+  if (cb_get == NULL || cb_release == NULL) {
+    return VPX_CODEC_INVALID_PARAM;
+  } else if (ctx->pbi == NULL) {
+    // If the decoder has already been initialized, do not accept changes to
+    // the frame buffer functions.
+    ctx->get_ext_fb_cb = cb_get;
+    ctx->release_ext_fb_cb = cb_release;
+    ctx->ext_priv = cb_priv;
+    return VPX_CODEC_OK;
+  }
+
+  return VPX_CODEC_ERROR;
+}
+
+static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t *ctx,
+                                        vpx_codec_mmap_t *mmap,
+                                        vpx_codec_iter_t *iter) {
+  vpx_codec_err_t res;
+  const mem_req_t *seg_iter = *iter;
 
   /* Get address of next segment request */
   do {
@@ -508,7 +536,7 @@ static vpx_codec_err_t vp9_xma_get_mmap(const vpx_codec_ctx_t      *ctx,
   return res;
 }
 
-static vpx_codec_err_t vp9_xma_set_mmap(vpx_codec_ctx_t         *ctx,
+static vpx_codec_err_t vp9_xma_set_mmap(vpx_codec_ctx_t *ctx,
                                         const vpx_codec_mmap_t  *mmap) {
   vpx_codec_err_t res = VPX_CODEC_MEM_ERROR;
   int i, done;
@@ -544,8 +572,7 @@ static vpx_codec_err_t vp9_xma_set_mmap(vpx_codec_ctx_t         *ctx,
   return res;
 }
 
-static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx,
-                                     int ctr_id,
+static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
                                      va_list args) {
   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
 
@@ -554,7 +581,6 @@ static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx,
     YV12_BUFFER_CONFIG sd;
 
     image2yuvconfig(&frame->img, &sd);
-
     return vp9_set_reference_dec(ctx->pbi,
                                  (VP9_REFFRAME)frame->frame_type, &sd);
   } else {
@@ -562,8 +588,7 @@ static vpx_codec_err_t set_reference(vpx_codec_alg_priv_t *ctx,
   }
 }
 
-static vpx_codec_err_t copy_reference(vpx_codec_alg_priv_t *ctx,
-                                      int ctr_id,
+static vpx_codec_err_t copy_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
                                       va_list args) {
   vpx_ref_frame_t *data = va_arg(args, vpx_ref_frame_t *);
 
@@ -580,8 +605,7 @@ static vpx_codec_err_t copy_reference(vpx_codec_alg_priv_t *ctx,
   }
 }
 
-static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx,
-                                     int ctr_id,
+static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx, int ctr_id,
                                      va_list args) {
   vp9_ref_frame_t *data = va_arg(args, vp9_ref_frame_t *);
 
@@ -596,8 +620,7 @@ static vpx_codec_err_t get_reference(vpx_codec_alg_priv_t *ctx,
   }
 }
 
-static vpx_codec_err_t set_postproc(vpx_codec_alg_priv_t *ctx,
-                                    int ctr_id,
+static vpx_codec_err_t set_postproc(vpx_codec_alg_priv_t *ctx, int ctr_id,
                                     va_list args) {
 #if CONFIG_VP9_POSTPROC
   vp8_postproc_cfg_t *data = va_arg(args, vp8_postproc_cfg_t *);
@@ -614,8 +637,7 @@ static vpx_codec_err_t set_postproc(vpx_codec_alg_priv_t *ctx,
 #endif
 }
 
-static vpx_codec_err_t set_dbg_options(vpx_codec_alg_priv_t *ctx,
-                                       int ctrl_id,
+static vpx_codec_err_t set_dbg_options(vpx_codec_alg_priv_t *ctx, int ctrl_id,
                                        va_list args) {
 #if CONFIG_POSTPROC_VISUALIZER && CONFIG_POSTPROC
   int data = va_arg(args, int);
@@ -636,10 +658,9 @@ static vpx_codec_err_t set_dbg_options(vpx_codec_alg_priv_t *ctx,
 }
 
 static vpx_codec_err_t get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
-                                            int ctrl_id,
-                                            va_list args) {
+                                            int ctrl_id, va_list args) {
   int *update_info = va_arg(args, int *);
-  VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+  VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
 
   if (update_info) {
     *update_info = pbi->refresh_frame_flags;
@@ -652,12 +673,11 @@ static vpx_codec_err_t get_last_ref_updates(vpx_codec_alg_priv_t *ctx,
 
 
 static vpx_codec_err_t get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
-                                           int ctrl_id,
-                                           va_list args) {
+                                           int ctrl_id, va_list args) {
   int *corrupted = va_arg(args, int *);
 
   if (corrupted) {
-    VP9D_COMP *pbi = (VP9D_COMP *)ctx->pbi;
+    VP9D_COMP *pbi = (VP9D_COMP*)ctx->pbi;
     if (pbi)
       *corrupted = pbi->common.frame_to_show->corrupted;
     else
@@ -668,6 +688,24 @@ static vpx_codec_err_t get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
   }
 }
 
+static vpx_codec_err_t get_display_size(vpx_codec_alg_priv_t *ctx,
+                                        int ctrl_id, va_list args) {
+  int *const display_size = va_arg(args, int *);
+
+  if (display_size) {
+    const VP9D_COMP *const pbi = (VP9D_COMP*)ctx->pbi;
+    if (pbi) {
+      display_size[0] = pbi->common.display_width;
+      display_size[1] = pbi->common.display_height;
+    } else {
+      return VPX_CODEC_ERROR;
+    }
+    return VPX_CODEC_OK;
+  } else {
+    return VPX_CODEC_INVALID_PARAM;
+  }
+}
+
 static vpx_codec_err_t set_invert_tile_order(vpx_codec_alg_priv_t *ctx,
                                              int ctr_id,
                                              va_list args) {
@@ -686,6 +724,7 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
   {VP8D_GET_LAST_REF_UPDATES,     get_last_ref_updates},
   {VP8D_GET_FRAME_CORRUPTED,      get_frame_corrupted},
   {VP9_GET_REFERENCE,             get_reference},
+  {VP9D_GET_DISPLAY_SIZE,         get_display_size},
   {VP9_INVERT_TILE_DECODE_ORDER,  set_invert_tile_order},
   { -1, NULL},
 };
@@ -697,7 +736,8 @@ static vpx_codec_ctrl_fn_map_t ctf_maps[] = {
 CODEC_INTERFACE(vpx_codec_vp9_dx) = {
   "WebM Project VP9 Decoder" VERSION_STRING,
   VPX_CODEC_INTERNAL_ABI_VERSION,
-  VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC,
+  VPX_CODEC_CAP_DECODER | VP9_CAP_POSTPROC |
+      VPX_CODEC_CAP_EXTERNAL_FRAME_BUFFER,
   /* vpx_codec_caps_t          caps; */
   vp9_init,         /* vpx_codec_init_fn_t       init; */
   vp9_destroy,      /* vpx_codec_destroy_fn_t    destroy; */
@@ -709,6 +749,7 @@ CODEC_INTERFACE(vpx_codec_vp9_dx) = {
     vp9_get_si,       /* vpx_codec_get_si_fn_t     get_si; */
     vp9_decode,       /* vpx_codec_decode_fn_t     decode; */
     vp9_get_frame,    /* vpx_codec_frame_get_fn_t  frame_get; */
+    vp9_set_fb_fn,    /* vpx_codec_set_fb_fn_t     set_fb_fn; */
   },
   { // NOLINT
     /* encoder functions */