FFmpeg  4.4.5
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  bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
227  length -= FFMIN(length, sizeof(codec_name) - 1);
228  if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
229  return AVERROR_INVALIDDATA;
230  compressed = 1;
231  goto skip;
232  case 103:
233  if (bytestream2_get_bytes_left(gb) < length)
234  return AVERROR_INVALIDDATA;
235  s->data = gb->buffer;
236  s->data_size = length;
237  goto skip;
238  case 105:
239  if (length <= 0)
240  return AVERROR_INVALIDDATA;
241  hflip = bytestream2_get_byte(gb) != 0;
242  length--;
243  goto skip;
244  case 106:
245  if (length <= 0)
246  return AVERROR_INVALIDDATA;
247  vflip = bytestream2_get_byte(gb) != 0;
248  length--;
249  goto skip;
250  case 107:
251  if (length != 4)
252  return AVERROR_INVALIDDATA;
253  framerate = av_int2float(bytestream2_get_le32(gb));
254  avctx->framerate.num = framerate * 1000;
255  avctx->framerate.den = 1000;
256  break;
257  case 119:
258  if (length != 32)
259  return AVERROR_INVALIDDATA;
260 
261  for (int i = 0; i < 4; i++)
262  s->tile_size[i] = bytestream2_get_le64(gb);
263  break;
264  default:
265  av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
266 skip:
267  bytestream2_skip(gb, length);
268  }
269  }
270 
271  switch (s->color_model) {
272  case 76:
273  case 88:
275  break;
276  case 77:
277  case 89:
279  break;
280  case 78:
281  case 90:
283  break;
284  case 45:
285  case 79:
286  case 91:
288  break;
289  }
290 
291  switch (s->color_model) {
292  case 45:
293  bps = 10;
294  break;
295  case 76:
296  case 77:
297  case 78:
298  case 79:
299  bps = 12;
300  break;
301  case 88:
302  case 89:
303  case 90:
304  case 91:
305  bps = 16;
306  break;
307  default:
308  return AVERROR_INVALIDDATA;
309  }
310 
311  if (compressed) {
312  for (int i = 0; i < 4; i++) {
313  if (s->tile_size[i] >= s->data_size)
314  return AVERROR_INVALIDDATA;
315  }
316 
317  if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
318  s->data_size)
319  return AVERROR_INVALIDDATA;
320  }
321 
322  if (!s->data || !s->data_size)
323  return AVERROR_INVALIDDATA;
324 
325  if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
326  return ret;
327 
328  avctx->bits_per_raw_sample = bps;
329 
330  if (!compressed && s->color_model == 45) {
331  uint16_t *dst = (uint16_t *)p->data[0];
332  GetByteContext gb;
333 
334  bytestream2_init(&gb, s->data, s->data_size);
335  unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
336  } else if (!compressed) {
337  GetBitContext gbit;
338  const int shift = 16 - bps;
339 
340  ret = init_get_bits8(&gbit, s->data, s->data_size);
341  if (ret < 0)
342  return ret;
343 
344  for (int y = 0; y < avctx->height; y++) {
345  uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
346 
347  if (get_bits_left(&gbit) < avctx->width * bps)
348  break;
349 
350  for (int x = 0; x < avctx->width; x++)
351  dst[x] = get_bits(&gbit, bps) << shift;
352  }
353  } else {
354  unsigned offset = 0;
355 
356  for (int tile = 0; tile < 4; tile++) {
357  av_packet_unref(s->jpkt);
358  s->jpkt->data = (uint8_t *)s->data + offset;
359  s->jpkt->size = s->tile_size[tile];
360 
361  ret = avcodec_send_packet(s->jpeg_avctx, s->jpkt);
362  if (ret < 0) {
363  av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
364  return ret;
365  }
366 
367  ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
368  if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
369  s->jpeg_avctx->width * 2 != avctx->width ||
370  s->jpeg_avctx->height * 2 != avctx->height) {
371  if (ret < 0) {
372  av_log(avctx, AV_LOG_ERROR,
373  "JPEG decoding error (%d).\n", ret);
374  } else {
375  av_log(avctx, AV_LOG_ERROR,
376  "JPEG invalid format.\n");
377  ret = AVERROR_INVALIDDATA;
378  }
379 
380  /* Normally skip, if error explode */
381  if (avctx->err_recognition & AV_EF_EXPLODE)
382  return ret;
383  else
384  return 0;
385  }
386 
387  for (int y = 0; y < s->jpeg_avctx->height; y++) {
388  const int hw = s->jpgframe->width / 2;
389  uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
390  const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
391 
392  memcpy(dst, src, hw * 2);
393  src += hw;
394  dst += p->linesize[0] / 2;
395  memcpy(dst, src, hw * 2);
396  }
397 
398  av_frame_unref(s->jpgframe);
399  offset += s->tile_size[tile];
400  }
401  }
402 
403  if (hflip || vflip) {
405  sizeof(int32_t) * 9);
406  if (rotation) {
407  av_display_rotation_set((int32_t *)rotation->data, 0.f);
408  av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
409  }
410  }
411 
413  p->key_frame = 1;
414 
415  *got_frame = 1;
416 
417  return 0;
418 }
419 
421 {
422  CRIContext *s = avctx->priv_data;
423 
424  av_frame_free(&s->jpgframe);
425  av_packet_free(&s->jpkt);
426  avcodec_free_context(&s->jpeg_avctx);
427 
428  return 0;
429 }
430 
432  .name = "cri",
433  .type = AVMEDIA_TYPE_VIDEO,
434  .id = AV_CODEC_ID_CRI,
435  .priv_data_size = sizeof(CRIContext),
438  .close = cri_decode_close,
441  .long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"),
442 };
#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:1656
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:431
static av_cold int cri_decode_close(AVCodecContext *avctx)
Definition: cri.c:420
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:1706
AVRational framerate
Definition: avcodec.h:2071
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1747
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1719
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:1645
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