Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * Canopus Lossless Codec decoder | ||
3 | * | ||
4 | * Copyright (c) 2012-2013 Derek Buitenhuis | ||
5 | * | ||
6 | * This file is part of FFmpeg. | ||
7 | * | ||
8 | * FFmpeg is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU Lesser General Public | ||
10 | * License as published by the Free Software Foundation; either | ||
11 | * version 2.1 of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * FFmpeg is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
16 | * Lesser General Public License for more details. | ||
17 | * | ||
18 | * You should have received a copy of the GNU Lesser General Public | ||
19 | * License along with FFmpeg; if not, write to the Free Software | ||
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | ||
21 | */ | ||
22 | |||
23 | #include <inttypes.h> | ||
24 | |||
25 | #include "libavutil/intreadwrite.h" | ||
26 | #include "libavutil/mem.h" | ||
27 | #include "bswapdsp.h" | ||
28 | #include "canopus.h" | ||
29 | #include "get_bits.h" | ||
30 | #include "avcodec.h" | ||
31 | #include "codec_internal.h" | ||
32 | #include "thread.h" | ||
33 | |||
34 | #define VLC_BITS 7 | ||
35 | #define VLC_DEPTH 2 | ||
36 | |||
37 | |||
38 | typedef struct CLLCContext { | ||
39 | AVCodecContext *avctx; | ||
40 | BswapDSPContext bdsp; | ||
41 | |||
42 | uint8_t *swapped_buf; | ||
43 | int swapped_buf_size; | ||
44 | } CLLCContext; | ||
45 | |||
46 | 106 | static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc) | |
47 | { | ||
48 | uint8_t symbols[256]; | ||
49 | uint8_t bits[256]; | ||
50 | int num_lens, num_codes, num_codes_sum; | ||
51 | int i, j, count; | ||
52 | |||
53 | 106 | count = 0; | |
54 | 106 | num_codes_sum = 0; | |
55 | |||
56 | 106 | num_lens = get_bits(gb, 5); | |
57 | |||
58 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 106 times.
|
106 | if (num_lens > VLC_BITS * VLC_DEPTH) { |
59 | ✗ | av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens); | |
60 | ✗ | return AVERROR_INVALIDDATA; | |
61 | } | ||
62 | |||
63 |
2/2✓ Branch 0 taken 1439 times.
✓ Branch 1 taken 106 times.
|
1545 | for (i = 0; i < num_lens; i++) { |
64 | 1439 | num_codes = get_bits(gb, 9); | |
65 | 1439 | num_codes_sum += num_codes; | |
66 | |||
67 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 1439 times.
|
1439 | if (num_codes_sum > 256) { |
68 | ✗ | av_log(ctx->avctx, AV_LOG_ERROR, | |
69 | "Too many VLCs (%d) to be read.\n", num_codes_sum); | ||
70 | ✗ | return AVERROR_INVALIDDATA; | |
71 | } | ||
72 | |||
73 |
2/2✓ Branch 0 taken 26037 times.
✓ Branch 1 taken 1439 times.
|
27476 | for (j = 0; j < num_codes; j++) { |
74 | 26037 | symbols[count] = get_bits(gb, 8); | |
75 | 26037 | bits[count] = i + 1; | |
76 | |||
77 | 26037 | count++; | |
78 | } | ||
79 | } | ||
80 | |||
81 | 106 | return ff_vlc_init_from_lengths(vlc, VLC_BITS, count, bits, 1, | |
82 | 106 | symbols, 1, 1, 0, 0, ctx->avctx); | |
83 | } | ||
84 | |||
85 | /* | ||
86 | * Unlike the RGB24 read/restore, which reads in a component at a time, | ||
87 | * ARGB read/restore reads in ARGB quads. | ||
88 | */ | ||
89 | 4320 | static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, | |
90 | VLC *vlc, uint8_t *outbuf) | ||
91 | { | ||
92 | uint8_t *dst; | ||
93 | int pred[4]; | ||
94 | int code; | ||
95 | int i; | ||
96 | |||
97 | 4320 | OPEN_READER(bits, gb); | |
98 | |||
99 | 4320 | dst = outbuf; | |
100 | 4320 | pred[0] = top_left[0]; | |
101 | 4320 | pred[1] = top_left[1]; | |
102 | 4320 | pred[2] = top_left[2]; | |
103 | 4320 | pred[3] = top_left[3]; | |
104 | |||
105 |
2/2✓ Branch 0 taken 5529600 times.
✓ Branch 1 taken 4320 times.
|
5533920 | for (i = 0; i < ctx->avctx->width; i++) { |
106 | /* Always get the alpha component */ | ||
107 | 5529600 | UPDATE_CACHE(bits, gb); | |
108 |
2/2✓ Branch 1 taken 178978 times.
✓ Branch 2 taken 5350622 times.
|
5529600 | GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH); |
109 | |||
110 | 5529600 | pred[0] += code; | |
111 | 5529600 | dst[0] = pred[0]; | |
112 | |||
113 | /* Skip the components if they are entirely transparent */ | ||
114 |
2/2✓ Branch 0 taken 872412 times.
✓ Branch 1 taken 4657188 times.
|
5529600 | if (dst[0]) { |
115 | /* Red */ | ||
116 | 872412 | UPDATE_CACHE(bits, gb); | |
117 |
2/2✓ Branch 1 taken 139454 times.
✓ Branch 2 taken 732958 times.
|
872412 | GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH); |
118 | |||
119 | 872412 | pred[1] += code; | |
120 | 872412 | dst[1] = pred[1]; | |
121 | |||
122 | /* Green */ | ||
123 | 872412 | UPDATE_CACHE(bits, gb); | |
124 |
2/2✓ Branch 1 taken 138928 times.
✓ Branch 2 taken 733484 times.
|
872412 | GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH); |
125 | |||
126 | 872412 | pred[2] += code; | |
127 | 872412 | dst[2] = pred[2]; | |
128 | |||
129 | /* Blue */ | ||
130 | 872412 | UPDATE_CACHE(bits, gb); | |
131 |
2/2✓ Branch 1 taken 141112 times.
✓ Branch 2 taken 731300 times.
|
872412 | GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH); |
132 | |||
133 | 872412 | pred[3] += code; | |
134 | 872412 | dst[3] = pred[3]; | |
135 | } else { | ||
136 | 4657188 | dst[1] = 0; | |
137 | 4657188 | dst[2] = 0; | |
138 | 4657188 | dst[3] = 0; | |
139 | } | ||
140 | |||
141 | 5529600 | dst += 4; | |
142 | } | ||
143 | |||
144 | 4320 | CLOSE_READER(bits, gb); | |
145 | |||
146 | 4320 | top_left[0] = outbuf[0]; | |
147 | |||
148 | /* Only stash components if they are not transparent */ | ||
149 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 4320 times.
|
4320 | if (top_left[0]) { |
150 | ✗ | top_left[1] = outbuf[1]; | |
151 | ✗ | top_left[2] = outbuf[2]; | |
152 | ✗ | top_left[3] = outbuf[3]; | |
153 | } | ||
154 | |||
155 | 4320 | return 0; | |
156 | } | ||
157 | |||
158 | 23040 | static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, | |
159 | int *top_left, VLC *vlc, uint8_t *outbuf) | ||
160 | { | ||
161 | uint8_t *dst; | ||
162 | int pred, code; | ||
163 | int i; | ||
164 | |||
165 | 23040 | OPEN_READER(bits, gb); | |
166 | |||
167 | 23040 | dst = outbuf; | |
168 | 23040 | pred = *top_left; | |
169 | |||
170 | /* Simultaneously read and restore the line */ | ||
171 |
2/2✓ Branch 0 taken 14745600 times.
✓ Branch 1 taken 23040 times.
|
14768640 | for (i = 0; i < ctx->avctx->width; i++) { |
172 | 14745600 | UPDATE_CACHE(bits, gb); | |
173 |
2/2✓ Branch 1 taken 180368 times.
✓ Branch 2 taken 14565232 times.
|
14745600 | GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH); |
174 | |||
175 | 14745600 | pred += code; | |
176 | 14745600 | dst[0] = pred; | |
177 | 14745600 | dst += 3; | |
178 | } | ||
179 | |||
180 | 23040 | CLOSE_READER(bits, gb); | |
181 | |||
182 | /* Stash the first pixel */ | ||
183 | 23040 | *top_left = outbuf[0]; | |
184 | |||
185 | 23040 | return 0; | |
186 | } | ||
187 | |||
188 | 24480 | static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, | |
189 | int *top_left, VLC *vlc, uint8_t *outbuf, | ||
190 | int is_chroma) | ||
191 | { | ||
192 | int pred, code; | ||
193 | int i; | ||
194 | |||
195 | 24480 | OPEN_READER(bits, gb); | |
196 | |||
197 | 24480 | pred = *top_left; | |
198 | |||
199 | /* Simultaneously read and restore the line */ | ||
200 |
2/2✓ Branch 0 taken 10444800 times.
✓ Branch 1 taken 24480 times.
|
10469280 | for (i = 0; i < ctx->avctx->width >> is_chroma; i++) { |
201 | 10444800 | UPDATE_CACHE(bits, gb); | |
202 |
2/2✓ Branch 1 taken 702838 times.
✓ Branch 2 taken 9741962 times.
|
10444800 | GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH); |
203 | |||
204 | 10444800 | pred += code; | |
205 | 10444800 | outbuf[i] = pred; | |
206 | } | ||
207 | |||
208 | 24480 | CLOSE_READER(bits, gb); | |
209 | |||
210 | /* Stash the first pixel */ | ||
211 | 24480 | *top_left = outbuf[0]; | |
212 | |||
213 | 24480 | return 0; | |
214 | } | ||
215 | |||
216 | 6 | static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | |
217 | { | ||
218 | 6 | AVCodecContext *avctx = ctx->avctx; | |
219 | uint8_t *dst; | ||
220 | int pred[4]; | ||
221 | int ret; | ||
222 | int i, j; | ||
223 | VLC vlc[4]; | ||
224 | |||
225 | 6 | pred[0] = 0; | |
226 | 6 | pred[1] = 0x80; | |
227 | 6 | pred[2] = 0x80; | |
228 | 6 | pred[3] = 0x80; | |
229 | |||
230 | 6 | dst = pic->data[0]; | |
231 | |||
232 | 6 | skip_bits(gb, 16); | |
233 | |||
234 | /* Read in code table for each plane */ | ||
235 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
|
30 | for (i = 0; i < 4; i++) { |
236 | 24 | ret = read_code_table(ctx, gb, &vlc[i]); | |
237 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 24 times.
|
24 | if (ret < 0) { |
238 | ✗ | for (j = 0; j < i; j++) | |
239 | ✗ | ff_vlc_free(&vlc[j]); | |
240 | |||
241 | ✗ | av_log(ctx->avctx, AV_LOG_ERROR, | |
242 | "Could not read code table %d.\n", i); | ||
243 | ✗ | return ret; | |
244 | } | ||
245 | } | ||
246 | |||
247 | /* Read in and restore every line */ | ||
248 |
2/2✓ Branch 0 taken 4320 times.
✓ Branch 1 taken 6 times.
|
4326 | for (i = 0; i < avctx->height; i++) { |
249 | 4320 | read_argb_line(ctx, gb, pred, vlc, dst); | |
250 | |||
251 | 4320 | dst += pic->linesize[0]; | |
252 | } | ||
253 | |||
254 |
2/2✓ Branch 0 taken 24 times.
✓ Branch 1 taken 6 times.
|
30 | for (i = 0; i < 4; i++) |
255 | 24 | ff_vlc_free(&vlc[i]); | |
256 | |||
257 | 6 | return 0; | |
258 | } | ||
259 | |||
260 | 16 | static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | |
261 | { | ||
262 | 16 | AVCodecContext *avctx = ctx->avctx; | |
263 | uint8_t *dst; | ||
264 | int pred[3]; | ||
265 | int ret; | ||
266 | int i, j; | ||
267 | VLC vlc[3]; | ||
268 | |||
269 | 16 | pred[0] = 0x80; | |
270 | 16 | pred[1] = 0x80; | |
271 | 16 | pred[2] = 0x80; | |
272 | |||
273 | 16 | dst = pic->data[0]; | |
274 | |||
275 | 16 | skip_bits(gb, 16); | |
276 | |||
277 | /* Read in code table for each plane */ | ||
278 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
|
64 | for (i = 0; i < 3; i++) { |
279 | 48 | ret = read_code_table(ctx, gb, &vlc[i]); | |
280 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 48 times.
|
48 | if (ret < 0) { |
281 | ✗ | for (j = 0; j < i; j++) | |
282 | ✗ | ff_vlc_free(&vlc[j]); | |
283 | |||
284 | ✗ | av_log(ctx->avctx, AV_LOG_ERROR, | |
285 | "Could not read code table %d.\n", i); | ||
286 | ✗ | return ret; | |
287 | } | ||
288 | } | ||
289 | |||
290 | /* Read in and restore every line */ | ||
291 |
2/2✓ Branch 0 taken 7680 times.
✓ Branch 1 taken 16 times.
|
7696 | for (i = 0; i < avctx->height; i++) { |
292 |
2/2✓ Branch 0 taken 23040 times.
✓ Branch 1 taken 7680 times.
|
30720 | for (j = 0; j < 3; j++) |
293 | 23040 | read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]); | |
294 | |||
295 | 7680 | dst += pic->linesize[0]; | |
296 | } | ||
297 | |||
298 |
2/2✓ Branch 0 taken 48 times.
✓ Branch 1 taken 16 times.
|
64 | for (i = 0; i < 3; i++) |
299 | 48 | ff_vlc_free(&vlc[i]); | |
300 | |||
301 | 16 | return 0; | |
302 | } | ||
303 | |||
304 | 17 | static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic) | |
305 | { | ||
306 | 17 | AVCodecContext *avctx = ctx->avctx; | |
307 | uint8_t block; | ||
308 | uint8_t *dst[3]; | ||
309 | int pred[3]; | ||
310 | int ret; | ||
311 | int i, j; | ||
312 | VLC vlc[2]; | ||
313 | |||
314 | 17 | pred[0] = 0x80; | |
315 | 17 | pred[1] = 0x80; | |
316 | 17 | pred[2] = 0x80; | |
317 | |||
318 | 17 | dst[0] = pic->data[0]; | |
319 | 17 | dst[1] = pic->data[1]; | |
320 | 17 | dst[2] = pic->data[2]; | |
321 | |||
322 | 17 | skip_bits(gb, 8); | |
323 | |||
324 | 17 | block = get_bits(gb, 8); | |
325 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (block) { |
326 | ✗ | avpriv_request_sample(ctx->avctx, "Blocked YUV"); | |
327 | ✗ | return AVERROR_PATCHWELCOME; | |
328 | } | ||
329 | |||
330 | /* Read in code table for luma and chroma */ | ||
331 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 17 times.
|
51 | for (i = 0; i < 2; i++) { |
332 | 34 | ret = read_code_table(ctx, gb, &vlc[i]); | |
333 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 34 times.
|
34 | if (ret < 0) { |
334 | ✗ | for (j = 0; j < i; j++) | |
335 | ✗ | ff_vlc_free(&vlc[j]); | |
336 | |||
337 | ✗ | av_log(ctx->avctx, AV_LOG_ERROR, | |
338 | "Could not read code table %d.\n", i); | ||
339 | ✗ | return ret; | |
340 | } | ||
341 | } | ||
342 | |||
343 | /* Read in and restore every line */ | ||
344 |
2/2✓ Branch 0 taken 8160 times.
✓ Branch 1 taken 17 times.
|
8177 | for (i = 0; i < avctx->height; i++) { |
345 | 8160 | read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */ | |
346 | 8160 | read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */ | |
347 | 8160 | read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */ | |
348 | |||
349 |
2/2✓ Branch 0 taken 24480 times.
✓ Branch 1 taken 8160 times.
|
32640 | for (j = 0; j < 3; j++) |
350 | 24480 | dst[j] += pic->linesize[j]; | |
351 | } | ||
352 | |||
353 |
2/2✓ Branch 0 taken 34 times.
✓ Branch 1 taken 17 times.
|
51 | for (i = 0; i < 2; i++) |
354 | 34 | ff_vlc_free(&vlc[i]); | |
355 | |||
356 | 17 | return 0; | |
357 | } | ||
358 | |||
359 | 39 | static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic, | |
360 | int *got_picture_ptr, AVPacket *avpkt) | ||
361 | { | ||
362 | 39 | CLLCContext *ctx = avctx->priv_data; | |
363 | 39 | const uint8_t *src = avpkt->data; | |
364 | uint32_t info_tag, info_offset; | ||
365 | int data_size; | ||
366 | GetBitContext gb; | ||
367 | int coding_type, ret; | ||
368 | |||
369 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (avpkt->size < 4 + 4) { |
370 | ✗ | av_log(avctx, AV_LOG_ERROR, "Frame is too small %d.\n", avpkt->size); | |
371 | ✗ | return AVERROR_INVALIDDATA; | |
372 | } | ||
373 | |||
374 | 39 | info_offset = 0; | |
375 | 39 | info_tag = AV_RL32(src); | |
376 |
1/2✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
|
39 | if (info_tag == MKTAG('I', 'N', 'F', 'O')) { |
377 | 39 | info_offset = AV_RL32(src + 4); | |
378 |
2/4✓ Branch 0 taken 39 times.
✗ Branch 1 not taken.
✗ Branch 2 not taken.
✓ Branch 3 taken 39 times.
|
39 | if (info_offset > UINT32_MAX - 8 || info_offset + 8 > avpkt->size) { |
379 | ✗ | av_log(avctx, AV_LOG_ERROR, | |
380 | "Invalid INFO header offset: 0x%08"PRIX32" is too large.\n", | ||
381 | info_offset); | ||
382 | ✗ | return AVERROR_INVALIDDATA; | |
383 | } | ||
384 | 39 | ff_canopus_parse_info_tag(avctx, src + 8, info_offset); | |
385 | |||
386 | 39 | info_offset += 8; | |
387 | 39 | src += info_offset; | |
388 | } | ||
389 | |||
390 | 39 | data_size = (avpkt->size - info_offset) & ~1; | |
391 | |||
392 | /* Make sure our bswap16'd buffer is big enough */ | ||
393 | 39 | av_fast_padded_malloc(&ctx->swapped_buf, | |
394 | 39 | &ctx->swapped_buf_size, data_size); | |
395 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 39 times.
|
39 | if (!ctx->swapped_buf) { |
396 | ✗ | av_log(avctx, AV_LOG_ERROR, "Could not allocate swapped buffer.\n"); | |
397 | ✗ | return AVERROR(ENOMEM); | |
398 | } | ||
399 | |||
400 | /* bswap16 the buffer since CLLC's bitreader works in 16-bit words */ | ||
401 | 39 | ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src, | |
402 | data_size / 2); | ||
403 | |||
404 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | if ((ret = init_get_bits8(&gb, ctx->swapped_buf, data_size)) < 0) |
405 | ✗ | return ret; | |
406 | |||
407 | /* | ||
408 | * Read in coding type. The types are as follows: | ||
409 | * | ||
410 | * 0 - YUY2 | ||
411 | * 1 - BGR24 (Triples) | ||
412 | * 2 - BGR24 (Quads) | ||
413 | * 3 - BGRA | ||
414 | */ | ||
415 | 39 | coding_type = (AV_RL32(src) >> 8) & 0xFF; | |
416 | 39 | av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type); | |
417 | |||
418 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 39 times.
|
39 | if(get_bits_left(&gb) < avctx->height * avctx->width) |
419 | ✗ | return AVERROR_INVALIDDATA; | |
420 | |||
421 |
3/4✓ Branch 0 taken 17 times.
✓ Branch 1 taken 16 times.
✓ Branch 2 taken 6 times.
✗ Branch 3 not taken.
|
39 | switch (coding_type) { |
422 | 17 | case 0: | |
423 | 17 | avctx->pix_fmt = AV_PIX_FMT_YUV422P; | |
424 | 17 | avctx->bits_per_raw_sample = 8; | |
425 | |||
426 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 17 times.
|
17 | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
427 | ✗ | return ret; | |
428 | |||
429 | 17 | ret = decode_yuv_frame(ctx, &gb, pic); | |
430 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 17 times.
|
17 | if (ret < 0) |
431 | ✗ | return ret; | |
432 | |||
433 | 17 | break; | |
434 | 16 | case 1: | |
435 | case 2: | ||
436 | 16 | avctx->pix_fmt = AV_PIX_FMT_RGB24; | |
437 | 16 | avctx->bits_per_raw_sample = 8; | |
438 | |||
439 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 16 times.
|
16 | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
440 | ✗ | return ret; | |
441 | |||
442 | 16 | ret = decode_rgb24_frame(ctx, &gb, pic); | |
443 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 16 times.
|
16 | if (ret < 0) |
444 | ✗ | return ret; | |
445 | |||
446 | 16 | break; | |
447 | 6 | case 3: | |
448 | 6 | avctx->pix_fmt = AV_PIX_FMT_ARGB; | |
449 | 6 | avctx->bits_per_raw_sample = 8; | |
450 | |||
451 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 6 times.
|
6 | if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0) |
452 | ✗ | return ret; | |
453 | |||
454 | 6 | ret = decode_argb_frame(ctx, &gb, pic); | |
455 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (ret < 0) |
456 | ✗ | return ret; | |
457 | |||
458 | 6 | break; | |
459 | ✗ | default: | |
460 | ✗ | av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type); | |
461 | ✗ | return AVERROR_INVALIDDATA; | |
462 | } | ||
463 | |||
464 | 39 | *got_picture_ptr = 1; | |
465 | |||
466 | 39 | return avpkt->size; | |
467 | } | ||
468 | |||
469 | 6 | static av_cold int cllc_decode_close(AVCodecContext *avctx) | |
470 | { | ||
471 | 6 | CLLCContext *ctx = avctx->priv_data; | |
472 | |||
473 | 6 | av_freep(&ctx->swapped_buf); | |
474 | |||
475 | 6 | return 0; | |
476 | } | ||
477 | |||
478 | 6 | static av_cold int cllc_decode_init(AVCodecContext *avctx) | |
479 | { | ||
480 | 6 | CLLCContext *ctx = avctx->priv_data; | |
481 | |||
482 | /* Initialize various context values */ | ||
483 | 6 | ctx->avctx = avctx; | |
484 | 6 | ctx->swapped_buf = NULL; | |
485 | 6 | ctx->swapped_buf_size = 0; | |
486 | |||
487 | 6 | ff_bswapdsp_init(&ctx->bdsp); | |
488 | |||
489 | 6 | return 0; | |
490 | } | ||
491 | |||
492 | const FFCodec ff_cllc_decoder = { | ||
493 | .p.name = "cllc", | ||
494 | CODEC_LONG_NAME("Canopus Lossless Codec"), | ||
495 | .p.type = AVMEDIA_TYPE_VIDEO, | ||
496 | .p.id = AV_CODEC_ID_CLLC, | ||
497 | .priv_data_size = sizeof(CLLCContext), | ||
498 | .init = cllc_decode_init, | ||
499 | FF_CODEC_DECODE_CB(cllc_decode_frame), | ||
500 | .close = cllc_decode_close, | ||
501 | .p.capabilities = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS, | ||
502 | }; | ||
503 |