1/* 2 * TDSC decoder 3 * Copyright (C) 2015 Vittorio Giovara <vittorio.giovara@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/** 23 * @file 24 * TDSC decoder 25 * 26 * Fourcc: TSDC 27 * 28 * TDSC is very simple. It codes picture by tiles, storing them in raw BGR24 29 * format or compressing them in JPEG. Frames can be full pictures or just 30 * updates to the previous frame. Cursor is found in its own frame or at the 31 * bottom of the picture. Every frame is then packed with zlib. 32 * 33 * Supports: BGR24 34 */ 35 36#include <stdint.h> 37#include <zlib.h> 38 39#include "libavutil/imgutils.h" 40 41#include "avcodec.h" 42#include "bytestream.h" 43#include "codec_internal.h" 44#include "internal.h" 45 46#define BITMAPINFOHEADER_SIZE 0x28 47#define TDSF_HEADER_SIZE 0x56 48#define TDSB_HEADER_SIZE 0x08 49 50typedef struct TDSCContext { 51 AVCodecContext *jpeg_avctx; // wrapper context for MJPEG 52 53 int width, height; 54 GetByteContext gbc; 55 56 AVFrame *refframe; // full decoded frame (without cursor) 57 AVPacket *jpkt; // encoded JPEG tile 58 AVFrame *jpgframe; // decoded JPEG tile 59 uint8_t *tilebuffer; // buffer containing tile data 60 61 /* zlib interaction */ 62 uint8_t *deflatebuffer; 63 uLongf deflatelen; 64 65 /* All that is cursor */ 66 uint8_t *cursor; 67 int cursor_stride; 68 int cursor_w, cursor_h, cursor_x, cursor_y; 69 int cursor_hot_x, cursor_hot_y; 70} TDSCContext; 71 72/* 1 byte bits, 1 byte planes, 2 bytes format (probably) */ 73enum TDSCCursorFormat { 74 CUR_FMT_MONO = 0x01010004, 75 CUR_FMT_BGRA = 0x20010004, 76 CUR_FMT_RGBA = 0x20010008, 77}; 78 79static av_cold int tdsc_close(AVCodecContext *avctx) 80{ 81 TDSCContext *ctx = avctx->priv_data; 82 83 av_frame_free(&ctx->refframe); 84 av_frame_free(&ctx->jpgframe); 85 av_packet_free(&ctx->jpkt); 86 av_freep(&ctx->deflatebuffer); 87 av_freep(&ctx->tilebuffer); 88 av_freep(&ctx->cursor); 89 avcodec_free_context(&ctx->jpeg_avctx); 90 91 return 0; 92} 93 94static av_cold int tdsc_init(AVCodecContext *avctx) 95{ 96 TDSCContext *ctx = avctx->priv_data; 97 const AVCodec *codec; 98 int ret; 99 100 avctx->pix_fmt = AV_PIX_FMT_BGR24; 101 102 /* These needs to be set to estimate buffer and frame size */ 103 if (!(avctx->width && avctx->height)) { 104 av_log(avctx, AV_LOG_ERROR, "Video size not set.\n"); 105 return AVERROR_INVALIDDATA; 106 } 107 108 /* This value should be large enough for a RAW-only frame plus headers */ 109 ctx->deflatelen = avctx->width * avctx->height * (3 + 1); 110 ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen); 111 if (ret < 0) 112 return ret; 113 114 /* Allocate reference and JPEG frame */ 115 ctx->refframe = av_frame_alloc(); 116 ctx->jpgframe = av_frame_alloc(); 117 ctx->jpkt = av_packet_alloc(); 118 if (!ctx->refframe || !ctx->jpgframe || !ctx->jpkt) 119 return AVERROR(ENOMEM); 120 121 /* Prepare everything needed for JPEG decoding */ 122 codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG); 123 if (!codec) 124 return AVERROR_BUG; 125 ctx->jpeg_avctx = avcodec_alloc_context3(codec); 126 if (!ctx->jpeg_avctx) 127 return AVERROR(ENOMEM); 128 ctx->jpeg_avctx->flags = avctx->flags; 129 ctx->jpeg_avctx->flags2 = avctx->flags2; 130 ctx->jpeg_avctx->dct_algo = avctx->dct_algo; 131 ctx->jpeg_avctx->idct_algo = avctx->idct_algo; 132 ret = avcodec_open2(ctx->jpeg_avctx, codec, NULL); 133 if (ret < 0) 134 return ret; 135 136 /* Set the output pixel format on the reference frame */ 137 ctx->refframe->format = avctx->pix_fmt; 138 139 return 0; 140} 141 142#define APPLY_ALPHA(src, new, alpha) \ 143 src = (src * (256 - alpha) + new * alpha) >> 8 144 145/* Paint a region over a buffer, without drawing out of its bounds. */ 146static void tdsc_paint_cursor(AVCodecContext *avctx, uint8_t *dst, int stride) 147{ 148 TDSCContext *ctx = avctx->priv_data; 149 const uint8_t *cursor = ctx->cursor; 150 int x = ctx->cursor_x - ctx->cursor_hot_x; 151 int y = ctx->cursor_y - ctx->cursor_hot_y; 152 int w = ctx->cursor_w; 153 int h = ctx->cursor_h; 154 int i, j; 155 156 if (!ctx->cursor) 157 return; 158 159 if (x + w > ctx->width) 160 w = ctx->width - x; 161 if (y + h > ctx->height) 162 h = ctx->height - y; 163 if (x < 0) { 164 w += x; 165 cursor += -x * 4; 166 } else { 167 dst += x * 3; 168 } 169 if (y < 0) { 170 h += y; 171 cursor += -y * ctx->cursor_stride; 172 } else { 173 dst += y * stride; 174 } 175 if (w < 0 || h < 0) 176 return; 177 178 for (j = 0; j < h; j++) { 179 for (i = 0; i < w; i++) { 180 uint8_t alpha = cursor[i * 4]; 181 APPLY_ALPHA(dst[i * 3 + 0], cursor[i * 4 + 1], alpha); 182 APPLY_ALPHA(dst[i * 3 + 1], cursor[i * 4 + 2], alpha); 183 APPLY_ALPHA(dst[i * 3 + 2], cursor[i * 4 + 3], alpha); 184 } 185 dst += stride; 186 cursor += ctx->cursor_stride; 187 } 188} 189 190/* Load cursor data and store it in ABGR mode. */ 191static int tdsc_load_cursor(AVCodecContext *avctx) 192{ 193 TDSCContext *ctx = avctx->priv_data; 194 int i, j, k, ret, cursor_fmt; 195 uint8_t *dst; 196 197 ctx->cursor_hot_x = bytestream2_get_le16(&ctx->gbc); 198 ctx->cursor_hot_y = bytestream2_get_le16(&ctx->gbc); 199 ctx->cursor_w = bytestream2_get_le16(&ctx->gbc); 200 ctx->cursor_h = bytestream2_get_le16(&ctx->gbc); 201 202 ctx->cursor_stride = FFALIGN(ctx->cursor_w, 32) * 4; 203 cursor_fmt = bytestream2_get_le32(&ctx->gbc); 204 205 if (ctx->cursor_x >= avctx->width || ctx->cursor_y >= avctx->height) { 206 av_log(avctx, AV_LOG_ERROR, 207 "Invalid cursor position (%d.%d outside %dx%d).\n", 208 ctx->cursor_x, ctx->cursor_y, avctx->width, avctx->height); 209 return AVERROR_INVALIDDATA; 210 } 211 if (ctx->cursor_w < 1 || ctx->cursor_w > 256 || 212 ctx->cursor_h < 1 || ctx->cursor_h > 256) { 213 av_log(avctx, AV_LOG_ERROR, 214 "Invalid cursor dimensions %dx%d.\n", 215 ctx->cursor_w, ctx->cursor_h); 216 return AVERROR_INVALIDDATA; 217 } 218 if (ctx->cursor_hot_x > ctx->cursor_w || 219 ctx->cursor_hot_y > ctx->cursor_h) { 220 av_log(avctx, AV_LOG_WARNING, "Invalid hotspot position %d.%d.\n", 221 ctx->cursor_hot_x, ctx->cursor_hot_y); 222 ctx->cursor_hot_x = FFMIN(ctx->cursor_hot_x, ctx->cursor_w - 1); 223 ctx->cursor_hot_y = FFMIN(ctx->cursor_hot_y, ctx->cursor_h - 1); 224 } 225 226 ret = av_reallocp(&ctx->cursor, ctx->cursor_stride * ctx->cursor_h); 227 if (ret < 0) { 228 av_log(avctx, AV_LOG_ERROR, "Cannot allocate cursor buffer.\n"); 229 return ret; 230 } 231 232 dst = ctx->cursor; 233 /* here data is packed in BE */ 234 switch (cursor_fmt) { 235 case CUR_FMT_MONO: 236 for (j = 0; j < ctx->cursor_h; j++) { 237 for (i = 0; i < ctx->cursor_w; i += 32) { 238 uint32_t bits = bytestream2_get_be32(&ctx->gbc); 239 for (k = 0; k < 32; k++) { 240 dst[0] = !!(bits & 0x80000000); 241 dst += 4; 242 bits <<= 1; 243 } 244 } 245 dst += ctx->cursor_stride - ctx->cursor_w * 4; 246 } 247 248 dst = ctx->cursor; 249 for (j = 0; j < ctx->cursor_h; j++) { 250 for (i = 0; i < ctx->cursor_w; i += 32) { 251 uint32_t bits = bytestream2_get_be32(&ctx->gbc); 252 for (k = 0; k < 32; k++) { 253 int mask_bit = !!(bits & 0x80000000); 254 switch (dst[0] * 2 + mask_bit) { 255 case 0: 256 dst[0] = 0xFF; 257 dst[1] = 0x00; 258 dst[2] = 0x00; 259 dst[3] = 0x00; 260 break; 261 case 1: 262 dst[0] = 0xFF; 263 dst[1] = 0xFF; 264 dst[2] = 0xFF; 265 dst[3] = 0xFF; 266 break; 267 default: 268 dst[0] = 0x00; 269 dst[1] = 0x00; 270 dst[2] = 0x00; 271 dst[3] = 0x00; 272 } 273 dst += 4; 274 bits <<= 1; 275 } 276 } 277 dst += ctx->cursor_stride - ctx->cursor_w * 4; 278 } 279 break; 280 case CUR_FMT_BGRA: 281 case CUR_FMT_RGBA: 282 /* Skip monochrome version of the cursor */ 283 bytestream2_skip(&ctx->gbc, 284 ctx->cursor_h * (FFALIGN(ctx->cursor_w, 32) >> 3)); 285 if (cursor_fmt & 8) { // RGBA -> ABGR 286 for (j = 0; j < ctx->cursor_h; j++) { 287 for (i = 0; i < ctx->cursor_w; i++) { 288 int val = bytestream2_get_be32(&ctx->gbc); 289 *dst++ = val >> 24; 290 *dst++ = val >> 16; 291 *dst++ = val >> 8; 292 *dst++ = val >> 0; 293 } 294 dst += ctx->cursor_stride - ctx->cursor_w * 4; 295 } 296 } else { // BGRA -> ABGR 297 for (j = 0; j < ctx->cursor_h; j++) { 298 for (i = 0; i < ctx->cursor_w; i++) { 299 int val = bytestream2_get_be32(&ctx->gbc); 300 *dst++ = val >> 0; 301 *dst++ = val >> 24; 302 *dst++ = val >> 16; 303 *dst++ = val >> 8; 304 } 305 dst += ctx->cursor_stride - ctx->cursor_w * 4; 306 } 307 } 308 break; 309 default: 310 avpriv_request_sample(avctx, "Cursor format %08x", cursor_fmt); 311 return AVERROR_PATCHWELCOME; 312 } 313 314 return 0; 315} 316 317/* Convert a single YUV pixel to RGB. */ 318static inline void tdsc_yuv2rgb(uint8_t *out, int Y, int U, int V) 319{ 320 out[0] = av_clip_uint8(Y + ( 91881 * V + 32768 >> 16)); 321 out[1] = av_clip_uint8(Y + (-22554 * U - 46802 * V + 32768 >> 16)); 322 out[2] = av_clip_uint8(Y + (116130 * U + 32768 >> 16)); 323} 324 325/* Convert a YUV420 buffer to a RGB buffer. */ 326static av_always_inline void tdsc_blit(uint8_t *dst, int dst_stride, 327 const uint8_t *srcy, int srcy_stride, 328 const uint8_t *srcu, const uint8_t *srcv, 329 int srcuv_stride, int width, int height) 330{ 331 int col, line; 332 for (line = 0; line < height; line++) { 333 for (col = 0; col < width; col++) 334 tdsc_yuv2rgb(dst + col * 3, srcy[col], 335 srcu[col >> 1] - 128, srcv[col >> 1] - 128); 336 337 dst += dst_stride; 338 srcy += srcy_stride; 339 srcu += srcuv_stride * (line & 1); 340 srcv += srcuv_stride * (line & 1); 341 } 342} 343 344/* Invoke the MJPEG decoder to decode the tile. */ 345static int tdsc_decode_jpeg_tile(AVCodecContext *avctx, int tile_size, 346 int x, int y, int w, int h) 347{ 348 TDSCContext *ctx = avctx->priv_data; 349 int ret; 350 351 /* Prepare a packet and send to the MJPEG decoder */ 352 av_packet_unref(ctx->jpkt); 353 ctx->jpkt->data = ctx->tilebuffer; 354 ctx->jpkt->size = tile_size; 355 356 ret = avcodec_send_packet(ctx->jpeg_avctx, ctx->jpkt); 357 if (ret < 0) { 358 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n"); 359 return ret; 360 } 361 362 ret = avcodec_receive_frame(ctx->jpeg_avctx, ctx->jpgframe); 363 if (ret < 0 || ctx->jpgframe->format != AV_PIX_FMT_YUVJ420P) { 364 av_log(avctx, AV_LOG_ERROR, 365 "JPEG decoding error (%d).\n", ret); 366 367 /* Normally skip, error if explode */ 368 if (avctx->err_recognition & AV_EF_EXPLODE) 369 return AVERROR_INVALIDDATA; 370 else 371 return 0; 372 } 373 374 /* Let's paint onto the buffer */ 375 tdsc_blit(ctx->refframe->data[0] + x * 3 + ctx->refframe->linesize[0] * y, 376 ctx->refframe->linesize[0], 377 ctx->jpgframe->data[0], ctx->jpgframe->linesize[0], 378 ctx->jpgframe->data[1], ctx->jpgframe->data[2], 379 ctx->jpgframe->linesize[1], w, h); 380 381 av_frame_unref(ctx->jpgframe); 382 383 return 0; 384} 385 386/* Parse frame and either copy data or decode JPEG. */ 387static int tdsc_decode_tiles(AVCodecContext *avctx, int number_tiles) 388{ 389 TDSCContext *ctx = avctx->priv_data; 390 int i; 391 392 /* Iterate over the number of tiles */ 393 for (i = 0; i < number_tiles; i++) { 394 int tile_size; 395 int tile_mode; 396 int x, y, x2, y2, w, h; 397 int ret; 398 399 if (bytestream2_get_bytes_left(&ctx->gbc) < 4 || 400 bytestream2_get_le32(&ctx->gbc) != MKTAG('T','D','S','B') || 401 bytestream2_get_bytes_left(&ctx->gbc) < TDSB_HEADER_SIZE - 4) { 402 av_log(avctx, AV_LOG_ERROR, "TDSB tag is too small.\n"); 403 return AVERROR_INVALIDDATA; 404 } 405 406 tile_size = bytestream2_get_le32(&ctx->gbc); 407 if (bytestream2_get_bytes_left(&ctx->gbc) < tile_size) 408 return AVERROR_INVALIDDATA; 409 410 tile_mode = bytestream2_get_le32(&ctx->gbc); 411 bytestream2_skip(&ctx->gbc, 4); // unknown 412 x = bytestream2_get_le32(&ctx->gbc); 413 y = bytestream2_get_le32(&ctx->gbc); 414 x2 = bytestream2_get_le32(&ctx->gbc); 415 y2 = bytestream2_get_le32(&ctx->gbc); 416 417 if (x < 0 || y < 0 || x2 <= x || y2 <= y || 418 x2 > ctx->width || y2 > ctx->height 419 ) { 420 av_log(avctx, AV_LOG_ERROR, 421 "Invalid tile position (%d.%d %d.%d outside %dx%d).\n", 422 x, y, x2, y2, ctx->width, ctx->height); 423 return AVERROR_INVALIDDATA; 424 } 425 w = x2 - x; 426 h = y2 - y; 427 428 ret = av_reallocp(&ctx->tilebuffer, tile_size); 429 if (!ctx->tilebuffer) 430 return ret; 431 432 bytestream2_get_buffer(&ctx->gbc, ctx->tilebuffer, tile_size); 433 434 if (tile_mode == MKTAG('G','E','P','J')) { 435 /* Decode JPEG tile and copy it in the reference frame */ 436 ret = tdsc_decode_jpeg_tile(avctx, tile_size, x, y, w, h); 437 if (ret < 0) 438 return ret; 439 } else if (tile_mode == MKTAG(' ','W','A','R')) { 440 /* Just copy the buffer to output */ 441 av_image_copy_plane(ctx->refframe->data[0] + x * 3 + 442 ctx->refframe->linesize[0] * y, 443 ctx->refframe->linesize[0], ctx->tilebuffer, 444 w * 3, w * 3, h); 445 } else { 446 av_log(avctx, AV_LOG_ERROR, "Unknown tile type %08x.\n", tile_mode); 447 return AVERROR_INVALIDDATA; 448 } 449 av_log(avctx, AV_LOG_DEBUG, "Tile %d, %dx%d (%d.%d)\n", i, w, h, x, y); 450 } 451 452 return 0; 453} 454 455static int tdsc_parse_tdsf(AVCodecContext *avctx, int number_tiles) 456{ 457 TDSCContext *ctx = avctx->priv_data; 458 int ret, w, h, init_refframe = !ctx->refframe->data[0]; 459 460 /* BITMAPINFOHEADER 461 * http://msdn.microsoft.com/en-us/library/windows/desktop/dd183376.aspx */ 462 if (bytestream2_get_le32(&ctx->gbc) != BITMAPINFOHEADER_SIZE) 463 return AVERROR_INVALIDDATA; 464 465 /* Store size, but wait for context reinit before updating avctx */ 466 w = bytestream2_get_le32(&ctx->gbc); 467 h = -bytestream2_get_le32(&ctx->gbc); 468 469 if (bytestream2_get_le16(&ctx->gbc) != 1 || // 1 plane 470 bytestream2_get_le16(&ctx->gbc) != 24) // BGR24 471 return AVERROR_INVALIDDATA; 472 473 bytestream2_skip(&ctx->gbc, 24); // unused fields 474 475 /* Update sizes */ 476 if (avctx->width != w || avctx->height != h) { 477 av_log(avctx, AV_LOG_DEBUG, "Size update %dx%d -> %d%d.\n", 478 avctx->width, avctx->height, ctx->width, ctx->height); 479 ret = ff_set_dimensions(avctx, w, h); 480 if (ret < 0) 481 return ret; 482 init_refframe = 1; 483 } 484 ctx->refframe->width = ctx->width = w; 485 ctx->refframe->height = ctx->height = h; 486 487 /* Allocate the reference frame if not already done or on size change */ 488 if (init_refframe) { 489 ret = av_frame_get_buffer(ctx->refframe, 0); 490 if (ret < 0) 491 return ret; 492 } 493 494 /* Decode all tiles in a frame */ 495 return tdsc_decode_tiles(avctx, number_tiles); 496} 497 498static int tdsc_parse_dtsm(AVCodecContext *avctx) 499{ 500 TDSCContext *ctx = avctx->priv_data; 501 int ret; 502 int action = bytestream2_get_le32(&ctx->gbc); 503 504 bytestream2_skip(&ctx->gbc, 4); // some kind of ID or version maybe? 505 506 if (action == 2 || action == 3) { 507 /* Load cursor coordinates */ 508 ctx->cursor_x = bytestream2_get_le32(&ctx->gbc); 509 ctx->cursor_y = bytestream2_get_le32(&ctx->gbc); 510 511 /* Load a full cursor sprite */ 512 if (action == 3) { 513 ret = tdsc_load_cursor(avctx); 514 /* Do not consider cursor errors fatal unless in explode mode */ 515 if (ret < 0 && (avctx->err_recognition & AV_EF_EXPLODE)) 516 return ret; 517 } 518 } else { 519 avpriv_request_sample(avctx, "Cursor action %d", action); 520 } 521 522 return 0; 523} 524 525static int tdsc_decode_frame(AVCodecContext *avctx, AVFrame *frame, 526 int *got_frame, AVPacket *avpkt) 527{ 528 TDSCContext *ctx = avctx->priv_data; 529 int ret, tag_header, keyframe = 0; 530 uLongf dlen; 531 532 /* Resize deflate buffer on resolution change */ 533 if (ctx->width != avctx->width || ctx->height != avctx->height) { 534 int deflatelen = avctx->width * avctx->height * (3 + 1); 535 if (deflatelen != ctx->deflatelen) { 536 ctx->deflatelen =deflatelen; 537 ret = av_reallocp(&ctx->deflatebuffer, ctx->deflatelen); 538 if (ret < 0) { 539 ctx->deflatelen = 0; 540 return ret; 541 } 542 } 543 } 544 dlen = ctx->deflatelen; 545 546 /* Frames are deflated, need to inflate them first */ 547 ret = uncompress(ctx->deflatebuffer, &dlen, avpkt->data, avpkt->size); 548 if (ret) { 549 av_log(avctx, AV_LOG_ERROR, "Deflate error %d.\n", ret); 550 return AVERROR_UNKNOWN; 551 } 552 553 bytestream2_init(&ctx->gbc, ctx->deflatebuffer, dlen); 554 555 /* Check for tag and for size info */ 556 if (bytestream2_get_bytes_left(&ctx->gbc) < 4 + 4) { 557 av_log(avctx, AV_LOG_ERROR, "Frame is too small.\n"); 558 return AVERROR_INVALIDDATA; 559 } 560 561 /* Read tag */ 562 tag_header = bytestream2_get_le32(&ctx->gbc); 563 564 if (tag_header == MKTAG('T','D','S','F')) { 565 int number_tiles; 566 if (bytestream2_get_bytes_left(&ctx->gbc) < TDSF_HEADER_SIZE) { 567 av_log(avctx, AV_LOG_ERROR, "TDSF tag is too small.\n"); 568 return AVERROR_INVALIDDATA; 569 } 570 /* First 4 bytes here are the number of GEPJ/WAR tiles in this frame */ 571 number_tiles = bytestream2_get_le32(&ctx->gbc); 572 573 bytestream2_skip(&ctx->gbc, 4); // internal timestamp maybe? 574 keyframe = bytestream2_get_le32(&ctx->gbc) == 0x30; 575 576 ret = tdsc_parse_tdsf(avctx, number_tiles); 577 if (ret < 0) 578 return ret; 579 580 /* Check if there is anything else we are able to parse */ 581 if (bytestream2_get_bytes_left(&ctx->gbc) >= 4 + 4) 582 tag_header = bytestream2_get_le32(&ctx->gbc); 583 } 584 585 /* This tag can be after a TDSF block or on its own frame */ 586 if (tag_header == MKTAG('D','T','S','M')) { 587 /* First 4 bytes here are the total size in bytes for this frame */ 588 int tag_size = bytestream2_get_le32(&ctx->gbc); 589 590 if (bytestream2_get_bytes_left(&ctx->gbc) < tag_size) { 591 av_log(avctx, AV_LOG_ERROR, "DTSM tag is too small.\n"); 592 return AVERROR_INVALIDDATA; 593 } 594 595 ret = tdsc_parse_dtsm(avctx); 596 if (ret < 0) 597 return ret; 598 } 599 600 /* Get the output frame and copy the reference frame */ 601 ret = ff_get_buffer(avctx, frame, 0); 602 if (ret < 0) 603 return ret; 604 605 ret = av_frame_copy(frame, ctx->refframe); 606 if (ret < 0) 607 return ret; 608 609 /* Paint the cursor on the output frame */ 610 tdsc_paint_cursor(avctx, frame->data[0], frame->linesize[0]); 611 612 /* Frame is ready to be output */ 613 if (keyframe) { 614 frame->pict_type = AV_PICTURE_TYPE_I; 615 frame->key_frame = 1; 616 } else { 617 frame->pict_type = AV_PICTURE_TYPE_P; 618 } 619 *got_frame = 1; 620 621 return avpkt->size; 622} 623 624const FFCodec ff_tdsc_decoder = { 625 .p.name = "tdsc", 626 .p.long_name = NULL_IF_CONFIG_SMALL("TDSC"), 627 .p.type = AVMEDIA_TYPE_VIDEO, 628 .p.id = AV_CODEC_ID_TDSC, 629 .init = tdsc_init, 630 FF_CODEC_DECODE_CB(tdsc_decode_frame), 631 .close = tdsc_close, 632 .priv_data_size = sizeof(TDSCContext), 633 .p.capabilities = AV_CODEC_CAP_DR1, 634 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | 635 FF_CODEC_CAP_INIT_CLEANUP, 636}; 637