]> granicus.if.org Git - libvpx/commitdiff
WIP: add support for using the modemv from the original stream directly
authorJohn Koleszar <jkoleszar@google.com>
Tue, 20 Mar 2012 23:38:25 +0000 (16:38 -0700)
committerJohn Koleszar <jkoleszar@google.com>
Wed, 21 Mar 2012 23:08:12 +0000 (16:08 -0700)
Change-Id: I4e849a67eaeb654cd1f5c2ac907145cac040a532

vp8/vp8_dx_iface.c
vpx/vp8dx.h
vpx/vpx_codec.h
vpx/vpx_encoder.h
vpxenc.c

index 276859d31c6b9ef059f4b06dd7f272d5384fb416..f97336711a8b8a825be6ec0f7415ec553d3db769 100644 (file)
@@ -70,6 +70,7 @@ struct vpx_codec_alg_priv
     vpx_image_t             img;
     int                     img_setup;
     int                     img_avail;
+    vpx_fixed_buf_t         mode_info;
 };
 
 static unsigned long vp8_priv_sz(const vpx_codec_dec_cfg_t *si, vpx_codec_flags_t flags)
@@ -743,6 +744,43 @@ static vpx_codec_err_t vp8_get_frame_corrupted(vpx_codec_alg_priv_t *ctx,
 
 }
 
+static vpx_codec_err_t get_mode_info(vpx_codec_alg_priv_t *ctx,
+                                     int ctrl_id,
+                                     va_list args)
+{
+    vpx_fixed_buf_t **data =  va_arg(args, vpx_fixed_buf_t **);
+    VP8D_COMP *pbi = (VP8D_COMP *)ctx->pbi;
+    size_t mi_sz = sizeof(MODE_INFO)*pbi->common.mb_rows * pbi->common.mb_cols;
+    char *buf;
+    size_t buf_stride;
+    int i;
+    MODE_INFO *mi;
+
+    if(data)
+    {
+        if(ctx->mode_info.sz != mi_sz)
+        {
+            free(ctx->mode_info.buf);
+            ctx->mode_info.buf = malloc(mi_sz);
+            ctx->mode_info.sz = mi_sz;
+        }
+
+        mi = pbi->common.mi;
+        buf = ctx->mode_info.buf;
+        buf_stride = pbi->common.mb_cols * sizeof(MODE_INFO);
+        for(i=0; i<pbi->common.mb_rows; i++)
+        {
+            memcpy(buf, mi, buf_stride);
+            buf += buf_stride;
+            mi += pbi->common.mode_info_stride;
+        }
+        *data = &ctx->mode_info;
+        return VPX_CODEC_OK;
+    }
+    else
+        return VPX_CODEC_INVALID_PARAM;
+}
+
 vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
 {
     {VP8_SET_REFERENCE,             vp8_set_reference},
@@ -755,6 +793,7 @@ vpx_codec_ctrl_fn_map_t vp8_ctf_maps[] =
     {VP8D_GET_LAST_REF_UPDATES,     vp8_get_last_ref_updates},
     {VP8D_GET_FRAME_CORRUPTED,      vp8_get_frame_corrupted},
     {VP8D_GET_LAST_REF_USED,        vp8_get_last_ref_frame},
+    {VP8D_GET_MODE_INFO,            get_mode_info},
     { -1, NULL},
 };
 
index 86610358cde7e71178665d42de334b6bcc039c0c..42310abf37f0e99af1210ef2f7aa29e2cfdc0b16 100644 (file)
@@ -60,6 +60,8 @@ enum vp8_dec_control_id
      */
     VP8D_GET_LAST_REF_USED,
 
+    VP8D_GET_MODE_INFO,
+
     VP8_DECODER_CTRL_ID_MAX
 } ;
 
@@ -75,6 +77,7 @@ enum vp8_dec_control_id
 VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_UPDATES,   int *)
 VPX_CTRL_USE_TYPE(VP8D_GET_FRAME_CORRUPTED,    int *)
 VPX_CTRL_USE_TYPE(VP8D_GET_LAST_REF_USED,      int *)
+VPX_CTRL_USE_TYPE(VP8D_GET_MODE_INFO,          vpx_fixed_buf_t **)
 
 /*! @} - end defgroup vp8_decoder */
 
