annotate ffmpeg/libavcodec/escape124.c @ 13:844d341cf643 tip

Back up before ISMIR
author Yading Song <yading.song@eecs.qmul.ac.uk>
date Thu, 31 Oct 2013 13:17:06 +0000
parents 6840f77b83aa
children
rev   line source
yading@10 1 /*
yading@10 2 * Escape 124 Video Decoder
yading@10 3 * Copyright (C) 2008 Eli Friedman (eli.friedman@gmail.com)
yading@10 4 *
yading@10 5 * This file is part of FFmpeg.
yading@10 6 *
yading@10 7 * FFmpeg is free software; you can redistribute it and/or
yading@10 8 * modify it under the terms of the GNU Lesser General Public
yading@10 9 * License as published by the Free Software Foundation; either
yading@10 10 * version 2.1 of the License, or (at your option) any later version.
yading@10 11 *
yading@10 12 * FFmpeg is distributed in the hope that it will be useful,
yading@10 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
yading@10 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
yading@10 15 * Lesser General Public License for more details.
yading@10 16 *
yading@10 17 * You should have received a copy of the GNU Lesser General Public
yading@10 18 * License along with FFmpeg; if not, write to the Free Software
yading@10 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
yading@10 20 */
yading@10 21
yading@10 22 #include "avcodec.h"
yading@10 23 #include "internal.h"
yading@10 24
yading@10 25 #define BITSTREAM_READER_LE
yading@10 26 #include "get_bits.h"
yading@10 27
yading@10 28 typedef union MacroBlock {
yading@10 29 uint16_t pixels[4];
yading@10 30 uint32_t pixels32[2];
yading@10 31 } MacroBlock;
yading@10 32
yading@10 33 typedef union SuperBlock {
yading@10 34 uint16_t pixels[64];
yading@10 35 uint32_t pixels32[32];
yading@10 36 } SuperBlock;
yading@10 37
yading@10 38 typedef struct CodeBook {
yading@10 39 unsigned depth;
yading@10 40 unsigned size;
yading@10 41 MacroBlock* blocks;
yading@10 42 } CodeBook;
yading@10 43
yading@10 44 typedef struct Escape124Context {
yading@10 45 AVFrame frame;
yading@10 46
yading@10 47 unsigned num_superblocks;
yading@10 48
yading@10 49 CodeBook codebooks[3];
yading@10 50 } Escape124Context;
yading@10 51
yading@10 52 static int can_safely_read(GetBitContext* gb, uint64_t bits) {
yading@10 53 return get_bits_left(gb) >= bits;
yading@10 54 }
yading@10 55
yading@10 56 /**
yading@10 57 * Initialize the decoder
yading@10 58 * @param avctx decoder context
yading@10 59 * @return 0 success, negative on error
yading@10 60 */
yading@10 61 static av_cold int escape124_decode_init(AVCodecContext *avctx)
yading@10 62 {
yading@10 63 Escape124Context *s = avctx->priv_data;
yading@10 64
yading@10 65 avcodec_get_frame_defaults(&s->frame);
yading@10 66 avctx->pix_fmt = AV_PIX_FMT_RGB555;
yading@10 67
yading@10 68 s->num_superblocks = ((unsigned)avctx->width / 8) *
yading@10 69 ((unsigned)avctx->height / 8);
yading@10 70
yading@10 71 return 0;
yading@10 72 }
yading@10 73
yading@10 74 static av_cold int escape124_decode_close(AVCodecContext *avctx)
yading@10 75 {
yading@10 76 unsigned i;
yading@10 77 Escape124Context *s = avctx->priv_data;
yading@10 78
yading@10 79 for (i = 0; i < 3; i++)
yading@10 80 av_free(s->codebooks[i].blocks);
yading@10 81
yading@10 82 av_frame_unref(&s->frame);
yading@10 83
yading@10 84 return 0;
yading@10 85 }
yading@10 86
yading@10 87 static CodeBook unpack_codebook(GetBitContext* gb, unsigned depth,
yading@10 88 unsigned size)
yading@10 89 {
yading@10 90 unsigned i, j;
yading@10 91 CodeBook cb = { 0 };
yading@10 92
yading@10 93 if (!can_safely_read(gb, (uint64_t)size * 34))
yading@10 94 return cb;
yading@10 95
yading@10 96 if (size >= INT_MAX / sizeof(MacroBlock))
yading@10 97 return cb;
yading@10 98 cb.blocks = av_malloc(size ? size * sizeof(MacroBlock) : 1);
yading@10 99 if (!cb.blocks)
yading@10 100 return cb;
yading@10 101
yading@10 102 cb.depth = depth;
yading@10 103 cb.size = size;
yading@10 104 for (i = 0; i < size; i++) {
yading@10 105 unsigned mask_bits = get_bits(gb, 4);
yading@10 106 unsigned color0 = get_bits(gb, 15);
yading@10 107 unsigned color1 = get_bits(gb, 15);
yading@10 108
yading@10 109 for (j = 0; j < 4; j++) {
yading@10 110 if (mask_bits & (1 << j))
yading@10 111 cb.blocks[i].pixels[j] = color1;
yading@10 112 else
yading@10 113 cb.blocks[i].pixels[j] = color0;
yading@10 114 }
yading@10 115 }
yading@10 116 return cb;
yading@10 117 }
yading@10 118
yading@10 119 static unsigned decode_skip_count(GetBitContext* gb)
yading@10 120 {
yading@10 121 unsigned value;
yading@10 122 // This function reads a maximum of 23 bits,
yading@10 123 // which is within the padding space
yading@10 124 if (!can_safely_read(gb, 1))
yading@10 125 return -1;
yading@10 126 value = get_bits1(gb);
yading@10 127 if (!value)
yading@10 128 return value;
yading@10 129
yading@10 130 value += get_bits(gb, 3);
yading@10 131 if (value != (1 + ((1 << 3) - 1)))
yading@10 132 return value;
yading@10 133
yading@10 134 value += get_bits(gb, 7);
yading@10 135 if (value != (1 + ((1 << 3) - 1)) + ((1 << 7) - 1))
yading@10 136 return value;
yading@10 137
yading@10 138 return value + get_bits(gb, 12);
yading@10 139 }
yading@10 140
yading@10 141 static MacroBlock decode_macroblock(Escape124Context* s, GetBitContext* gb,
yading@10 142 int* codebook_index, int superblock_index)
yading@10 143 {
yading@10 144 // This function reads a maximum of 22 bits; the callers
yading@10 145 // guard this function appropriately
yading@10 146 unsigned block_index, depth;
yading@10 147
yading@10 148 if (get_bits1(gb)) {
yading@10 149 static const char transitions[3][2] = { {2, 1}, {0, 2}, {1, 0} };
yading@10 150 *codebook_index = transitions[*codebook_index][get_bits1(gb)];
yading@10 151 }
yading@10 152
yading@10 153 depth = s->codebooks[*codebook_index].depth;
yading@10 154
yading@10 155 // depth = 0 means that this shouldn't read any bits;
yading@10 156 // in theory, this is the same as get_bits(gb, 0), but
yading@10 157 // that doesn't actually work.
yading@10 158 block_index = depth ? get_bits(gb, depth) : 0;
yading@10 159
yading@10 160 if (*codebook_index == 1) {
yading@10 161 block_index += superblock_index << s->codebooks[1].depth;
yading@10 162 }
yading@10 163
yading@10 164 // This condition can occur with invalid bitstreams and
yading@10 165 // *codebook_index == 2
yading@10 166 if (block_index >= s->codebooks[*codebook_index].size)
yading@10 167 return (MacroBlock) { { 0 } };
yading@10 168
yading@10 169 return s->codebooks[*codebook_index].blocks[block_index];
yading@10 170 }
yading@10 171
yading@10 172 static void insert_mb_into_sb(SuperBlock* sb, MacroBlock mb, unsigned index) {
yading@10 173 // Formula: ((index / 4) * 16 + (index % 4) * 2) / 2
yading@10 174 uint32_t *dst = sb->pixels32 + index + (index & -4);
yading@10 175
yading@10 176 // This technically violates C99 aliasing rules, but it should be safe.
yading@10 177 dst[0] = mb.pixels32[0];
yading@10 178 dst[4] = mb.pixels32[1];
yading@10 179 }
yading@10 180
yading@10 181 static void copy_superblock(uint16_t* dest, unsigned dest_stride,
yading@10 182 uint16_t* src, unsigned src_stride)
yading@10 183 {
yading@10 184 unsigned y;
yading@10 185 if (src)
yading@10 186 for (y = 0; y < 8; y++)
yading@10 187 memcpy(dest + y * dest_stride, src + y * src_stride,
yading@10 188 sizeof(uint16_t) * 8);
yading@10 189 else
yading@10 190 for (y = 0; y < 8; y++)
yading@10 191 memset(dest + y * dest_stride, 0, sizeof(uint16_t) * 8);
yading@10 192 }
yading@10 193
yading@10 194 static const uint16_t mask_matrix[] = {0x1, 0x2, 0x10, 0x20,
yading@10 195 0x4, 0x8, 0x40, 0x80,
yading@10 196 0x100, 0x200, 0x1000, 0x2000,
yading@10 197 0x400, 0x800, 0x4000, 0x8000};
yading@10 198
yading@10 199 static int escape124_decode_frame(AVCodecContext *avctx,
yading@10 200 void *data, int *got_frame,
yading@10 201 AVPacket *avpkt)
yading@10 202 {
yading@10 203 const uint8_t *buf = avpkt->data;
yading@10 204 int buf_size = avpkt->size;
yading@10 205 Escape124Context *s = avctx->priv_data;
yading@10 206 AVFrame *frame = data;
yading@10 207
yading@10 208 GetBitContext gb;
yading@10 209 unsigned frame_flags, frame_size;
yading@10 210 unsigned i;
yading@10 211
yading@10 212 unsigned superblock_index, cb_index = 1,
yading@10 213 superblock_col_index = 0,
yading@10 214 superblocks_per_row = avctx->width / 8, skip = -1;
yading@10 215
yading@10 216 uint16_t* old_frame_data, *new_frame_data;
yading@10 217 unsigned old_stride, new_stride;
yading@10 218
yading@10 219 int ret;
yading@10 220
yading@10 221 init_get_bits(&gb, buf, buf_size * 8);
yading@10 222
yading@10 223 // This call also guards the potential depth reads for the
yading@10 224 // codebook unpacking.
yading@10 225 if (!can_safely_read(&gb, 64))
yading@10 226 return -1;
yading@10 227
yading@10 228 frame_flags = get_bits_long(&gb, 32);
yading@10 229 frame_size = get_bits_long(&gb, 32);
yading@10 230
yading@10 231 // Leave last frame unchanged
yading@10 232 // FIXME: Is this necessary? I haven't seen it in any real samples
yading@10 233 if (!(frame_flags & 0x114) || !(frame_flags & 0x7800000)) {
yading@10 234 if (!s->frame.data[0])
yading@10 235 return AVERROR_INVALIDDATA;
yading@10 236
yading@10 237 av_log(NULL, AV_LOG_DEBUG, "Skipping frame\n");
yading@10 238
yading@10 239 *got_frame = 1;
yading@10 240 if ((ret = av_frame_ref(frame, &s->frame)) < 0)
yading@10 241 return ret;
yading@10 242
yading@10 243 return frame_size;
yading@10 244 }
yading@10 245
yading@10 246 for (i = 0; i < 3; i++) {
yading@10 247 if (frame_flags & (1 << (17 + i))) {
yading@10 248 unsigned cb_depth, cb_size;
yading@10 249 if (i == 2) {
yading@10 250 // This codebook can be cut off at places other than
yading@10 251 // powers of 2, leaving some of the entries undefined.
yading@10 252 cb_size = get_bits_long(&gb, 20);
yading@10 253 cb_depth = av_log2(cb_size - 1) + 1;
yading@10 254 } else {
yading@10 255 cb_depth = get_bits(&gb, 4);
yading@10 256 if (i == 0) {
yading@10 257 // This is the most basic codebook: pow(2,depth) entries
yading@10 258 // for a depth-length key
yading@10 259 cb_size = 1 << cb_depth;
yading@10 260 } else {
yading@10 261 // This codebook varies per superblock
yading@10 262 // FIXME: I don't think this handles integer overflow
yading@10 263 // properly
yading@10 264 cb_size = s->num_superblocks << cb_depth;
yading@10 265 }
yading@10 266 }
yading@10 267 av_free(s->codebooks[i].blocks);
yading@10 268 s->codebooks[i] = unpack_codebook(&gb, cb_depth, cb_size);
yading@10 269 if (!s->codebooks[i].blocks)
yading@10 270 return -1;
yading@10 271 }
yading@10 272 }
yading@10 273
yading@10 274 if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
yading@10 275 return ret;
yading@10 276
yading@10 277 new_frame_data = (uint16_t*)frame->data[0];
yading@10 278 new_stride = frame->linesize[0] / 2;
yading@10 279 old_frame_data = (uint16_t*)s->frame.data[0];
yading@10 280 old_stride = s->frame.linesize[0] / 2;
yading@10 281
yading@10 282 for (superblock_index = 0; superblock_index < s->num_superblocks;
yading@10 283 superblock_index++) {
yading@10 284 MacroBlock mb;
yading@10 285 SuperBlock sb;
yading@10 286 unsigned multi_mask = 0;
yading@10 287
yading@10 288 if (skip == -1) {
yading@10 289 // Note that this call will make us skip the rest of the blocks
yading@10 290 // if the frame prematurely ends
yading@10 291 skip = decode_skip_count(&gb);
yading@10 292 }
yading@10 293
yading@10 294 if (skip) {
yading@10 295 copy_superblock(new_frame_data, new_stride,
yading@10 296 old_frame_data, old_stride);
yading@10 297 } else {
yading@10 298 copy_superblock(sb.pixels, 8,
yading@10 299 old_frame_data, old_stride);
yading@10 300
yading@10 301 while (can_safely_read(&gb, 1) && !get_bits1(&gb)) {
yading@10 302 unsigned mask;
yading@10 303 mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
yading@10 304 mask = get_bits(&gb, 16);
yading@10 305 multi_mask |= mask;
yading@10 306 for (i = 0; i < 16; i++) {
yading@10 307 if (mask & mask_matrix[i]) {
yading@10 308 insert_mb_into_sb(&sb, mb, i);
yading@10 309 }
yading@10 310 }
yading@10 311 }
yading@10 312
yading@10 313 if (can_safely_read(&gb, 1) && !get_bits1(&gb)) {
yading@10 314 unsigned inv_mask = get_bits(&gb, 4);
yading@10 315 for (i = 0; i < 4; i++) {
yading@10 316 if (inv_mask & (1 << i)) {
yading@10 317 multi_mask ^= 0xF << i*4;
yading@10 318 } else {
yading@10 319 multi_mask ^= get_bits(&gb, 4) << i*4;
yading@10 320 }
yading@10 321 }
yading@10 322
yading@10 323 for (i = 0; i < 16; i++) {
yading@10 324 if (multi_mask & mask_matrix[i]) {
yading@10 325 if (!can_safely_read(&gb, 1))
yading@10 326 break;
yading@10 327 mb = decode_macroblock(s, &gb, &cb_index,
yading@10 328 superblock_index);
yading@10 329 insert_mb_into_sb(&sb, mb, i);
yading@10 330 }
yading@10 331 }
yading@10 332 } else if (frame_flags & (1 << 16)) {
yading@10 333 while (can_safely_read(&gb, 1) && !get_bits1(&gb)) {
yading@10 334 mb = decode_macroblock(s, &gb, &cb_index, superblock_index);
yading@10 335 insert_mb_into_sb(&sb, mb, get_bits(&gb, 4));
yading@10 336 }
yading@10 337 }
yading@10 338
yading@10 339 copy_superblock(new_frame_data, new_stride, sb.pixels, 8);
yading@10 340 }
yading@10 341
yading@10 342 superblock_col_index++;
yading@10 343 new_frame_data += 8;
yading@10 344 if (old_frame_data)
yading@10 345 old_frame_data += 8;
yading@10 346 if (superblock_col_index == superblocks_per_row) {
yading@10 347 new_frame_data += new_stride * 8 - superblocks_per_row * 8;
yading@10 348 if (old_frame_data)
yading@10 349 old_frame_data += old_stride * 8 - superblocks_per_row * 8;
yading@10 350 superblock_col_index = 0;
yading@10 351 }
yading@10 352 skip--;
yading@10 353 }
yading@10 354
yading@10 355 av_log(NULL, AV_LOG_DEBUG,
yading@10 356 "Escape sizes: %i, %i, %i\n",
yading@10 357 frame_size, buf_size, get_bits_count(&gb) / 8);
yading@10 358
yading@10 359 av_frame_unref(&s->frame);
yading@10 360 if ((ret = av_frame_ref(&s->frame, frame)) < 0)
yading@10 361 return ret;
yading@10 362
yading@10 363 *got_frame = 1;
yading@10 364
yading@10 365 return frame_size;
yading@10 366 }
yading@10 367
yading@10 368
yading@10 369 AVCodec ff_escape124_decoder = {
yading@10 370 .name = "escape124",
yading@10 371 .type = AVMEDIA_TYPE_VIDEO,
yading@10 372 .id = AV_CODEC_ID_ESCAPE124,
yading@10 373 .priv_data_size = sizeof(Escape124Context),
yading@10 374 .init = escape124_decode_init,
yading@10 375 .close = escape124_decode_close,
yading@10 376 .decode = escape124_decode_frame,
yading@10 377 .capabilities = CODEC_CAP_DR1,
yading@10 378 .long_name = NULL_IF_CONFIG_SMALL("Escape 124"),
yading@10 379 };