static int escape124_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Escape124Context *s = avctx->priv_data; AVFrame *frame = data; GetBitContext gb; unsigned frame_flags, frame_size; unsigned i; unsigned superblock_index, cb_index = 1, superblock_col_index = 0, superblocks_per_row = avctx->width / 8, skip = -1; uint16_t* old_frame_data, *new_frame_data; unsigned old_stride, new_stride; int ret; init_get_bits(&gb, buf, buf_size * 8); // This call also guards the potential depth reads for the // codebook unpacking. if (!can_safely_read(&gb, 64)) return -1; frame_flags = get_bits_long(&gb, 32); frame_size = get_bits_long(&gb, 32); // Leave last frame unchanged // FIXME: Is this necessary? I haven't seen it in any real samples if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) { if (!s->frame->data[0]) return AVERROR_INVALIDDATA; av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n"); *got_frame = 1; if ((ret = av_frame_ref(frame, s->frame)) < 0) return ret; return frame_size; } for (i = 0; i < 3; i++) { if (frame_flags & (1 << (17 + i))) { unsigned cb_depth, cb_size; if (i == 2) { // This codebook can be cut off at places other than // powers of 2, leaving some of the entries undefined. cb_size = get_bits_long(&gb, 20); cb_depth = av_log2(cb_size - 1) + 1; } else { cb_depth = get_bits(&gb, 4); if (i == 0) { // This is the most basic codebook: pow(2,depth) entries // for a depth-length key cb_size = 1 << cb_depth; } else { // This codebook varies per superblock // FIXME: I don't think this handles integer overflow // properly cb_size = s->num_superblocks << cb_depth; } } av_free(s->codebooks[i].blocks); s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size); if (!s->codebooks[i].blocks) return -1; } } if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return ret; } new_frame_data = (uint16_t*)frame->data[0]; new_stride = frame->linesize[0] / 2; old_frame_data = (uint16_t*)s->frame->data[0]; old_stride = s->frame->linesize[0] / 2; for (superblock_index = 0; superblock_index < s->num_superblocks; superblock_index++) { MacroBlock mb; SuperBlock sb; unsigned multi_mask = 0; if (skip == -1) { // Note that this call will make us skip the rest of the blocks // if the frame prematurely ends skip = decode_skip_count(&gb); } if (skip) { copy_superblock(new_frame_data, new_stride, old_frame_data, old_stride); } else { copy_superblock(sb.pixels, 8, old_frame_data, old_stride); while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { unsigned mask; mb = decode_macroblock(s, &gb, &cb_index, superblock_index); mask = get_bits(&gb, 16); multi_mask |= mask; for (i = 0; i < 16; i++) { if (mask & mask_matrix[i]) { insert_mb_into_sb(&sb, mb, i); } } } if (can_safely_read(&gb, 1) && !get_bits1(&gb)) { unsigned inv_mask = get_bits(&gb, 4); for (i = 0; i < 4; i++) { if (inv_mask & (1 << i)) { multi_mask ^= 0xF << i*4; } else { multi_mask ^= get_bits(&gb, 4) << i*4; } } for (i = 0; i < 16; i++) { if (multi_mask & mask_matrix[i]) { if (!can_safely_read(&gb, 1)) break; mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, i); } } } else if (frame_flags & (1 << 16)) { while (can_safely_read(&gb, 1) && !get_bits1(&gb)) { mb = decode_macroblock(s, &gb, &cb_index, superblock_index); insert_mb_into_sb(&sb, mb, get_bits(&gb, 4)); } } copy_superblock(new_frame_data, new_stride, sb.pixels, 8); } superblock_col_index++; new_frame_data += 8; if (old_frame_data) old_frame_data += 8; if (superblock_col_index == superblocks_per_row) { new_frame_data += new_stride * 8 - superblocks_per_row * 8; if (old_frame_data) old_frame_data += old_stride * 8 - superblocks_per_row * 8; superblock_col_index = 0; } skip--; } av_log(NULL, AV_LOG_DEBUG, "Escape sizes: %i, %i, %i\n", frame_size, buf_size, get_bits_count(&gb) / 8); av_frame_unref(s->frame); if ((ret = av_frame_ref(s->frame, frame)) < 0) return ret; *got_frame = 1; return frame_size; }
static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt) { int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; AVFrame *pic = data; GetBitContext gb; int ret; uint8_t *old_y, *old_cb, *old_cr, *new_y, *new_cb, *new_cr; uint8_t *dstY, *dstU, *dstV; unsigned old_y_stride, old_cb_stride, old_cr_stride, new_y_stride, new_cb_stride, new_cr_stride; unsigned total_blocks = avctx->width * avctx->height / 4, block_index, block_x = 0; unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10; int skip = -1, y_avg = 0, i, j; uint8_t *ya = s->old_y_avg; // first 16 bytes are header; no useful information in here if (buf_size <= 16) { av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n"); return AVERROR_INVALIDDATA; } if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) return ret; if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) return ret; skip_bits_long(&gb, 16 * 8); new_y = s->new_y; new_cb = s->new_u; new_cr = s->new_v; new_y_stride = s->linesize[0]; new_cb_stride = s->linesize[1]; new_cr_stride = s->linesize[2]; old_y = s->old_y; old_cb = s->old_u; old_cr = s->old_v; old_y_stride = s->linesize[0]; old_cb_stride = s->linesize[1]; old_cr_stride = s->linesize[2]; for (block_index = 0; block_index < total_blocks; block_index++) { // Note that this call will make us skip the rest of the blocks // if the frame ends prematurely. if (skip == -1) skip = decode_skip_count(&gb); if (skip == -1) { av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n"); return AVERROR_INVALIDDATA; } if (skip) { y[0] = old_y[0]; y[1] = old_y[1]; y[2] = old_y[old_y_stride]; y[3] = old_y[old_y_stride + 1]; y_avg = ya[0]; cb = old_cb[0]; cr = old_cr[0]; } else { if (get_bits1(&gb)) { unsigned sign_selector = get_bits(&gb, 6); unsigned difference_selector = get_bits(&gb, 2); y_avg = 2 * get_bits(&gb, 5); for (i = 0; i < 4; i++) { y[i] = av_clip(y_avg + offset_table[difference_selector] * sign_table[sign_selector][i], 0, 63); } } else if (get_bits1(&gb)) { if (get_bits1(&gb)) { y_avg = get_bits(&gb, 6); } else { unsigned adjust_index = get_bits(&gb, 3); y_avg = (y_avg + luma_adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) y[i] = y_avg; } if (get_bits1(&gb)) { if (get_bits1(&gb)) { cb = get_bits(&gb, 5); cr = get_bits(&gb, 5); } else { unsigned adjust_index = get_bits(&gb, 3); cb = (cb + chroma_adjust[0][adjust_index]) & 31; cr = (cr + chroma_adjust[1][adjust_index]) & 31; } } } *ya++ = y_avg; new_y[0] = y[0]; new_y[1] = y[1]; new_y[new_y_stride] = y[2]; new_y[new_y_stride + 1] = y[3]; *new_cb = cb; *new_cr = cr; old_y += 2; old_cb++; old_cr++; new_y += 2; new_cb++; new_cr++; block_x++; if (block_x * 2 == avctx->width) { block_x = 0; old_y += old_y_stride * 2 - avctx->width; old_cb += old_cb_stride - avctx->width / 2; old_cr += old_cr_stride - avctx->width / 2; new_y += new_y_stride * 2 - avctx->width; new_cb += new_cb_stride - avctx->width / 2; new_cr += new_cr_stride - avctx->width / 2; } skip--; } new_y = s->new_y; new_cb = s->new_u; new_cr = s->new_v; dstY = pic->data[0]; dstU = pic->data[1]; dstV = pic->data[2]; for (j = 0; j < avctx->height; j++) { for (i = 0; i < avctx->width; i++) dstY[i] = new_y[i] << 2; dstY += pic->linesize[0]; new_y += new_y_stride; } for (j = 0; j < avctx->height / 2; j++) { for (i = 0; i < avctx->width / 2; i++) { dstU[i] = chroma_vals[new_cb[i]]; dstV[i] = chroma_vals[new_cr[i]]; } dstU += pic->linesize[1]; dstV += pic->linesize[2]; new_cb += new_cb_stride; new_cr += new_cr_stride; } av_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", buf_size, get_bits_count(&gb) >> 3); FFSWAP(uint8_t*, s->old_y, s->new_y); FFSWAP(uint8_t*, s->old_u, s->new_u); FFSWAP(uint8_t*, s->old_v, s->new_v); *got_frame = 1; return buf_size; }
/** * Decode a single frame * @param avctx decoder context * @param data decoded frame * @param data_size size of the decoded frame * @param buf input buffer * @param buf_size input buffer size * @return 0 success, -1 on error */ static int escape130_decode_frame(AVCodecContext *avctx, void *data, int *data_size, AVPacket *avpkt) { const uint8_t *buf = avpkt->data; int buf_size = avpkt->size; Escape130Context *s = avctx->priv_data; GetBitContext gb; unsigned i; uint8_t *old_y, *old_cb, *old_cr, *new_y, *new_cb, *new_cr; unsigned old_y_stride, old_cb_stride, old_cr_stride, new_y_stride, new_cb_stride, new_cr_stride; unsigned total_blocks = avctx->width * avctx->height / 4, block_index, row_index = 0; unsigned y[4] = {0}, cb = 16, cr = 16; unsigned skip = -1; unsigned y_base = 0; uint8_t *yb= s->bases; AVFrame new_frame = { { 0 } }; init_get_bits(&gb, buf, buf_size * 8); if (get_bits_left(&gb) < 128) return -1; // Header; no useful information in here skip_bits_long(&gb, 128); new_frame.reference = 3; if (avctx->get_buffer(avctx, &new_frame)) { av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n"); return -1; } new_y = new_frame.data[0]; new_cb = new_frame.data[1]; new_cr = new_frame.data[2]; new_y_stride = new_frame.linesize[0]; new_cb_stride = new_frame.linesize[1]; new_cr_stride = new_frame.linesize[2]; old_y = s->frame.data[0]; old_cb = s->frame.data[1]; old_cr = s->frame.data[2]; old_y_stride = s->frame.linesize[0]; old_cb_stride = s->frame.linesize[1]; old_cr_stride = s->frame.linesize[2]; av_log(avctx, AV_LOG_DEBUG, "Strides: %i, %i\n", new_y_stride, new_cb_stride); for (block_index = 0; block_index < total_blocks; block_index++) { // Note that this call will make us skip the rest of the blocks // if the frame prematurely ends if (skip == -1) skip = decode_skip_count(&gb); if (skip) { if (old_y) { y[0] = old_y[0] / 4; y[1] = old_y[1] / 4; y[2] = old_y[old_y_stride] / 4; y[3] = old_y[old_y_stride+1] / 4; y_base= yb[0]; cb = old_cb[0] / 8; cr = old_cr[0] / 8; } else { y_base=y[0] = y[1] = y[2] = y[3] = 0; cb = cr = 16; } } else { if (get_bits1(&gb)) { static const uint8_t offset_table[] = {2, 4, 10, 20}; static const int8_t sign_table[64][4] = { {0, 0, 0, 0}, {-1, 1, 0, 0}, {1, -1, 0, 0}, {-1, 0, 1, 0}, {-1, 1, 1, 0}, {0, -1, 1, 0}, {1, -1, 1, 0}, {-1, -1, 1, 0}, {1, 0, -1, 0}, {0, 1, -1, 0}, {1, 1, -1, 0}, {-1, 1, -1, 0}, {1, -1, -1, 0}, {-1, 0, 0, 1}, {-1, 1, 0, 1}, {0, -1, 0, 1}, {0, 0, 0, 0}, {1, -1, 0, 1}, {-1, -1, 0, 1}, {-1, 0, 1, 1}, {-1, 1, 1, 1}, {0, -1, 1, 1}, {1, -1, 1, 1}, {-1, -1, 1, 1}, {0, 0, -1, 1}, {1, 0, -1, 1}, {-1, 0, -1, 1}, {0, 1, -1, 1}, {1, 1, -1, 1}, {-1, 1, -1, 1}, {0, -1, -1, 1}, {1, -1, -1, 1}, {0, 0, 0, 0}, {-1, -1, -1, 1}, {1, 0, 0, -1}, {0, 1, 0, -1}, {1, 1, 0, -1}, {-1, 1, 0, -1}, {1, -1, 0, -1}, {0, 0, 1, -1}, {1, 0, 1, -1}, {-1, 0, 1, -1}, {0, 1, 1, -1}, {1, 1, 1, -1}, {-1, 1, 1, -1}, {0, -1, 1, -1}, {1, -1, 1, -1}, {-1, -1, 1, -1}, {0, 0, 0, 0}, {1, 0, -1, -1}, {0, 1, -1, -1}, {1, 1, -1, -1}, {-1, 1, -1, -1}, {1, -1, -1, -1} }; unsigned sign_selector = get_bits(&gb, 6); unsigned difference_selector = get_bits(&gb, 2); y_base = 2 * get_bits(&gb, 5); for (i = 0; i < 4; i++) { y[i] = av_clip((int)y_base + offset_table[difference_selector] * sign_table[sign_selector][i], 0, 63); } } else if (get_bits1(&gb)) { if (get_bits1(&gb)) { y_base = get_bits(&gb, 6); } else { unsigned adjust_index = get_bits(&gb, 3); static const int8_t adjust[] = {-4, -3, -2, -1, 1, 2, 3, 4}; y_base = (y_base + adjust[adjust_index]) & 63; } for (i = 0; i < 4; i++) y[i] = y_base; } if (get_bits1(&gb)) { if (get_bits1(&gb)) { cb = get_bits(&gb, 5); cr = get_bits(&gb, 5); } else { unsigned adjust_index = get_bits(&gb, 3); static const int8_t adjust[2][8] = { { 1, 1, 0, -1, -1, -1, 0, 1 }, { 0, 1, 1, 1, 0, -1, -1, -1 } }; cb = (cb + adjust[0][adjust_index]) & 31; cr = (cr + adjust[1][adjust_index]) & 31; } } } *yb++= y_base; new_y[0] = y[0] * 4; new_y[1] = y[1] * 4; new_y[new_y_stride] = y[2] * 4; new_y[new_y_stride + 1] = y[3] * 4; *new_cb = cb * 8; *new_cr = cr * 8; if (old_y) old_y += 2, old_cb++, old_cr++; new_y += 2, new_cb++, new_cr++; row_index++; if (avctx->width / 2 == row_index) { row_index = 0; if (old_y) { old_y += old_y_stride * 2 - avctx->width; old_cb += old_cb_stride - avctx->width / 2; old_cr += old_cr_stride - avctx->width / 2; } new_y += new_y_stride * 2 - avctx->width; new_cb += new_cb_stride - avctx->width / 2; new_cr += new_cr_stride - avctx->width / 2; } skip--; } av_log(avctx, AV_LOG_DEBUG, "Escape sizes: %i, %i\n", buf_size, get_bits_count(&gb) / 8); if (s->frame.data[0]) avctx->release_buffer(avctx, &s->frame); *(AVFrame*)data = s->frame = new_frame; *data_size = sizeof(AVFrame); return buf_size; }