index d92e165ffc5dcb80ffef90358415143954e28d0b..4692edc9be04cbbf024e11933b383a465aa8a07a 100644 (file)
@@ -134,6 +134,17 @@ extern "C" {
     vpx_codec_err_t;
 
 
+    /*!\brief Generic fixed size buffer structure
+     *
+     * This structure is able to hold a reference to any fixed size buffer.
+     */
+    typedef struct vpx_fixed_buf
+    {
+        void          *buf; /**< Pointer to the data */
+        size_t         sz;  /**< Length of the buffer, in chars */
+    } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */
+
+
     /*! \brief Codec capabilities bitfield
      *
      *  Each codec advertises the capabilities it supports as part of its
index c5429c9bc837ee65a6f8118e01fd96afcf9d7f41..093749c3970465fb3afefff5b825dd89f9bc6cf9 100644 (file)
@@ -77,17 +77,6 @@ extern "C" {
                                                      partition at a time. */
 
 
-    /*!\brief Generic fixed size buffer structure
-     *
-     * This structure is able to hold a reference to any fixed size buffer.
-     */
-    typedef struct vpx_fixed_buf
-    {
-        void          *buf; /**< Pointer to the data */
-        size_t         sz;  /**< Length of the buffer, in chars */
-    } vpx_fixed_buf_t; /**< alias for struct vpx_fixed_buf */
-
-
     /*!\brief Time Stamp Type
      *
      * An integer, which when multiplied by the stream's time base, provides
index d8c4fd71a99ce1697c812ded8333347105885b4b..8f125d7c3355a816c8153887666147012ec77275 100644 (file)
--- a/vpxenc.c
+++ b/vpxenc.c
@@ -2612,12 +2612,14 @@ float usec_to_fps(uint64_t usec, unsigned int frames)
 
 
 static void set_modeinfo(struct stream_state *stream,
-                         struct webm_ctx     *webm)
+                         struct input_state  *input)
 {
+    struct webm_ctx     *webm = &input->webm;
     unsigned char *ptr;
     struct link_record link;
     int again;
     int refs=0;
+    int mi_set = 0;
 
     vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, NULL);
     ptr = webm->buf + webm->buf_sz;
@@ -2638,9 +2640,32 @@ static void set_modeinfo(struct stream_state *stream,
             vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, &modeinfo);
             vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, link.refs_updated);
             ctx_exit_on_error(&stream->encoder, "Failed to set refs");
+            mi_set = 1;
             break;
         }
+        if((link.w|link.sz)&0xF)
+            break;
+        if(link.w > 16383 || link.h > 16383)
+            break;
     } while(again);
+
+    if(!mi_set
+       && stream->config.cfg.g_w == input->w
+       && stream->config.cfg.g_h == input->h)
+    {
+        vpx_fixed_buf_t *modeinfo;
+        int refs_updated;
+
+        vpx_codec_control(&webm->decoder, VP8D_GET_MODE_INFO, &modeinfo);
+        ctx_exit_on_error(&webm->decoder, "Failed to get mode info");
+        vpx_codec_control(&stream->encoder, VP8E_SET_MODEINFO, modeinfo);
+        ctx_exit_on_error(&webm->decoder, "Failed to set mode info");
+
+        vpx_codec_control(&webm->decoder, VP8D_GET_LAST_REF_UPDATES, &refs_updated);
+        ctx_exit_on_error(&webm->decoder, "Failed to get ref updates");
+        vpx_codec_control(&stream->encoder, VP8E_UPD_REFERENCE, refs_updated);
+        ctx_exit_on_error(&stream->encoder, "Failed to set ref updates");
+    }
 }
 
 int main(int argc, const char **argv_)
@@ -2801,7 +2826,7 @@ int main(int argc, const char **argv_)
 
             /* Update mode/mv info if available */
             if(input.file_type == FILE_TYPE_WEBM && global.read_modemv)
-                FOREACH_STREAM(set_modeinfo(stream, &input.webm));
+                FOREACH_STREAM(set_modeinfo(stream, &input));
 
             vpx_usec_timer_start(&timer);
             FOREACH_STREAM(encode_frame(stream, &global,