1/* 2 * Duck TrueMotion 2.0 Real Time decoder 3 * 4 * This file is part of FFmpeg. 5 * 6 * FFmpeg is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * FFmpeg is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with FFmpeg; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 19 */ 20 21#include <stdio.h> 22#include <stdlib.h> 23#include <string.h> 24 25#include "libavutil/imgutils.h" 26#include "libavutil/internal.h" 27#include "libavutil/intreadwrite.h" 28 29#define BITSTREAM_READER_LE 30#include "avcodec.h" 31#include "codec_internal.h" 32#include "get_bits.h" 33#include "internal.h" 34 35typedef struct TrueMotion2RTContext { 36 GetBitContext gb; 37 int delta_size; 38 int hscale; 39} TrueMotion2RTContext; 40 41static const int16_t delta_tab2[] = { 42 5, -7, 36, -36, 43}; 44 45static const int16_t delta_tab3[] = { 46 2, -3, 8, -8, 18, -18, 36, -36, 47}; 48 49static const int16_t delta_tab4[] = { 50 1, -1, 2, -3, 8, -8, 18, -18, 36, -36, 54, -54, 96, -96, 144, -144, 51}; 52 53static const int16_t *const delta_tabs[] = { 54 delta_tab2, delta_tab3, delta_tab4, 55}; 56 57/* Returns the number of bytes consumed from the bytestream, or 58 * AVERROR_INVALIDDATA if there was an error while decoding the header. */ 59static int truemotion2rt_decode_header(AVCodecContext *avctx, const AVPacket *avpkt) 60{ 61 TrueMotion2RTContext *s = avctx->priv_data; 62 int header_size; 63 uint8_t header_buffer[128] = { 0 }; /* logical maximum header size */ 64 const uint8_t *buf = avpkt->data; 65 int size = avpkt->size; 66 int width, height; 67 int ret, i; 68 69 if (size < 1) { 70 av_log(avctx, AV_LOG_ERROR, "input packet too small (%d)\n", size); 71 return AVERROR_INVALIDDATA; 72 } 73 74 header_size = ((buf[0] >> 5) | (buf[0] << 3)) & 0x7f; 75 if (header_size < 10) { 76 av_log(avctx, AV_LOG_ERROR, "invalid header size (%d)\n", header_size); 77 return AVERROR_INVALIDDATA; 78 } 79 80 if (header_size + 1 > size) { 81 av_log(avctx, AV_LOG_ERROR, "input packet too small (%d)\n", size); 82 return AVERROR_INVALIDDATA; 83 } 84 85 /* unscramble the header bytes with a XOR operation */ 86 for (i = 1; i < header_size; i++) 87 header_buffer[i - 1] = buf[i] ^ buf[i + 1]; 88 89 s->delta_size = header_buffer[1]; 90 s->hscale = 1 + !!header_buffer[3]; 91 if (s->delta_size < 2 || s->delta_size > 4) 92 return AVERROR_INVALIDDATA; 93 94 height = AV_RL16(header_buffer + 5); 95 width = AV_RL16(header_buffer + 7); 96 97 ret = ff_set_dimensions(avctx, width, height); 98 if (ret < 0) 99 return ret; 100 101 av_log(avctx, AV_LOG_DEBUG, "Header size: %d\n", header_size); 102 return header_size; 103} 104 105static int truemotion2rt_decode_frame(AVCodecContext *avctx, AVFrame *p, 106 int *got_frame, AVPacket *avpkt) 107{ 108 TrueMotion2RTContext *s = avctx->priv_data; 109 GetBitContext *gb = &s->gb; 110 uint8_t *dst; 111 int x, y, delta_mode; 112 int ret; 113 114 ret = truemotion2rt_decode_header(avctx, avpkt); 115 if (ret < 0) 116 return ret; 117 118 if ((avctx->width + s->hscale - 1)/ s->hscale * avctx->height * s->delta_size > avpkt->size * 8LL * 4) 119 return AVERROR_INVALIDDATA; 120 121 ret = init_get_bits8(gb, avpkt->data + ret, avpkt->size - ret); 122 if (ret < 0) 123 return ret; 124 125 ret = ff_get_buffer(avctx, p, 0); 126 if (ret < 0) 127 return ret; 128 129 skip_bits(gb, 32); 130 delta_mode = s->delta_size - 2; 131 dst = p->data[0]; 132 for (y = 0; y < avctx->height; y++) { 133 int diff = 0; 134 for (x = 0; x < avctx->width; x += s->hscale) { 135 diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; 136 dst[x] = av_clip_uint8((y ? dst[x - p->linesize[0]] : 0) + diff); 137 } 138 dst += p->linesize[0]; 139 } 140 141 if (s->hscale > 1) { 142 dst = p->data[0]; 143 for (y = 0; y < avctx->height; y++) { 144 for (x = 1; x < avctx->width; x += s->hscale) 145 dst[x] = dst[x - 1]; 146 dst += p->linesize[0]; 147 } 148 } 149 150 dst = p->data[0]; 151 for (y = 0; y < avctx->height; y++) { 152 for (x = 0; x < avctx->width; x++) 153 dst[x] = av_clip_uint8(dst[x] + (dst[x] - 128) / 3); 154 dst += p->linesize[0]; 155 } 156 157 dst = p->data[1]; 158 for (y = 0; y < avctx->height >> 2; y++) { 159 int diff = 0; 160 for (x = 0; x < avctx->width >> 2; x += s->hscale) { 161 diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; 162 dst[x] = av_clip_uint8((y ? dst[x - p->linesize[1]] : 128) + diff); 163 } 164 dst += p->linesize[1]; 165 } 166 167 if (s->hscale > 1) { 168 dst = p->data[1]; 169 for (y = 0; y < avctx->height >> 2; y++) { 170 for (x = 1; x < avctx->width >> 2; x += s->hscale) 171 dst[x] = dst[x - 1]; 172 dst += p->linesize[1]; 173 } 174 } 175 176 dst = p->data[1]; 177 for (y = 0; y < avctx->height >> 2; y++) { 178 for (x = 0; x < avctx->width >> 2; x++) 179 dst[x] += (dst[x] - 128) / 8; 180 dst += p->linesize[1]; 181 } 182 183 dst = p->data[2]; 184 for (y = 0; y < avctx->height >> 2; y++) { 185 int diff = 0; 186 for (x = 0; x < avctx->width >> 2; x += s->hscale) { 187 diff += delta_tabs[delta_mode][get_bits(gb, s->delta_size)]; 188 dst[x] = av_clip_uint8((y ? dst[x - p->linesize[2]] : 128) + diff); 189 } 190 dst += p->linesize[2]; 191 } 192 193 if (s->hscale > 1) { 194 dst = p->data[2]; 195 for (y = 0; y < avctx->height >> 2; y++) { 196 for (x = 1; x < avctx->width >> 2; x += s->hscale) 197 dst[x] = dst[x - 1]; 198 dst += p->linesize[2]; 199 } 200 } 201 202 dst = p->data[2]; 203 for (y = 0; y < avctx->height >> 2; y++) { 204 for (x = 0; x < avctx->width >> 2; x++) 205 dst[x] += (dst[x] - 128) / 8; 206 dst += p->linesize[2]; 207 } 208 209 p->pict_type = AV_PICTURE_TYPE_I; 210 p->key_frame = 1; 211 *got_frame = 1; 212 213 return avpkt->size; 214} 215 216static av_cold int truemotion2rt_decode_init(AVCodecContext *avctx) 217{ 218 avctx->pix_fmt = AV_PIX_FMT_YUV410P; 219 return 0; 220} 221 222const FFCodec ff_truemotion2rt_decoder = { 223 .p.name = "truemotion2rt", 224 .p.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 2.0 Real Time"), 225 .p.type = AVMEDIA_TYPE_VIDEO, 226 .p.id = AV_CODEC_ID_TRUEMOTION2RT, 227 .priv_data_size = sizeof(TrueMotion2RTContext), 228 .init = truemotion2rt_decode_init, 229 FF_CODEC_DECODE_CB(truemotion2rt_decode_frame), 230 .p.capabilities = AV_CODEC_CAP_DR1, 231 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE, 232}; 233