FFmpeg
Loading...
Searching...
No Matches
cri.c
Go to the documentation of this file.
1/*
2 * CRI image decoder
3 *
4 * Copyright (c) 2020 Paul B Mahol
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/**
24 * @file
25 * Cintel RAW image decoder
26 */
27
28#define BITSTREAM_READER_LE
29
31#include "libavutil/intfloat.h"
32#include "libavutil/display.h"
33#include "avcodec.h"
34#include "bytestream.h"
35#include "codec_internal.h"
36#include "decode.h"
37#include "get_bits.h"
38#include "thread.h"
39
40typedef struct CRIContext {
41 AVCodecContext *jpeg_avctx; // wrapper context for MJPEG
42 AVPacket *jpkt; // encoded JPEG tile
43 AVFrame *jpgframe; // decoded JPEG tile
44
47 const uint8_t *data;
48 unsigned data_size;
49 uint64_t tile_size[4];
51
53{
54 CRIContext *s = avctx->priv_data;
55 int ret;
56
57 s->jpgframe = av_frame_alloc();
58 if (!s->jpgframe)
59 return AVERROR(ENOMEM);
60
61 s->jpkt = av_packet_alloc();
62 if (!s->jpkt)
63 return AVERROR(ENOMEM);
64
67 if (!s->jpeg_avctx)
68 return AVERROR(ENOMEM);
69 s->jpeg_avctx->flags = avctx->flags;
70 s->jpeg_avctx->flags2 = avctx->flags2;
71 s->jpeg_avctx->idct_algo = avctx->idct_algo;
72 s->jpeg_avctx->max_pixels = avctx->max_pixels;
73 ret = avcodec_open2(s->jpeg_avctx, NULL, NULL);
74 if (ret < 0)
75 return ret;
76
77 return 0;
78}
79
80static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift,
81 int w, int h, ptrdiff_t stride)
82{
83 int count = w * h;
84 int pos = 0;
85
86 while (count > 0) {
87 uint32_t a0, a1, a2, a3;
89 break;
90 a0 = bytestream2_get_le32(gb);
91 a1 = bytestream2_get_le32(gb);
92 a2 = bytestream2_get_le32(gb);
93 a3 = bytestream2_get_le32(gb);
94 dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
95 pos++;
96 if (pos >= w) {
97 if (count == 1)
98 break;
99 dst += stride;
100 pos = 0;
101 }
102 dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
103 pos++;
104 if (pos >= w) {
105 if (count == 2)
106 break;
107 dst += stride;
108 pos = 0;
109 }
110 dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
111 pos++;
112 if (pos >= w) {
113 if (count == 3)
114 break;
115 dst += stride;
116 pos = 0;
117 }
118 dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
119 pos++;
120 if (pos >= w) {
121 if (count == 4)
122 break;
123 dst += stride;
124 pos = 0;
125 }
126 dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
127 pos++;
128 if (pos >= w) {
129 if (count == 5)
130 break;
131 dst += stride;
132 pos = 0;
133 }
134 dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
135 pos++;
136 if (pos >= w) {
137 if (count == 6)
138 break;
139 dst += stride;
140 pos = 0;
141 }
142 dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
143 pos++;
144 if (pos >= w) {
145 if (count == 7)
146 break;
147 dst += stride;
148 pos = 0;
149 }
150 dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
151 pos++;
152 if (pos >= w) {
153 if (count == 8)
154 break;
155 dst += stride;
156 pos = 0;
157 }
158 dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
159 pos++;
160 if (pos >= w) {
161 if (count == 9)
162 break;
163 dst += stride;
164 pos = 0;
165 }
166
167 count -= 9;
168 }
169}
170
172 int *got_frame, AVPacket *avpkt)
173{
174 CRIContext *s = avctx->priv_data;
175 GetByteContext *gb = &s->gb;
176 int ret, bps, hflip = 0, vflip = 0;
177 AVFrameSideData *rotation;
178 int compressed = 0;
179
180 s->data = NULL;
181 s->data_size = 0;
182
183 bytestream2_init(gb, avpkt->data, avpkt->size);
184
185 while (bytestream2_get_bytes_left(gb) > 8) {
186 char codec_name[1024];
187 uint32_t key, length;
188 float framerate;
189 int width, height;
190
191 key = bytestream2_get_le32(gb);
192 length = bytestream2_get_le32(gb);
193
194 switch (key) {
195 case 1:
196 if (length != 4)
197 return AVERROR_INVALIDDATA;
198
199 if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
200 return AVERROR_INVALIDDATA;
201 break;
202 case 100:
203 if (length < 16)
204 return AVERROR_INVALIDDATA;
205 width = bytestream2_get_le32(gb);
206 height = bytestream2_get_le32(gb);
207 s->color_model = bytestream2_get_le32(gb);
208 if (bytestream2_get_le32(gb) != 1)
209 return AVERROR_INVALIDDATA;
210 ret = ff_set_dimensions(avctx, width, height);
211 if (ret < 0)
212 return ret;
213 length -= 16;
214 goto skip;
215 case 101:
216 if (length != 4)
217 return AVERROR_INVALIDDATA;
218
219 if (bytestream2_get_le32(gb) != 0)
220 return AVERROR_INVALIDDATA;
221 break;
222 case 102:;
223 int read_len = FFMIN(length, sizeof(codec_name) - 1);
224 if (read_len != bytestream2_get_buffer(gb, codec_name, read_len))
225 return AVERROR_INVALIDDATA;
226 length -= read_len;
227 if (strncmp(codec_name, "cintel_craw", read_len))
228 return AVERROR_INVALIDDATA;
229 compressed = 1;
230 goto skip;
231 case 103:
232 if (bytestream2_get_bytes_left(gb) < length)
233 return AVERROR_INVALIDDATA;
234 s->data = gb->buffer;
235 s->data_size = length;
236 goto skip;
237 case 105:
238 if (length <= 0)
239 return AVERROR_INVALIDDATA;
240 hflip = bytestream2_get_byte(gb) != 0;
241 length--;
242 goto skip;
243 case 106:
244 if (length <= 0)
245 return AVERROR_INVALIDDATA;
246 vflip = bytestream2_get_byte(gb) != 0;
247 length--;
248 goto skip;
249 case 107:
250 if (length != 4)
251 return AVERROR_INVALIDDATA;
252 framerate = av_int2float(bytestream2_get_le32(gb));
253 avctx->framerate.num = framerate * 1000;
254 avctx->framerate.den = 1000;
255 break;
256 case 119:
257 if (length != 32)
258 return AVERROR_INVALIDDATA;
259
260 for (int i = 0; i < 4; i++)
261 s->tile_size[i] = bytestream2_get_le64(gb);
262 break;
263 default:
264 av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
265skip:
266 bytestream2_skip(gb, length);
267 }
268 }
269
270 switch (s->color_model) {
271 case 76:
272 case 88:
274 break;
275 case 77:
276 case 89:
278 break;
279 case 78:
280 case 90:
282 break;
283 case 45:
284 case 79:
285 case 91:
287 break;
288 }
289
290 switch (s->color_model) {
291 case 45:
292 bps = 10;
293 break;
294 case 76:
295 case 77:
296 case 78:
297 case 79:
298 bps = 12;
299 break;
300 case 88:
301 case 89:
302 case 90:
303 case 91:
304 bps = 16;
305 break;
306 default:
307 return AVERROR_INVALIDDATA;
308 }
309
310 if (compressed) {
311 for (int i = 0; i < 4; i++) {
312 if (s->tile_size[i] >= s->data_size)
313 return AVERROR_INVALIDDATA;
314 }
315
316 if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
317 s->data_size)
318 return AVERROR_INVALIDDATA;
319 }
320
321 if (!s->data || !s->data_size)
322 return AVERROR_INVALIDDATA;
323
324 if (avctx->skip_frame >= AVDISCARD_ALL)
325 return avpkt->size;
326
327 if ((ret = ff_thread_get_buffer(avctx, p, 0)) < 0)
328 return ret;
329
330 avctx->bits_per_raw_sample = bps;
331
332 if (!compressed && s->color_model == 45) {
333 uint16_t *dst = (uint16_t *)p->data[0];
335
336 bytestream2_init(&gb, s->data, s->data_size);
337 unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
338 } else if (!compressed) {
339 GetBitContext gbit;
340 const int shift = 16 - bps;
341
342 ret = init_get_bits8(&gbit, s->data, s->data_size);
343 if (ret < 0)
344 return ret;
345
346 for (int y = 0; y < avctx->height; y++) {
347 uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
348
349 if (get_bits_left(&gbit) < avctx->width * bps)
350 break;
351
352 for (int x = 0; x < avctx->width; x++)
353 dst[x] = get_bits(&gbit, bps) << shift;
354 }
355 } else {
356 unsigned offset = 0;
357
358 for (int tile = 0; tile < 4; tile++) {
359 av_packet_unref(s->jpkt);
360 s->jpkt->data = (uint8_t *)s->data + offset;
361 s->jpkt->size = s->tile_size[tile];
362
363 ret = avcodec_send_packet(s->jpeg_avctx, s->jpkt);
364 if (ret < 0) {
365 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
366 return ret;
367 }
368
369 ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
370 if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
371 s->jpeg_avctx->width * 2 != avctx->width ||
372 s->jpeg_avctx->height * 2 != avctx->height) {
373 if (ret < 0) {
374 av_log(avctx, AV_LOG_ERROR,
375 "JPEG decoding error (%d).\n", ret);
376 } else {
377 av_log(avctx, AV_LOG_ERROR,
378 "JPEG invalid format.\n");
380 }
381
382 /* Normally skip, if error explode */
383 if (avctx->err_recognition & AV_EF_EXPLODE)
384 return ret;
385 else
386 return 0;
387 }
388
389 for (int y = 0; y < s->jpeg_avctx->height; y++) {
390 const int hw = s->jpgframe->width / 2;
391 uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
392 const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
393
394 memcpy(dst, src, hw * 2);
395 src += hw;
396 dst += p->linesize[0] / 2;
397 memcpy(dst, src, hw * 2);
398 }
399
400 av_frame_unref(s->jpgframe);
401 offset += s->tile_size[tile];
402 }
403 }
404
405 if (hflip || vflip) {
407 sizeof(int32_t) * 9, &rotation);
408 if (rotation) {
409 av_display_rotation_set((int32_t *)rotation->data, 0.f);
410 av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
411 }
412 }
413
414 *got_frame = 1;
415
416 return 0;
417}
418
420{
421 CRIContext *s = avctx->priv_data;
422
423 av_frame_free(&s->jpgframe);
424 av_packet_free(&s->jpkt);
425 avcodec_free_context(&s->jpeg_avctx);
426
427 return 0;
428}
429
431 .p.name = "cri",
432 .p.type = AVMEDIA_TYPE_VIDEO,
433 .p.id = AV_CODEC_ID_CRI,
434 .priv_data_size = sizeof(CRIContext),
437 .close = cri_decode_close,
439 .caps_internal = FF_CODEC_CAP_INIT_CLEANUP |
441 CODEC_LONG_NAME("Cintel RAW"),
442};
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_mjpeg_decoder
const FFCodec ff_cri_decoder
Definition cri.c:430
#define EXTERN
int32_t
Libavcodec external API header.
static void BS_FUNC skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition bytestream.h:267
static av_always_inline int bytestream2_get_bytes_left(const GetByteContext *g)
Definition bytestream.h:158
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition bytestream.h:137
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition bytestream.h:168
static int FUNC tile(CodedBitstreamContext *ctx, RWContext *rw, APVRawTile *current, int tile_idx, uint32_t tile_size)
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define s(width, name)
Definition cbs_vp9.c:198
#define FF_CODEC_CAP_SKIP_FRAME_FILL_PARAM
The decoder extracts and fills its parameters even if the frame is skipped due to the skip_frame sett...
#define FF_CODEC_DECODE_CB(func)
#define CODEC_LONG_NAME(str)
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
#define NULL
Definition coverity.c:32
static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift, int w, int h, ptrdiff_t stride)
Definition cri.c:80
static av_cold int cri_decode_init(AVCodecContext *avctx)
Definition cri.c:52
static int cri_decode_frame(AVCodecContext *avctx, AVFrame *p, int *got_frame, AVPacket *avpkt)
Definition cri.c:171
static av_cold int cri_decode_close(AVCodecContext *avctx)
Definition cri.c:419
int ff_frame_new_side_data(const AVCodecContext *avctx, AVFrame *frame, enum AVFrameSideDataType type, size_t size, AVFrameSideData **psd)
Wrapper around av_frame_new_side_data, which rejects side data overridden by the demuxer.
Definition decode.c:2184
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Definition utils.c:91
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition defs.h:51
Display matrix.
int(* init)(AVBSFContext *ctx)
Definition dts2pts.c:608
const char * key
bitstream reader API header.
static int get_bits_left(GetBitContext *gb)
Definition get_bits.h:688
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
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition avcodec.c:144
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition options.c:149
#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
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition options.c:164
@ AV_CODEC_ID_CRI
Definition codec_id.h:303
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Alias for avcodec_receive_frame_flags(avctx, frame, 0).
Definition avcodec.c:720
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition decode.c:730
@ AVDISCARD_ALL
discard all
Definition defs.h:232
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition error.h:61
#define AVERROR(e)
Definition error.h:45
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition frame.c:496
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition frame.h:85
#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
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure clockwise rotation by the specified angle (in de...
Definition display.c:51
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition display.c:66
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition intfloat.h:40
unsigned offset
Definition libaomenc.c:763
static int shift(int a, int b)
Definition bonk.c:261
Multithreading API for decoders.
#define av_cold
Definition attributes.h:117
uint8_t w
Definition llvidencdsp.c:39
#define FFMIN(a, b)
Definition macros.h:49
#define MKTAG(a, b, c, d)
Definition macros.h:55
unsigned bps
Definition movenc.c:2074
#define AV_PIX_FMT_BAYER_GRBG16
Definition pixfmt.h:580
#define AV_PIX_FMT_BAYER_BGGR16
Definition pixfmt.h:577
#define AV_PIX_FMT_BAYER_RGGB16
Definition pixfmt.h:578
#define AV_PIX_FMT_BAYER_GBRG16
Definition pixfmt.h:579
#define AV_PIX_FMT_GRAY16
Definition pixfmt.h:528
int ff_thread_get_buffer(AVCodecContext *avctx, AVFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
unsigned int pos
Definition spdifenc.c:431
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 flags2
AV_CODEC_FLAG2_*.
Definition avcodec.h:507
int64_t max_pixels
The number of pixels per image to maximally accept.
Definition avcodec.h:1787
AVRational framerate
Definition avcodec.h:563
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition avcodec.h:1571
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition avcodec.h:1544
int flags
AV_CODEC_FLAG_*.
Definition avcodec.h:500
void * priv_data
Definition avcodec.h:470
enum AVDiscard skip_frame
Skip decoding for selected frames.
Definition avcodec.h:1667
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition avcodec.h:1416
Structure to hold side data for an AVFrame.
Definition frame.h:327
uint8_t * data
Definition frame.h:329
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
int size
Definition packet.h:604
uint8_t * data
Definition packet.h:603
int num
Numerator.
Definition rational.h:59
int den
Denominator.
Definition rational.h:60
AVPacket * jpkt
Definition cri.c:42
unsigned data_size
Definition cri.c:48
uint64_t tile_size[4]
Definition cri.c:49
AVFrame * jpgframe
Definition cri.c:43
const uint8_t * data
Definition cri.c:47
AVCodecContext * jpeg_avctx
Definition cri.c:41
int color_model
Definition cri.c:46
GetByteContext gb
Definition cri.c:45
const uint8_t * buffer
Definition bytestream.h:34
#define stride
#define av_log(a,...)
float framerate
Definition av1_levels.c:29
#define src
Definition vp8dsp.c:248
#define height
Definition dsp.h:89
#define width
Definition dsp.h:89
static double a0(void *priv, double x, double y)
Definition vf_xfade.c:2028
static double a3(void *priv, double x, double y)
Definition vf_xfade.c:2031
static double a2(void *priv, double x, double y)
Definition vf_xfade.c:2030
static double a1(void *priv, double x, double y)
Definition vf_xfade.c:2029