Directory: | ../../../ffmpeg/ |
---|---|
File: | src/libavcodec/truemotion1.c |
Date: | 2022-07-07 01:21:54 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 263 | 353 | 74.5% |
Branches: | 290 | 734 | 39.5% |
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 "internal.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 |
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 || |
412 |
2/2✓ Branch 0 taken 1 times.
✓ Branch 1 taken 121 times.
|
122 | new_pix_fmt != s->avctx->pix_fmt) { |
413 | 2 | av_frame_unref(s->frame); | |
414 | 2 | s->avctx->sample_aspect_ratio = (AVRational){ 1 << width_shift, 1 }; | |
415 | 2 | s->avctx->pix_fmt = new_pix_fmt; | |
416 | |||
417 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 2 times.
|
2 | if ((ret = ff_set_dimensions(s->avctx, s->w, s->h)) < 0) |
418 | ✗ | return ret; | |
419 | |||
420 | 2 | ff_set_sar(s->avctx, s->avctx->sample_aspect_ratio); | |
421 | |||
422 | 2 | av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); | |
423 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 2 times.
|
2 | if (!s->vert_pred) |
424 | ✗ | return AVERROR(ENOMEM); | |
425 | } | ||
426 | |||
427 | /* There is 1 change bit per 4 pixels, so each change byte represents | ||
428 | * 32 pixels; divide width by 4 to obtain the number of change bits and | ||
429 | * then round up to the nearest byte. */ | ||
430 | 123 | s->mb_change_bits_row_size = ((s->avctx->width >> (2 - width_shift)) + 7) >> 3; | |
431 | |||
432 |
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)) |
433 | { | ||
434 |
2/2✓ Branch 0 taken 2 times.
✓ Branch 1 taken 2 times.
|
4 | if (compression_types[header.compression].algorithm == ALGO_RGB24H) |
435 | 2 | gen_vector_table24(s, sel_vector_table); | |
436 | else | ||
437 |
1/2✓ Branch 0 taken 2 times.
✗ Branch 1 not taken.
|
2 | if (s->avctx->pix_fmt == AV_PIX_FMT_RGB555) |
438 | 2 | gen_vector_table15(s, sel_vector_table); | |
439 | else | ||
440 | ✗ | gen_vector_table16(s, sel_vector_table); | |
441 | } | ||
442 | |||
443 | /* set up pointers to the other key data chunks */ | ||
444 | 123 | s->mb_change_bits = s->buf + header.header_size; | |
445 |
2/2✓ Branch 0 taken 25 times.
✓ Branch 1 taken 98 times.
|
123 | if (s->flags & FLAG_KEYFRAME) { |
446 | /* no change bits specified for a keyframe; only index bytes */ | ||
447 | 25 | s->index_stream = s->mb_change_bits; | |
448 |
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) |
449 | ✗ | return AVERROR_INVALIDDATA; | |
450 | } else { | ||
451 | /* one change bit per 4x4 block */ | ||
452 | 98 | s->index_stream = s->mb_change_bits + | |
453 | 98 | (s->mb_change_bits_row_size * (s->avctx->height >> 2)); | |
454 | } | ||
455 | 123 | s->index_stream_size = s->size - (s->index_stream - s->buf); | |
456 | |||
457 | 123 | s->last_deltaset = header.deltaset; | |
458 | 123 | s->last_vectable = header.vectable; | |
459 | 123 | s->compression = header.compression; | |
460 | 123 | s->block_width = compression_types[header.compression].block_width; | |
461 | 123 | s->block_height = compression_types[header.compression].block_height; | |
462 | 123 | s->block_type = compression_types[header.compression].block_type; | |
463 | |||
464 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 123 times.
|
123 | if (s->avctx->debug & FF_DEBUG_PICT_INFO) |
465 | ✗ | av_log(s->avctx, AV_LOG_INFO, "tables: %d / %d c:%d %dx%d t:%d %s%s%s%s\n", | |
466 | s->last_deltaset, s->last_vectable, s->compression, s->block_width, | ||
467 | s->block_height, s->block_type, | ||
468 | ✗ | s->flags & FLAG_KEYFRAME ? " KEY" : "", | |
469 | ✗ | s->flags & FLAG_INTERFRAME ? " INTER" : "", | |
470 | ✗ | s->flags & FLAG_SPRITE ? " SPRITE" : "", | |
471 | ✗ | s->flags & FLAG_INTERPOLATED ? " INTERPOL" : ""); | |
472 | |||
473 | 123 | return header.header_size; | |
474 | } | ||
475 | |||
476 | 4 | static av_cold int truemotion1_decode_init(AVCodecContext *avctx) | |
477 | { | ||
478 | 4 | TrueMotion1Context *s = avctx->priv_data; | |
479 | |||
480 | 4 | s->avctx = avctx; | |
481 | |||
482 | // FIXME: it may change ? | ||
483 | // if (avctx->bits_per_sample == 24) | ||
484 | // avctx->pix_fmt = AV_PIX_FMT_RGB24; | ||
485 | // else | ||
486 | // avctx->pix_fmt = AV_PIX_FMT_RGB555; | ||
487 | |||
488 | 4 | s->frame = av_frame_alloc(); | |
489 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!s->frame) |
490 | ✗ | return AVERROR(ENOMEM); | |
491 | |||
492 | /* there is a vertical predictor for each pixel in a line; each vertical | ||
493 | * predictor is 0 to start with */ | ||
494 | 4 | av_fast_malloc(&s->vert_pred, &s->vert_pred_size, s->avctx->width * sizeof(unsigned int)); | |
495 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4 times.
|
4 | if (!s->vert_pred) |
496 | ✗ | return AVERROR(ENOMEM); | |
497 | |||
498 | 4 | return 0; | |
499 | } | ||
500 | |||
501 | /* | ||
502 | Block decoding order: | ||
503 | |||
504 | dxi: Y-Y | ||
505 | dxic: Y-C-Y | ||
506 | dxic2: Y-C-Y-C | ||
507 | |||
508 | hres,vres,i,i%vres (0 < i < 4) | ||
509 | 2x2 0: 0 dxic2 | ||
510 | 2x2 1: 1 dxi | ||
511 | 2x2 2: 0 dxic2 | ||
512 | 2x2 3: 1 dxi | ||
513 | 2x4 0: 0 dxic2 | ||
514 | 2x4 1: 1 dxi | ||
515 | 2x4 2: 2 dxi | ||
516 | 2x4 3: 3 dxi | ||
517 | 4x2 0: 0 dxic | ||
518 | 4x2 1: 1 dxi | ||
519 | 4x2 2: 0 dxic | ||
520 | 4x2 3: 1 dxi | ||
521 | 4x4 0: 0 dxic | ||
522 | 4x4 1: 1 dxi | ||
523 | 4x4 2: 2 dxi | ||
524 | 4x4 3: 3 dxi | ||
525 | */ | ||
526 | |||
527 | #define GET_NEXT_INDEX() \ | ||
528 | {\ | ||
529 | if (index_stream_index >= s->index_stream_size) { \ | ||
530 | av_log(s->avctx, AV_LOG_INFO, " help! truemotion1 decoder went out of bounds\n"); \ | ||
531 | return; \ | ||
532 | } \ | ||
533 | index = s->index_stream[index_stream_index++] * 4; \ | ||
534 | } | ||
535 | |||
536 | #define INC_INDEX \ | ||
537 | do { \ | ||
538 | if (index >= 1023) { \ | ||
539 | av_log(s->avctx, AV_LOG_ERROR, "Invalid index value.\n"); \ | ||
540 | return; \ | ||
541 | } \ | ||
542 | index++; \ | ||
543 | } while (0) | ||
544 | |||
545 | #define APPLY_C_PREDICTOR() \ | ||
546 | predictor_pair = s->c_predictor_table[index]; \ | ||
547 | horiz_pred += (predictor_pair >> 1); \ | ||
548 | if (predictor_pair & 1) { \ | ||
549 | GET_NEXT_INDEX() \ | ||
550 | if (!index) { \ | ||
551 | GET_NEXT_INDEX() \ | ||
552 | predictor_pair = s->c_predictor_table[index]; \ | ||
553 | horiz_pred += ((predictor_pair >> 1) * 5); \ | ||
554 | if (predictor_pair & 1) \ | ||
555 | GET_NEXT_INDEX() \ | ||
556 | else \ | ||
557 | INC_INDEX; \ | ||
558 | } \ | ||
559 | } else \ | ||
560 | INC_INDEX; | ||
561 | |||
562 | #define APPLY_C_PREDICTOR_24() \ | ||
563 | predictor_pair = s->c_predictor_table[index]; \ | ||
564 | horiz_pred += (predictor_pair >> 1); \ | ||
565 | if (predictor_pair & 1) { \ | ||
566 | GET_NEXT_INDEX() \ | ||
567 | if (!index) { \ | ||
568 | GET_NEXT_INDEX() \ | ||
569 | predictor_pair = s->fat_c_predictor_table[index]; \ | ||
570 | horiz_pred += (predictor_pair >> 1); \ | ||
571 | if (predictor_pair & 1) \ | ||
572 | GET_NEXT_INDEX() \ | ||
573 | else \ | ||
574 | INC_INDEX; \ | ||
575 | } \ | ||
576 | } else \ | ||
577 | INC_INDEX; | ||
578 | |||
579 | |||
580 | #define APPLY_Y_PREDICTOR() \ | ||
581 | predictor_pair = s->y_predictor_table[index]; \ | ||
582 | horiz_pred += (predictor_pair >> 1); \ | ||
583 | if (predictor_pair & 1) { \ | ||
584 | GET_NEXT_INDEX() \ | ||
585 | if (!index) { \ | ||
586 | GET_NEXT_INDEX() \ | ||
587 | predictor_pair = s->y_predictor_table[index]; \ | ||
588 | horiz_pred += ((predictor_pair >> 1) * 5); \ | ||
589 | if (predictor_pair & 1) \ | ||
590 | GET_NEXT_INDEX() \ | ||
591 | else \ | ||
592 | INC_INDEX; \ | ||
593 | } \ | ||
594 | } else \ | ||
595 | INC_INDEX; | ||
596 | |||
597 | #define APPLY_Y_PREDICTOR_24() \ | ||
598 | predictor_pair = s->y_predictor_table[index]; \ | ||
599 | horiz_pred += (predictor_pair >> 1); \ | ||
600 | if (predictor_pair & 1) { \ | ||
601 | GET_NEXT_INDEX() \ | ||
602 | if (!index) { \ | ||
603 | GET_NEXT_INDEX() \ | ||
604 | predictor_pair = s->fat_y_predictor_table[index]; \ | ||
605 | horiz_pred += (predictor_pair >> 1); \ | ||
606 | if (predictor_pair & 1) \ | ||
607 | GET_NEXT_INDEX() \ | ||
608 | else \ | ||
609 | INC_INDEX; \ | ||
610 | } \ | ||
611 | } else \ | ||
612 | INC_INDEX; | ||
613 | |||
614 | #define OUTPUT_PIXEL_PAIR() \ | ||
615 | *current_pixel_pair = *vert_pred + horiz_pred; \ | ||
616 | *vert_pred++ = *current_pixel_pair++; | ||
617 | |||
618 | 97 | static void truemotion1_decode_16bit(TrueMotion1Context *s) | |
619 | { | ||
620 | int y; | ||
621 | int pixels_left; /* remaining pixels on this line */ | ||
622 | unsigned int predictor_pair; | ||
623 | unsigned int horiz_pred; | ||
624 | unsigned int *vert_pred; | ||
625 | unsigned int *current_pixel_pair; | ||
626 | 97 | unsigned char *current_line = s->frame->data[0]; | |
627 | 97 | int keyframe = s->flags & FLAG_KEYFRAME; | |
628 | |||
629 | /* these variables are for managing the stream of macroblock change bits */ | ||
630 | 97 | const unsigned char *mb_change_bits = s->mb_change_bits; | |
631 | unsigned char mb_change_byte; | ||
632 | unsigned char mb_change_byte_mask; | ||
633 | int mb_change_index; | ||
634 | |||
635 | /* these variables are for managing the main index stream */ | ||
636 | 97 | int index_stream_index = 0; /* yes, the index into the index stream */ | |
637 | int index; | ||
638 | |||
639 | /* clean out the line buffer */ | ||
640 | 97 | memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); | |
641 | |||
642 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 97 times.
|
97 | GET_NEXT_INDEX(); |
643 | |||
644 |
2/2✓ Branch 0 taken 16296 times.
✓ Branch 1 taken 97 times.
|
16393 | for (y = 0; y < s->avctx->height; y++) { |
645 | |||
646 | /* re-init variables for the next line iteration */ | ||
647 | 16296 | horiz_pred = 0; | |
648 | 16296 | current_pixel_pair = (unsigned int *)current_line; | |
649 | 16296 | vert_pred = s->vert_pred; | |
650 | 16296 | mb_change_index = 0; | |
651 |
2/2✓ Branch 0 taken 12600 times.
✓ Branch 1 taken 3696 times.
|
16296 | if (!keyframe) |
652 | 12600 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
653 | 16296 | mb_change_byte_mask = 0x01; | |
654 | 16296 | pixels_left = s->avctx->width; | |
655 | |||
656 |
2/2✓ Branch 0 taken 1303680 times.
✓ Branch 1 taken 16296 times.
|
1319976 | while (pixels_left > 0) { |
657 | |||
658 |
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)) { |
659 | |||
660 |
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) { |
661 | 176615 | case 0: | |
662 | /* if macroblock width is 2, apply C-Y-C-Y; else | ||
663 | * apply C-Y-Y */ | ||
664 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | if (s->block_width == 2) { |
665 | ✗ | APPLY_C_PREDICTOR(); | |
666 | ✗ | APPLY_Y_PREDICTOR(); | |
667 | ✗ | OUTPUT_PIXEL_PAIR(); | |
668 | ✗ | APPLY_C_PREDICTOR(); | |
669 | ✗ | APPLY_Y_PREDICTOR(); | |
670 | ✗ | OUTPUT_PIXEL_PAIR(); | |
671 | } else { | ||
672 |
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(); |
673 |
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(); |
674 | 176615 | OUTPUT_PIXEL_PAIR(); | |
675 |
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(); |
676 | 176615 | OUTPUT_PIXEL_PAIR(); | |
677 | } | ||
678 | 176615 | break; | |
679 | |||
680 | 353230 | case 1: | |
681 | case 3: | ||
682 | /* always apply 2 Y predictors on these iterations */ | ||
683 |
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(); |
684 | 353230 | OUTPUT_PIXEL_PAIR(); | |
685 |
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(); |
686 | 353230 | OUTPUT_PIXEL_PAIR(); | |
687 | 353230 | break; | |
688 | |||
689 | 176615 | case 2: | |
690 | /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y | ||
691 | * depending on the macroblock type */ | ||
692 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | if (s->block_type == BLOCK_2x2) { |
693 | ✗ | APPLY_C_PREDICTOR(); | |
694 | ✗ | APPLY_Y_PREDICTOR(); | |
695 | ✗ | OUTPUT_PIXEL_PAIR(); | |
696 | ✗ | APPLY_C_PREDICTOR(); | |
697 | ✗ | APPLY_Y_PREDICTOR(); | |
698 | ✗ | OUTPUT_PIXEL_PAIR(); | |
699 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 176615 times.
|
176615 | } else if (s->block_type == BLOCK_4x2) { |
700 | ✗ | APPLY_C_PREDICTOR(); | |
701 | ✗ | APPLY_Y_PREDICTOR(); | |
702 | ✗ | OUTPUT_PIXEL_PAIR(); | |
703 | ✗ | APPLY_Y_PREDICTOR(); | |
704 | ✗ | OUTPUT_PIXEL_PAIR(); | |
705 | } else { | ||
706 |
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(); |
707 | 176615 | OUTPUT_PIXEL_PAIR(); | |
708 |
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(); |
709 | 176615 | OUTPUT_PIXEL_PAIR(); | |
710 | } | ||
711 | 176615 | break; | |
712 | } | ||
713 | |||
714 | } else { | ||
715 | |||
716 | /* skip (copy) four pixels, but reassign the horizontal | ||
717 | * predictor */ | ||
718 | 597220 | *vert_pred++ = *current_pixel_pair++; | |
719 | 597220 | horiz_pred = *current_pixel_pair - *vert_pred; | |
720 | 597220 | *vert_pred++ = *current_pixel_pair++; | |
721 | |||
722 | } | ||
723 | |||
724 |
2/2✓ Branch 0 taken 1008000 times.
✓ Branch 1 taken 295680 times.
|
1303680 | if (!keyframe) { |
725 | 1008000 | mb_change_byte_mask <<= 1; | |
726 | |||
727 | /* next byte */ | ||
728 |
2/2✓ Branch 0 taken 126000 times.
✓ Branch 1 taken 882000 times.
|
1008000 | if (!mb_change_byte_mask) { |
729 | 126000 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
730 | 126000 | mb_change_byte_mask = 0x01; | |
731 | } | ||
732 | } | ||
733 | |||
734 | 1303680 | pixels_left -= 4; | |
735 | } | ||
736 | |||
737 | /* next change row */ | ||
738 |
2/2✓ Branch 0 taken 4074 times.
✓ Branch 1 taken 12222 times.
|
16296 | if (((y + 1) & 3) == 0) |
739 | 4074 | mb_change_bits += s->mb_change_bits_row_size; | |
740 | |||
741 | 16296 | current_line += s->frame->linesize[0]; | |
742 | } | ||
743 | } | ||
744 | |||
745 | 17 | static void truemotion1_decode_24bit(TrueMotion1Context *s) | |
746 | { | ||
747 | int y; | ||
748 | int pixels_left; /* remaining pixels on this line */ | ||
749 | unsigned int predictor_pair; | ||
750 | unsigned int horiz_pred; | ||
751 | unsigned int *vert_pred; | ||
752 | unsigned int *current_pixel_pair; | ||
753 | 17 | unsigned char *current_line = s->frame->data[0]; | |
754 | 17 | int keyframe = s->flags & FLAG_KEYFRAME; | |
755 | |||
756 | /* these variables are for managing the stream of macroblock change bits */ | ||
757 | 17 | const unsigned char *mb_change_bits = s->mb_change_bits; | |
758 | unsigned char mb_change_byte; | ||
759 | unsigned char mb_change_byte_mask; | ||
760 | int mb_change_index; | ||
761 | |||
762 | /* these variables are for managing the main index stream */ | ||
763 | 17 | int index_stream_index = 0; /* yes, the index into the index stream */ | |
764 | int index; | ||
765 | |||
766 | /* clean out the line buffer */ | ||
767 | 17 | memset(s->vert_pred, 0, s->avctx->width * sizeof(unsigned int)); | |
768 | |||
769 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | GET_NEXT_INDEX(); |
770 | |||
771 |
2/2✓ Branch 0 taken 2691 times.
✓ Branch 1 taken 16 times.
|
2707 | for (y = 0; y < s->avctx->height; y++) { |
772 | |||
773 | /* re-init variables for the next line iteration */ | ||
774 | 2691 | horiz_pred = 0; | |
775 | 2691 | current_pixel_pair = (unsigned int *)current_line; | |
776 | 2691 | vert_pred = s->vert_pred; | |
777 | 2691 | mb_change_index = 0; | |
778 | 2691 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
779 | 2691 | mb_change_byte_mask = 0x01; | |
780 | 2691 | pixels_left = s->avctx->width; | |
781 | |||
782 |
2/2✓ Branch 0 taken 193705 times.
✓ Branch 1 taken 2690 times.
|
196395 | while (pixels_left > 0) { |
783 | |||
784 |
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)) { |
785 | |||
786 |
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) { |
787 | 38453 | case 0: | |
788 | /* if macroblock width is 2, apply C-Y-C-Y; else | ||
789 | * apply C-Y-Y */ | ||
790 |
1/2✓ Branch 0 taken 38453 times.
✗ Branch 1 not taken.
|
38453 | if (s->block_width == 2) { |
791 |
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(); |
792 |
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(); |
793 | 38453 | OUTPUT_PIXEL_PAIR(); | |
794 |
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(); |
795 |
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(); |
796 | 38453 | OUTPUT_PIXEL_PAIR(); | |
797 | } else { | ||
798 | ✗ | APPLY_C_PREDICTOR_24(); | |
799 | ✗ | APPLY_Y_PREDICTOR_24(); | |
800 | ✗ | OUTPUT_PIXEL_PAIR(); | |
801 | ✗ | APPLY_Y_PREDICTOR_24(); | |
802 | ✗ | OUTPUT_PIXEL_PAIR(); | |
803 | } | ||
804 | 38453 | break; | |
805 | |||
806 | 76846 | case 1: | |
807 | case 3: | ||
808 | /* always apply 2 Y predictors on these iterations */ | ||
809 |
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(); |
810 | 76846 | OUTPUT_PIXEL_PAIR(); | |
811 |
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(); |
812 | 76846 | OUTPUT_PIXEL_PAIR(); | |
813 | 76846 | break; | |
814 | |||
815 | 38411 | case 2: | |
816 | /* this iteration might be C-Y-C-Y, Y-Y, or C-Y-Y | ||
817 | * depending on the macroblock type */ | ||
818 |
1/2✓ Branch 0 taken 38411 times.
✗ Branch 1 not taken.
|
38411 | if (s->block_type == BLOCK_2x2) { |
819 |
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(); |
820 |
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(); |
821 | 38411 | OUTPUT_PIXEL_PAIR(); | |
822 |
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(); |
823 |
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(); |
824 | 38410 | OUTPUT_PIXEL_PAIR(); | |
825 | ✗ | } else if (s->block_type == BLOCK_4x2) { | |
826 | ✗ | APPLY_C_PREDICTOR_24(); | |
827 | ✗ | APPLY_Y_PREDICTOR_24(); | |
828 | ✗ | OUTPUT_PIXEL_PAIR(); | |
829 | ✗ | APPLY_Y_PREDICTOR_24(); | |
830 | ✗ | OUTPUT_PIXEL_PAIR(); | |
831 | } else { | ||
832 | ✗ | APPLY_Y_PREDICTOR_24(); | |
833 | ✗ | OUTPUT_PIXEL_PAIR(); | |
834 | ✗ | APPLY_Y_PREDICTOR_24(); | |
835 | ✗ | OUTPUT_PIXEL_PAIR(); | |
836 | } | ||
837 | 38410 | break; | |
838 | } | ||
839 | |||
840 | } else { | ||
841 | |||
842 | /* skip (copy) four pixels, but reassign the horizontal | ||
843 | * predictor */ | ||
844 | 39995 | *vert_pred++ = *current_pixel_pair++; | |
845 | 39995 | horiz_pred = *current_pixel_pair - *vert_pred; | |
846 | 39995 | *vert_pred++ = *current_pixel_pair++; | |
847 | |||
848 | } | ||
849 | |||
850 |
2/2✓ Branch 0 taken 159144 times.
✓ Branch 1 taken 34560 times.
|
193704 | if (!keyframe) { |
851 | 159144 | mb_change_byte_mask <<= 1; | |
852 | |||
853 | /* next byte */ | ||
854 |
2/2✓ Branch 0 taken 19893 times.
✓ Branch 1 taken 139251 times.
|
159144 | if (!mb_change_byte_mask) { |
855 | 19893 | mb_change_byte = mb_change_bits[mb_change_index++]; | |
856 | 19893 | mb_change_byte_mask = 0x01; | |
857 | } | ||
858 | } | ||
859 | |||
860 | 193704 | pixels_left -= 2; | |
861 | } | ||
862 | |||
863 | /* next change row */ | ||
864 |
2/2✓ Branch 0 taken 672 times.
✓ Branch 1 taken 2018 times.
|
2690 | if (((y + 1) & 3) == 0) |
865 | 672 | mb_change_bits += s->mb_change_bits_row_size; | |
866 | |||
867 | 2690 | current_line += s->frame->linesize[0]; | |
868 | } | ||
869 | } | ||
870 | |||
871 | |||
872 | 123 | static int truemotion1_decode_frame(AVCodecContext *avctx, AVFrame *rframe, | |
873 | int *got_frame, AVPacket *avpkt) | ||
874 | { | ||
875 | 123 | const uint8_t *buf = avpkt->data; | |
876 | 123 | int ret, buf_size = avpkt->size; | |
877 | 123 | TrueMotion1Context *s = avctx->priv_data; | |
878 | |||
879 | 123 | s->buf = buf; | |
880 | 123 | s->size = buf_size; | |
881 | |||
882 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = truemotion1_decode_header(s)) < 0) |
883 | ✗ | return ret; | |
884 | |||
885 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = ff_reget_buffer(avctx, s->frame, 0)) < 0) |
886 | ✗ | return ret; | |
887 | |||
888 |
2/2✓ Branch 0 taken 17 times.
✓ Branch 1 taken 106 times.
|
123 | if (compression_types[s->compression].algorithm == ALGO_RGB24H) { |
889 | 17 | truemotion1_decode_24bit(s); | |
890 |
2/2✓ Branch 0 taken 97 times.
✓ Branch 1 taken 9 times.
|
106 | } else if (compression_types[s->compression].algorithm != ALGO_NOP) { |
891 | 97 | truemotion1_decode_16bit(s); | |
892 | } | ||
893 | |||
894 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 123 times.
|
123 | if ((ret = av_frame_ref(rframe, s->frame)) < 0) |
895 | ✗ | return ret; | |
896 | |||
897 | 123 | *got_frame = 1; | |
898 | |||
899 | /* report that the buffer was completely consumed */ | ||
900 | 123 | return buf_size; | |
901 | } | ||
902 | |||
903 | 4 | static av_cold int truemotion1_decode_end(AVCodecContext *avctx) | |
904 | { | ||
905 | 4 | TrueMotion1Context *s = avctx->priv_data; | |
906 | |||
907 | 4 | av_frame_free(&s->frame); | |
908 | 4 | av_freep(&s->vert_pred); | |
909 | |||
910 | 4 | return 0; | |
911 | } | ||
912 | |||
913 | const FFCodec ff_truemotion1_decoder = { | ||
914 | .p.name = "truemotion1", | ||
915 | .p.long_name = NULL_IF_CONFIG_SMALL("Duck TrueMotion 1.0"), | ||
916 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
917 | .p.id = AV_CODEC_ID_TRUEMOTION1, | ||
918 | .priv_data_size = sizeof(TrueMotion1Context), | ||
919 | .init = truemotion1_decode_init, | ||
920 | .close = truemotion1_decode_end, | ||
921 | FF_CODEC_DECODE_CB(truemotion1_decode_frame), | ||
922 | .p.capabilities = AV_CODEC_CAP_DR1, | ||
923 | .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, | ||
924 | }; | ||
925 |