Libav
dpcm.c
Go to the documentation of this file.
1 /*
2  * Assorted DPCM codecs
3  * Copyright (c) 2003 The ffmpeg Project
4  *
5  * This file is part of Libav.
6  *
7  * Libav 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  * Libav 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 Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
40 #include "libavutil/intreadwrite.h"
41 #include "avcodec.h"
42 #include "bytestream.h"
43 #include "internal.h"
44 #include "mathops.h"
45 
46 typedef struct DPCMContext {
47  int16_t roq_square_array[256];
48  int sample[2];
49  const int8_t *sol_table;
50 } DPCMContext;
51 
52 static const int16_t interplay_delta_table[] = {
53  0, 1, 2, 3, 4, 5, 6, 7,
54  8, 9, 10, 11, 12, 13, 14, 15,
55  16, 17, 18, 19, 20, 21, 22, 23,
56  24, 25, 26, 27, 28, 29, 30, 31,
57  32, 33, 34, 35, 36, 37, 38, 39,
58  40, 41, 42, 43, 47, 51, 56, 61,
59  66, 72, 79, 86, 94, 102, 112, 122,
60  133, 145, 158, 173, 189, 206, 225, 245,
61  267, 292, 318, 348, 379, 414, 452, 493,
62  538, 587, 640, 699, 763, 832, 908, 991,
63  1081, 1180, 1288, 1405, 1534, 1673, 1826, 1993,
64  2175, 2373, 2590, 2826, 3084, 3365, 3672, 4008,
65  4373, 4772, 5208, 5683, 6202, 6767, 7385, 8059,
66  8794, 9597, 10472, 11428, 12471, 13609, 14851, 16206,
67  17685, 19298, 21060, 22981, 25078, 27367, 29864, 32589,
68  -29973, -26728, -23186, -19322, -15105, -10503, -5481, -1,
69  1, 1, 5481, 10503, 15105, 19322, 23186, 26728,
70  29973, -32589, -29864, -27367, -25078, -22981, -21060, -19298,
71  -17685, -16206, -14851, -13609, -12471, -11428, -10472, -9597,
72  -8794, -8059, -7385, -6767, -6202, -5683, -5208, -4772,
73  -4373, -4008, -3672, -3365, -3084, -2826, -2590, -2373,
74  -2175, -1993, -1826, -1673, -1534, -1405, -1288, -1180,
75  -1081, -991, -908, -832, -763, -699, -640, -587,
76  -538, -493, -452, -414, -379, -348, -318, -292,
77  -267, -245, -225, -206, -189, -173, -158, -145,
78  -133, -122, -112, -102, -94, -86, -79, -72,
79  -66, -61, -56, -51, -47, -43, -42, -41,
80  -40, -39, -38, -37, -36, -35, -34, -33,
81  -32, -31, -30, -29, -28, -27, -26, -25,
82  -24, -23, -22, -21, -20, -19, -18, -17,
83  -16, -15, -14, -13, -12, -11, -10, -9,
84  -8, -7, -6, -5, -4, -3, -2, -1
85 
86 };
87 
88 static const int8_t sol_table_old[16] = {
89  0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
90  -0x15, -0xF, -0xA, -0x6, -0x3, -0x2, -0x1, 0x0
91 };
92 
93 static const int8_t sol_table_new[16] = {
94  0x0, 0x1, 0x2, 0x3, 0x6, 0xA, 0xF, 0x15,
95  0x0, -0x1, -0x2, -0x3, -0x6, -0xA, -0xF, -0x15
96 };
97 
98 static const int16_t sol_table_16[128] = {
99  0x000, 0x008, 0x010, 0x020, 0x030, 0x040, 0x050, 0x060, 0x070, 0x080,
100  0x090, 0x0A0, 0x0B0, 0x0C0, 0x0D0, 0x0E0, 0x0F0, 0x100, 0x110, 0x120,
101  0x130, 0x140, 0x150, 0x160, 0x170, 0x180, 0x190, 0x1A0, 0x1B0, 0x1C0,
102  0x1D0, 0x1E0, 0x1F0, 0x200, 0x208, 0x210, 0x218, 0x220, 0x228, 0x230,
103  0x238, 0x240, 0x248, 0x250, 0x258, 0x260, 0x268, 0x270, 0x278, 0x280,
104  0x288, 0x290, 0x298, 0x2A0, 0x2A8, 0x2B0, 0x2B8, 0x2C0, 0x2C8, 0x2D0,
105  0x2D8, 0x2E0, 0x2E8, 0x2F0, 0x2F8, 0x300, 0x308, 0x310, 0x318, 0x320,
106  0x328, 0x330, 0x338, 0x340, 0x348, 0x350, 0x358, 0x360, 0x368, 0x370,
107  0x378, 0x380, 0x388, 0x390, 0x398, 0x3A0, 0x3A8, 0x3B0, 0x3B8, 0x3C0,
108  0x3C8, 0x3D0, 0x3D8, 0x3E0, 0x3E8, 0x3F0, 0x3F8, 0x400, 0x440, 0x480,
109  0x4C0, 0x500, 0x540, 0x580, 0x5C0, 0x600, 0x640, 0x680, 0x6C0, 0x700,
110  0x740, 0x780, 0x7C0, 0x800, 0x900, 0xA00, 0xB00, 0xC00, 0xD00, 0xE00,
111  0xF00, 0x1000, 0x1400, 0x1800, 0x1C00, 0x2000, 0x3000, 0x4000
112 };
113 
114 
116 {
117  DPCMContext *s = avctx->priv_data;
118  int i;
119 
120  if (avctx->channels < 1 || avctx->channels > 2) {
121  av_log(avctx, AV_LOG_INFO, "invalid number of channels\n");
122  return AVERROR(EINVAL);
123  }
124 
125  s->sample[0] = s->sample[1] = 0;
126 
127  switch(avctx->codec->id) {
128 
130  /* initialize square table */
131  for (i = 0; i < 128; i++) {
132  int16_t square = i * i;
133  s->roq_square_array[i ] = square;
134  s->roq_square_array[i + 128] = -square;
135  }
136  break;
137 
139  switch(avctx->codec_tag){
140  case 1:
142  s->sample[0] = s->sample[1] = 0x80;
143  break;
144  case 2:
146  s->sample[0] = s->sample[1] = 0x80;
147  break;
148  case 3:
149  break;
150  default:
151  av_log(avctx, AV_LOG_ERROR, "Unknown SOL subcodec\n");
152  return -1;
153  }
154  break;
155 
156  default:
157  break;
158  }
159 
160  if (avctx->codec->id == AV_CODEC_ID_SOL_DPCM && avctx->codec_tag != 3)
161  avctx->sample_fmt = AV_SAMPLE_FMT_U8;
162  else
163  avctx->sample_fmt = AV_SAMPLE_FMT_S16;
164 
165  return 0;
166 }
167 
168 
169 static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
170  int *got_frame_ptr, AVPacket *avpkt)
171 {
172  int buf_size = avpkt->size;
173  DPCMContext *s = avctx->priv_data;
174  AVFrame *frame = data;
175  int out = 0, ret;
176  int predictor[2];
177  int ch = 0;
178  int stereo = avctx->channels - 1;
179  int16_t *output_samples, *samples_end;
180  GetByteContext gb;
181 
182  if (stereo && (buf_size & 1))
183  buf_size--;
184  bytestream2_init(&gb, avpkt->data, buf_size);
185 
186  /* calculate output size */
187  switch(avctx->codec->id) {
189  out = buf_size - 8;
190  break;
192  out = buf_size - 6 - avctx->channels;
193  break;
195  out = buf_size - 2 * avctx->channels;
196  break;
198  if (avctx->codec_tag != 3)
199  out = buf_size * 2;
200  else
201  out = buf_size;
202  break;
203  }
204  if (out <= 0) {
205  av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
206  return AVERROR(EINVAL);
207  }
208 
209  /* get output buffer */
210  frame->nb_samples = out / avctx->channels;
211  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
212  av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
213  return ret;
214  }
215  output_samples = (int16_t *)frame->data[0];
216  samples_end = output_samples + out;
217 
218  switch(avctx->codec->id) {
219 
221  bytestream2_skipu(&gb, 6);
222 
223  if (stereo) {
224  predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
225  predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
226  } else {
227  predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16);
228  }
229 
230  /* decode the samples */
231  while (output_samples < samples_end) {
232  predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)];
233  predictor[ch] = av_clip_int16(predictor[ch]);
234  *output_samples++ = predictor[ch];
235 
236  /* toggle channel */
237  ch ^= stereo;
238  }
239  break;
240 
242  bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */
243 
244  for (ch = 0; ch < avctx->channels; ch++) {
245  predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
246  *output_samples++ = predictor[ch];
247  }
248 
249  ch = 0;
250  while (output_samples < samples_end) {
251  predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)];
252  predictor[ch] = av_clip_int16(predictor[ch]);
253  *output_samples++ = predictor[ch];
254 
255  /* toggle channel */
256  ch ^= stereo;
257  }
258  break;
259 
261  {
262  int shift[2] = { 4, 4 };
263 
264  for (ch = 0; ch < avctx->channels; ch++)
265  predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
266 
267  ch = 0;
268  while (output_samples < samples_end) {
269  int diff = bytestream2_get_byteu(&gb);
270  int n = diff & 3;
271 
272  if (n == 3)
273  shift[ch]++;
274  else
275  shift[ch] -= (2 * n);
276  diff = sign_extend((diff &~ 3) << 8, 16);
277 
278  /* saturate the shifter to a lower limit of 0 */
279  if (shift[ch] < 0)
280  shift[ch] = 0;
281 
282  diff >>= shift[ch];
283  predictor[ch] += diff;
284 
285  predictor[ch] = av_clip_int16(predictor[ch]);
286  *output_samples++ = predictor[ch];
287 
288  /* toggle channel */
289  ch ^= stereo;
290  }
291  break;
292  }
294  if (avctx->codec_tag != 3) {
295  uint8_t *output_samples_u8 = frame->data[0],
296  *samples_end_u8 = output_samples_u8 + out;
297  while (output_samples_u8 < samples_end_u8) {
298  int n = bytestream2_get_byteu(&gb);
299 
300  s->sample[0] += s->sol_table[n >> 4];
301  s->sample[0] = av_clip_uint8(s->sample[0]);
302  *output_samples_u8++ = s->sample[0];
303 
304  s->sample[stereo] += s->sol_table[n & 0x0F];
305  s->sample[stereo] = av_clip_uint8(s->sample[stereo]);
306  *output_samples_u8++ = s->sample[stereo];
307  }
308  } else {
309  while (output_samples < samples_end) {
310  int n = bytestream2_get_byteu(&gb);
311  if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
312  else s->sample[ch] += sol_table_16[n & 0x7F];
313  s->sample[ch] = av_clip_int16(s->sample[ch]);
314  *output_samples++ = s->sample[ch];
315  /* toggle channel */
316  ch ^= stereo;
317  }
318  }
319  break;
320  }
321 
322  *got_frame_ptr = 1;
323 
324  return avpkt->size;
325 }
326 
327 #define DPCM_DECODER(id_, name_, long_name_) \
328 AVCodec ff_ ## name_ ## _decoder = { \
329  .name = #name_, \
330  .long_name = NULL_IF_CONFIG_SMALL(long_name_), \
331  .type = AVMEDIA_TYPE_AUDIO, \
332  .id = id_, \
333  .priv_data_size = sizeof(DPCMContext), \
334  .init = dpcm_decode_init, \
335  .decode = dpcm_decode_frame, \
336  .capabilities = CODEC_CAP_DR1, \
337 }
338 
339 DPCM_DECODER(AV_CODEC_ID_INTERPLAY_DPCM, interplay_dpcm, "DPCM Interplay");
340 DPCM_DECODER(AV_CODEC_ID_ROQ_DPCM, roq_dpcm, "DPCM id RoQ");
341 DPCM_DECODER(AV_CODEC_ID_SOL_DPCM, sol_dpcm, "DPCM Sol");
342 DPCM_DECODER(AV_CODEC_ID_XAN_DPCM, xan_dpcm, "DPCM Xan");
const struct AVCodec * codec
Definition: avcodec.h:1059
int16_t roq_square_array[256]
Definition: dpcm.c:47
This structure describes decoded (raw) audio or video data.
Definition: frame.h:135
static const int8_t sol_table_old[16]
Definition: dpcm.c:88
int size
Definition: avcodec.h:974
const int8_t * sol_table
delta table for SOL_DPCM
Definition: dpcm.c:49
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:132
uint8_t pi<< 24) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0f/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_U8, uint8_t,(*(const uint8_t *) pi - 0x80) *(1.0/(1<< 7))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S16, int16_t,(*(const int16_t *) pi >> 8)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0f/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S16, int16_t, *(const int16_t *) pi *(1.0/(1<< 15))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_S32, int32_t,(*(const int32_t *) pi >> 24)+0x80) CONV_FUNC_GROUP(AV_SAMPLE_FMT_FLT, float, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0f/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_DBL, double, AV_SAMPLE_FMT_S32, int32_t, *(const int32_t *) pi *(1.0/(1U<< 31))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_FLT, float, av_clip_uint8(lrintf(*(const float *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_FLT, float, av_clip_int16(lrintf(*(const float *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_FLT, float, av_clipl_int32(llrintf(*(const float *) pi *(1U<< 31)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_U8, uint8_t, AV_SAMPLE_FMT_DBL, double, av_clip_uint8(lrint(*(const double *) pi *(1<< 7))+0x80)) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S16, int16_t, AV_SAMPLE_FMT_DBL, double, av_clip_int16(lrint(*(const double *) pi *(1<< 15)))) CONV_FUNC_GROUP(AV_SAMPLE_FMT_S32, int32_t, AV_SAMPLE_FMT_DBL, double, av_clipl_int32(llrint(*(const double *) pi *(1U<< 31)))) #define SET_CONV_FUNC_GROUP(ofmt, ifmt) static void set_generic_function(AudioConvert *ac) { } void ff_audio_convert_free(AudioConvert **ac) { if(! *ac) return;ff_dither_free(&(*ac) ->dc);av_freep(ac);} AudioConvert *ff_audio_convert_alloc(AVAudioResampleContext *avr, enum AVSampleFormat out_fmt, enum AVSampleFormat in_fmt, int channels, int sample_rate, int apply_map) { AudioConvert *ac;int in_planar, out_planar;ac=av_mallocz(sizeof(*ac));if(!ac) return NULL;ac->avr=avr;ac->out_fmt=out_fmt;ac->in_fmt=in_fmt;ac->channels=channels;ac->apply_map=apply_map;if(avr->dither_method !=AV_RESAMPLE_DITHER_NONE &&av_get_packed_sample_fmt(out_fmt)==AV_SAMPLE_FMT_S16 &&av_get_bytes_per_sample(in_fmt) > 2) { ac->dc=ff_dither_alloc(avr, out_fmt, in_fmt, channels, sample_rate, apply_map);if(!ac->dc) { av_free(ac);return NULL;} return ac;} in_planar=ff_sample_fmt_is_planar(in_fmt, channels);out_planar=ff_sample_fmt_is_planar(out_fmt, channels);if(in_planar==out_planar) { ac->func_type=CONV_FUNC_TYPE_FLAT;ac->planes=in_planar ? ac->channels :1;} else if(in_planar) ac->func_type=CONV_FUNC_TYPE_INTERLEAVE;else ac->func_type=CONV_FUNC_TYPE_DEINTERLEAVE;set_generic_function(ac);if(ARCH_AARCH64) ff_audio_convert_init_aarch64(ac);if(ARCH_ARM) ff_audio_convert_init_arm(ac);if(ARCH_X86) ff_audio_convert_init_x86(ac);return ac;} int ff_audio_convert(AudioConvert *ac, AudioData *out, AudioData *in) { int use_generic=1;int len=in->nb_samples;int p;if(ac->dc) { av_dlog(ac->avr, "%d samples - audio_convert: %s to %s (dithered)\", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
enum AVSampleFormat sample_fmt
audio sample format
Definition: avcodec.h:1815
uint8_t
#define av_cold
Definition: attributes.h:66
AV_SAMPLE_FMT_U8
static const int16_t interplay_delta_table[]
Definition: dpcm.c:52
const char data[16]
Definition: mxf.c:70
uint8_t * data
Definition: avcodec.h:973
static av_always_inline void bytestream2_skipu(GetByteContext *g, unsigned int size)
Definition: bytestream.h:167
static void predictor(uint8_t *src, int size)
Definition: exr.c:151
enum AVCodecID id
Definition: avcodec.h:2826
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:123
static const int8_t sol_table_new[16]
Definition: dpcm.c:93
#define AVERROR(e)
Definition: error.h:43
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *got_frame_ptr, AVPacket *avpkt)
Definition: dpcm.c:169
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:169
static int square(int x)
Definition: roqvideoenc.c:112
#define AV_LOG_INFO
Standard information.
Definition: log.h:134
Libavcodec external API header.
static const int16_t sol_table_16[128]
Definition: dpcm.c:98
main external API structure.
Definition: avcodec.h:1050
int ff_get_buffer(AVCodecContext *avctx, AVFrame *frame, int flags)
Get a buffer for a frame.
Definition: utils.c:612
unsigned int codec_tag
fourcc (LSB first, so "ABCD" -> (&#39;D&#39;<<24) + (&#39;C&#39;<<16) + (&#39;B&#39;<<8) + &#39;A&#39;).
Definition: avcodec.h:1082
static av_const int sign_extend(int val, unsigned bits)
Definition: mathops.h:127
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:141
#define DPCM_DECODER(id_, name_, long_name_)
Definition: dpcm.c:327
common internal api header.
signed 16 bits
Definition: samplefmt.h:64
static av_cold int dpcm_decode_init(AVCodecContext *avctx)
Definition: dpcm.c:115
void * priv_data
Definition: avcodec.h:1092
int channels
number of audio channels
Definition: avcodec.h:1808
This structure stores compressed data.
Definition: avcodec.h:950
int sample[2]
previous sample (for SOL_DPCM)
Definition: dpcm.c:48
int nb_samples
number of audio samples (per channel) described by this frame
Definition: frame.h:179