1/* 2 * Escape 130 video decoder 3 * Copyright (C) 2008 Eli Friedman (eli.friedman <at> gmail.com) 4 * 5 * This file is part of FFmpeg. 6 * 7 * FFmpeg is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * FFmpeg is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with FFmpeg; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 */ 21 22#include "libavutil/attributes.h" 23#include "libavutil/mem.h" 24 25#define BITSTREAM_READER_LE 26#include "avcodec.h" 27#include "codec_internal.h" 28#include "get_bits.h" 29#include "internal.h" 30 31typedef struct Escape130Context { 32 uint8_t *old_y_avg; 33 34 uint8_t *new_y, *old_y; 35 uint8_t *new_u, *old_u; 36 uint8_t *new_v, *old_v; 37 38 uint8_t *buf1, *buf2; 39 int linesize[3]; 40} Escape130Context; 41 42static const uint8_t offset_table[] = { 2, 4, 10, 20 }; 43static const int8_t sign_table[64][4] = { 44 { 0, 0, 0, 0 }, 45 { -1, 1, 0, 0 }, 46 { 1, -1, 0, 0 }, 47 { -1, 0, 1, 0 }, 48 { -1, 1, 1, 0 }, 49 { 0, -1, 1, 0 }, 50 { 1, -1, 1, 0 }, 51 { -1, -1, 1, 0 }, 52 { 1, 0, -1, 0 }, 53 { 0, 1, -1, 0 }, 54 { 1, 1, -1, 0 }, 55 { -1, 1, -1, 0 }, 56 { 1, -1, -1, 0 }, 57 { -1, 0, 0, 1 }, 58 { -1, 1, 0, 1 }, 59 { 0, -1, 0, 1 }, 60 61 { 0, 0, 0, 0 }, 62 { 1, -1, 0, 1 }, 63 { -1, -1, 0, 1 }, 64 { -1, 0, 1, 1 }, 65 { -1, 1, 1, 1 }, 66 { 0, -1, 1, 1 }, 67 { 1, -1, 1, 1 }, 68 { -1, -1, 1, 1 }, 69 { 0, 0, -1, 1 }, 70 { 1, 0, -1, 1 }, 71 { -1, 0, -1, 1 }, 72 { 0, 1, -1, 1 }, 73 { 1, 1, -1, 1 }, 74 { -1, 1, -1, 1 }, 75 { 0, -1, -1, 1 }, 76 { 1, -1, -1, 1 }, 77 78 { 0, 0, 0, 0 }, 79 { -1, -1, -1, 1 }, 80 { 1, 0, 0, -1 }, 81 { 0, 1, 0, -1 }, 82 { 1, 1, 0, -1 }, 83 { -1, 1, 0, -1 }, 84 { 1, -1, 0, -1 }, 85 { 0, 0, 1, -1 }, 86 { 1, 0, 1, -1 }, 87 { -1, 0, 1, -1 }, 88 { 0, 1, 1, -1 }, 89 { 1, 1, 1, -1 }, 90 { -1, 1, 1, -1 }, 91 { 0, -1, 1, -1 }, 92 { 1, -1, 1, -1 }, 93 { -1, -1, 1, -1 }, 94 95 { 0, 0, 0, 0 }, 96 { 1, 0, -1, -1 }, 97 { 0, 1, -1, -1 }, 98 { 1, 1, -1, -1 }, 99 { -1, 1, -1, -1 }, 100 { 1, -1, -1, -1 } 101}; 102 103static const int8_t luma_adjust[] = { -4, -3, -2, -1, 1, 2, 3, 4 }; 104 105static const int8_t chroma_adjust[2][8] = { 106 { 1, 1, 0, -1, -1, -1, 0, 1 }, 107 { 0, 1, 1, 1, 0, -1, -1, -1 } 108}; 109 110static const uint8_t chroma_vals[] = { 111 20, 28, 36, 44, 52, 60, 68, 76, 112 84, 92, 100, 106, 112, 116, 120, 124, 113 128, 132, 136, 140, 144, 150, 156, 164, 114 172, 180, 188, 196, 204, 212, 220, 228 115}; 116 117static av_cold int escape130_decode_init(AVCodecContext *avctx) 118{ 119 Escape130Context *s = avctx->priv_data; 120 avctx->pix_fmt = AV_PIX_FMT_YUV420P; 121 122 if ((avctx->width & 1) || (avctx->height & 1)) { 123 av_log(avctx, AV_LOG_ERROR, 124 "Dimensions should be a multiple of two.\n"); 125 return AVERROR_INVALIDDATA; 126 } 127 128 s->old_y_avg = av_malloc(avctx->width * avctx->height / 4); 129 s->buf1 = av_malloc(avctx->width * avctx->height * 3 / 2); 130 s->buf2 = av_malloc(avctx->width * avctx->height * 3 / 2); 131 if (!s->old_y_avg || !s->buf1 || !s->buf2) { 132 av_log(avctx, AV_LOG_ERROR, "Could not allocate buffer.\n"); 133 return AVERROR(ENOMEM); 134 } 135 136 s->linesize[0] = avctx->width; 137 s->linesize[1] = 138 s->linesize[2] = avctx->width / 2; 139 140 s->new_y = s->buf1; 141 s->new_u = s->new_y + avctx->width * avctx->height; 142 s->new_v = s->new_u + avctx->width * avctx->height / 4; 143 s->old_y = s->buf2; 144 s->old_u = s->old_y + avctx->width * avctx->height; 145 s->old_v = s->old_u + avctx->width * avctx->height / 4; 146 memset(s->old_y, 0, avctx->width * avctx->height); 147 memset(s->old_u, 0x10, avctx->width * avctx->height / 4); 148 memset(s->old_v, 0x10, avctx->width * avctx->height / 4); 149 150 return 0; 151} 152 153static av_cold int escape130_decode_close(AVCodecContext *avctx) 154{ 155 Escape130Context *s = avctx->priv_data; 156 157 av_freep(&s->old_y_avg); 158 av_freep(&s->buf1); 159 av_freep(&s->buf2); 160 161 return 0; 162} 163 164static int decode_skip_count(GetBitContext* gb) 165{ 166 int value; 167 168 if (get_bits_left(gb) < 1+3) 169 return -1; 170 171 value = get_bits1(gb); 172 if (value) 173 return 0; 174 175 value = get_bits(gb, 3); 176 if (value) 177 return value; 178 179 value = get_bits(gb, 8); 180 if (value) 181 return value + 7; 182 183 value = get_bits(gb, 15); 184 if (value) 185 return value + 262; 186 187 return -1; 188} 189 190static int escape130_decode_frame(AVCodecContext *avctx, AVFrame *pic, 191 int *got_frame, AVPacket *avpkt) 192{ 193 int buf_size = avpkt->size; 194 Escape130Context *s = avctx->priv_data; 195 GetBitContext gb; 196 int ret; 197 198 uint8_t *old_y, *old_cb, *old_cr, 199 *new_y, *new_cb, *new_cr; 200 uint8_t *dstY, *dstU, *dstV; 201 unsigned old_y_stride, old_cb_stride, old_cr_stride, 202 new_y_stride, new_cb_stride, new_cr_stride; 203 unsigned total_blocks = avctx->width * avctx->height / 4, 204 block_index, block_x = 0; 205 unsigned y[4] = { 0 }, cb = 0x10, cr = 0x10; 206 int skip = -1, y_avg = 0, i, j; 207 uint8_t *ya = s->old_y_avg; 208 209 // first 16 bytes are header; no useful information in here 210 if (buf_size <= 16) { 211 av_log(avctx, AV_LOG_ERROR, "Insufficient frame data\n"); 212 return AVERROR_INVALIDDATA; 213 } 214 215 if ((ret = ff_get_buffer(avctx, pic, 0)) < 0) 216 return ret; 217 218 if ((ret = init_get_bits8(&gb, avpkt->data, avpkt->size)) < 0) 219 return ret; 220 skip_bits_long(&gb, 16 * 8); 221 222 new_y = s->new_y; 223 new_cb = s->new_u; 224 new_cr = s->new_v; 225 new_y_stride = s->linesize[0]; 226 new_cb_stride = s->linesize[1]; 227 new_cr_stride = s->linesize[2]; 228 old_y = s->old_y; 229 old_cb = s->old_u; 230 old_cr = s->old_v; 231 old_y_stride = s->linesize[0]; 232 old_cb_stride = s->linesize[1]; 233 old_cr_stride = s->linesize[2]; 234 235 for (block_index = 0; block_index < total_blocks; block_index++) { 236 // Note that this call will make us skip the rest of the blocks 237 // if the frame ends prematurely. 238 if (skip == -1) 239 skip = decode_skip_count(&gb); 240 if (skip == -1) { 241 av_log(avctx, AV_LOG_ERROR, "Error decoding skip value\n"); 242 return AVERROR_INVALIDDATA; 243 } 244 245 if (skip) { 246 y[0] = old_y[0]; 247 y[1] = old_y[1]; 248 y[2] = old_y[old_y_stride]; 249 y[3] = old_y[old_y_stride + 1]; 250 y_avg = ya[0]; 251 cb = old_cb[0]; 252 cr = old_cr[0]; 253 } else { 254 if (get_bits1(&gb)) { 255 unsigned sign_selector = get_bits(&gb, 6); 256 unsigned difference_selector = get_bits(&gb, 2); 257 y_avg = 2 * get_bits(&gb, 5); 258 for (i = 0; i < 4; i++) { 259 y[i] = av_clip(y_avg + offset_table[difference_selector] * 260 sign_table[sign_selector][i], 0, 63); 261 } 262 } else if (get_bits1(&gb)) { 263 if (get_bits1(&gb)) { 264 y_avg = get_bits(&gb, 6); 265 } else { 266 unsigned adjust_index = get_bits(&gb, 3); 267 y_avg = (y_avg + luma_adjust[adjust_index]) & 63; 268 } 269 for (i = 0; i < 4; i++) 270 y[i] = y_avg; 271 } 272 273 if (get_bits1(&gb)) { 274 if (get_bits1(&gb)) { 275 cb = get_bits(&gb, 5); 276 cr = get_bits(&gb, 5); 277 } else { 278 unsigned adjust_index = get_bits(&gb, 3); 279 cb = (cb + chroma_adjust[0][adjust_index]) & 31; 280 cr = (cr + chroma_adjust[1][adjust_index]) & 31; 281 } 282 } 283 } 284 *ya++ = y_avg; 285 286 new_y[0] = y[0]; 287 new_y[1] = y[1]; 288 new_y[new_y_stride] = y[2]; 289 new_y[new_y_stride + 1] = y[3]; 290 *new_cb = cb; 291 *new_cr = cr; 292 293 old_y += 2; 294 old_cb++; 295 old_cr++; 296 new_y += 2; 297 new_cb++; 298 new_cr++; 299 block_x++; 300 if (block_x * 2 == avctx->width) { 301 block_x = 0; 302 old_y += old_y_stride * 2 - avctx->width; 303 old_cb += old_cb_stride - avctx->width / 2; 304 old_cr += old_cr_stride - avctx->width / 2; 305 new_y += new_y_stride * 2 - avctx->width; 306 new_cb += new_cb_stride - avctx->width / 2; 307 new_cr += new_cr_stride - avctx->width / 2; 308 } 309 310 skip--; 311 } 312 313 new_y = s->new_y; 314 new_cb = s->new_u; 315 new_cr = s->new_v; 316 dstY = pic->data[0]; 317 dstU = pic->data[1]; 318 dstV = pic->data[2]; 319 for (j = 0; j < avctx->height; j++) { 320 for (i = 0; i < avctx->width; i++) 321 dstY[i] = new_y[i] << 2; 322 dstY += pic->linesize[0]; 323 new_y += new_y_stride; 324 } 325 for (j = 0; j < avctx->height / 2; j++) { 326 for (i = 0; i < avctx->width / 2; i++) { 327 dstU[i] = chroma_vals[new_cb[i]]; 328 dstV[i] = chroma_vals[new_cr[i]]; 329 } 330 dstU += pic->linesize[1]; 331 dstV += pic->linesize[2]; 332 new_cb += new_cb_stride; 333 new_cr += new_cr_stride; 334 } 335 336 ff_dlog(avctx, "Frame data: provided %d bytes, used %d bytes\n", 337 buf_size, get_bits_count(&gb) >> 3); 338 339 FFSWAP(uint8_t*, s->old_y, s->new_y); 340 FFSWAP(uint8_t*, s->old_u, s->new_u); 341 FFSWAP(uint8_t*, s->old_v, s->new_v); 342 343 *got_frame = 1; 344 345 return buf_size; 346} 347 348const FFCodec ff_escape130_decoder = { 349 .p.name = "escape130", 350 .p.long_name = NULL_IF_CONFIG_SMALL("Escape 130"), 351 .p.type = AVMEDIA_TYPE_VIDEO, 352 .p.id = AV_CODEC_ID_ESCAPE130, 353 .priv_data_size = sizeof(Escape130Context), 354 .init = escape130_decode_init, 355 .close = escape130_decode_close, 356 FF_CODEC_DECODE_CB(escape130_decode_frame), 357 .p.capabilities = AV_CODEC_CAP_DR1, 358 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 359}; 360