Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Duck TrueMotion 1.0 Decoder | ||
3 | * Copyright (C) 2003 Alex Beregszaszi & Mike Melanson | ||
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 | * Duck TrueMotion v1 Video Decoder by | ||
25 | * Alex Beregszaszi and | ||
26 | * Mike Melanson (melanson@pcisys.net) | ||
27 | * | ||
28 | * The TrueMotion v1 decoder presently only decodes 16-bit TM1 data and | ||
29 | * outputs RGB555 (or RGB565) data. 24-bit TM1 data is not supported yet. | ||
30 | */ | ||
31 | |||
32 | #include <stdio.h> | ||
33 | #include <stdlib.h> | ||
34 | #include <string.h> | ||
35 | |||
36 | #include "avcodec.h" | ||
37 | #include "codec_internal.h" | ||
38 | #include "decode.h" | ||
39 | #include "libavutil/imgutils.h" | ||
40 | #include "libavutil/internal.h" | ||
41 | #include "libavutil/intreadwrite.h" | ||
42 | #include "libavutil/mem.h" | ||
43 | |||
44 | #include "truemotion1data.h" | ||
45 | |||
46 | typedef struct TrueMotion1Context { | ||
47 | AVCodecContext *avctx; | ||
48 | AVFrame *frame; | ||
49 | |||
50 | const uint8_t *buf; | ||
51 | int size; | ||
52 | |||
53 | const uint8_t *mb_change_bits; | ||
54 | int mb_change_bits_row_size; | ||
55 | const uint8_t *index_stream; | ||
56 | int index_stream_size; | ||
57 | |||
58 | int flags; | ||
59 | int x, y, w, h; | ||
60 | |||
61 | uint32_t y_predictor_table[1024]; | ||
62 | uint32_t c_predictor_table[1024]; | ||
63 | uint32_t fat_y_predictor_table[1024]; | ||
64 | uint32_t fat_c_predictor_table[1024]; | ||
65 | |||
66 | int compression; | ||
67 | int block_type; | ||
68 | int block_width; | ||
69 | int block_height; | ||
70 | |||
71 | int16_t ydt[8]; | ||
72 | int16_t cdt[8]; | ||
73 | int16_t fat_ydt[8]; | ||
74 | int16_t fat_cdt[8]; | ||
75 | |||
76 | int last_deltaset, last_vectable; | ||
77 | |||
78 | unsigned int *vert_pred; | ||
79 | int vert_pred_size; | ||
80 | |||
81 | } TrueMotion1Context; | ||
82 | |||
83 | #define FLAG_SPRITE 32 | ||
84 | #define FLAG_KEYFRAME 16 | ||
85 | #define FLAG_INTERFRAME 8 | ||
86 | #define FLAG_INTERPOLATED 4 | ||
87 | |||
88 | struct frame_header { | ||
89 | uint8_t header_size; | ||
90 | uint8_t compression; | ||
91 | uint8_t deltaset; | ||
92 | uint8_t vectable; | ||
93 | uint16_t ysize; | ||
94 | uint16_t xsize; | ||
95 | uint16_t checksum; | ||
96 | uint8_t version; | ||
97 | uint8_t header_type; | ||
98 | uint8_t flags; | ||
99 | uint8_t control; | ||
100 | uint16_t xoffset; | ||
101 | uint16_t yoffset; | ||
102 | uint16_t width; | ||
103 | uint16_t height; | ||
104 | }; | ||
105 | |||
106 | #define ALGO_NOP 0 | ||
107 | #define ALGO_RGB16V 1 | ||
108 | #define ALGO_RGB16H 2 | ||
109 | #define ALGO_RGB24H 3 | ||
110 | |||
111 | /* these are the various block sizes that can occupy a 4x4 block */ | ||
112 | #define BLOCK_2x2 0 | ||
113 | #define BLOCK_2x4 1 | ||
114 | #define BLOCK_4x2 2 | ||
115 | #define BLOCK_4x4 3 | ||
116 | |||
117 | typedef struct comp_types { | ||
118 | int algorithm; | ||
119 | int block_width; // vres | ||
120 | int block_height; // hres | ||
121 | int block_type; | ||
122 | } comp_types; | ||
123 | |||
124 | /* { valid for metatype }, algorithm, num of deltas, vert res, horiz res */ | ||
125 | static const comp_types compression_types[17] = { | ||
126 | { ALGO_NOP, 0, 0, 0 }, | ||
127 | |||
128 | { ALGO_RGB16V, 4, 4, BLOCK_4x4 }, | ||
129 | { ALGO_RGB16H, 4, 4, BLOCK_4x4 }, | ||
130 | { ALGO_RGB16V, 4, 2, BLOCK_4x2 }, | ||
131 | { ALGO_RGB16H, 4, 2, BLOCK_4x2 }, | ||
132 | |||
133 | { ALGO_RGB16V, 2, 4, BLOCK_2x4 }, | ||
134 | { ALGO_RGB16H, 2, 4, BLOCK_2x4 }, | ||
135 | { ALGO_RGB16V, 2, 2, BLOCK_2x2 }, | ||
136 | { ALGO_RGB16H, 2, 2, BLOCK_2x2 }, | ||
137 | |||
138 | { ALGO_NOP, 4, 4, BLOCK_4x4 }, | ||
139 | { ALGO_RGB24H, 4, 4, BLOCK_4x4 }, | ||
140 | { ALGO_NOP, 4, 2, BLOCK_4x2 }, | ||
141 | { ALGO_RGB24H, 4, 2, BLOCK_4x2 }, | ||
142 | |||
143 | { ALGO_NOP, 2, 4, BLOCK_2x4 }, | ||
144 | { ALGO_RGB24H, 2, 4, BLOCK_2x4 }, | ||
145 | { ALGO_NOP, 2, 2, BLOCK_2x2 }, | ||
146 | { ALGO_RGB24H, 2, 2, BLOCK_2x2 } | ||
147 | }; | ||
148 | |||
149 | 4 | static void select_delta_tables(TrueMotion1Context *s, int delta_table_index) | |
150 | { | ||
151 | int i; | ||
152 | |||
153 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (delta_table_index > 3) |
154 | ✗ | return; | |
155 | |||
156 | 4 | memcpy(s->ydt, ydts[delta_table_index], 8 * sizeof(int16_t)); | |
157 | 4 | memcpy(s->cdt, cdts[delta_table_index], 8 * sizeof(int16_t)); | |
158 | 4 | memcpy(s->fat_ydt, fat_ydts[delta_table_index], 8 * sizeof(int16_t)); | |
159 | 4 | memcpy(s->fat_cdt, fat_cdts[delta_table_index], 8 * sizeof(int16_t)); | |
160 | |||
161 | /* Y skinny deltas need to be halved for some reason; maybe the | ||
162 | * skinny Y deltas should be modified */ | ||
163 |
2/2✓ Branch 0 taken 32 times.
✓ Branch 1 taken 4 times.
|
36 | for (i = 0; i < 8; i++) |
164 | { | ||
165 | /* drop the lsb before dividing by 2-- net effect: round down | ||
166 | * when dividing a negative number (e.g., -3/2 = -2, not -1) */ | ||
167 | 32 | s->ydt[i] &= 0xFFFE; | |
168 | 32 | s->ydt[i] /= 2; | |
169 | } | ||
170 | } | ||
171 | |||
172 | #if HAVE_BIGENDIAN | ||
173 | static int make_ydt15_entry(int p2, int p1, int16_t *ydt) | ||
174 | #else | ||
175 | 1104 | static int make_ydt15_entry(int p1, int p2, int16_t *ydt) | |
176 | #endif | ||
177 | { | ||
178 | int lo, hi; | ||
179 | |||
180 | 1104 | lo = ydt[p1]; | |
181 | 1104 | lo += (lo * 32) + (lo * 1024); | |
182 | 1104 | hi = ydt[p2]; | |
183 | 1104 | hi += (hi * 32) + (hi * 1024); | |
184 | 1104 | return (lo + (hi * (1U << 16))) * 2; | |
185 | } | ||
186 | |||
187 | 1104 | static int make_cdt15_entry(int p1, int p2, int16_t *cdt) | |
188 | { | ||
189 | int r, b, lo; | ||
190 | |||
191 | 1104 | b = cdt[p2]; | |
192 | 1104 | r = cdt[p1] * 1024; | |
193 | 1104 | lo = b + r; | |
194 | 1104 | return (lo + (lo * (1U << 16))) * 2; | |
195 | } | ||
196 | |||
197 | #if HAVE_BIGENDIAN | ||
198 | static int make_ydt16_entry(int p2, int p1, int16_t *ydt) | ||
199 | #else | ||
200 | ✗ | static int make_ydt16_entry(int p1, int p2, int16_t *ydt) | |
201 | #endif | ||
202 | { | ||
203 | int lo, hi; | ||
204 | |||
205 | ✗ | lo = ydt[p1]; | |
206 | ✗ | lo += (lo << 6) + (lo << 11); | |
207 | ✗ | hi = ydt[p2]; | |
208 | ✗ | hi += (hi << 6) + (hi << 11); | |
209 | ✗ | return (lo + (hi << 16)) << 1; | |
210 | } | ||
211 | |||
212 | ✗ | static int make_cdt16_entry(int p1, int p2, int16_t *cdt) | |
213 | { | ||
214 | int r, b, lo; | ||
215 | |||
216 | ✗ | b = cdt[p2]; | |
217 | ✗ | r = cdt[p1] << 11; | |
218 | ✗ | lo = b + r; | |
219 | ✗ | return (lo + (lo * (1 << 16))) * 2; | |
220 | } | ||
221 | |||
222 | 2048 | static int make_ydt24_entry(int p1, int p2, int16_t *ydt) | |
223 | { | ||
224 | int lo, hi; | ||
225 | |||
226 | 2048 | lo = ydt[p1]; | |
227 | 2048 | hi = ydt[p2]; | |
228 | 2048 | return (lo + (hi * (1 << 8)) + (hi * (1 << 16))) * 2; | |
229 | } | ||
230 | |||
231 | 2048 | static int make_cdt24_entry(int p1, int p2, int16_t *cdt) | |
232 | { | ||
233 | int r, b; | ||
234 | |||
235 | 2048 | b = cdt[p2]; | |
236 | 2048 | r = cdt[p1] * (1 << 16); | |
237 | 2048 | return (b+r) * 2; | |
238 | } | ||
239 | |||
240 | 2 | static void gen_vector_table15(TrueMotion1Context *s, const uint8_t *sel_vector_table) | |
241 | { | ||
242 | int len, i, j; | ||
243 | unsigned char delta_pair; | ||
244 | |||
245 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 2 times.
|
514 | for (i = 0; i < 1024; i += 4) |
246 | { | ||
247 | 512 | len = *sel_vector_table++ / 2; | |
248 |
2/2✓ Branch 0 taken 1104 times.
✓ Branch 1 taken 512 times.
|
1616 | for (j = 0; j < len; j++) |
249 | { | ||
250 | 1104 | delta_pair = *sel_vector_table++; | |
251 | 1104 | s->y_predictor_table[i+j] = 0xfffffffe & | |
252 | 1104 | make_ydt15_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | |
253 | 1104 | s->c_predictor_table[i+j] = 0xfffffffe & | |
254 | 1104 | make_cdt15_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | |
255 | } | ||
256 | 512 | s->y_predictor_table[i+(j-1)] |= 1; | |
257 | 512 | s->c_predictor_table[i+(j-1)] |= 1; | |
258 | } | ||
259 | 2 | } | |
260 | |||
261 | ✗ | static void gen_vector_table16(TrueMotion1Context *s, const uint8_t *sel_vector_table) | |
262 | { | ||
263 | int len, i, j; | ||
264 | unsigned char delta_pair; | ||
265 | |||
266 | ✗ | for (i = 0; i < 1024; i += 4) | |
267 | { | ||
268 | ✗ | len = *sel_vector_table++ / 2; | |
269 | ✗ | for (j = 0; j < len; j++) | |
270 | { | ||
271 | ✗ | delta_pair = *sel_vector_table++; | |
272 | ✗ | s->y_predictor_table[i+j] = 0xfffffffe & | |
273 | ✗ | make_ydt16_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | |
274 | ✗ | s->c_predictor_table[i+j] = 0xfffffffe & | |
275 | ✗ | make_cdt16_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | |
276 | } | ||
277 | ✗ | s->y_predictor_table[i+(j-1)] |= 1; | |
278 | ✗ | s->c_predictor_table[i+(j-1)] |= 1; | |
279 | } | ||
280 | ✗ | } | |
281 | |||
282 | 2 | static void gen_vector_table24(TrueMotion1Context *s, const uint8_t *sel_vector_table) | |
283 | { | ||
284 | int len, i, j; | ||
285 | unsigned char delta_pair; | ||
286 | |||
287 |
2/2✓ Branch 0 taken 512 times.
✓ Branch 1 taken 2 times.
|
514 | for (i = 0; i < 1024; i += 4) |
288 | { | ||
289 | 512 | len = *sel_vector_table++ / 2; | |
290 |
2/2✓ Branch 0 taken 1024 times.
✓ Branch 1 taken 512 times.
|
1536 | for (j = 0; j < len; j++) |
291 | { | ||
292 | 1024 | delta_pair = *sel_vector_table++; | |
293 | 1024 | s->y_predictor_table[i+j] = 0xfffffffe & | |
294 | 1024 | make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->ydt); | |
295 | 1024 | s->c_predictor_table[i+j] = 0xfffffffe & | |
296 | 1024 | make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->cdt); | |
297 | 1024 | s->fat_y_predictor_table[i+j] = 0xfffffffe & | |
298 | 1024 | make_ydt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_ydt); | |
299 | 1024 | s->fat_c_predictor_table[i+j] = 0xfffffffe & | |
300 | 1024 | make_cdt24_entry(delta_pair >> 4, delta_pair & 0xf, s->fat_cdt); | |
301 | } | ||
302 | 512 | s->y_predictor_table[i+(j-1)] |= 1; | |
303 | 512 | s->c_predictor_table[i+(j-1)] |= 1; | |
304 | 512 | s->fat_y_predictor_table[i+(j-1)] |= 1; | |
305 | 512 | s->fat_c_predictor_table[i+(j-1)] |= 1; | |
306 | } | ||
307 | 2 | } | |
308 | |||
309 | /* Returns the number of bytes consumed from the bytestream. Returns -1 if | ||
310 | * there was an error while decoding the header */ | ||
311 | 123 | static int truemotion1_decode_header(TrueMotion1Context *s) | |
312 | { | ||
313 | int i, ret; | ||
314 | 123 | int width_shift = 0; | |
315 | int new_pix_fmt; | ||
316 | struct frame_header header; | ||
317 | 123 | uint8_t header_buffer[128] = { 0 }; /* logical maximum size of the header */ | |
318 | const uint8_t *sel_vector_table; | ||
319 | |||
320 | 123 | header.header_size = ((s->buf[0] >> 5) | (s->buf[0] << 3)) & 0x7f; | |
321 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->buf[0] < 0x10) |
322 | { | ||
323 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "invalid header size (%d)\n", s->buf[0]); | |
324 | ✗ | return AVERROR_INVALIDDATA; | |
325 | } | ||
326 | |||
327 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (header.header_size + 1 > s->size) { |
328 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "Input packet too small.\n"); | |
329 | ✗ | return AVERROR_INVALIDDATA; | |
330 | } | ||
331 | |||
332 | /* unscramble the header bytes with a XOR operation */ | ||
333 |
2/2✓ Branch 0 taken 1693 times.
✓ Branch 1 taken 123 times.
|
1816 | for (i = 1; i < header.header_size; i++) |
334 | 1693 | header_buffer[i - 1] = s->buf[i] ^ s->buf[i + 1]; | |
335 | |||
336 | 123 | header.compression = header_buffer[0]; | |
337 | 123 | header.deltaset = header_buffer[1]; | |
338 | 123 | header.vectable = header_buffer[2]; | |
339 | 123 | header.ysize = AV_RL16(&header_buffer[3]); | |
340 | 123 | header.xsize = AV_RL16(&header_buffer[5]); | |
341 | 123 | header.checksum = AV_RL16(&header_buffer[7]); | |
342 | 123 | header.version = header_buffer[9]; | |
343 | 123 | header.header_type = header_buffer[10]; | |
344 | 123 | header.flags = header_buffer[11]; | |
345 | 123 | header.control = header_buffer[12]; | |
346 | |||
347 | /* Version 2 */ | ||
348 |
1/2✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
|
123 | if (header.version >= 2) |
349 | { | ||
350 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (header.header_type > 3) |
351 | { | ||
352 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "invalid header type (%d)\n", header.header_type); | |
353 | ✗ | return AVERROR_INVALIDDATA; | |
354 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
123 | } else if ((header.header_type == 2) || (header.header_type == 3)) { |
355 | 123 | s->flags = header.flags; | |
356 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (!(s->flags & FLAG_INTERFRAME)) |
357 | ✗ | s->flags |= FLAG_KEYFRAME; | |
358 | } else | ||
359 | ✗ | s->flags = FLAG_KEYFRAME; | |
360 | } else /* Version 1 */ | ||
361 | ✗ | s->flags = FLAG_KEYFRAME; | |
362 | |||
363 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->flags & FLAG_SPRITE) { |
364 | ✗ | avpriv_request_sample(s->avctx, "Frame with sprite"); | |
365 | /* FIXME header.width, height, xoffset and yoffset aren't initialized */ | ||
366 | ✗ | return AVERROR_PATCHWELCOME; | |
367 | } else { | ||
368 | 123 | s->w = header.xsize; | |
369 | 123 | s->h = header.ysize; | |
370 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (header.header_type < 2) { |
371 | ✗ | if ((s->w < 213) && (s->h >= 176)) | |
372 | { | ||
373 | ✗ | s->flags |= FLAG_INTERPOLATED; | |
374 | ✗ | avpriv_request_sample(s->avctx, "Interpolated frame"); | |
375 | } | ||
376 | } | ||
377 | } | ||
378 | |||
379 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (header.compression >= 17) { |
380 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "invalid compression type (%d)\n", header.compression); | |
381 | ✗ | return AVERROR_INVALIDDATA; | |
382 | } | ||
383 | |||
384 |
2/2✓ Branch 0 taken 121 times.
✓ Branch 1 taken 2 times.
|
123 | if ((header.deltaset != s->last_deltaset) || |
385 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 119 times.
|
121 | (header.vectable != s->last_vectable)) |
386 | 4 | select_delta_tables(s, header.deltaset); | |
387 | |||
388 |
1/4✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
123 | if ((header.compression & 1) && header.header_type) |
389 | ✗ | sel_vector_table = pc_tbl2; | |
390 | else { | ||
391 |
2/4✓ Branch 0 taken 123 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
✗ Branch 3 not taken.
|
123 | if (header.vectable > 0 && header.vectable < 4) |
392 | 123 | sel_vector_table = tables[header.vectable - 1]; | |
393 | else { | ||
394 | ✗ | av_log(s->avctx, AV_LOG_ERROR, "invalid vector table id (%d)\n", header.vectable); | |
395 | ✗ | return AVERROR_INVALIDDATA; | |
396 | } | ||
397 | } | ||
398 | |||
399 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 106 times.
|
123 | if (compression_types[header.compression].algorithm == ALGO_RGB24H) { |
400 | 17 | new_pix_fmt = AV_PIX_FMT_0RGB32; | |
401 | 17 | width_shift = 1; | |
402 | } else | ||
403 | 106 | new_pix_fmt = AV_PIX_FMT_RGB555; // RGB565 is supported as well | |
404 | |||
405 | 123 | s->w >>= width_shift; | |
406 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->w & 1) { |
407 | ✗ | avpriv_request_sample(s->avctx, "Frame with odd width"); | |
408 | ✗ | return AVERROR_PATCHWELCOME; | |
409 | } | ||
410 | |||
411 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->h & 3) { |
412 | ✗ | avpriv_request_sample(s->avctx, "Frame with height not being a multiple of 4"); | |
413 | ✗ | return AVERROR_PATCHWELCOME; | |
414 | } | ||
415 | |||
416 |
3/4✓ Branch 0 taken 122 times.
✓ Branch 1 taken 1 times.
✓ Branch 2 taken 122 times.
✗ Branch 3 not taken.
|
123 | if (s->w != s->avctx->width || s->h != s->avctx->height || |
417 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 121 times.
|
122 | new_pix_fmt != s->avctx->pix_fmt) { |
418 | 2 | av_frame_unref(s->frame); | |
419 | 2 | s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; | |
420 | 2 | s->avctx->pix_fmt = new_pix_fmt; | |
421 | |||
422 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0) |
423 | ✗ | return ret; | |
424 | |||
425 | 2 | ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); | |
426 | |||
427 | 2 | av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); | |
428 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!s->vert_pred) |
429 | ✗ | return AVERROR(ENOMEM); | |
430 | } | ||
431 | |||
432 | /* There is 1 change bit per 4 pixels, so each change byte represents | ||
433 | * 32 pixels; divide width by 4 to obtain the number of change bits and | ||
434 | * then round up to the nearest byte. */ | ||
435 | 123 | s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3; | |
436 | |||
437 |
4/4✓ Branch 0 taken 121 times.
✓ Branch 1 taken 2 times.
✓ Branch 2 taken 2 times.
✓ Branch 3 taken 119 times.
|
123 | if ((header.deltaset != s->last_deltaset) || (header.vectable != s->last_vectable)) |
438 | { | ||
439 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (compression_types[header.compression].algorithm == ALGO_RGB24H) |
440 | 2 | gen_vector_table24(s, sel_vector_table); | |
441 | else | ||
442 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555) |
443 | 2 | gen_vector_table15(s, sel_vector_table); | |
444 | else | ||
445 | ✗ | gen_vector_table16(s, sel_vector_table); | |
446 | } | ||
447 | |||
448 | /* set up pointers to the other key data chunks */ | ||
449 | 123 | s->mb_change_bits = s->buf + header.header_size; | |
450 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 98 times.
|
123 | if (s->flags & FLAG_KEYFRAME) { |
451 | /* no change bits specified for a keyframe; only index bytes */ | ||
452 | 25 | s->index_stream = s->mb_change_bits; | |
453 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 25 times.
|
25 | if (s->avctx->width * s->avctx->height / 2048 + header.header_size > s->size) |
454 | ✗ | return AVERROR_INVALIDDATA; | |
455 | } else { | ||
456 | /* one change bit per 4x4 block */ | ||
457 | 98 | s->index_stream = s->mb_change_bits + | |
458 | 98 | (s->mb_change_bits_row_size * (s->avctx->height >> 2)); | |
459 | } | ||
460 | 123 | s->index_stream_size = s->size - (s->index_stream - s->buf); | |
461 | |||
462 | 123 | s->last_deltaset = header.deltaset; | |
463 | 123 | s->last_vectable = header.vectable; | |
464 | 123 | s->compression = header.compression; | |
465 | 123 | s->block_width = compression_types[header.compression].block_width; | |
466 | 123 | s->block_height = compression_types[header.compression].block_height; | |
467 | 123 | s->block_type = compression_types[header.compression].block_type; | |
468 | |||
469 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->avctx->debug & FF_DEBUG_PICT_INFO) |
470 | ✗ | av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n", | |
471 | s->last_deltaset, s->last_vectable, s->compression, s->block_width, | ||
472 | s->block_height, s->block_type, | ||
473 | ✗ | s->flags & FLAG_KEYFRAME ? " KEY" : "", | |
474 | ✗ | s->flags & FLAG_INTERFRAME ? " INTER" : "", | |
475 | ✗ | s->flags & FLAG_SPRITE ? " SPRITE" : "", | |
476 | ✗ | s->flags & FLAG_INTERPOLATED ? " INTERPOL" : ""); | |
477 | |||
478 | 123 | return header.header_size; | |
479 | } | ||
480 | |||
481 | 4 | static av_cold int truemotion1_decode_init(AVCodecContext *avctx) | |
482 | { | ||
483 | 4 | TrueMotion1Context *s = avctx->priv_data; | |
484 | |||
485 | 4 | s->avctx = avctx; | |
486 | |||
487 | // FIXME: it may change ? | ||
488 | // if (avctx->bits_per_sample == 24) | ||
489 | // avctx->pix_fmt = AV_PIX_FMT_RGB24; | ||
490 | // else | ||
491 | // avctx->pix_fmt = AV_PIX_FMT_RGB555; | ||
492 | |||
493 | 4 | s->frame = av_frame_alloc(); | |
494 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!s->frame) |
495 | ✗ | return AVERROR(ENOMEM); | |
496 | |||
497 | /* there is a vertical predictor for each pixel in a line; each vertical | ||
498 | * predictor is 0 to start with */ | ||
499 | 4 | av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); | |
500 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!s->vert_pred) |
501 | ✗ | return AVERROR(ENOMEM); | |
502 | |||
503 | 4 | return 0; | |
504 | } | ||
505 | |||
506 | /* | ||
507 | Block decoding order: | ||
508 | |||
509 | dxi: Y-Y | ||
510 | dxic: Y-C-Y | ||
511 | dxic2: Y-C-Y-C | ||
512 | |||
513 | hres,vres,i,i%vres (0 < i < 4) | ||
514 | 2x2 0: 0 dxic2 | ||
515 | 2x2 1: 1 dxi | ||
516 | 2x2 2: 0 dxic2 | ||
517 | 2x2 3: 1 dxi | ||
518 | 2x4 0: 0 dxic2 | ||
519 | 2x4 1: 1 dxi | ||
520 | 2x4 2: 2 dxi | ||
521 | 2x4 3: 3 dxi | ||
522 | 4x2 0: 0 dxic | ||
523 | 4x2 1: 1 dxi | ||
524 | 4x2 2: 0 dxic | ||
525 | 4x2 3: 1 dxi | ||
526 | 4x4 0: 0 dxic | ||
527 | 4x4 1: 1 dxi | ||
528 | 4x4 2: 2 dxi | ||
529 | 4x4 3: 3 dxi | ||
530 | */ | ||
531 | |||
532 | #define GET_NEXT_INDEX() \ | ||
533 | {\ | ||
534 | if (index_stream_index >= s->index_stream_size) { \ | ||
535 | av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \ | ||
536 | return; \ | ||
537 | } \ | ||
538 | index = s->index_stream[index_stream_index++] * 4; \ | ||
539 | } | ||
540 | |||
541 | #define INC_INDEX \ | ||
542 | do { \ | ||
543 | if (index >= 1023) { \ | ||
544 | av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \ | ||
545 | return; \ | ||
546 | } \ | ||
547 | index++; \ | ||
548 | } while (0) | ||
549 | |||
550 | #define APPLY_C_PREDICTOR() \ | ||
551 | predictor_pair = s->c_predictor_table[index]; \ | ||
552 | horiz_pred += (predictor_pair >> 1); \ | ||
553 | if (predictor_pair & 1) { \ | ||
554 | GET_NEXT_INDEX() \ | ||
555 | if (!index) { \ | ||
556 | GET_NEXT_INDEX() \ | ||
557 | predictor_pair = s->c_predictor_table[index]; \ | ||
558 | horiz_pred += ((predictor_pair >> 1) * 5); \ | ||
559 | if (predictor_pair & 1) \ | ||
560 | GET_NEXT_INDEX() \ | ||
561 | else \ | ||
562 | INC_INDEX; \ | ||
563 | } \ | ||
564 | } else \ | ||
565 | INC_INDEX; | ||
566 | |||
567 | #define APPLY_C_PREDICTOR_24() \ | ||
568 | predictor_pair = s->c_predictor_table[index]; \ | ||
569 | horiz_pred += (predictor_pair >> 1); \ | ||
570 | if (predictor_pair & 1) { \ | ||
571 | GET_NEXT_INDEX() \ | ||
572 | if (!index) { \ | ||
573 | GET_NEXT_INDEX() \ | ||
574 | predictor_pair = s->fat_c_predictor_table[index]; \ | ||
575 | horiz_pred += (predictor_pair >> 1); \ | ||
576 | if (predictor_pair & 1) \ | ||
577 | GET_NEXT_INDEX() \ | ||
578 | else \ | ||
579 | INC_INDEX; \ | ||
580 | } \ | ||
581 | } else \ | ||
582 | INC_INDEX; | ||
583 | |||
584 | |||
585 | #define APPLY_Y_PREDICTOR() \ | ||
586 | predictor_pair = s->y_predictor_table[index]; \ | ||
587 | horiz_pred += (predictor_pair >> 1); \ | ||
588 | if (predictor_pair & 1) { \ | ||
589 | GET_NEXT_INDEX() \ | ||
590 | if (!index) { \ | ||
591 | GET_NEXT_INDEX() \ | ||
592 | predictor_pair = s->y_predictor_table[index]; \ | ||
593 | horiz_pred += ((predictor_pair >> 1) * 5); \ | ||
594 | if (predictor_pair & 1) \ | ||
595 | GET_NEXT_INDEX() \ | ||
596 | else \ | ||
597 | INC_INDEX; \ | ||
598 | } \ | ||
599 | } else \ | ||
600 | INC_INDEX; | ||
601 | |||
602 | #define APPLY_Y_PREDICTOR_24() \ | ||
603 | predictor_pair = s->y_predictor_table[index]; \ | ||
604 | horiz_pred += (predictor_pair >> 1); \ | ||
605 | if (predictor_pair & 1) { \ | ||
606 | GET_NEXT_INDEX() \ | ||
607 | if (!index) { \ | ||
608 | GET_NEXT_INDEX() \ | ||
609 | predictor_pair = s->fat_y_predictor_table[index]; \ | ||
610 | horiz_pred += (predictor_pair >> 1); \ | ||
611 | if (predictor_pair & 1) \ | ||
612 | GET_NEXT_INDEX() \ | ||
613 | else \ | ||
614 | INC_INDEX; \ | ||
615 | } \ | ||
616 | } else \ | ||
617 | INC_INDEX; | ||
618 | |||
619 | #define OUTPUT_PIXEL_PAIR() \ | ||
620 | *current_pixel_pair = *vert_pred + horiz_pred; \ | ||
621 | *vert_pred++ = *current_pixel_pair++; | ||
622 | |||
623 | 97 | static void truemotion1_decode_16bit(TrueMotion1Context *s) | |
624 | { | ||
625 | int y; | ||
626 | int pixels_left; /* remaining pixels on this line */ | ||
627 | unsigned int predictor_pair; | ||
628 | unsigned int horiz_pred; | ||
629 | unsigned int *vert_pred; | ||
630 | unsigned int *current_pixel_pair; | ||
631 | 97 | unsigned char *current_line = s->frame->data[0]; | |
632 | 97 | int keyframe = s->flags & FLAG_KEYFRAME; | |
633 | |||
634 | /* these variables are for managing the stream of macroblock change bits */ | ||
635 | 97 | const unsigned char *mb_change_bits = s->mb_change_bits; | |
636 | unsigned char mb_change_byte; | ||
637 | unsigned char mb_change_byte_mask; | ||
638 | int mb_change_index; | ||
639 | |||
640 | /* these variables are for managing the main index stream */ | ||
641 | 97 | int index_stream_index = 0; /* yes, the index into the index stream */ | |
642 | int index; | ||
643 | |||
644 | /* clean out the line buffer */ | ||
645 | 97 | memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); | |
646 | |||
647 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | GET_NEXT_INDEX(); |
648 | |||
649 |
2/2✓ Branch 0 taken 16296 times.
✓ Branch 1 taken 97 times.
|
16393 | for (y = 0; y < s->avctx->height; y++) { |
650 | |||
651 | /* re-init variables for the next line iteration */ | ||
652 | 16296 | horiz_pred = 0; | |
653 | 16296 | current_pixel_pair = (unsigned int *)current_line; | |
654 | 16296 | vert_pred = s->vert_pred; | |
655 | 16296 | mb_change_index = 0; | |
656 |
2/2✓ Branch 0 taken 12600 times.
✓ Branch 1 taken 3696 times.
|
16296 | if (!keyframe) |
657 | 12600 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
658 | 16296 | mb_change_byte_mask = 0x01; | |
659 | 16296 | pixels_left = s->avctx->width; | |
660 | |||
661 |
2/2✓ Branch 0 taken 1303680 times.
✓ Branch 1 taken 16296 times.
|
1319976 | while (pixels_left > 0) { |
662 | |||
663 |
4/4✓ Branch 0 taken 1008000 times.
✓ Branch 1 taken 295680 times.
✓ Branch 2 taken 410780 times.
✓ Branch 3 taken 597220 times.
|
1303680 | if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) { |
664 | |||
665 |
3/4✓ Branch 0 taken 176615 times.
✓ Branch 1 taken 353230 times.
✓ Branch 2 taken 176615 times.
✗ Branch 3 not taken.
|
706460 | switch (y & 3) { |
666 | 176615 | case 0: | |
667 | /* if macroblock width is 2, apply C-Y-C-Y; else | ||
668 | * apply C-Y-Y */ | ||
669 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | if (s->block_width == 2) { |
670 | ✗ | APPLY_C_PREDICTOR(); | |
671 | ✗ | APPLY_Y_PREDICTOR(); | |
672 | ✗ | OUTPUT_PIXEL_PAIR(); | |
673 | ✗ | APPLY_C_PREDICTOR(); | |
674 | ✗ | APPLY_Y_PREDICTOR(); | |
675 | ✗ | OUTPUT_PIXEL_PAIR(); | |
676 | } else { | ||
677 |
11/16✓ Branch 0 taken 83205 times.
✓ Branch 1 taken 93410 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 83205 times.
✓ Branch 5 taken 280 times.
✓ Branch 6 taken 82925 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 280 times.
✓ Branch 10 taken 188 times.
✓ Branch 11 taken 92 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 188 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 92 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 93410 times.
|
176615 | APPLY_C_PREDICTOR(); |
678 |
11/16✓ Branch 0 taken 79080 times.
✓ Branch 1 taken 97535 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 79080 times.
✓ Branch 5 taken 2902 times.
✓ Branch 6 taken 76178 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2902 times.
✓ Branch 10 taken 2346 times.
✓ Branch 11 taken 556 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2346 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 556 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 97535 times.
|
176615 | APPLY_Y_PREDICTOR(); |
679 | 176615 | OUTPUT_PIXEL_PAIR(); | |
680 |
11/16✓ Branch 0 taken 84071 times.
✓ Branch 1 taken 92544 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 84071 times.
✓ Branch 5 taken 2390 times.
✓ Branch 6 taken 81681 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2390 times.
✓ Branch 10 taken 1301 times.
✓ Branch 11 taken 1089 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1301 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 1089 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 92544 times.
|
176615 | APPLY_Y_PREDICTOR(); |
681 | 176615 | OUTPUT_PIXEL_PAIR(); | |
682 | } | ||
683 | 176615 | break; | |
684 | |||
685 | 353230 | case 1: | |
686 | case 3: | ||
687 | /* always apply 2 Y predictors on these iterations */ | ||
688 |
11/16✓ Branch 0 taken 163011 times.
✓ Branch 1 taken 190219 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 163011 times.
✓ Branch 5 taken 5105 times.
✓ Branch 6 taken 157906 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5105 times.
✓ Branch 10 taken 4503 times.
✓ Branch 11 taken 602 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4503 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 602 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 190219 times.
|
353230 | APPLY_Y_PREDICTOR(); |
689 | 353230 | OUTPUT_PIXEL_PAIR(); | |
690 |
11/16✓ Branch 0 taken 170406 times.
✓ Branch 1 taken 182824 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 170406 times.
✓ Branch 5 taken 5129 times.
✓ Branch 6 taken 165277 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 5129 times.
✓ Branch 10 taken 4175 times.
✓ Branch 11 taken 954 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 4175 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 954 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 182824 times.
|
353230 | APPLY_Y_PREDICTOR(); |
691 | 353230 | OUTPUT_PIXEL_PAIR(); | |
692 | 353230 | break; | |
693 | |||
694 | 176615 | case 2: | |
695 | /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y | ||
696 | * depending on the macroblock type */ | ||
697 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | if (s->block_type == BLOCK_2x2) { |
698 | ✗ | APPLY_C_PREDICTOR(); | |
699 | ✗ | APPLY_Y_PREDICTOR(); | |
700 | ✗ | OUTPUT_PIXEL_PAIR(); | |
701 | ✗ | APPLY_C_PREDICTOR(); | |
702 | ✗ | APPLY_Y_PREDICTOR(); | |
703 | ✗ | OUTPUT_PIXEL_PAIR(); | |
704 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | } else if (s->block_type == BLOCK_4x2) { |
705 | ✗ | APPLY_C_PREDICTOR(); | |
706 | ✗ | APPLY_Y_PREDICTOR(); | |
707 | ✗ | OUTPUT_PIXEL_PAIR(); | |
708 | ✗ | APPLY_Y_PREDICTOR(); | |
709 | ✗ | OUTPUT_PIXEL_PAIR(); | |
710 | } else { | ||
711 |
11/16✓ Branch 0 taken 88475 times.
✓ Branch 1 taken 88140 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 88475 times.
✓ Branch 5 taken 2598 times.
✓ Branch 6 taken 85877 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2598 times.
✓ Branch 10 taken 2210 times.
✓ Branch 11 taken 388 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2210 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 388 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 88140 times.
|
176615 | APPLY_Y_PREDICTOR(); |
712 | 176615 | OUTPUT_PIXEL_PAIR(); | |
713 |
11/16✓ Branch 0 taken 80543 times.
✓ Branch 1 taken 96072 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 80543 times.
✓ Branch 5 taken 2540 times.
✓ Branch 6 taken 78003 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 2540 times.
✓ Branch 10 taken 2090 times.
✓ Branch 11 taken 450 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 2090 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 450 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 96072 times.
|
176615 | APPLY_Y_PREDICTOR(); |
714 | 176615 | OUTPUT_PIXEL_PAIR(); | |
715 | } | ||
716 | 176615 | break; | |
717 | } | ||
718 | |||
719 | } else { | ||
720 | |||
721 | /* skip (copy) four pixels, but reassign the horizontal | ||
722 | * predictor */ | ||
723 | 597220 | *vert_pred++ = *current_pixel_pair++; | |
724 | 597220 | horiz_pred = *current_pixel_pair - *vert_pred; | |
725 | 597220 | *vert_pred++ = *current_pixel_pair++; | |
726 | |||
727 | } | ||
728 | |||
729 |
2/2✓ Branch 0 taken 1008000 times.
✓ Branch 1 taken 295680 times.
|
1303680 | if (!keyframe) { |
730 | 1008000 | mb_change_byte_mask <<= 1; | |
731 | |||
732 | /* next byte */ | ||
733 |
2/2✓ Branch 0 taken 126000 times.
✓ Branch 1 taken 882000 times.
|
1008000 | if (!mb_change_byte_mask) { |
734 | 126000 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
735 | 126000 | mb_change_byte_mask = 0x01; | |
736 | } | ||
737 | } | ||
738 | |||
739 | 1303680 | pixels_left -= 4; | |
740 | } | ||
741 | |||
742 | /* next change row */ | ||
743 |
2/2✓ Branch 0 taken 4074 times.
✓ Branch 1 taken 12222 times.
|
16296 | if (((y + 1) & 3) == 0) |
744 | 4074 | mb_change_bits += s->mb_change_bits_row_size; | |
745 | |||
746 | 16296 | current_line += s->frame->linesize[0]; | |
747 | } | ||
748 | } | ||
749 | |||
750 | 17 | static void truemotion1_decode_24bit(TrueMotion1Context *s) | |
751 | { | ||
752 | int y; | ||
753 | int pixels_left; /* remaining pixels on this line */ | ||
754 | unsigned int predictor_pair; | ||
755 | unsigned int horiz_pred; | ||
756 | unsigned int *vert_pred; | ||
757 | unsigned int *current_pixel_pair; | ||
758 | 17 | unsigned char *current_line = s->frame->data[0]; | |
759 | 17 | int keyframe = s->flags & FLAG_KEYFRAME; | |
760 | |||
761 | /* these variables are for managing the stream of macroblock change bits */ | ||
762 | 17 | const unsigned char *mb_change_bits = s->mb_change_bits; | |
763 | unsigned char mb_change_byte; | ||
764 | unsigned char mb_change_byte_mask; | ||
765 | int mb_change_index; | ||
766 | |||
767 | /* these variables are for managing the main index stream */ | ||
768 | 17 | int index_stream_index = 0; /* yes, the index into the index stream */ | |
769 | int index; | ||
770 | |||
771 | /* clean out the line buffer */ | ||
772 | 17 | memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); | |
773 | |||
774 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | GET_NEXT_INDEX(); |
775 | |||
776 |
2/2✓ Branch 0 taken 2691 times.
✓ Branch 1 taken 16 times.
|
2707 | for (y = 0; y < s->avctx->height; y++) { |
777 | |||
778 | /* re-init variables for the next line iteration */ | ||
779 | 2691 | horiz_pred = 0; | |
780 | 2691 | current_pixel_pair = (unsigned int *)current_line; | |
781 | 2691 | vert_pred = s->vert_pred; | |
782 | 2691 | mb_change_index = 0; | |
783 | 2691 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
784 | 2691 | mb_change_byte_mask = 0x01; | |
785 | 2691 | pixels_left = s->avctx->width; | |
786 | |||
787 |
2/2✓ Branch 0 taken 193705 times.
✓ Branch 1 taken 2690 times.
|
196395 | while (pixels_left > 0) { |
788 | |||
789 |
4/4✓ Branch 0 taken 159145 times.
✓ Branch 1 taken 34560 times.
✓ Branch 2 taken 119150 times.
✓ Branch 3 taken 39995 times.
|
193705 | if (keyframe || ((mb_change_byte & mb_change_byte_mask) == 0)) { |
790 | |||
791 |
3/4✓ Branch 0 taken 38453 times.
✓ Branch 1 taken 76846 times.
✓ Branch 2 taken 38411 times.
✗ Branch 3 not taken.
|
153710 | switch (y & 3) { |
792 | 38453 | case 0: | |
793 | /* if macroblock width is 2, apply C-Y-C-Y; else | ||
794 | * apply C-Y-Y */ | ||
795 |
1/2✓ Branch 0 taken 38453 times.
✗ Branch 1 not taken.
|
38453 | if (s->block_width == 2) { |
796 |
11/16✓ Branch 0 taken 22859 times.
✓ Branch 1 taken 15594 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22859 times.
✓ Branch 5 taken 1482 times.
✓ Branch 6 taken 21377 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1482 times.
✓ Branch 10 taken 1409 times.
✓ Branch 11 taken 73 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1409 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 73 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 15594 times.
|
38453 | APPLY_C_PREDICTOR_24(); |
797 |
11/16✓ Branch 0 taken 23487 times.
✓ Branch 1 taken 14966 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23487 times.
✓ Branch 5 taken 1054 times.
✓ Branch 6 taken 22433 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1054 times.
✓ Branch 10 taken 961 times.
✓ Branch 11 taken 93 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 961 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 93 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 14966 times.
|
38453 | APPLY_Y_PREDICTOR_24(); |
798 | 38453 | OUTPUT_PIXEL_PAIR(); | |
799 |
11/16✓ Branch 0 taken 23179 times.
✓ Branch 1 taken 15274 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23179 times.
✓ Branch 5 taken 1530 times.
✓ Branch 6 taken 21649 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1530 times.
✓ Branch 10 taken 1428 times.
✓ Branch 11 taken 102 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1428 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 102 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 15274 times.
|
38453 | APPLY_C_PREDICTOR_24(); |
800 |
11/16✓ Branch 0 taken 23588 times.
✓ Branch 1 taken 14865 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23588 times.
✓ Branch 5 taken 1031 times.
✓ Branch 6 taken 22557 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1031 times.
✓ Branch 10 taken 918 times.
✓ Branch 11 taken 113 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 918 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 113 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 14865 times.
|
38453 | APPLY_Y_PREDICTOR_24(); |
801 | 38453 | OUTPUT_PIXEL_PAIR(); | |
802 | } else { | ||
803 | ✗ | APPLY_C_PREDICTOR_24(); | |
804 | ✗ | APPLY_Y_PREDICTOR_24(); | |
805 | ✗ | OUTPUT_PIXEL_PAIR(); | |
806 | ✗ | APPLY_Y_PREDICTOR_24(); | |
807 | ✗ | OUTPUT_PIXEL_PAIR(); | |
808 | } | ||
809 | 38453 | break; | |
810 | |||
811 | 76846 | case 1: | |
812 | case 3: | ||
813 | /* always apply 2 Y predictors on these iterations */ | ||
814 |
11/16✓ Branch 0 taken 41862 times.
✓ Branch 1 taken 34984 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 41862 times.
✓ Branch 5 taken 1092 times.
✓ Branch 6 taken 40770 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1092 times.
✓ Branch 10 taken 993 times.
✓ Branch 11 taken 99 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 993 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 99 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 34984 times.
|
76846 | APPLY_Y_PREDICTOR_24(); |
815 | 76846 | OUTPUT_PIXEL_PAIR(); | |
816 |
11/16✓ Branch 0 taken 42048 times.
✓ Branch 1 taken 34798 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 42048 times.
✓ Branch 5 taken 1146 times.
✓ Branch 6 taken 40902 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1146 times.
✓ Branch 10 taken 981 times.
✓ Branch 11 taken 165 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 981 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 165 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 34798 times.
|
76846 | APPLY_Y_PREDICTOR_24(); |
817 | 76846 | OUTPUT_PIXEL_PAIR(); | |
818 | 76846 | break; | |
819 | |||
820 | 38411 | case 2: | |
821 | /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y | ||
822 | * depending on the macroblock type */ | ||
823 |
1/2✓ Branch 0 taken 38411 times.
✗ Branch 1 not taken.
|
38411 | if (s->block_type == BLOCK_2x2) { |
824 |
11/16✓ Branch 0 taken 22692 times.
✓ Branch 1 taken 15719 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 22692 times.
✓ Branch 5 taken 1459 times.
✓ Branch 6 taken 21233 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1459 times.
✓ Branch 10 taken 1366 times.
✓ Branch 11 taken 93 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1366 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 93 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 15719 times.
|
38411 | APPLY_C_PREDICTOR_24(); |
825 |
11/16✓ Branch 0 taken 23417 times.
✓ Branch 1 taken 14994 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23417 times.
✓ Branch 5 taken 1064 times.
✓ Branch 6 taken 22353 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1064 times.
✓ Branch 10 taken 956 times.
✓ Branch 11 taken 108 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 956 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 108 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 14994 times.
|
38411 | APPLY_Y_PREDICTOR_24(); |
826 | 38411 | OUTPUT_PIXEL_PAIR(); | |
827 |
11/16✓ Branch 0 taken 23253 times.
✓ Branch 1 taken 15158 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 23253 times.
✓ Branch 5 taken 1571 times.
✓ Branch 6 taken 21682 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1571 times.
✓ Branch 10 taken 1487 times.
✓ Branch 11 taken 84 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 1487 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 84 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 15158 times.
|
38411 | APPLY_C_PREDICTOR_24(); |
828 |
12/16✓ Branch 0 taken 23675 times.
✓ Branch 1 taken 14736 times.
✓ Branch 2 taken 1 times.
✓ Branch 3 taken 23674 times.
✓ Branch 5 taken 1117 times.
✓ Branch 6 taken 22557 times.
✗ Branch 7 not taken.
✓ Branch 8 taken 1117 times.
✓ Branch 10 taken 951 times.
✓ Branch 11 taken 166 times.
✗ Branch 12 not taken.
✓ Branch 13 taken 951 times.
✗ Branch 15 not taken.
✓ Branch 16 taken 166 times.
✗ Branch 18 not taken.
✓ Branch 19 taken 14736 times.
|
38411 | APPLY_Y_PREDICTOR_24(); |
829 | 38410 | OUTPUT_PIXEL_PAIR(); | |
830 | ✗ | } else if (s->block_type == BLOCK_4x2) { | |
831 | ✗ | APPLY_C_PREDICTOR_24(); | |
832 | ✗ | APPLY_Y_PREDICTOR_24(); | |
833 | ✗ | OUTPUT_PIXEL_PAIR(); | |
834 | ✗ | APPLY_Y_PREDICTOR_24(); | |
835 | ✗ | OUTPUT_PIXEL_PAIR(); | |
836 | } else { | ||
837 | ✗ | APPLY_Y_PREDICTOR_24(); | |
838 | ✗ | OUTPUT_PIXEL_PAIR(); | |
839 | ✗ | APPLY_Y_PREDICTOR_24(); | |
840 | ✗ | OUTPUT_PIXEL_PAIR(); | |
841 | } | ||
842 | 38410 | break; | |
843 | } | ||
844 | |||
845 | } else { | ||
846 | |||
847 | /* skip (copy) four pixels, but reassign the horizontal | ||
848 | * predictor */ | ||
849 | 39995 | *vert_pred++ = *current_pixel_pair++; | |
850 | 39995 | horiz_pred = *current_pixel_pair - *vert_pred; | |
851 | 39995 | *vert_pred++ = *current_pixel_pair++; | |
852 | |||
853 | } | ||
854 | |||
855 |
2/2✓ Branch 0 taken 159144 times.
✓ Branch 1 taken 34560 times.
|
193704 | if (!keyframe) { |
856 | 159144 | mb_change_byte_mask <<= 1; | |
857 | |||
858 | /* next byte */ | ||
859 |
2/2✓ Branch 0 taken 19893 times.
✓ Branch 1 taken 139251 times.
|
159144 | if (!mb_change_byte_mask) { |
860 | 19893 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
861 | 19893 | mb_change_byte_mask = 0x01; | |
862 | } | ||
863 | } | ||
864 | |||
865 | 193704 | pixels_left -= 2; | |
866 | } | ||
867 | |||
868 | /* next change row */ | ||
869 |
2/2✓ Branch 0 taken 672 times.
✓ Branch 1 taken 2018 times.
|
2690 | if (((y + 1) & 3) == 0) |
870 | 672 | mb_change_bits += s->mb_change_bits_row_size; | |
871 | |||
872 | 2690 | current_line += s->frame->linesize[0]; | |
873 | } | ||
874 | } | ||
875 | |||
876 | |||
877 | 123 | static int truemotion1_decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
878 | int *got_frame, AVPacket *avpkt) | ||
879 | { | ||
880 | 123 | const uint8_t *buf = avpkt->data; | |
881 | 123 | int ret, buf_size = avpkt->size; | |
882 | 123 | TrueMotion1Context *s = avctx->priv_data; | |
883 | |||
884 | 123 | s->buf = buf; | |
885 | 123 | s->size = buf_size; | |
886 | |||
887 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = truemotion1_decode_header(s)) < 0) |
888 | ✗ | return ret; | |
889 | |||
890 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0) |
891 | ✗ | return ret; | |
892 | |||
893 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 106 times.
|
123 | if (compression_types[s->compression].algorithm == ALGO_RGB24H) { |
894 | 17 | truemotion1_decode_24bit(s); | |
895 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 9 times.
|
106 | } else if (compression_types[s->compression].algorithm != ALGO_NOP) { |
896 | 97 | truemotion1_decode_16bit(s); | |
897 | } | ||
898 | |||
899 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = av_frame_ref(rframe, s->frame)) < 0) |
900 | ✗ | return ret; | |
901 | |||
902 | 123 | *got_frame = 1; | |
903 | |||
904 | /* report that the buffer was completely consumed */ | ||
905 | 123 | return buf_size; | |
906 | } | ||
907 | |||
908 | 4 | static av_cold int truemotion1_decode_end(AVCodecContext *avctx) | |
909 | { | ||
910 | 4 | TrueMotion1Context *s = avctx->priv_data; | |
911 | |||
912 | 4 | av_frame_free(&s->frame); | |
913 | 4 | av_freep(&s->vert_pred); | |
914 | |||
915 | 4 | return 0; | |
916 | } | ||
917 | |||
918 | const FFCodec ff_truemotion1_decoder = { | ||
919 | .p.name = "truemotion1", | ||
920 | CODEC_LONG_NAME("Duck TrueMotion 1.0"), | ||
921 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
922 | .p.id = AV_CODEC_ID_TRUEMOTION1, | ||
923 | .priv_data_size = sizeof(TrueMotion1Context), | ||
924 | .init = truemotion1_decode_init, | ||
925 | .close = truemotion1_decode_end, | ||
926 | FF_CODEC_DECODE_CB(truemotion1_decode_frame), | ||
927 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
928 | .caps_internal = FF_CODEC_CAP_INIT_CLEANUP, | ||
929 | }; | ||
930 |