FFmpeg
Loading...
Searching...
No Matches
cllc.c
Go to the documentation of this file.
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
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
45
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 count = 0;
54 num_codes_sum = 0;
55
56 num_lens = get_bits(gb, 5);
57
58 if (num_lens > VLC_BITS * VLC_DEPTH) {
59 av_log(ctx->avctx, AV_LOG_ERROR, "To long VLCs %d\n", num_lens);
61 }
62
63 for (i = 0; i < num_lens; i++) {
64 num_codes = get_bits(gb, 9);
65 num_codes_sum += num_codes;
66
67 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);
71 }
72
73 for (j = 0; j < num_codes; j++) {
74 symbols[count] = get_bits(gb, 8);
75 bits[count] = i + 1;
76
77 count++;
78 }
79 }
80
81 return ff_vlc_init_from_lengths(vlc, VLC_BITS, count, bits, 1,
82 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 */
89static 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 OPEN_READER(bits, gb);
98
99 dst = outbuf;
100 pred[0] = top_left[0];
101 pred[1] = top_left[1];
102 pred[2] = top_left[2];
103 pred[3] = top_left[3];
104
105 for (i = 0; i < ctx->avctx->width; i++) {
106 /* Always get the alpha component */
107 UPDATE_CACHE(bits, gb);
108 GET_VLC(code, bits, gb, vlc[0].table, VLC_BITS, VLC_DEPTH);
109
110 pred[0] += code;
111 dst[0] = pred[0];
112
113 /* Skip the components if they are entirely transparent */
114 if (dst[0]) {
115 /* Red */
116 UPDATE_CACHE(bits, gb);
117 GET_VLC(code, bits, gb, vlc[1].table, VLC_BITS, VLC_DEPTH);
118
119 pred[1] += code;
120 dst[1] = pred[1];
121
122 /* Green */
123 UPDATE_CACHE(bits, gb);
124 GET_VLC(code, bits, gb, vlc[2].table, VLC_BITS, VLC_DEPTH);
125
126 pred[2] += code;
127 dst[2] = pred[2];
128
129 /* Blue */
130 UPDATE_CACHE(bits, gb);
131 GET_VLC(code, bits, gb, vlc[3].table, VLC_BITS, VLC_DEPTH);
132
133 pred[3] += code;
134 dst[3] = pred[3];
135 } else {
136 dst[1] = 0;
137 dst[2] = 0;
138 dst[3] = 0;
139 }
140
141 dst += 4;
142 }
143
144 CLOSE_READER(bits, gb);
145
146 top_left[0] = outbuf[0];
147
148 /* Only stash components if they are not transparent */
149 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 return 0;
156}
157
159 int *top_left, VLC *vlc, uint8_t *outbuf)
160{
161 uint8_t *dst;
162 int pred, code;
163 int i;
164
165 OPEN_READER(bits, gb);
166
167 dst = outbuf;
168 pred = *top_left;
169
170 /* Simultaneously read and restore the line */
171 for (i = 0; i < ctx->avctx->width; i++) {
172 UPDATE_CACHE(bits, gb);
173 GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
174
175 pred += code;
176 dst[0] = pred;
177 dst += 3;
178 }
179
180 CLOSE_READER(bits, gb);
181
182 /* Stash the first pixel */
183 *top_left = outbuf[0];
184
185 return 0;
186}
187
189 int *top_left, VLC *vlc, uint8_t *outbuf,
190 int is_chroma)
191{
192 int pred, code;
193 int i;
194
195 OPEN_READER(bits, gb);
196
197 pred = *top_left;
198
199 /* Simultaneously read and restore the line */
200 for (i = 0; i < ctx->avctx->width >> is_chroma; i++) {
201 UPDATE_CACHE(bits, gb);
202 GET_VLC(code, bits, gb, vlc->table, VLC_BITS, VLC_DEPTH);
203
204 pred += code;
205 outbuf[i] = pred;
206 }
207
208 CLOSE_READER(bits, gb);
209
210 /* Stash the first pixel */
211 *top_left = outbuf[0];
212
213 return 0;
214}
215
217{
218 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 pred[0] = 0;
226 pred[1] = 0x80;
227 pred[2] = 0x80;
228 pred[3] = 0x80;
229
230 dst = pic->data[0];
231
232 skip_bits(gb, 16);
233
234 /* Read in code table for each plane */
235 for (i = 0; i < 4; i++) {
236 ret = read_code_table(ctx, gb, &vlc[i]);
237 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 for (i = 0; i < avctx->height; i++) {
249 read_argb_line(ctx, gb, pred, vlc, dst);
250
251 dst += pic->linesize[0];
252 }
253
254 for (i = 0; i < 4; i++)
255 ff_vlc_free(&vlc[i]);
256
257 return 0;
258}
259
261{
262 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 pred[0] = 0x80;
270 pred[1] = 0x80;
271 pred[2] = 0x80;
272
273 dst = pic->data[0];
274
275 skip_bits(gb, 16);
276
277 /* Read in code table for each plane */
278 for (i = 0; i < 3; i++) {
279 ret = read_code_table(ctx, gb, &vlc[i]);
280 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 for (i = 0; i < avctx->height; i++) {
292 for (j = 0; j < 3; j++)
293 read_rgb24_component_line(ctx, gb, &pred[j], &vlc[j], &dst[j]);
294
295 dst += pic->linesize[0];
296 }
297
298 for (i = 0; i < 3; i++)
299 ff_vlc_free(&vlc[i]);
300
301 return 0;
302}
303
305{
306 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 pred[0] = 0x80;
315 pred[1] = 0x80;
316 pred[2] = 0x80;
317
318 dst[0] = pic->data[0];
319 dst[1] = pic->data[1];
320 dst[2] = pic->data[2];
321
322 skip_bits(gb, 8);
323
324 block = get_bits(gb, 8);
325 if (block) {
326 avpriv_request_sample(ctx->avctx, "Blocked YUV");
328 }
329
330 /* Read in code table for luma and chroma */
331 for (i = 0; i < 2; i++) {
332 ret = read_code_table(ctx, gb, &vlc[i]);
333 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 for (i = 0; i < avctx->height; i++) {
345 read_yuv_component_line(ctx, gb, &pred[0], &vlc[0], dst[0], 0); /* Y */
346 read_yuv_component_line(ctx, gb, &pred[1], &vlc[1], dst[1], 1); /* U */
347 read_yuv_component_line(ctx, gb, &pred[2], &vlc[1], dst[2], 1); /* V */
348
349 for (j = 0; j < 3; j++)
350 dst[j] += pic->linesize[j];
351 }
352
353 for (i = 0; i < 2; i++)
354 ff_vlc_free(&vlc[i]);
355
356 return 0;
357}
358
360 int *got_picture_ptr, AVPacket *avpkt)
361{
362 CLLCContext *ctx = avctx->priv_data;
363 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 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 info_offset = 0;
375 info_tag = AV_RL32(src);
376 if (info_tag == MKTAG('I', 'N', 'F', 'O')) {
377 info_offset = AV_RL32(src + 4);
378 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 ff_canopus_parse_info_tag(avctx, src + 8, info_offset);
385
386 info_offset += 8;
387 src += info_offset;
388 }
389
390 data_size = (avpkt->size - info_offset) & ~1;
391
392 /* Make sure our bswap16'd buffer is big enough */
393 av_fast_padded_malloc(&ctx->swapped_buf,
394 &ctx->swapped_buf_size, data_size);
395 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 ctx->bdsp.bswap16_buf((uint16_t *) ctx->swapped_buf, (uint16_t *) src,
402 data_size / 2);
403
404 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 coding_type = (AV_RL32(src) >> 8) & 0xFF;
416 av_log(avctx, AV_LOG_DEBUG, "Frame coding type: %d\n", coding_type);
417
418 if(get_bits_left(&gb) < avctx->height * avctx->width)
419 return AVERROR_INVALIDDATA;
420
421 switch (coding_type) {
422 case 0:
424 avctx->bits_per_raw_sample = 8;
425
426 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
427 return ret;
428
429 ret = decode_yuv_frame(ctx, &gb, pic);
430 if (ret < 0)
431 return ret;
432
433 break;
434 case 1:
435 case 2:
436 avctx->pix_fmt = AV_PIX_FMT_RGB24;
437 avctx->bits_per_raw_sample = 8;
438
439 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
440 return ret;
441
442 ret = decode_rgb24_frame(ctx, &gb, pic);
443 if (ret < 0)
444 return ret;
445
446 break;
447 case 3:
448 avctx->pix_fmt = AV_PIX_FMT_ARGB;
449 avctx->bits_per_raw_sample = 8;
450
451 if ((ret = ff_thread_get_buffer(avctx, pic, 0)) < 0)
452 return ret;
453
454 ret = decode_argb_frame(ctx, &gb, pic);
455 if (ret < 0)
456 return ret;
457
458 break;
459 default:
460 av_log(avctx, AV_LOG_ERROR, "Unknown coding type: %d.\n", coding_type);
461 return AVERROR_INVALIDDATA;
462 }
463
464 *got_picture_ptr = 1;
465
466 return avpkt->size;
467}
468
470{
471 CLLCContext *ctx = avctx->priv_data;
472
473 av_freep(&ctx->swapped_buf);
474
475 return 0;
476}
477
479{
480 CLLCContext *ctx = avctx->priv_data;
481
482 /* Initialize various context values */
483 ctx->avctx = avctx;
484 ctx->swapped_buf = NULL;
485 ctx->swapped_buf_size = 0;
486
487 ff_bswapdsp_init(&ctx->bdsp);
488
489 return 0;
490}
491
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),
500 .close = cllc_decode_close,
502};
uint8_t ptrdiff_t const uint8_t ptrdiff_t int intptr_t intptr_t int int16_t * dst
Definition dsp.h:87
const FFCodec ff_cllc_decoder
Definition cllc.c:492
Libavcodec external API header.
int ff_canopus_parse_info_tag(AVCodecContext *avctx, const uint8_t *src, size_t size)
Definition canopus.c:30
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define VLC_BITS
Definition cfhd.h:103
static int decode_argb_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
Definition cllc.c:216
#define VLC_DEPTH
Definition cllc.c:35
static int cllc_decode_frame(AVCodecContext *avctx, AVFrame *pic, int *got_picture_ptr, AVPacket *avpkt)
Definition cllc.c:359
static int decode_rgb24_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
Definition cllc.c:260
static int read_code_table(CLLCContext *ctx, GetBitContext *gb, VLC *vlc)
Definition cllc.c:46
static int read_yuv_component_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, VLC *vlc, uint8_t *outbuf, int is_chroma)
Definition cllc.c:188
static int read_rgb24_component_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, VLC *vlc, uint8_t *outbuf)
Definition cllc.c:158
static av_cold int cllc_decode_close(AVCodecContext *avctx)
Definition cllc.c:469
static int read_argb_line(CLLCContext *ctx, GetBitContext *gb, int *top_left, VLC *vlc, uint8_t *outbuf)
Definition cllc.c:89
static int decode_yuv_frame(CLLCContext *ctx, GetBitContext *gb, AVFrame *pic)
Definition cllc.c:304
static av_cold int cllc_decode_init(AVCodecContext *avctx)
Definition cllc.c:478
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define NULL
Definition coverity.c:32
static int16_t block[64]
Definition dct.c:125
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
static const uint8_t bits[8]
Definition fastaudio.c:100
bitstream reader API header.
#define GET_VLC(code, name, gb, table, bits, max_depth)
If the vlc code is invalid and max_depth=1, then no bits will be removed.
Definition get_bits.h:573
#define CLOSE_READER(name, gb)
Definition get_bits.h:189
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
#define OPEN_READER(name, gb)
Definition get_bits.h:182
static void skip_bits(GetBitContext *s, int n)
Definition get_bits.h:383
#define UPDATE_CACHE(name, gb)
Definition get_bits.h:213
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition get_bits.h:544
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition get_bits.h:337
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition codec.h:49
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition codec.h:98
@ AV_CODEC_ID_CLLC
Definition codec_id.h:215
void av_fast_padded_malloc(void *ptr, unsigned int *size, size_t min_size)
Same behaviour av_fast_malloc but the buffer has additional AV_INPUT_BUFFER_PADDING_SIZE at the end w...
Definition utils.c:53
#define AVERROR_PATCHWELCOME
Not yet implemented in FFmpeg, patches welcome.
Definition error.h:64
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition log.h:231
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition log.h:210
@ AVMEDIA_TYPE_VIDEO
Definition avutil.h:200
#define AV_RL32(p)
av_cold void ff_bswapdsp_init(BswapDSPContext *c)
Definition bswapdsp.c:37
Multithreading API for decoders.
#define av_cold
Definition attributes.h:117
#define MKTAG(a, b, c, d)
Definition macros.h:55
Memory handling functions.
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition pixfmt.h:75
@ AV_PIX_FMT_YUV422P
planar YUV 4:2:2, 16bpp, (1 Cr & Cb sample per 2x1 Y samples)
Definition pixfmt.h:77
@ AV_PIX_FMT_ARGB
packed ARGB 8:8:8:8, 32bpp, ARGBARGB...
Definition pixfmt.h:99
static const uint16_t table[]
Definition prosumer.c:203
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
static const float pred[4]
Definition siprdata.h:259
const uint8_t * code
Definition spdifenc.c:433
main external API structure.
Definition avcodec.h:443
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition avcodec.h:643
int width
picture width / height.
Definition avcodec.h:604
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition avcodec.h:1571
void * priv_data
Definition avcodec.h:470
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition frame.h:493
int linesize[AV_NUM_DATA_POINTERS]
For video, a positive or negative value, which is typically indicating the size in bytes of each pict...
Definition frame.h:517
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
uint8_t * swapped_buf
Definition cllc.c:42
BswapDSPContext bdsp
Definition cllc.c:40
int swapped_buf_size
Definition cllc.c:43
AVCodecContext * avctx
Definition cllc.c:39
Definition vlc.h:50
VLCElem * table
Definition vlc.h:52
#define avpriv_request_sample(...)
#define av_freep(p)
#define av_log(a,...)
#define src
Definition vp8dsp.c:248
static AVFormatContext * ctx
Definition movenc.c:49
int ff_vlc_init_from_lengths(VLC *vlc, int nb_bits, int nb_codes, const int8_t *lens, int lens_wrap, const void *symbols, int symbols_wrap, int symbols_size, int offset, int flags, void *logctx)
Build VLC decoding tables suitable for use with get_vlc2()
Definition vlc.c:306
void ff_vlc_free(VLC *vlc)
Definition vlc.c:580