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);