shithub: libvpx

Download patch

ref: 3a0cfb36172f047eadcc156a85358b6dcc1e6db0
parent: 9f53661e8b8cfe288c8c8674810f2291de5cc1f2
parent: bc9670eee0c2a8731cca5e967d8e90a3a13911c3
author: John Koleszar <jkoleszar@google.com>
date: Fri Nov 9 07:31:37 EST 2012

Merge "Packing Altref along with succeeding frame and length encoding frames" into experimental

--- a/vp9/vp9_cx_iface.c
+++ b/vp9/vp9_cx_iface.c
@@ -77,6 +77,8 @@
   VP9_PTR             cpi;
   unsigned char          *cx_data;
   unsigned int            cx_data_sz;
+  unsigned char           *altref_cx_data;
+  unsigned int            altref_size;
   vpx_image_t             preview_img;
   unsigned int            next_frame_flag;
   vp8_postproc_cfg_t      preview_ppcfg;
@@ -575,6 +577,19 @@
   }
 }
 
+static void append_length(unsigned char* cx_data, unsigned long int *cx_size) {
+  unsigned char chunk;
+  unsigned int offset = 0;
+  unsigned long int size = *cx_size;
+  do {
+    chunk = size & 0x7F;
+    size >>= 7;
+    chunk |= (offset == 0) << 7;
+    cx_data[offset] = chunk;
+    offset++;
+  } while (size);
+  *cx_size += offset;
+}
 
 static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t  *ctx,
                                    const vpx_image_t     *img,
@@ -678,10 +693,16 @@
       ctx->next_frame_flag = 0;
     }
 
-    cx_data = ctx->cx_data;
-    cx_data_sz = ctx->cx_data_sz;
     lib_flags = 0;
 
+    if (ctx->altref_size) {
+      cx_data = ctx->altref_cx_data + ctx->altref_size;
+      cx_data_sz = ctx->cx_data_sz - ctx->altref_size;
+    } else {
+      cx_data = ctx->cx_data;
+      cx_data_sz = ctx->cx_data_sz;
+    }
+
     while (cx_data_sz >= ctx->cx_data_sz / 2 &&
            -1 != vp9_get_compressed_data(ctx->cpi, &lib_flags, &size,
                                          cx_data, &dst_time_stamp,
@@ -691,6 +712,18 @@
         vpx_codec_cx_pkt_t pkt;
         VP9_COMP *cpi = (VP9_COMP *)ctx->cpi;
 
+        /* TODO(jkoleszar): for now we append lengths to all frames, revisit
+         * this later to ensure if this is necessary */
+        append_length(cx_data + size, &size);
+
+        if (!cpi->common.show_frame) {
+          ctx->altref_cx_data = cx_data;
+          ctx->altref_size = size;
+          cx_data += size;
+          cx_data_sz -= size;
+          continue;
+        }
+
         /* Add the frame packet to the list of returned packets. */
         round = 1000000 * ctx->cfg.g_timebase.num / 2 - 1;
         delta = (dst_end_time_stamp - dst_time_stamp);
@@ -744,8 +777,15 @@
         }
         else*/
         {
-          pkt.data.frame.buf = cx_data;
-          pkt.data.frame.sz  = size;
+          if (ctx->altref_size) {
+            pkt.data.frame.sz = ctx->altref_size + size;
+            pkt.data.frame.buf = ctx->altref_cx_data;
+            ctx->altref_size = 0;
+            ctx->altref_cx_data = NULL;
+          } else {
+            pkt.data.frame.buf = cx_data;
+            pkt.data.frame.sz = size;
+          }
           pkt.data.frame.partition_id = -1;
           vpx_codec_pkt_list_add(&ctx->pkt_list.head, &pkt);
           cx_data += size;
--- a/vpx/src/vpx_decoder.c
+++ b/vpx/src/vpx_decoder.c
@@ -109,7 +109,30 @@
   return SAVE_STATUS(ctx, res);
 }
 
+static int read_frame_length(const uint8_t *data, uint64_t size,
+                             uint64_t *frame_length, int *size_length) {
+  uint64_t value = 0;
+  *size_length = 0;
+  do {
+    uint64_t index;
+    size -= value + *size_length;
+    index = size - 1;
+    value = 0;
+    do {
+      if (data + index < data) {
+          *frame_length = -1;
+          return -1;
+      }
+      value <<= 7;
+      value |= (data[index] & 0x7F);
+    } while (!(data[index--] >> 7));
+    *size_length = size - 1 - index;
+  } while (value + *size_length < size);
+  *frame_length = value;
+  return 0;
+}
 
+
 vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t    *ctx,
                                  const uint8_t        *data,
                                  unsigned int    data_sz,
@@ -116,6 +139,11 @@
                                  void       *user_priv,
                                  long        deadline) {
   vpx_codec_err_t res;
+  int offset = 0;
+  uint64_t length = 0;
+  unsigned char altref_frame;
+  unsigned int cx_size = data_sz;
+  uint8_t *cx_data = data;
 
   /* Sanity checks */
   /* NULL data ptr allowed if data_sz is 0 too */
@@ -124,8 +152,18 @@
   else if (!ctx->iface || !ctx->priv)
     res = VPX_CODEC_ERROR;
   else {
-    res = ctx->iface->dec.decode(ctx->priv->alg_priv, data, data_sz,
-                                 user_priv, deadline);
+    do {
+      altref_frame = !(*cx_data & 0x10);
+      res = read_frame_length(cx_data, cx_size, &length, &offset);
+      if (res != 0)
+        return SAVE_STATUS(ctx, VPX_CODEC_UNSUP_BITSTREAM);
+      res = ctx->iface->dec.decode(ctx->priv->alg_priv, cx_data,
+                                         length, user_priv, deadline);
+      if (res != 0)
+        return SAVE_STATUS(ctx, res);
+      cx_data += offset + length;
+      cx_size -= offset + length;
+    } while (cx_data - data <= data_sz && altref_frame);
   }
 
   return SAVE_STATUS(ctx, res);