FFmpeg
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  AVFrame *jpgframe; // decoded JPEG tile
41 
44  const uint8_t *data;
45  unsigned data_size;
46  uint64_t tile_size[4];
47 } CRIContext;
48 
50 {
51  CRIContext *s = avctx->priv_data;
52  const AVCodec *codec;
53  int ret;
54 
55  s->jpgframe = av_frame_alloc();
56  if (!s->jpgframe)
57  return AVERROR(ENOMEM);
58 
60  if (!codec)
61  return AVERROR_BUG;
63  if (!s->jpeg_avctx)
64  return AVERROR(ENOMEM);
65  s->jpeg_avctx->flags = avctx->flags;
66  s->jpeg_avctx->flags2 = avctx->flags2;
67  s->jpeg_avctx->dct_algo = avctx->dct_algo;
68  s->jpeg_avctx->idct_algo = avctx->idct_algo;
69  ret = ff_codec_open2_recursive(s->jpeg_avctx, codec, NULL);
70  if (ret < 0)
71  return ret;
72 
73  return 0;
74 }
75 
76 static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift,
77  int w, int h, ptrdiff_t stride)
78 {
79  int count = w * h;
80  int pos = 0;
81 
82  while (count > 0) {
83  uint32_t a0 = bytestream2_get_le32(gb);
84  uint32_t a1 = bytestream2_get_le32(gb);
85  uint32_t a2 = bytestream2_get_le32(gb);
86  uint32_t a3 = bytestream2_get_le32(gb);
87  dst[pos] = (((a0 >> 1) & 0xE00) | (a0 & 0x1FF)) << shift;
88  pos++;
89  if (pos >= w) {
90  if (count == 1)
91  break;
92  dst += stride;
93  pos = 0;
94  }
95  dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
96  pos++;
97  if (pos >= w) {
98  if (count == 2)
99  break;
100  dst += stride;
101  pos = 0;
102  }
103  dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
104  pos++;
105  if (pos >= w) {
106  if (count == 3)
107  break;
108  dst += stride;
109  pos = 0;
110  }
111  dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
112  pos++;
113  if (pos >= w) {
114  if (count == 4)
115  break;
116  dst += stride;
117  pos = 0;
118  }
119  dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
120  pos++;
121  if (pos >= w) {
122  if (count == 5)
123  break;
124  dst += stride;
125  pos = 0;
126  }
127  dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
128  pos++;
129  if (pos >= w) {
130  if (count == 6)
131  break;
132  dst += stride;
133  pos = 0;
134  }
135  dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
136  pos++;
137  if (pos >= w) {
138  if (count == 7)
139  break;
140  dst += stride;
141  pos = 0;
142  }
143  dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
144  pos++;
145  if (pos >= w) {
146  if (count == 8)
147  break;
148  dst += stride;
149  pos = 0;
150  }
151  dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
152  pos++;
153  if (pos >= w) {
154  if (count == 9)
155  break;
156  dst += stride;
157  pos = 0;
158  }
159 
160  count -= 9;
161  }
162 }
163 
164 static int cri_decode_frame(AVCodecContext *avctx, void *data,
165  int *got_frame, AVPacket *avpkt)
166 {
167  CRIContext *s = avctx->priv_data;
168  GetByteContext *gb = &s->gb;
169  ThreadFrame frame = { .f = data };
170  int ret, bps, hflip = 0, vflip = 0;
171  AVFrameSideData *rotation;
172  int compressed = 0;
173  AVFrame *p = data;
174 
175  s->data = NULL;
176  s->data_size = 0;
177 
178  bytestream2_init(gb, avpkt->data, avpkt->size);
179 
180  while (bytestream2_get_bytes_left(gb) > 8) {
181  char codec_name[1024];
182  uint32_t key, length;
183  float framerate;
184 
185  key = bytestream2_get_le32(gb);
186  length = bytestream2_get_le32(gb);
187 
188  switch (key) {
189  case 1:
190  if (length != 4)
191  return AVERROR_INVALIDDATA;
192 
193  if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
194  return AVERROR_INVALIDDATA;
195  break;
196  case 100:
197  if (length < 16)
198  return AVERROR_INVALIDDATA;
199  avctx->width = bytestream2_get_le32(gb);
200  avctx->height = bytestream2_get_le32(gb);
201  s->color_model = bytestream2_get_le32(gb);
202  if (bytestream2_get_le32(gb) != 1)
203  return AVERROR_INVALIDDATA;
204  length -= 16;
205  goto skip;
206  case 101:
207  if (length != 4)
208  return AVERROR_INVALIDDATA;
209 
210  if (bytestream2_get_le32(gb) != 0)
211  return AVERROR_INVALIDDATA;
212  break;
213  case 102:
214  bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
215  length -= FFMIN(length, sizeof(codec_name) - 1);
216  if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
217  return AVERROR_INVALIDDATA;
218  compressed = 1;
219  goto skip;
220  case 103:
221  if (bytestream2_get_bytes_left(gb) < length)
222  return AVERROR_INVALIDDATA;
223  s->data = gb->buffer;
224  s->data_size = length;
225  goto skip;
226  case 105:
227  hflip = bytestream2_get_byte(gb) != 0;
228  length--;
229  goto skip;
230  case 106:
231  vflip = bytestream2_get_byte(gb) != 0;
232  length--;
233  goto skip;
234  case 107:
235  if (length != 4)
236  return AVERROR_INVALIDDATA;
237  framerate = av_int2float(bytestream2_get_le32(gb));
238  avctx->framerate.num = framerate * 1000;
239  avctx->framerate.den = 1000;
240  break;
241  case 119:
242  if (length != 32)
243  return AVERROR_INVALIDDATA;
244 
245  for (int i = 0; i < 4; i++)
246  s->tile_size[i] = bytestream2_get_le64(gb);
247  break;
248  default:
249  av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
250 skip:
251  bytestream2_skip(gb, length);
252  }
253  }
254 
255  switch (s->color_model) {
256  case 76:
257  case 88:
259  break;
260  case 77:
261  case 89:
263  break;
264  case 78:
265  case 90:
267  break;
268  case 45:
269  case 79:
270  case 91:
272  break;
273  }
274 
275  switch (s->color_model) {
276  case 45:
277  bps = 10;
278  break;
279  case 76:
280  case 77:
281  case 78:
282  case 79:
283  bps = 12;
284  break;
285  case 88:
286  case 89:
287  case 90:
288  case 91:
289  bps = 16;
290  break;
291  default:
292  return AVERROR_INVALIDDATA;
293  }
294 
295  if (compressed) {
296  for (int i = 0; i < 4; i++) {
297  if (s->tile_size[i] >= s->data_size)
298  return AVERROR_INVALIDDATA;
299  }
300 
301  if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
302  s->data_size)
303  return AVERROR_INVALIDDATA;
304  }
305 
306  if (!s->data || !s->data_size)
307  return AVERROR_INVALIDDATA;
308 
309  if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
310  return ret;
311 
312  avctx->bits_per_raw_sample = bps;
313 
314  if (!compressed && s->color_model == 45) {
315  uint16_t *dst = (uint16_t *)p->data[0];
316  GetByteContext gb;
317 
318  bytestream2_init(&gb, s->data, s->data_size);
319  unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
320  } else if (!compressed) {
321  GetBitContext gbit;
322  const int shift = 16 - bps;
323 
324  ret = init_get_bits8(&gbit, s->data, s->data_size);
325  if (ret < 0)
326  return ret;
327 
328  for (int y = 0; y < avctx->height; y++) {
329  uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
330 
331  for (int x = 0; x < avctx->width; x++)
332  dst[x] = get_bits(&gbit, bps) << shift;
333  }
334  } else {
335  unsigned offset = 0;
336 
337  for (int tile = 0; tile < 4; tile++) {
338  AVPacket jpkt;
339 
340  av_init_packet(&jpkt);
341  jpkt.data = (uint8_t *)s->data + offset;
342  jpkt.size = s->tile_size[tile];
343 
344  ret = avcodec_send_packet(s->jpeg_avctx, &jpkt);
345  if (ret < 0) {
346  av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
347  return ret;
348  }
349 
351  if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
352  s->jpeg_avctx->width * 2 != avctx->width ||
353  s->jpeg_avctx->height * 2 != avctx->height) {
354  if (ret < 0) {
355  av_log(avctx, AV_LOG_ERROR,
356  "JPEG decoding error (%d).\n", ret);
357  } else {
358  av_log(avctx, AV_LOG_ERROR,
359  "JPEG invalid format.\n");
360  ret = AVERROR_INVALIDDATA;
361  }
362 
363  /* Normally skip, if error explode */
364  if (avctx->err_recognition & AV_EF_EXPLODE)
365  return ret;
366  else
367  return 0;
368  }
369 
370  for (int y = 0; y < s->jpeg_avctx->height; y++) {
371  const int hw = s->jpgframe->width / 2;
372  uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
373  const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
374 
375  memcpy(dst, src, hw * 2);
376  src += hw;
377  dst += p->linesize[0] / 2;
378  memcpy(dst, src, hw * 2);
379  }
380 
382  offset += s->tile_size[tile];
383  }
384  }
385 
386  if (hflip || vflip) {
388  sizeof(int32_t) * 9);
389  if (rotation) {
390  av_display_rotation_set((int32_t *)rotation->data, 0.f);
391  av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
392  }
393  }
394 
396  p->key_frame = 1;
397 
398  *got_frame = 1;
399 
400  return 0;
401 }
402 
404 {
405  CRIContext *s = avctx->priv_data;
406 
407  av_frame_free(&s->jpgframe);
409 
410  return 0;
411 }
412 
414  .name = "cri",
415  .type = AVMEDIA_TYPE_VIDEO,
416  .id = AV_CODEC_ID_CRI,
417  .priv_data_size = sizeof(CRIContext),
420  .close = cri_decode_close,
422  .caps_internal = FF_CODEC_CAP_INIT_CLEANUP,
423  .long_name = NULL_IF_CONFIG_SMALL("Cintel RAW"),
424 };
#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:48
#define NULL
Definition: coverity.c:32
AVRational framerate
Definition: avcodec.h:2069
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
const uint8_t * data
Definition: cri.c:44
static int shift(int a, int b)
Definition: sonic.c:82
This structure describes decoded (raw) audio or video data.
Definition: frame.h:308
int dct_algo
DCT algorithm, see FF_DCT_* below.
Definition: avcodec.h:1716
ptrdiff_t const GLvoid * data
Definition: opengl_enc.c:100
static unsigned int get_bits(GetBitContext *s, int n)
Read 1-25 bits.
Definition: get_bits.h:379
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static av_always_inline float av_int2float(uint32_t i)
Reinterpret a 32-bit integer as a float.
Definition: intfloat.h:40
#define a0
Definition: regdef.h:46
int num
Numerator.
Definition: rational.h:59
int size
Definition: packet.h:364
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
Definition: avcodec.h:736
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:137
#define a1
Definition: regdef.h:47
const char * key
int bits_per_raw_sample
Bits per sample/pixel of internal libavcodec pixel/sample format.
Definition: avcodec.h:1757
GetByteContext gb
Definition: cri.c:42
AVCodec.
Definition: codec.h:190
int framerate
Definition: h264_levels.c:65
static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame, FILE *outfile)
Definition: decode_audio.c:71
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
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
static void unpack_10bit(GetByteContext *gb, uint16_t *dst, int shift, int w, int h, ptrdiff_t stride)
Definition: cri.c:76
#define a3
Definition: regdef.h:49
uint8_t
#define av_cold
Definition: attributes.h:88
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:190
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Multithreading support functions.
AVFrame * jpgframe
Definition: cri.c:40
Structure to hold side data for an AVFrame.
Definition: frame.h:214
uint8_t * data
Definition: packet.h:363
const uint8_t * buffer
Definition: bytestream.h:34
bitstream reader API header.
#define AV_PIX_FMT_BAYER_GRBG16
Definition: pixfmt.h:426
#define av_log(a,...)
static av_always_inline int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:158
uint64_t tile_size[4]
Definition: cri.c:46
#define src
Definition: vp8dsp.c:254
int width
Definition: frame.h:366
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:194
int ff_codec_open2_recursive(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Call avcodec_open2 recursively by decrementing counter, unlocking mutex, calling the function and the...
Definition: utils.c:538
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:168
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:203
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:153
Display matrix.
int avcodec_receive_frame(AVCodecContext *avctx, AVFrame *frame)
Return decoded output data from a decoder.
Definition: decode.c:669
static av_always_inline unsigned int bytestream2_get_buffer(GetByteContext *g, uint8_t *dst, unsigned int size)
Definition: bytestream.h:267
unsigned int pos
Definition: spdifenc.c:410
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
int color_model
Definition: cri.c:43
int flags
AV_CODEC_FLAG_*.
Definition: avcodec.h:606
GLsizei GLsizei * length
Definition: opengl_enc.c:114
const char * name
Name of the codec implementation.
Definition: codec.h:197
GLsizei count
Definition: opengl_enc.c:108
AVCodec ff_cri_decoder
Definition: cri.c:413
#define AV_CODEC_CAP_FRAME_THREADS
Codec supports frame-level multithreading.
Definition: codec.h:106
unsigned data_size
Definition: cri.c:45
the pkt_dts and pkt_pts fields in AVFrame will work as usual Restrictions on codec whose streams don t reset across will not work because their bitstreams cannot be decoded in parallel *The contents of buffers must not be read before as well as code calling up to before the decode process starts Call have so the codec calls ff_thread_report set FF_CODEC_CAP_ALLOCATE_PROGRESS in AVCodec caps_internal and use ff_thread_get_buffer() to allocate frames.The frames must then be freed with ff_thread_release_buffer().Otherwise decode directly into the user-supplied frames.Call ff_thread_report_progress() after some part of the current picture has decoded.A good place to put this is where draw_horiz_band() is called-add this if it isn't called anywhere
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:391
int err_recognition
Error recognition; may misdetect some more or less valid parts as errors.
Definition: avcodec.h:1655
#define AV_PIX_FMT_GRAY16
Definition: pixfmt.h:383
#define FFMIN(a, b)
Definition: common.h:96
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition: options.c:172
int width
picture width / height.
Definition: avcodec.h:699
int idct_algo
IDCT algorithm, see FF_IDCT_* below.
Definition: avcodec.h:1729
uint8_t w
Definition: llviddspenc.c:38
int32_t
#define a2
Definition: regdef.h:48
these buffered frames must be flushed immediately if a new input produces new the filter must not call request_frame to get more It must just process the frame or queue it The task of requesting more frames is left to the filter s request_frame method or the application If a filter has several the filter must be ready for frames arriving randomly on any input any filter with several inputs will most likely require some kind of queuing mechanism It is perfectly acceptable to have a limited queue and to drop frames when the inputs are too unbalanced request_frame For filters that do not use the this method is called when a frame is wanted on an output For a it should directly call filter_frame on the corresponding output For a if there are queued frames already one of these frames should be pushed If the filter should request a frame on one of its repeatedly until at least one frame has been pushed Return or at least make progress towards producing a frame
#define s(width, name)
Definition: cbs_vp9.c:257
#define AV_EF_EXPLODE
abort decoding on minor error detection
Definition: avcodec.h:1666
#define AV_PIX_FMT_BAYER_BGGR16
Definition: pixfmt.h:423
int format
format of the frame, -1 if unknown or unset Values correspond to enum AVPixelFormat for video frames...
Definition: frame.h:381
int avcodec_send_packet(AVCodecContext *avctx, const AVPacket *avpkt)
Supply raw packet data as input to a decoder.
Definition: decode.c:606
#define AV_PIX_FMT_BAYER_GBRG16
Definition: pixfmt.h:425
Libavcodec external API header.
This side data contains a 3x3 transformation matrix describing an affine transformation that needs to...
Definition: frame.h:84
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:187
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:339
static int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size)
Initialize GetBitContext.
Definition: get_bits.h:677
main external API structure.
Definition: avcodec.h:526
uint8_t * data
Definition: frame.h:216
#define AVERROR_BUG
Internal bug, also see AVERROR_BUG2.
Definition: error.h:50
AVFrameSideData * av_frame_new_side_data(AVFrame *frame, enum AVFrameSideDataType type, int size)
Add a new side data to a frame.
Definition: frame.c:726
static av_cold int cri_decode_close(AVCodecContext *avctx)
Definition: cri.c:403
AVCodecContext * jpeg_avctx
Definition: cri.c:39
AVCodec * avcodec_find_decoder(enum AVCodecID id)
Find a registered decoder with a matching codec ID.
Definition: allcodecs.c:939
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:553
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:322
#define AV_PIX_FMT_BAYER_RGGB16
Definition: pixfmt.h:424
GLint GLenum GLboolean GLsizei stride
Definition: opengl_enc.c:104
common internal api header.
void av_init_packet(AVPacket *pkt)
Initialize optional fields of a packet with default values.
Definition: avpacket.c:35
int den
Denominator.
Definition: rational.h:60
unsigned bps
Definition: movenc.c:1598
void * priv_data
Definition: avcodec.h:553
Definition: cri.c:38
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:386
int flags2
AV_CODEC_FLAG2_*.
Definition: avcodec.h:613
static av_cold int cri_decode_init(AVCodecContext *avctx)
Definition: cri.c:49
static int cri_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: cri.c:164
#define stride
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame structure Format for each input and each output the list of supported formats For video that means pixel format For audio that means channel sample they are references to shared objects When the negotiation mechanism computes the intersection of the formats supported at each end of a all references to both lists are replaced with a reference to the intersection And when a single format is eventually chosen for a link amongst the remaining all references to the list are updated That means that if a filter requires that its input and output have the same format amongst a supported all it has to do is use a reference to the same list of formats query_formats can leave some formats unset and return AVERROR(EAGAIN) to cause the negotiation mechanism toagain later.That can be used by filters with complex requirements to use the format negotiated on one link to set the formats supported on another.Frame references ownership and permissions
#define MKTAG(a, b, c, d)
Definition: common.h:405
This structure stores compressed data.
Definition: packet.h:340
#define AV_CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
Definition: codec.h:50
int i
Definition: input.c:407