static vpx_codec_err_t vp9_decode(vpx_codec_alg_priv_t *ctx, const uint8_t *data, unsigned int data_sz, void *user_priv, long deadline) { const uint8_t *data_start = data; const uint8_t *data_end = data + data_sz; vpx_codec_err_t res = 0; uint32_t sizes[8]; int frames_this_pts, frame_count = 0; parse_superframe_index(data, data_sz, sizes, &frames_this_pts); do { // Skip over the superframe index, if present if (data_sz && (*data_start & 0xe0) == 0xc0) { const uint8_t marker = *data_start; const uint32_t frames = (marker & 0x7) + 1; const uint32_t mag = ((marker >> 3) & 0x3) + 1; const uint32_t index_sz = 2 + mag * frames; if (data_sz >= index_sz && data_start[index_sz - 1] == marker) { data_start += index_sz; data_sz -= index_sz; if (data_start < data_end) continue; else break; } } // Use the correct size for this frame, if an index is present. if (frames_this_pts) { uint32_t this_sz = sizes[frame_count]; if (data_sz < this_sz) { ctx->base.err_detail = "Invalid frame size in index"; return VPX_CODEC_CORRUPT_FRAME; } data_sz = this_sz; frame_count++; } res = decode_one(ctx, &data_start, data_sz, user_priv, deadline); assert(data_start >= data); assert(data_start <= data_end); /* Early exit if there was a decode error */ if (res) break; /* Account for suboptimal termination by the encoder. */ while (data_start < data_end && *data_start == 0) data_start++; data_sz = data_end - data_start; } while (data_start < data_end); return res; }
static vpx_codec_err_t decoder_decode(vpx_codec_alg_priv_t *ctx, const uint8_t *data, unsigned int data_sz, void *user_priv, long deadline) { const uint8_t *data_start = data; const uint8_t *const data_end = data + data_sz; vpx_codec_err_t res; uint32_t frame_sizes[8]; int frame_count; if (data == NULL || data_sz == 0) return VPX_CODEC_INVALID_PARAM; parse_superframe_index(data, data_sz, frame_sizes, &frame_count, ctx->decrypt_cb, ctx->decrypt_state); if (frame_count > 0) { int i; for (i = 0; i < frame_count; ++i) { const uint32_t frame_size = frame_sizes[i]; if (data_start < data || frame_size > (uint32_t)(data_end - data_start)) { ctx->base.err_detail = "Invalid frame size in index"; return VPX_CODEC_CORRUPT_FRAME; } res = decode_one_iter(ctx, &data_start, data_end, frame_size, user_priv, deadline); if (res != VPX_CODEC_OK) return res; } } else { while (data_start < data_end) { res = decode_one_iter(ctx, &data_start, data_end, (uint32_t)(data_end - data_start), user_priv, deadline); if (res != VPX_CODEC_OK) return res; } } return VPX_CODEC_OK; }