dsicinav.c
Go to the documentation of this file.
1 /*
2  * Delphine Software International CIN Audio/Video Decoders
3  * Copyright (c) 2006 Gregory Montoir (cyx@users.sourceforge.net)
4  *
5  * This file is part of FFmpeg.
6  *
7  * FFmpeg is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * FFmpeg is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with FFmpeg; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
22 /**
23  * @file
24  * Delphine Software International CIN audio/video decoders
25  */
26 
28 #include "avcodec.h"
29 #include "bytestream.h"
30 #include "internal.h"
31 #include "mathops.h"
32 
33 
34 typedef enum CinVideoBitmapIndex {
35  CIN_CUR_BMP = 0, /* current */
36  CIN_PRE_BMP = 1, /* previous */
37  CIN_INT_BMP = 2 /* intermediate */
39 
40 typedef struct CinVideoContext {
43  unsigned int bitmap_size;
44  uint32_t palette[256];
45  uint8_t *bitmap_table[3];
47 
48 typedef struct CinAudioContext {
50  int delta;
52 
53 
54 /* table defining a geometric sequence with multiplier = 32767 ^ (1 / 128) */
55 static const int16_t cinaudio_delta16_table[256] = {
56  0, 0, 0, 0, 0, 0, 0, 0,
57  0, 0, 0, 0, 0, 0, 0, 0,
58  0, 0, 0, -30210, -27853, -25680, -23677, -21829,
59  -20126, -18556, -17108, -15774, -14543, -13408, -12362, -11398,
60  -10508, -9689, -8933, -8236, -7593, -7001, -6455, -5951,
61  -5487, -5059, -4664, -4300, -3964, -3655, -3370, -3107,
62  -2865, -2641, -2435, -2245, -2070, -1908, -1759, -1622,
63  -1495, -1379, -1271, -1172, -1080, -996, -918, -847,
64  -781, -720, -663, -612, -564, -520, -479, -442,
65  -407, -376, -346, -319, -294, -271, -250, -230,
66  -212, -196, -181, -166, -153, -141, -130, -120,
67  -111, -102, -94, -87, -80, -74, -68, -62,
68  -58, -53, -49, -45, -41, -38, -35, -32,
69  -30, -27, -25, -23, -21, -20, -18, -17,
70  -15, -14, -13, -12, -11, -10, -9, -8,
71  -7, -6, -5, -4, -3, -2, -1, 0,
72  0, 1, 2, 3, 4, 5, 6, 7,
73  8, 9, 10, 11, 12, 13, 14, 15,
74  17, 18, 20, 21, 23, 25, 27, 30,
75  32, 35, 38, 41, 45, 49, 53, 58,
76  62, 68, 74, 80, 87, 94, 102, 111,
77  120, 130, 141, 153, 166, 181, 196, 212,
78  230, 250, 271, 294, 319, 346, 376, 407,
79  442, 479, 520, 564, 612, 663, 720, 781,
80  847, 918, 996, 1080, 1172, 1271, 1379, 1495,
81  1622, 1759, 1908, 2070, 2245, 2435, 2641, 2865,
82  3107, 3370, 3655, 3964, 4300, 4664, 5059, 5487,
83  5951, 6455, 7001, 7593, 8236, 8933, 9689, 10508,
84  11398, 12362, 13408, 14543, 15774, 17108, 18556, 20126,
85  21829, 23677, 25680, 27853, 30210, 0, 0, 0,
86  0, 0, 0, 0, 0, 0, 0, 0,
87  0, 0, 0, 0, 0, 0, 0, 0
88 };
89 
91 {
92  int i;
93 
94  for (i = 0; i < 3; ++i)
95  av_freep(&cin->bitmap_table[i]);
96 }
97 
99 {
100  int i;
101 
102  for (i = 0; i < 3; ++i) {
103  cin->bitmap_table[i] = av_mallocz(cin->bitmap_size);
104  if (!cin->bitmap_table[i]) {
105  av_log(cin->avctx, AV_LOG_ERROR, "Can't allocate bitmap buffers.\n");
106  destroy_buffers(cin);
107  return AVERROR(ENOMEM);
108  }
109  }
110 
111  return 0;
112 }
113 
115 {
116  CinVideoContext *cin = avctx->priv_data;
117 
118  cin->avctx = avctx;
119  avctx->pix_fmt = AV_PIX_FMT_PAL8;
120 
122 
123  cin->bitmap_size = avctx->width * avctx->height;
124  if (allocate_buffers(cin))
125  return AVERROR(ENOMEM);
126 
127  return 0;
128 }
129 
130 static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
131 {
132  while (size--)
133  *dst++ += *src++;
134 }
135 
136 static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
137 {
138  int b, huff_code = 0;
139  unsigned char huff_code_table[15];
140  unsigned char *dst_cur = dst;
141  unsigned char *dst_end = dst + dst_size;
142  const unsigned char *src_end = src + src_size;
143 
144  memcpy(huff_code_table, src, 15); src += 15;
145 
146  while (src < src_end) {
147  huff_code = *src++;
148  if ((huff_code >> 4) == 15) {
149  b = huff_code << 4;
150  huff_code = *src++;
151  *dst_cur++ = b | (huff_code >> 4);
152  } else
153  *dst_cur++ = huff_code_table[huff_code >> 4];
154  if (dst_cur >= dst_end)
155  break;
156 
157  huff_code &= 15;
158  if (huff_code == 15) {
159  *dst_cur++ = *src++;
160  } else
161  *dst_cur++ = huff_code_table[huff_code];
162  if (dst_cur >= dst_end)
163  break;
164  }
165 
166  return dst_cur - dst;
167 }
168 
169 static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
170 {
171  uint16_t cmd;
172  int i, sz, offset, code;
173  unsigned char *dst_end = dst + dst_size, *dst_start = dst;
174  const unsigned char *src_end = src + src_size;
175 
176  while (src < src_end && dst < dst_end) {
177  code = *src++;
178  for (i = 0; i < 8 && src < src_end && dst < dst_end; ++i) {
179  if (code & (1 << i)) {
180  *dst++ = *src++;
181  } else {
182  cmd = AV_RL16(src); src += 2;
183  offset = cmd >> 4;
184  if ((int) (dst - dst_start) < offset + 1)
185  return AVERROR_INVALIDDATA;
186  sz = (cmd & 0xF) + 2;
187  /* don't use memcpy/memmove here as the decoding routine (ab)uses */
188  /* buffer overlappings to repeat bytes in the destination */
189  sz = FFMIN(sz, dst_end - dst);
190  while (sz--) {
191  *dst = *(dst - offset - 1);
192  ++dst;
193  }
194  }
195  }
196  }
197 
198  return 0;
199 }
200 
201 static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
202 {
203  int len, code;
204  unsigned char *dst_end = dst + dst_size;
205  const unsigned char *src_end = src + src_size;
206 
207  while (src + 1 < src_end && dst < dst_end) {
208  code = *src++;
209  if (code & 0x80) {
210  len = code - 0x7F;
211  memset(dst, *src++, FFMIN(len, dst_end - dst));
212  } else {
213  len = code + 1;
214  if (len > src_end-src) {
215  av_log(NULL, AV_LOG_ERROR, "RLE overread\n");
216  return AVERROR_INVALIDDATA;
217  }
218  memcpy(dst, src, FFMIN(len, dst_end - dst));
219  src += len;
220  }
221  dst += len;
222  }
223  return 0;
224 }
225 
227  void *data, int *got_frame,
228  AVPacket *avpkt)
229 {
230  const uint8_t *buf = avpkt->data;
231  int buf_size = avpkt->size;
232  CinVideoContext *cin = avctx->priv_data;
233  int i, y, palette_type, palette_colors_count, bitmap_frame_type, bitmap_frame_size, res = 0;
234 
235  palette_type = buf[0];
236  palette_colors_count = AV_RL16(buf+1);
237  bitmap_frame_type = buf[3];
238  buf += 4;
239 
240  bitmap_frame_size = buf_size - 4;
241 
242  /* handle palette */
243  if (bitmap_frame_size < palette_colors_count * (3 + (palette_type != 0)))
244  return AVERROR_INVALIDDATA;
245  if (palette_type == 0) {
246  if (palette_colors_count > 256)
247  return AVERROR_INVALIDDATA;
248  for (i = 0; i < palette_colors_count; ++i) {
249  cin->palette[i] = 0xFFU << 24 | bytestream_get_le24(&buf);
250  bitmap_frame_size -= 3;
251  }
252  } else {
253  for (i = 0; i < palette_colors_count; ++i) {
254  cin->palette[buf[0]] = 0xFFU << 24 | AV_RL24(buf+1);
255  buf += 4;
256  bitmap_frame_size -= 4;
257  }
258  }
259 
260  /* note: the decoding routines below assumes that surface.width = surface.pitch */
261  switch (bitmap_frame_type) {
262  case 9:
263  cin_decode_rle(buf, bitmap_frame_size,
264  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
265  break;
266  case 34:
267  cin_decode_rle(buf, bitmap_frame_size,
268  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
270  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
271  break;
272  case 35:
273  bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
274  cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
275  cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
276  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
277  break;
278  case 36:
279  bitmap_frame_size = cin_decode_huffman(buf, bitmap_frame_size,
280  cin->bitmap_table[CIN_INT_BMP], cin->bitmap_size);
281  cin_decode_rle(cin->bitmap_table[CIN_INT_BMP], bitmap_frame_size,
282  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
284  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
285  break;
286  case 37:
287  cin_decode_huffman(buf, bitmap_frame_size,
288  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
289  break;
290  case 38:
291  res = cin_decode_lzss(buf, bitmap_frame_size,
293  cin->bitmap_size);
294  if (res < 0)
295  return res;
296  break;
297  case 39:
298  res = cin_decode_lzss(buf, bitmap_frame_size,
300  cin->bitmap_size);
301  if (res < 0)
302  return res;
304  cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_size);
305  break;
306  }
307 
308  if ((res = ff_reget_buffer(avctx, &cin->frame)) < 0)
309  return res;
310 
311  memcpy(cin->frame.data[1], cin->palette, sizeof(cin->palette));
312  cin->frame.palette_has_changed = 1;
313  for (y = 0; y < cin->avctx->height; ++y)
314  memcpy(cin->frame.data[0] + (cin->avctx->height - 1 - y) * cin->frame.linesize[0],
315  cin->bitmap_table[CIN_CUR_BMP] + y * cin->avctx->width,
316  cin->avctx->width);
317 
318  FFSWAP(uint8_t *, cin->bitmap_table[CIN_CUR_BMP], cin->bitmap_table[CIN_PRE_BMP]);
319 
320  if ((res = av_frame_ref(data, &cin->frame)) < 0)
321  return res;
322 
323  *got_frame = 1;
324 
325  return buf_size;
326 }
327 
329 {
330  CinVideoContext *cin = avctx->priv_data;
331 
332  av_frame_unref(&cin->frame);
333 
334  destroy_buffers(cin);
335 
336  return 0;
337 }
338 
340 {
341  CinAudioContext *cin = avctx->priv_data;
342 
343  cin->initial_decode_frame = 1;
344  cin->delta = 0;
345  avctx->sample_fmt = AV_SAMPLE_FMT_S16;
346  avctx->channels = 1;
348 
349  return 0;
350 }
351 
353  int *got_frame_ptr, AVPacket *avpkt)
354 {
355  AVFrame *frame = data;
356  const uint8_t *buf = avpkt->data;
357  CinAudioContext *cin = avctx->priv_data;
358  const uint8_t *buf_end = buf + avpkt->size;
359  int16_t *samples;
360  int delta, ret;
361 
362  /* get output buffer */
363  frame->nb_samples = avpkt->size - cin->initial_decode_frame;
364  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
365  return ret;
366  samples = (int16_t *)frame->data[0];
367 
368  delta = cin->delta;
369  if (cin->initial_decode_frame) {
370  cin->initial_decode_frame = 0;
371  delta = sign_extend(AV_RL16(buf), 16);
372  buf += 2;
373  *samples++ = delta;
374  }
375  while (buf < buf_end) {
376  delta += cinaudio_delta16_table[*buf++];
377  delta = av_clip_int16(delta);
378  *samples++ = delta;
379  }
380  cin->delta = delta;
381 
382  *got_frame_ptr = 1;
383 
384  return avpkt->size;
385 }
386 
387 
389  .name = "dsicinvideo",
390  .type = AVMEDIA_TYPE_VIDEO,
392  .priv_data_size = sizeof(CinVideoContext),
396  .capabilities = CODEC_CAP_DR1,
397  .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN video"),
398 };
399 
401  .name = "dsicinaudio",
402  .type = AVMEDIA_TYPE_AUDIO,
404  .priv_data_size = sizeof(CinAudioContext),
407  .capabilities = CODEC_CAP_DR1,
408  .long_name = NULL_IF_CONFIG_SMALL("Delphine Software International CIN audio"),
409 };
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
int size
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
static av_cold int cinvideo_decode_init(AVCodecContext *avctx)
Definition: dsicinav.c:114
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
#define AV_RL16
AVCodecContext * avctx
Definition: dsicinav.c:41
signed 16 bits
Definition: samplefmt.h:52
static int cinaudio_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: dsicinav.c:352
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:198
initialize output if(nPeaks >3)%at least 3 peaks in spectrum for trying to find f0 nf0peaks
CinVideoBitmapIndex
Definition: dsicinav.c:34
static int cin_decode_lzss(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
Definition: dsicinav.c:169
enum AVSampleFormat sample_fmt
audio sample format
#define av_cold
Definition: attributes.h:78
float delta
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define b
Definition: input.c:42
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
uint8_t * data[8]
pointer to the picture/channel planes.
Definition: frame.h:87
#define U(x)
AVFrame frame
Definition: dsicinav.c:42
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
uint8_t * bitmap_table[3]
Definition: dsicinav.c:45
Spectrum Plot time data
struct CinVideoContext CinVideoContext
void av_log(void *avcl, int level, const char *fmt,...)
Send the specified message to the log if the level is less than or equal to the current av_log_level...
Definition: log.c:246
const char * name
Name of the codec implementation.
static const uint8_t offset[127][2]
Definition: vf_spp.c:70
external API header
uint64_t channel_layout
Audio channel layout.
static const int16_t cinaudio_delta16_table[256]
Definition: dsicinav.c:55
static av_cold void destroy_buffers(CinVideoContext *cin)
Definition: dsicinav.c:90
int ff_reget_buffer(AVCodecContext *avctx, AVFrame *frame)
Identical in function to av_frame_make_writable(), except it uses ff_get_buffer() to allocate the buf...
void * av_mallocz(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:205
audio channel layout utility functions
#define FFMIN(a, b)
Definition: common.h:58
AVCodec ff_dsicinaudio_decoder
Definition: dsicinav.c:400
ret
Definition: avfilter.c:821
int width
picture width / height.
static int cin_decode_rle(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
Definition: dsicinav.c:201
NULL
Definition: eval.c:55
or the Software in violation of any applicable export control laws in any jurisdiction Except as provided by mandatorily applicable UPF has no obligation to provide you with source code to the Software In the event Software contains any source code
static av_cold int cinvideo_decode_end(AVCodecContext *avctx)
Definition: dsicinav.c:328
AVS_Value src
Definition: avisynth_c.h:523
main external API structure.
static void close(AVCodecParserContext *s)
Definition: h264_parser.c:375
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:148
void * buf
Definition: avisynth_c.h:594
void avcodec_get_frame_defaults(AVFrame *frame)
Set the fields of the given AVFrame to default values.
synthesis window for stochastic i
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:280
void av_frame_unref(AVFrame *frame)
Unreference all the buffers referenced by frame and reset the frame fields.
Definition: frame.c:330
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFilterBuffer 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.Buffer references ownership and permissions
struct CinAudioContext CinAudioContext
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:123
#define AV_RL24
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
static av_cold int allocate_buffers(CinVideoContext *cin)
Definition: dsicinav.c:98
static void cin_apply_delta_data(const unsigned char *src, unsigned char *dst, int size)
Definition: dsicinav.c:130
common internal api header.
function y
Definition: D.m:1
int linesize[8]
For video, size in bytes of each picture line.
Definition: frame.h:101
static int cin_decode_huffman(const unsigned char *src, int src_size, unsigned char *dst, int dst_size)
Definition: dsicinav.c:136
int len
int channels
number of audio channels
static int cinvideo_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: dsicinav.c:226
Filter the word “frame” indicates either a video frame or a group of audio samples
static av_cold int cinaudio_decode_init(AVCodecContext *avctx)
Definition: dsicinav.c:339
unsigned int bitmap_size
Definition: dsicinav.c:43
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
AVCodec ff_dsicinvideo_decoder
Definition: dsicinav.c:388
#define FFSWAP(type, a, b)
Definition: common.h:61
static av_always_inline unsigned int bytestream_get_le24(const uint8_t **b)
Definition: bytestream.h:86
#define AV_CH_LAYOUT_MONO
uint32_t palette[256]
Definition: dsicinav.c:44
int initial_decode_frame
Definition: dsicinav.c:49
This structure stores compressed data.
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:127