FFmpeg  4.4.7
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 
30 #include "libavutil/intfloat.h"
31 #include "libavutil/display.h"
32 #include "avcodec.h"
33 #include "bytestream.h"
34 #include "get_bits.h"
35 #include "internal.h"
36 #include "thread.h"
37 
38 typedef struct CRIContext {
39  AVCodecContext *jpeg_avctx; // wrapper context for MJPEG
40  AVPacket *jpkt; // encoded JPEG tile
41  AVFrame *jpgframe; // decoded JPEG tile
42 
45  const uint8_t *data;
46  unsigned data_size;
47  uint64_t tile_size[4];
48 } CRIContext;
49 
51 {
52  CRIContext *s = avctx->priv_data;
53  const AVCodec *codec;
54  int ret;
55 
56  s->jpgframe = av_frame_alloc();
57  if (!s->jpgframe)
58  return AVERROR(ENOMEM);
59 
60  s->jpkt = av_packet_alloc();
61  if (!s->jpkt)
62  return AVERROR(ENOMEM);
63 
65  if (!codec)
66  return AVERROR_BUG;
67  s->jpeg_avctx = avcodec_alloc_context3(codec);
68  if (!s->jpeg_avctx)
69  return AVERROR(ENOMEM);
70  s->jpeg_avctx->flags = avctx->flags;
71  s->jpeg_avctx->flags2 = avctx->flags2;
72  s->jpeg_avctx->dct_algo = avctx->dct_algo;
73  s->jpeg_avctx->idct_algo = avctx->idct_algo;
74  ret = avcodec_open2(s->jpeg_avctx, codec, NULL);
75  if (ret < 0)
76  return ret;
77 
78  return 0;
79 }
80 
81 static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift,
82  int w, int h, ptrdiff_t stride)
83 {
84  int count = w * h;
85  int pos = 0;
86 
87  while (count > 0) {
88  uint32_t a0, a1, a2, a3;
89  if (bytestream2_get_bytes_left(gb) < 4)
90  break;
91  a0 = bytestream2_get_le32(gb);
92  a1 = bytestream2_get_le32(gb);
93  a2 = bytestream2_get_le32(gb);
94  a3 = bytestream2_get_le32(gb);
95  dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
96  pos++;
97  if (pos >= w) {
98  if (count == 1)
99  break;
100  dst += stride;
101  pos = 0;
102  }
103  dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
104  pos++;
105  if (pos >= w) {
106  if (count == 2)
107  break;
108  dst += stride;
109  pos = 0;
110  }
111  dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
112  pos++;
113  if (pos >= w) {
114  if (count == 3)
115  break;
116  dst += stride;
117  pos = 0;
118  }
119  dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
120  pos++;
121  if (pos >= w) {
122  if (count == 4)
123  break;
124  dst += stride;
125  pos = 0;
126  }
127  dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
128  pos++;
129  if (pos >= w) {
130  if (count == 5)
131  break;
132  dst += stride;
133  pos = 0;
134  }
135  dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
136  pos++;
137  if (pos >= w) {
138  if (count == 6)
139  break;
140  dst += stride;
141  pos = 0;
142  }
143  dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
144  pos++;
145  if (pos >= w) {
146  if (count == 7)
147  break;
148  dst += stride;
149  pos = 0;
150  }
151  dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
152  pos++;
153  if (pos >= w) {
154  if (count == 8)
155  break;
156  dst += stride;
157  pos = 0;
158  }
159  dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
160  pos++;
161  if (pos >= w) {
162  if (count == 9)
163  break;
164  dst += stride;
165  pos = 0;
166  }
167 
168  count -= 9;
169  }
170 }
171 
172 static int cri_decode_frame(AVCodecContext *avctx, void *data,
173  int *got_frame, AVPacket *avpkt)
174 {
175  CRIContext *s = avctx->priv_data;
176  GetByteContext *gb = &s->gb;
177  ThreadFrame frame = { .f = data };
178  int ret, bps, hflip = 0, vflip = 0;
179  AVFrameSideData *rotation;
180  int compressed = 0;
181  AVFrame *p = data;
182 
183  s->data = NULL;
184  s->data_size = 0;
185 
186  bytestream2_init(gb, avpkt->data, avpkt->size);
187 
188  while (bytestream2_get_bytes_left(gb) > 8) {
189  char codec_name[1024];
190  uint32_t key, length;
191  float framerate;
192  int width, height;
193 
194  key = bytestream2_get_le32(gb);
195  length = bytestream2_get_le32(gb);
196 
197  switch (key) {
198  case 1:
199  if (length != 4)
200  return AVERROR_INVALIDDATA;
201 
202  if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
203  return AVERROR_INVALIDDATA;
204  break;
205  case 100:
206  if (length < 16)
207  return AVERROR_INVALIDDATA;
208  width = bytestream2_get_le32(gb);
209  height = bytestream2_get_le32(gb);
210  s->color_model = bytestream2_get_le32(gb);
211  if (bytestream2_get_le32(gb) != 1)
212  return AVERROR_INVALIDDATA;
213  ret = ff_set_dimensions(avctx, width, height);
214  if (ret < 0)
215  return ret;
216  length -= 16;
217  goto skip;
218  case 101:
219  if (length != 4)
220  return AVERROR_INVALIDDATA;
221 
222  if (bytestream2_get_le32(gb) != 0)
223  return AVERROR_INVALIDDATA;
224  break;
225  case 102:;
226  int read_len = FFMIN(length, sizeof(codec_name) - 1);
227  if (read_len != bytestream2_get_buffer(gb, codec_name, read_len))
228  return AVERROR_INVALIDDATA;
229  length -= read_len;
230  if (strncmp(codec_name, "cintel_craw", read_len))
231  return AVERROR_INVALIDDATA;
232  compressed = 1;
233  goto skip;
234  case 103:
235  if (bytestream2_get_bytes_left(gb) < length)
236  return AVERROR_INVALIDDATA;
237  s->data = gb->buffer;
238  s->data_size = length;
239  goto skip;
240  case 105:
241  if (length <= 0)
242  return AVERROR_INVALIDDATA;
243  hflip = bytestream2_get_byte(gb) != 0;
244  length--;
245  goto skip;
246  case 106:
247  if (length <= 0)
248  return AVERROR_INVALIDDATA;
249  vflip = bytestream2_get_byte(gb) != 0;
250  length--;
251  goto skip;
252  case 107:
253  if (length != 4)
254  return AVERROR_INVALIDDATA;
255  framerate = av_int2float(bytestream2_get_le32(gb));
256  avctx->framerate.num = framerate * 1000;
257  avctx->framerate.den = 1000;
258  break;
259  case 119:
260  if (length != 32)
261  return AVERROR_INVALIDDATA;
262 
263  for (int i = 0; i < 4; i++)
264  s->tile_size[i] = bytestream2_get_le64(gb);
265  break;
266  default:
267  av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
268 skip:
269  bytestream2_skip(gb, length);
270  }
271  }
272 
273  switch (s->color_model) {
274  case 76:
275  case 88:
277  break;
278  case 77:
279  case 89:
281  break;
282  case 78:
283  case 90:
285  break;
286  case 45:
287  case 79:
288  case 91:
290  break;
291  }
292 
293  switch (s->color_model) {
294  case 45:
295  bps = 10;
296  break;
297  case 76:
298  case 77:
299  case 78:
300  case 79:
301  bps = 12;
302  break;
303  case 88:
304  case 89:
305  case 90:
306  case 91:
307  bps = 16;
308  break;
309  default:
310  return AVERROR_INVALIDDATA;
311  }
312 
313  if (compressed) {
314  for (int i = 0; i < 4; i++) {
315  if (s->tile_size[i] >= s->data_size)
316  return AVERROR_INVALIDDATA;
317  }
318 
319  if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
320  s->data_size)
321  return AVERROR_INVALIDDATA;
322  }
323 
324  if (!s->data || !s->data_size)
325  return AVERROR_INVALIDDATA;
326 
327  if ((ret = ff_thread_get_buffer(avctx, &frame, 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];
334  GetByteContext gb;
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");
379  ret = AVERROR_INVALIDDATA;
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);
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 
415  p->key_frame = 1;
416 
417  *got_frame = 1;
418 
419  return 0;
420 }
421 
423 {
424  CRIContext *s = avctx->priv_data;
425 
426  av_frame_free(&s->jpgframe);
427  av_packet_free(&s->jpkt);
428  avcodec_free_context(&s->jpeg_avctx);
429 
430  return 0;
431 }
432 
434  .name = "cri",
435  .type = AVMEDIA_TYPE_VIDEO,
436  .id = AV_CODEC_ID_CRI,
437  .priv_data_size = sizeof(CRIContext),
440  .close = cri_decode_close,
443  .long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"),
444 };
#define av_cold
Definition: attributes.h:88
uint8_t
int32_t
Libavcodec external API header.
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:1660
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:31
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(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
#define s(width, name)
Definition: cbs_vp9.c:257
#define FFMIN(a, b)
Definition: common.h:105
#define MKTAG(a, b, c, d)
Definition: common.h:478
#define NULL
Definition: coverity.c:32
static int cri_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: cri.c:172
static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift, int w, int h, ptrdiff_t stride)
Definition: cri.c:81
static av_cold int cri_decode_init(AVCodecContext *avctx)
Definition: cri.c:50
AVCodec ff_cri_decoder
Definition: cri.c:433
static av_cold int cri_decode_close(AVCodecContext *avctx)
Definition: cri.c:422
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
static AVFrame * frame
Display matrix.
bitstream reader API header.
static int get_bits_left(GetBitContext *gb)
Definition: get_bits.h:849
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
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
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:946
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() or get_encode_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:52
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:108
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:173
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:188
@ AV_CODEC_ID_CRI
Definition: codec_id.h:307
@ AV_CODEC_ID_MJPEG
Definition: codec_id.h:56
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
Definition: decode.c:652
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:589
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition: avpacket.c:75
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition: avpacket.c:634
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition: avpacket.c:64
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define AVERROR(e)
Definition: error.h:43
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
AVFrameSideData * av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, buffer_size_t size)
Add a new side data to a frame.
Definition: frame.c:726
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
@ AV_FRAME_DATA_DISPLAYMATRIX
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: frame.h:84
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
@ AV_PICTURE_TYPE_I
Intra.
Definition: avutil.h:274
void av_display_rotation_set(int32_t matrix[9], double angle)
Initialize a transformation matrix describing a pure counterclockwise rotation by the specified angle...
Definition: display.c:50
void av_display_matrix_flip(int32_t matrix[9], int hflip, int vflip)
Flip the input matrix horizontally and/or vertically.
Definition: display.c:65
const char * key
int i
Definition: input.c:407
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
#define FF_CODEC_CAP_INIT_THREADSAFE
The codec does not modify any global variables in the init function, allowing to call the init functi...
Definition: internal.h:41
#define FF_CODEC_CAP_INIT_CLEANUP
The codec allows calling the close function for deallocation even if the init function returned a fai...
Definition: internal.h:49
int ff_set_dimensions(AVCodecContext *s, int width, int height)
Check that the provided frame dimensions are valid and set them on the codec context.
Definition: utils.c:84
common internal API header
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
uint8_t w
Definition: llviddspenc.c:39
int stride
Definition: mace.c:144
unsigned bps
Definition: movenc.c:1612
const char data[16]
Definition: mxf.c:142
#define AV_PIX_FMT_BAYER_GRBG16
Definition: pixfmt.h:426
#define AV_PIX_FMT_BAYER_BGGR16
Definition: pixfmt.h:423
#define AV_PIX_FMT_BAYER_RGGB16
Definition: pixfmt.h:424
#define AV_PIX_FMT_BAYER_GBRG16
Definition: pixfmt.h:425
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
FF_ENABLE_DEPRECATION_WARNINGS int ff_thread_get_buffer(AVCodecContext *avctx, ThreadFrame *f, int flags)
Wrapper around get_buffer() for frame-multithreaded codecs.
#define a3
Definition: regdef.h:49
#define a2
Definition: regdef.h:48
#define a0
Definition: regdef.h:46
#define a1
Definition: regdef.h:47
static int shift(int a, int b)
Definition: sonic.c:82
unsigned int pos
Definition: spdifenc.c:412
main external API structure.
Definition: avcodec.h:536
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:746
int width
picture width / height.
Definition: avcodec.h:709
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:623
int dct_algo
DCT algorithm, see FF_DCT_* below.
Definition: avcodec.h:1710
AVRational framerate
Definition: avcodec.h:2075
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1751
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1723
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:616
void * priv_data
Definition: avcodec.h:563
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:1649
AVCodec.
Definition: codec.h:197
const char * name
Name of the codec implementation.
Definition: codec.h:204
Structure to hold side data for an AVFrame.
Definition: frame.h:220
uint8_t * data
Definition: frame.h:222
This structure describes decoded (raw) audio or video data.
Definition: frame.h:318
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:332
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:396
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:349
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:401
This structure stores compressed data.
Definition: packet.h:346
int size
Definition: packet.h:370
uint8_t * data
Definition: packet.h:369
int num
Numerator.
Definition: rational.h:59
int den
Denominator.
Definition: rational.h:60
Definition: cri.c:38
AVPacket * jpkt
Definition: cri.c:40
unsigned data_size
Definition: cri.c:46
uint64_t tile_size[4]
Definition: cri.c:47
AVFrame * jpgframe
Definition: cri.c:41
const uint8_t * data
Definition: cri.c:45
AVCodecContext * jpeg_avctx
Definition: cri.c:39
int color_model
Definition: cri.c:44
GetByteContext gb
Definition: cri.c:43
const uint8_t * buffer
Definition: bytestream.h:34
#define av_log(a,...)
#define src
Definition: vp8dsp.c:255
int framerate
Definition: h264_levels.c:65
#define height
#define width
static const uint8_t offset[127][2]
Definition: vf_spp.c:107