From: Vignesh Venkatasubramanian Date: Mon, 29 Oct 2012 22:57:44 +0000 (-0700) Subject: Packing Altref along with succeeding frame and length encoding frames X-Git-Tag: v1.3.0~1217^2~116^2 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=bc9670eee0c2a8731cca5e967d8e90a3a13911c3;p=platform%2Fupstream%2Flibvpx.git Packing Altref along with succeeding frame and length encoding frames The altref frame is packed along with the next P frame. So that outside of the codec there are now only two types of frames P and I. Also, now it is one frame in and one frame out with respect to the codec. Apart from that, all the frames are length encoded with the length of each frame appended to the frame itself. There are two categories of frames and each of them will look as follows: - Packed frames (an altref along with the succeeding p frame) - altref_frame_data | altref_lenngth | frame_data | length - Unpacked frames (all frames other than the above) - frame_data | length Change-Id: If1eabf5c473f7d46b3f2d026bd30c803588c5330 --- diff --git a/vp9/vp9_cx_iface.c b/vp9/vp9_cx_iface.c index 1333cc1..ad3b6be 100644 --- a/vp9/vp9_cx_iface.c +++ b/vp9/vp9_cx_iface.c @@ -79,6 +79,8 @@ struct vpx_codec_alg_priv { 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; @@ -568,6 +570,19 @@ static void pick_quickcompress_mode(vpx_codec_alg_priv_t *ctx, } } +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, @@ -671,10 +686,16 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, 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, @@ -684,6 +705,18 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, 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); @@ -737,8 +770,15 @@ static vpx_codec_err_t vp8e_encode(vpx_codec_alg_priv_t *ctx, } 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; diff --git a/vpx/src/vpx_decoder.c b/vpx/src/vpx_decoder.c index 9fa1bf6..7b3aa56 100644 --- a/vpx/src/vpx_decoder.c +++ b/vpx/src/vpx_decoder.c @@ -106,6 +106,29 @@ vpx_codec_err_t vpx_codec_get_stream_info(vpx_codec_ctx_t *ctx, 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, @@ -113,6 +136,11 @@ vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, 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 */ @@ -121,8 +149,18 @@ vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, 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);