]> git.sesse.net Git - ffmpeg/blob - libavcodec/cri.c
avcodec: add Cintel RAW decoder
[ffmpeg] / libavcodec / cri.c
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
42     GetByteContext gb;
43     int color_model;
44     const uint8_t *data;
45     unsigned data_size;
46     uint64_t tile_size[4];
47 } CRIContext;
48
49 static av_cold int cri_decode_init(AVCodecContext *avctx)
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
59     codec = avcodec_find_decoder(AV_CODEC_ID_MJPEG);
60     if (!codec)
61         return AVERROR_BUG;
62     s->jpeg_avctx = avcodec_alloc_context3(codec);
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             dst += stride;
91             pos = 0;
92         }
93         dst[pos] = (((a0 >> 13) & 0x3F) | ((a0 >> 14) & 0xFC0)) << shift;
94         pos++;
95         if (pos >= w) {
96             dst += stride;
97             pos = 0;
98         }
99         dst[pos] = (((a0 >> 26) & 7) | ((a1 & 0x1FF) << 3)) << shift;
100         pos++;
101         if (pos >= w) {
102             dst += stride;
103             pos = 0;
104         }
105         dst[pos] = (((a1 >> 10) & 0x1FF) | ((a1 >> 11) & 0xE00)) << shift;
106         pos++;
107         if (pos >= w) {
108             dst += stride;
109             pos = 0;
110         }
111         dst[pos] = (((a1 >> 23) & 0x3F) | ((a2 & 0x3F) << 6)) << shift;
112         pos++;
113         if (pos >= w) {
114             dst += stride;
115             pos = 0;
116         }
117         dst[pos] = (((a2 >> 7) & 0xFF8) | ((a2 >> 6) & 7)) << shift;
118         pos++;
119         if (pos >= w) {
120             dst += stride;
121             pos = 0;
122         }
123         dst[pos] = (((a3 & 7) << 9) | ((a2 >> 20) & 0x1FF)) << shift;
124         pos++;
125         if (pos >= w) {
126             dst += stride;
127             pos = 0;
128         }
129         dst[pos] = (((a3 >> 4) & 0xFC0) | ((a3 >> 3) & 0x3F)) << shift;
130         pos++;
131         if (pos >= w) {
132             dst += stride;
133             pos = 0;
134         }
135         dst[pos] = (((a3 >> 16) & 7) | ((a3 >> 17) & 0xFF8)) << shift;
136         pos++;
137         if (pos >= w) {
138             dst += stride;
139             pos = 0;
140         }
141
142         count -= 9;
143     }
144 }
145
146 static int cri_decode_frame(AVCodecContext *avctx, void *data,
147                             int *got_frame, AVPacket *avpkt)
148 {
149     CRIContext *s = avctx->priv_data;
150     GetByteContext *gb = &s->gb;
151     ThreadFrame frame = { .f = data };
152     int ret, bps, hflip = 0, vflip = 0;
153     AVFrameSideData *rotation;
154     int compressed = 0;
155     AVFrame *p = data;
156
157     s->data = NULL;
158     s->data_size = 0;
159
160     bytestream2_init(gb, avpkt->data, avpkt->size);
161
162     while (bytestream2_get_bytes_left(gb) > 8) {
163         char codec_name[1024];
164         uint32_t key, length;
165         float framerate;
166
167         key    = bytestream2_get_le32(gb);
168         length = bytestream2_get_le32(gb);
169
170         switch (key) {
171         case 1:
172             if (length != 4)
173                 return AVERROR_INVALIDDATA;
174
175             if (bytestream2_get_le32(gb) != MKTAG('D', 'V', 'C', 'C'))
176                 return AVERROR_INVALIDDATA;
177             break;
178         case 100:
179             if (length < 16)
180                 return AVERROR_INVALIDDATA;
181             avctx->width   = bytestream2_get_le32(gb);
182             avctx->height  = bytestream2_get_le32(gb);
183             s->color_model = bytestream2_get_le32(gb);
184             if (bytestream2_get_le32(gb) != 1)
185                 return AVERROR_INVALIDDATA;
186             length -= 16;
187             goto skip;
188         case 101:
189             if (length != 4)
190                 return AVERROR_INVALIDDATA;
191
192             if (bytestream2_get_le32(gb) != 0)
193                 return AVERROR_INVALIDDATA;
194             break;
195         case 102:
196             bytestream2_get_buffer(gb, codec_name, FFMIN(length, sizeof(codec_name) - 1));
197             length -= FFMIN(length, sizeof(codec_name) - 1);
198             if (strncmp(codec_name, "cintel_craw", FFMIN(length, sizeof(codec_name) - 1)))
199                 return AVERROR_INVALIDDATA;
200             compressed = 1;
201             goto skip;
202         case 103:
203             if (bytestream2_get_bytes_left(gb) < length)
204                 return AVERROR_INVALIDDATA;
205             s->data = gb->buffer;
206             s->data_size = length;
207             goto skip;
208         case 105:
209             hflip = bytestream2_get_byte(gb) != 0;
210             length--;
211             goto skip;
212         case 106:
213             vflip = bytestream2_get_byte(gb) != 0;
214             length--;
215             goto skip;
216         case 107:
217             if (length != 4)
218                 return AVERROR_INVALIDDATA;
219             framerate = av_int2float(bytestream2_get_le32(gb));
220             avctx->framerate.num = framerate * 1000;
221             avctx->framerate.den = 1000;
222             break;
223         case 119:
224             if (length != 32)
225                 return AVERROR_INVALIDDATA;
226
227             for (int i = 0; i < 4; i++)
228                 s->tile_size[i] = bytestream2_get_le64(gb);
229             break;
230         default:
231             av_log(avctx, AV_LOG_DEBUG, "skipping unknown key %u of length %u\n", key, length);
232 skip:
233             bytestream2_skip(gb, length);
234         }
235     }
236
237     switch (s->color_model) {
238     case 76:
239     case 88:
240         avctx->pix_fmt = AV_PIX_FMT_BAYER_BGGR16;
241         break;
242     case 77:
243     case 89:
244         avctx->pix_fmt = AV_PIX_FMT_BAYER_GBRG16;
245         break;
246     case 78:
247     case 90:
248         avctx->pix_fmt = AV_PIX_FMT_BAYER_RGGB16;
249         break;
250     case 45:
251     case 79:
252     case 91:
253         avctx->pix_fmt = AV_PIX_FMT_BAYER_GRBG16;
254         break;
255     }
256
257     switch (s->color_model) {
258     case 45:
259         bps = 10;
260         break;
261     case 76:
262     case 77:
263     case 78:
264     case 79:
265         bps = 12;
266         break;
267     case 88:
268     case 89:
269     case 90:
270     case 91:
271         bps = 16;
272         break;
273     default:
274         return AVERROR_INVALIDDATA;
275     }
276
277     if (compressed) {
278         for (int i = 0; i < 4; i++) {
279             if (s->tile_size[i] >= s->data_size)
280                 return AVERROR_INVALIDDATA;
281         }
282
283         if (s->tile_size[0] + s->tile_size[1] + s->tile_size[2] + s->tile_size[3] !=
284             s->data_size)
285             return AVERROR_INVALIDDATA;
286     }
287
288     if (!s->data || !s->data_size)
289         return AVERROR_INVALIDDATA;
290
291     if ((ret = ff_thread_get_buffer(avctx, &frame, 0)) < 0)
292         return ret;
293
294     avctx->bits_per_raw_sample = bps;
295
296     if (!compressed && s->color_model == 45) {
297         uint16_t *dst = (uint16_t *)p->data[0];
298         GetByteContext gb;
299
300         bytestream2_init(&gb, s->data, s->data_size);
301         unpack_10bit(&gb, dst, 4, avctx->width, avctx->height, p->linesize[0] / 2);
302     } else if (!compressed) {
303         GetBitContext gbit;
304         const int shift = 16 - bps;
305
306         ret = init_get_bits8(&gbit, s->data, s->data_size);
307         if (ret < 0)
308             return ret;
309
310         for (int y = 0; y < avctx->height; y++) {
311             uint16_t *dst = (uint16_t *)(p->data[0] + y * p->linesize[0]);
312
313             for (int x = 0; x < avctx->width; x++)
314                 dst[x] = get_bits(&gbit, bps) << shift;
315         }
316     } else {
317         unsigned offset = 0;
318
319         for (int tile = 0; tile < 4; tile++) {
320             AVPacket jpkt;
321
322             av_init_packet(&jpkt);
323             jpkt.data = (uint8_t *)s->data + offset;
324             jpkt.size = s->tile_size[tile];
325
326             ret = avcodec_send_packet(s->jpeg_avctx, &jpkt);
327             if (ret < 0) {
328                 av_log(avctx, AV_LOG_ERROR, "Error submitting a packet for decoding\n");
329                 return ret;
330             }
331
332             ret = avcodec_receive_frame(s->jpeg_avctx, s->jpgframe);
333             if (ret < 0 || s->jpgframe->format != AV_PIX_FMT_GRAY16 ||
334                 s->jpeg_avctx->width  * 2 != avctx->width ||
335                 s->jpeg_avctx->height * 2 != avctx->height) {
336                 if (ret < 0) {
337                     av_log(avctx, AV_LOG_ERROR,
338                            "JPEG decoding error (%d).\n", ret);
339                 } else {
340                     av_log(avctx, AV_LOG_ERROR,
341                            "JPEG invalid format.\n");
342                     ret = AVERROR_INVALIDDATA;
343                 }
344
345                 /* Normally skip, if error explode */
346                 if (avctx->err_recognition & AV_EF_EXPLODE)
347                     return ret;
348                 else
349                     return 0;
350             }
351
352             for (int y = 0; y < s->jpeg_avctx->height; y++) {
353                 const int hw =  s->jpgframe->width / 2;
354                 uint16_t *dst = (uint16_t *)(p->data[0] + (y * 2) * p->linesize[0] + tile * hw * 2);
355                 const uint16_t *src = (const uint16_t *)(s->jpgframe->data[0] + y * s->jpgframe->linesize[0]);
356
357                 memcpy(dst, src, hw * 2);
358                 src += hw;
359                 dst += p->linesize[0] / 2;
360                 memcpy(dst, src, hw * 2);
361             }
362
363             av_frame_unref(s->jpgframe);
364             offset += s->tile_size[tile];
365         }
366     }
367
368     if (hflip || vflip) {
369         rotation = av_frame_new_side_data(p, AV_FRAME_DATA_DISPLAYMATRIX,
370                                           sizeof(int32_t) * 9);
371         if (rotation) {
372             av_display_rotation_set((int32_t *)rotation->data, 0.f);
373             av_display_matrix_flip((int32_t *)rotation->data, hflip, vflip);
374         }
375     }
376
377     p->pict_type = AV_PICTURE_TYPE_I;
378     p->key_frame = 1;
379
380     *got_frame = 1;
381
382     return 0;
383 }
384
385 static av_cold int cri_decode_close(AVCodecContext *avctx)
386 {
387     CRIContext *s = avctx->priv_data;
388
389     av_frame_free(&s->jpgframe);
390     avcodec_free_context(&s->jpeg_avctx);
391
392     return 0;
393 }
394
395 AVCodec ff_cri_decoder = {
396     .name           = "cri",
397     .type           = AVMEDIA_TYPE_VIDEO,
398     .id             = AV_CODEC_ID_CRI,
399     .priv_data_size = sizeof(CRIContext),
400     .init           = cri_decode_init,
401     .decode         = cri_decode_frame,
402     .close          = cri_decode_close,
403     .capabilities   = AV_CODEC_CAP_DR1 | AV_CODEC_CAP_FRAME_THREADS,
404     .caps_internal  = FF_CODEC_CAP_INIT_CLEANUP,
405     .long_name      = NULL_IF_CONFIG_SMALL("Cintel RAW"),
406 };