55 #define BS_8BIT_PEL (1 << 1) 56 #define BS_KEYFRAME (1 << 2) 57 #define BS_MV_Y_HALF (1 << 4) 58 #define BS_MV_X_HALF (1 << 5) 59 #define BS_NONREF (1 << 8) 71 #define CELL_STACK_MAX 20 120 static int8_t offsets[8] = { 1, 1, 2, -3, -3, 3, 4, 4 };
121 static int8_t deltas [8] = { 0, 1, 0, 4, 4, 1, 0, 1 };
125 for (i = 0; i < 8; i++) {
127 for (j = 0; j < 128; j++)
128 requant_tab[i][j] = (j + offsets[i]) / step * step + deltas[i];
153 int p, luma_width, luma_height, chroma_width, chroma_height;
154 int luma_pitch, chroma_pitch, luma_size, chroma_size;
156 luma_width = ctx->
width;
157 luma_height = ctx->
height;
159 if (luma_width < 16 || luma_width > 640 ||
160 luma_height < 16 || luma_height > 480 ||
161 luma_width & 3 || luma_height & 3) {
163 luma_width, luma_height);
167 chroma_width =
FFALIGN(luma_width >> 2, 4);
168 chroma_height =
FFALIGN(luma_height >> 2, 4);
170 luma_pitch =
FFALIGN(luma_width, 16);
171 chroma_pitch =
FFALIGN(chroma_width, 16);
175 luma_size = luma_pitch * (luma_height + 1);
179 chroma_size = chroma_pitch * (chroma_height + 1);
182 for (p = 0; p < 3; p++) {
183 ctx->
planes[p].
pitch = !p ? luma_pitch : chroma_pitch;
184 ctx->
planes[p].
width = !p ? luma_width : chroma_width;
185 ctx->
planes[p].
height = !p ? luma_height : chroma_height;
209 for (p = 0; p < 3; p++) {
227 int h, w, mv_x, mv_y, offset, offset_dst;
231 offset_dst = (cell->
ypos << 2) * plane->
pitch + (cell->
xpos << 2);
237 if ((cell->
ypos << 2) + mv_y < -1 || (cell->
xpos << 2) + mv_x < 0 ||
241 "Motion vectors point out of the frame.\n");
245 offset = offset_dst + mv_y * plane->
pitch + mv_x;
250 for (w = cell->
width; w > 0;) {
252 if (!((cell->
xpos << 2) & 15) && w >= 4) {
253 for (; w >= 4; src += 16, dst += 16, w -= 4)
258 if (!((cell->
xpos << 2) & 7) && w >= 2) {
276 #define AVG_32(dst, src, ref) \ 277 AV_WN32A(dst, ((AV_RN32(src) + AV_RN32(ref)) >> 1) & 0x7F7F7F7FUL) 279 #define AVG_64(dst, src, ref) \ 280 AV_WN64A(dst, ((AV_RN64(src) + AV_RN64(ref)) >> 1) & 0x7F7F7F7F7F7F7F7FULL) 289 a &= 0xFF00FF00FF00FF00ULL;
292 a &= 0x00FF00FF00FF00FFULL;
314 for (; n > 0; dst += row_offset, n--)
330 #define BUFFER_PRECHECK \ 331 if (*data_ptr >= last_ptr) \ 332 return IV3_OUT_OF_DATA; \ 334 #define RLE_BLOCK_COPY \ 335 if (cell->mv_ptr || !skip_flag) \ 336 ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, 4 << v_zoom) 338 #define RLE_BLOCK_COPY_8 \ 339 pix64 = AV_RN64(ref);\ 341 pix64 = replicate64(pix64);\ 342 fill_64(dst + row_offset, pix64, 7, row_offset);\ 343 AVG_64(dst, ref, dst + row_offset);\ 345 fill_64(dst, pix64, 8, row_offset) 347 #define RLE_LINES_COPY \ 348 ctx->hdsp.put_pixels_tab[2][0](dst, ref, row_offset, num_lines << v_zoom) 350 #define RLE_LINES_COPY_M10 \ 351 pix64 = AV_RN64(ref);\ 352 if (is_top_of_cell) {\ 353 pix64 = replicate64(pix64);\ 354 fill_64(dst + row_offset, pix64, (num_lines << 1) - 1, row_offset);\ 355 AVG_64(dst, ref, dst + row_offset);\ 357 fill_64(dst, pix64, num_lines << 1, row_offset) 359 #define APPLY_DELTA_4 \ 360 AV_WN16A(dst + line_offset ,\ 361 (AV_RN16(ref ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ 362 AV_WN16A(dst + line_offset + 2,\ 363 (AV_RN16(ref + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ 365 if (is_top_of_cell && !cell->ypos) {\ 366 AV_COPY32U(dst, dst + row_offset);\ 368 AVG_32(dst, ref, dst + row_offset);\ 372 #define APPLY_DELTA_8 \ 374 if (is_top_of_cell) { \ 375 AV_WN32A(dst + row_offset , \ 376 (replicate32(AV_RN32(ref )) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ 377 AV_WN32A(dst + row_offset + 4, \ 378 (replicate32(AV_RN32(ref + 4)) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ 380 AV_WN32A(dst + row_offset , \ 381 (AV_RN32(ref ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ 382 AV_WN32A(dst + row_offset + 4, \ 383 (AV_RN32(ref + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ 388 if (is_top_of_cell && !cell->ypos) {\ 389 AV_COPY64U(dst, dst + row_offset);\ 391 AVG_64(dst, ref, dst + row_offset); 394 #define APPLY_DELTA_1011_INTER \ 397 (AV_RN32(dst ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ 399 (AV_RN32(dst + 4 ) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ 400 AV_WN32A(dst + row_offset , \ 401 (AV_RN32(dst + row_offset ) + delta_tab->deltas_m10[dyad1]) & 0x7F7F7F7F);\ 402 AV_WN32A(dst + row_offset + 4, \ 403 (AV_RN32(dst + row_offset + 4) + delta_tab->deltas_m10[dyad2]) & 0x7F7F7F7F);\ 406 (AV_RN16(dst ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ 408 (AV_RN16(dst + 2 ) + delta_tab->deltas[dyad2]) & 0x7F7F);\ 409 AV_WN16A(dst + row_offset , \ 410 (AV_RN16(dst + row_offset ) + delta_tab->deltas[dyad1]) & 0x7F7F);\ 411 AV_WN16A(dst + row_offset + 2, \ 412 (AV_RN16(dst + row_offset + 2) + delta_tab->deltas[dyad2]) & 0x7F7F);\ 418 int pitch,
int h_zoom,
int v_zoom,
int mode,
422 int x, y,
line, num_lines;
426 unsigned int dyad1, dyad2;
428 int skip_flag = 0, is_top_of_cell, is_first_row = 1;
429 int row_offset, blk_row_offset, line_offset;
432 blk_row_offset = (row_offset << (2 + v_zoom)) - (cell->
width << 2);
433 line_offset = v_zoom ? row_offset : 0;
438 for (y = 0; y < cell->
height; is_first_row = 0, y += 1 + v_zoom) {
439 for (x = 0; x < cell->
width; x += 1 + h_zoom) {
443 if (rle_blocks > 0) {
446 }
else if (mode == 10 && !cell->
mv_ptr) {
451 for (line = 0; line < 4;) {
453 is_top_of_cell = is_first_row && !line;
457 delta_tab = delta[line & 1];
459 delta_tab = delta[1];
461 code = bytestream_get_byte(data_ptr);
463 if (code < delta_tab->num_dyads) {
465 dyad1 = bytestream_get_byte(data_ptr);
467 if (dyad1 >= delta_tab->
num_dyads || dyad1 >= 248)
474 if (swap_quads[line & 1])
475 FFSWAP(
unsigned int, dyad1, dyad2);
479 }
else if (mode == 10 && !cell->
mv_ptr) {
495 num_lines = 257 - code - line;
500 }
else if (mode == 10 && !cell->
mv_ptr) {
506 code = bytestream_get_byte(data_ptr);
507 rle_blocks = (code & 0x1F) - 1;
508 if (code >= 64 || rle_blocks < 0)
510 skip_flag = code & 0x20;
511 num_lines = 4 - line;
512 if (mode >= 10 || (cell->
mv_ptr || !skip_flag)) {
515 }
else if (mode == 10 && !cell->
mv_ptr) {
531 }
else if (mode == 10 && !cell->
mv_ptr) {
542 ref += row_offset * (num_lines << v_zoom);
543 dst += row_offset * (num_lines << v_zoom);
548 block += 4 << h_zoom;
549 ref_block += 4 << h_zoom;
553 ref_block += blk_row_offset;
554 block += blk_row_offset;
577 int x, mv_x, mv_y, mode, vq_index, prim_indx, second_indx;
579 int offset, error = 0, swap_quads[2];
582 const uint8_t *data_start = data_ptr;
587 vq_index = code & 0xF;
590 offset = (cell->
ypos << 2) * plane->
pitch + (cell->
xpos << 2);
594 ref_block = block - plane->
pitch;
595 }
else if (mode >= 10) {
607 if ((cell->
ypos << 2) + mv_y < -1 || (cell->
xpos << 2) + mv_x < 0 ||
611 "Motion vectors point out of the frame.\n");
615 offset += mv_y * plane->
pitch + mv_x;
622 if (mode == 1 || mode == 4) {
624 prim_indx = (code >> 4) + ctx->
cb_offset;
625 second_indx = (code & 0xF) + ctx->
cb_offset;
628 prim_indx = second_indx = vq_index;
631 if (prim_indx >= 24 || second_indx >= 24) {
632 av_log(avctx,
AV_LOG_ERROR,
"Invalid VQ table indexes! Primary: %d, secondary: %d!\n",
633 prim_indx, second_indx);
637 delta[0] = &
vq_tab[second_indx];
638 delta[1] = &
vq_tab[prim_indx];
639 swap_quads[0] = second_indx >= 16;
640 swap_quads[1] = prim_indx >= 16;
644 if (vq_index >= 8 && ref_block) {
645 for (x = 0; x < cell->
width << 2; x++)
646 ref_block[x] =
requant_tab[vq_index & 7][ref_block[x]];
656 if (mode >= 3 && cell->
mv_ptr) {
661 zoom_fac = mode >= 3;
663 0, zoom_fac, mode, delta, swap_quads,
664 &data_ptr, last_ptr);
668 if (mode == 10 && !cell->
mv_ptr) {
670 1, 1, mode, delta, swap_quads,
671 &data_ptr, last_ptr);
673 if (mode == 11 && !cell->
mv_ptr) {
678 zoom_fac = mode == 10;
680 zoom_fac, 1, mode, delta, swap_quads,
681 &data_ptr, last_ptr);
691 av_log(avctx,
AV_LOG_ERROR,
"Mode %d: RLE code %X is not allowed at the current line\n",
701 av_log(avctx,
AV_LOG_ERROR,
"Mode %d: unsupported RLE code: %X\n", mode, data_ptr[-1]);
708 return data_ptr - data_start;
721 #define SPLIT_CELL(size, new_size) (new_size) = ((size) > 2) ? ((((size) + 2) >> 2) << 1) : 1 723 #define UPDATE_BITPOS(n) \ 724 ctx->skip_bits += (n); \ 727 #define RESYNC_BITSTREAM \ 728 if (ctx->need_resync && !(get_bits_count(&ctx->gb) & 7)) { \ 729 skip_bits_long(&ctx->gb, ctx->skip_bits); \ 730 ctx->skip_bits = 0; \ 731 ctx->need_resync = 0; \ 735 if (curr_cell.xpos + curr_cell.width > (plane->width >> 2) || \ 736 curr_cell.ypos + curr_cell.height > (plane->height >> 2)) { \ 737 av_log(avctx, AV_LOG_ERROR, "Invalid cell: x=%d, y=%d, w=%d, h=%d\n", \ 738 curr_cell.xpos, curr_cell.ypos, curr_cell.width, curr_cell.height); \ 739 return AVERROR_INVALIDDATA; \ 745 const int depth,
const int strip_width)
755 curr_cell = *ref_cell;
763 if (curr_cell.
width > strip_width) {
765 curr_cell.
width = (curr_cell.
width <= (strip_width << 1) ? 1 : 2) * strip_width;
770 if (ref_cell->
width <= 0 || curr_cell.
width <= 0)
779 if (
parse_bintree(ctx, avctx, plane, code, &curr_cell, depth - 1, strip_width))
783 if (!curr_cell.
tree) {
804 if (!curr_cell.
tree) {
822 bytes_used =
decode_cell(ctx, avctx, plane, &curr_cell,
844 unsigned num_vectors;
848 num_vectors = bytestream_get_le32(&data);
849 if (num_vectors > 256) {
851 "Read invalid number of motion vectors %d\n", num_vectors);
854 if (num_vectors * 2 >= data_size)
861 init_get_bits(&ctx->
gb, &data[num_vectors * 2], (data_size - num_vectors * 2) << 3);
868 curr_cell.
xpos = curr_cell.
ypos = 0;
878 #define OS_HDR_ID MKBETAG('F', 'R', 'M', 'H') 881 const uint8_t *buf,
int buf_size)
885 uint32_t frame_num, word2, check_sum, data_size;
886 uint32_t y_offset, u_offset, v_offset, starts[3], ends[3];
893 frame_num = bytestream2_get_le32(&gb);
894 word2 = bytestream2_get_le32(&gb);
895 check_sum = bytestream2_get_le32(&gb);
896 data_size = bytestream2_get_le32(&gb);
898 if ((frame_num ^ word2 ^ data_size ^
OS_HDR_ID) != check_sum) {
906 if (bytestream2_get_le16(&gb) != 32) {
913 ctx->
data_size = (bytestream2_get_le32(&gb) + 7) >> 3;
914 ctx->
cb_offset = bytestream2_get_byte(&gb);
923 height = bytestream2_get_le16(&gb);
924 width = bytestream2_get_le16(&gb);
928 if (width != ctx->
width || height != ctx->
height) {
931 av_dlog(avctx,
"Frame dimensions changed!\n");
933 if (width < 16 || width > 640 ||
934 height < 16 || height > 480 ||
935 width & 3 || height & 3) {
937 "Invalid picture dimensions: %d x %d!\n", width, height);
951 y_offset = bytestream2_get_le32(&gb);
952 v_offset = bytestream2_get_le32(&gb);
953 u_offset = bytestream2_get_le32(&gb);
958 starts[0] = y_offset;
959 starts[1] = v_offset;
960 starts[2] = u_offset;
962 for (j = 0; j < 3; j++) {
964 for (i = 2; i >= 0; i--)
965 if (starts[i] < ends[j] && starts[i] > starts[j])
973 FFMIN3(y_offset, v_offset, u_offset) < gb.
buffer - bs_hdr + 16 ||
1014 int dst_pitch,
int dst_height)
1021 for (y = 0; y < dst_height; y++) {
1023 for (x = 0; x < plane->
width >> 2; x++) {
1029 for (x <<= 2; x < plane->
width; x++)
1030 *dst++ = *src++ << 1;
1032 src += pitch - plane->
width;
1033 dst += dst_pitch - plane->
width;
1062 int buf_size = avpkt->
size;
1110 (avctx->
height + 3) >> 2);
1113 (avctx->
height + 3) >> 2);
static int decode_cell(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, Cell *cell, const uint8_t *data_ptr, const uint8_t *last_ptr)
Decode a vector-quantized cell.
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
discard all frames except keyframes
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
This structure describes decoded (raw) audio or video data.
#define BS_8BIT_PEL
8bit pixel bitdepth indicator
const uint8_t * next_cell_data
static int decode_plane(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, const uint8_t *data, int32_t data_size, int32_t strip_width)
int16_t xpos
cell coordinates in 4x4 blocks
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
const uint8_t * y_data_ptr
int16_t height
cell height in 4x4 blocks
uint8_t quad_exp
log2 of four-pixel deltas
uint8_t num_dyads
number of two-pixel deltas
const uint8_t * v_data_ptr
#define RLE_LINES_COPY_M10
#define BS_BUFFER
indicates which of two frame buffers should be used
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
static av_cold void free_frame_buffers(Indeo3DecodeContext *ctx)
uint32_t frame_num
current frame number (zero-based)
uint8_t buf_sel
active frame buffer: 0 - primary, 1 -secondary
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
enum AVDiscard skip_frame
INTRA: skip block, INTER: copy data from reference.
av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
static int decode(MimicContext *ctx, int quality, int num_coeffs, int is_iframe)
#define BS_KEYFRAME
intra frame indicator
void void avpriv_request_sample(void *avc, const char *msg,...) av_printf_format(2
Log a generic warning message about a missing feature.
static av_cold int decode_close(AVCodecContext *avctx)
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
static int get_bits_count(const GetBitContext *s)
bitstream reader API header.
static int decode_frame_headers(Indeo3DecodeContext *ctx, AVCodecContext *avctx, const uint8_t *buf, int buf_size)
static uint64_t replicate64(uint64_t a)
apply null delta to all remaining lines of this block
const uint8_t * last_byte
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
static void output_plane(const Plane *plane, int buf_sel, uint8_t *dst, int dst_pitch, int dst_height)
Convert and output the current plane.
uint16_t frame_flags
frame properties
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
uint8_t cb_offset
needed for selecting VQ tables
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
static const vqEntry vq_tab[24]
void av_log(void *avcl, int level, const char *fmt,...)
const char * name
Name of the codec implementation.
av_cold void ff_hpeldsp_init(HpelDSPContext *c, int flags)
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx)
Check if the given dimension of an image is valid, meaning that all bytes of the image can be address...
apply null delta to all lines up to the 2nd line
#define BS_NONREF
nonref (discardable) frame indicator
uint8_t * pixels[2]
pointer to the actual pixel data of the buffers above
In the ELBG jargon, a cell is the set of points that are closest to a codebook entry.
int width
picture width / height.
#define BS_MV_X_HALF
horizontal mv halfpel resolution indicator
const uint8_t * alt_quant
secondary VQ table set for the modes 1 and 4
static uint32_t replicate32(uint32_t a)
const int8_t * mv_ptr
ptr to the motion vector if any
#define AVERROR_PATCHWELCOME
Not yet implemented in Libav, patches welcome.
static void fill_64(uint8_t *dst, const uint64_t pix, int32_t n, int32_t row_offset)
Libavcodec external API header.
static int copy_cell(Indeo3DecodeContext *ctx, Plane *plane, Cell *cell)
Copy pixels of the cell(x + mv_x, y + mv_y) from the previous frame into the cell(x, y) in the current frame.
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
main external API structure.
static void close(AVCodecParserContext *s)
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
op_pixels_func put_pixels_tab[4][4]
Halfpel motion compensation with rounding (a+b+1)>>1.
planar YUV 4:1:0, 9bpp, (1 Cr & Cb sample per 4x4 Y samples)
const int8_t * mc_vectors
#define SPLIT_CELL(size, new_size)
apply null delta to all lines up to the 3rd line
apply null delta to N blocks / skip N blocks
int16_t width
cell width in 4x4 blocks
static int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size)
Initialize GetBitContext.
static av_cold int decode_init(AVCodecContext *avctx)
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
static int parse_bintree(Indeo3DecodeContext *ctx, AVCodecContext *avctx, Plane *plane, int code, Cell *ref_cell, const int depth, const int strip_width)
static av_cold void build_requant_tab(void)
discard all non reference
static uint8_t requant_tab[8][128]
common internal api header.
static av_cold int init(AVCodecParserContext *s)
unsigned num_vectors
number of motion vectors in mc_vectors
uint32_t data_size
size of the frame data in bytes
#define BS_MV_Y_HALF
vertical mv halfpel resolution indicator
same as RLE_ESC_FA + do the same with next block
AVCodec ff_indeo3_decoder
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
static int decode_cell_data(Indeo3DecodeContext *ctx, Cell *cell, uint8_t *block, uint8_t *ref_block, int pitch, int h_zoom, int v_zoom, int mode, const vqEntry *delta[2], int swap_quads[2], const uint8_t **data_ptr, const uint8_t *last_ptr)
const uint8_t * u_data_ptr
same as RLE_ESC_FD + do the same with next block
uint8_t tree
tree id: 0- MC tree, 1 - VQ tree
#define FFSWAP(type, a, b)
static av_cold int allocate_frame_buffers(Indeo3DecodeContext *ctx, AVCodecContext *avctx)
This structure stores compressed data.
#define APPLY_DELTA_1011_INTER