kmvc.c
Go to the documentation of this file.
1 /*
2  * KMVC decoder
3  * Copyright (c) 2006 Konstantin Shishkov
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  * Karl Morton's Video Codec decoder
25  */
26 
27 #include <stdio.h>
28 #include <stdlib.h>
29 
30 #include "avcodec.h"
31 #include "bytestream.h"
32 #include "internal.h"
33 
34 #define KMVC_KEYFRAME 0x80
35 #define KMVC_PALETTE 0x40
36 #define KMVC_METHOD 0x0F
37 #define MAX_PALSIZE 256
38 
39 /*
40  * Decoder context
41  */
42 typedef struct KmvcContext {
44 
45  int setpal;
46  int palsize;
47  uint32_t pal[MAX_PALSIZE];
51 } KmvcContext;
52 
53 typedef struct BitBuf {
54  int bits;
55  int bitbuf;
56 } BitBuf;
57 
58 #define BLK(data, x, y) data[(x) + (y) * 320]
59 
60 #define kmvc_init_getbits(bb, g) bb.bits = 7; bb.bitbuf = bytestream2_get_byte(g);
61 
62 #define kmvc_getbit(bb, g, res) {\
63  res = 0; \
64  if (bb.bitbuf & (1 << bb.bits)) res = 1; \
65  bb.bits--; \
66  if(bb.bits == -1) { \
67  bb.bitbuf = bytestream2_get_byte(g); \
68  bb.bits = 7; \
69  } \
70 }
71 
72 static int kmvc_decode_intra_8x8(KmvcContext * ctx, int w, int h)
73 {
74  BitBuf bb;
75  int res, val;
76  int i, j;
77  int bx, by;
78  int l0x, l1x, l0y, l1y;
79  int mx, my;
80 
81  kmvc_init_getbits(bb, &ctx->g);
82 
83  for (by = 0; by < h; by += 8)
84  for (bx = 0; bx < w; bx += 8) {
85  if (!bytestream2_get_bytes_left(&ctx->g)) {
86  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
87  return AVERROR_INVALIDDATA;
88  }
89  kmvc_getbit(bb, &ctx->g, res);
90  if (!res) { // fill whole 8x8 block
91  val = bytestream2_get_byte(&ctx->g);
92  for (i = 0; i < 64; i++)
93  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
94  } else { // handle four 4x4 subblocks
95  for (i = 0; i < 4; i++) {
96  l0x = bx + (i & 1) * 4;
97  l0y = by + (i & 2) * 2;
98  kmvc_getbit(bb, &ctx->g, res);
99  if (!res) {
100  kmvc_getbit(bb, &ctx->g, res);
101  if (!res) { // fill whole 4x4 block
102  val = bytestream2_get_byte(&ctx->g);
103  for (j = 0; j < 16; j++)
104  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
105  } else { // copy block from already decoded place
106  val = bytestream2_get_byte(&ctx->g);
107  mx = val & 0xF;
108  my = val >> 4;
109  if ((l0x-mx) + 320*(l0y-my) < 0 || (l0x-mx) + 320*(l0y-my) > 316*196) {
110  av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
111  return AVERROR_INVALIDDATA;
112  }
113  for (j = 0; j < 16; j++)
114  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
115  BLK(ctx->cur, l0x + (j & 3) - mx, l0y + (j >> 2) - my);
116  }
117  } else { // descend to 2x2 sub-sub-blocks
118  for (j = 0; j < 4; j++) {
119  l1x = l0x + (j & 1) * 2;
120  l1y = l0y + (j & 2);
121  kmvc_getbit(bb, &ctx->g, res);
122  if (!res) {
123  kmvc_getbit(bb, &ctx->g, res);
124  if (!res) { // fill whole 2x2 block
125  val = bytestream2_get_byte(&ctx->g);
126  BLK(ctx->cur, l1x, l1y) = val;
127  BLK(ctx->cur, l1x + 1, l1y) = val;
128  BLK(ctx->cur, l1x, l1y + 1) = val;
129  BLK(ctx->cur, l1x + 1, l1y + 1) = val;
130  } else { // copy block from already decoded place
131  val = bytestream2_get_byte(&ctx->g);
132  mx = val & 0xF;
133  my = val >> 4;
134  if ((l1x-mx) + 320*(l1y-my) < 0 || (l1x-mx) + 320*(l1y-my) > 318*198) {
135  av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
136  return AVERROR_INVALIDDATA;
137  }
138  BLK(ctx->cur, l1x, l1y) = BLK(ctx->cur, l1x - mx, l1y - my);
139  BLK(ctx->cur, l1x + 1, l1y) =
140  BLK(ctx->cur, l1x + 1 - mx, l1y - my);
141  BLK(ctx->cur, l1x, l1y + 1) =
142  BLK(ctx->cur, l1x - mx, l1y + 1 - my);
143  BLK(ctx->cur, l1x + 1, l1y + 1) =
144  BLK(ctx->cur, l1x + 1 - mx, l1y + 1 - my);
145  }
146  } else { // read values for block
147  BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
148  BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
149  BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
150  BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
151  }
152  }
153  }
154  }
155  }
156  }
157 
158  return 0;
159 }
160 
161 static int kmvc_decode_inter_8x8(KmvcContext * ctx, int w, int h)
162 {
163  BitBuf bb;
164  int res, val;
165  int i, j;
166  int bx, by;
167  int l0x, l1x, l0y, l1y;
168  int mx, my;
169 
170  kmvc_init_getbits(bb, &ctx->g);
171 
172  for (by = 0; by < h; by += 8)
173  for (bx = 0; bx < w; bx += 8) {
174  kmvc_getbit(bb, &ctx->g, res);
175  if (!res) {
176  kmvc_getbit(bb, &ctx->g, res);
177  if (!res) { // fill whole 8x8 block
178  if (!bytestream2_get_bytes_left(&ctx->g)) {
179  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
180  return AVERROR_INVALIDDATA;
181  }
182  val = bytestream2_get_byte(&ctx->g);
183  for (i = 0; i < 64; i++)
184  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) = val;
185  } else { // copy block from previous frame
186  for (i = 0; i < 64; i++)
187  BLK(ctx->cur, bx + (i & 0x7), by + (i >> 3)) =
188  BLK(ctx->prev, bx + (i & 0x7), by + (i >> 3));
189  }
190  } else { // handle four 4x4 subblocks
191  if (!bytestream2_get_bytes_left(&ctx->g)) {
192  av_log(ctx->avctx, AV_LOG_ERROR, "Data overrun\n");
193  return AVERROR_INVALIDDATA;
194  }
195  for (i = 0; i < 4; i++) {
196  l0x = bx + (i & 1) * 4;
197  l0y = by + (i & 2) * 2;
198  kmvc_getbit(bb, &ctx->g, res);
199  if (!res) {
200  kmvc_getbit(bb, &ctx->g, res);
201  if (!res) { // fill whole 4x4 block
202  val = bytestream2_get_byte(&ctx->g);
203  for (j = 0; j < 16; j++)
204  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) = val;
205  } else { // copy block
206  val = bytestream2_get_byte(&ctx->g);
207  mx = (val & 0xF) - 8;
208  my = (val >> 4) - 8;
209  if ((l0x+mx) + 320*(l0y+my) < 0 || (l0x+mx) + 320*(l0y+my) > 318*198) {
210  av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
211  return AVERROR_INVALIDDATA;
212  }
213  for (j = 0; j < 16; j++)
214  BLK(ctx->cur, l0x + (j & 3), l0y + (j >> 2)) =
215  BLK(ctx->prev, l0x + (j & 3) + mx, l0y + (j >> 2) + my);
216  }
217  } else { // descend to 2x2 sub-sub-blocks
218  for (j = 0; j < 4; j++) {
219  l1x = l0x + (j & 1) * 2;
220  l1y = l0y + (j & 2);
221  kmvc_getbit(bb, &ctx->g, res);
222  if (!res) {
223  kmvc_getbit(bb, &ctx->g, res);
224  if (!res) { // fill whole 2x2 block
225  val = bytestream2_get_byte(&ctx->g);
226  BLK(ctx->cur, l1x, l1y) = val;
227  BLK(ctx->cur, l1x + 1, l1y) = val;
228  BLK(ctx->cur, l1x, l1y + 1) = val;
229  BLK(ctx->cur, l1x + 1, l1y + 1) = val;
230  } else { // copy block
231  val = bytestream2_get_byte(&ctx->g);
232  mx = (val & 0xF) - 8;
233  my = (val >> 4) - 8;
234  if ((l1x+mx) + 320*(l1y+my) < 0 || (l1x+mx) + 320*(l1y+my) > 318*198) {
235  av_log(ctx->avctx, AV_LOG_ERROR, "Invalid MV\n");
236  return AVERROR_INVALIDDATA;
237  }
238  BLK(ctx->cur, l1x, l1y) = BLK(ctx->prev, l1x + mx, l1y + my);
239  BLK(ctx->cur, l1x + 1, l1y) =
240  BLK(ctx->prev, l1x + 1 + mx, l1y + my);
241  BLK(ctx->cur, l1x, l1y + 1) =
242  BLK(ctx->prev, l1x + mx, l1y + 1 + my);
243  BLK(ctx->cur, l1x + 1, l1y + 1) =
244  BLK(ctx->prev, l1x + 1 + mx, l1y + 1 + my);
245  }
246  } else { // read values for block
247  BLK(ctx->cur, l1x, l1y) = bytestream2_get_byte(&ctx->g);
248  BLK(ctx->cur, l1x + 1, l1y) = bytestream2_get_byte(&ctx->g);
249  BLK(ctx->cur, l1x, l1y + 1) = bytestream2_get_byte(&ctx->g);
250  BLK(ctx->cur, l1x + 1, l1y + 1) = bytestream2_get_byte(&ctx->g);
251  }
252  }
253  }
254  }
255  }
256  }
257 
258  return 0;
259 }
260 
261 static int decode_frame(AVCodecContext * avctx, void *data, int *got_frame,
262  AVPacket *avpkt)
263 {
264  KmvcContext *const ctx = avctx->priv_data;
265  AVFrame *frame = data;
266  uint8_t *out, *src;
267  int i, ret;
268  int header;
269  int blocksize;
271 
272  bytestream2_init(&ctx->g, avpkt->data, avpkt->size);
273 
274  if ((ret = ff_get_buffer(avctx, frame, 0)) < 0)
275  return ret;
276 
277  header = bytestream2_get_byte(&ctx->g);
278 
279  /* blocksize 127 is really palette change event */
280  if (bytestream2_peek_byte(&ctx->g) == 127) {
281  bytestream2_skip(&ctx->g, 3);
282  for (i = 0; i < 127; i++) {
283  ctx->pal[i + (header & 0x81)] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
284  bytestream2_skip(&ctx->g, 1);
285  }
286  bytestream2_seek(&ctx->g, -127 * 4 - 3, SEEK_CUR);
287  }
288 
289  if (header & KMVC_KEYFRAME) {
290  frame->key_frame = 1;
291  frame->pict_type = AV_PICTURE_TYPE_I;
292  } else {
293  frame->key_frame = 0;
294  frame->pict_type = AV_PICTURE_TYPE_P;
295  }
296 
297  if (header & KMVC_PALETTE) {
298  frame->palette_has_changed = 1;
299  // palette starts from index 1 and has 127 entries
300  for (i = 1; i <= ctx->palsize; i++) {
301  ctx->pal[i] = 0xFFU << 24 | bytestream2_get_be24(&ctx->g);
302  }
303  }
304 
305  if (pal) {
306  frame->palette_has_changed = 1;
307  memcpy(ctx->pal, pal, AVPALETTE_SIZE);
308  }
309 
310  if (ctx->setpal) {
311  ctx->setpal = 0;
312  frame->palette_has_changed = 1;
313  }
314 
315  /* make the palette available on the way out */
316  memcpy(frame->data[1], ctx->pal, 1024);
317 
318  blocksize = bytestream2_get_byte(&ctx->g);
319 
320  if (blocksize != 8 && blocksize != 127) {
321  av_log(avctx, AV_LOG_ERROR, "Block size = %i\n", blocksize);
322  return AVERROR_INVALIDDATA;
323  }
324  memset(ctx->cur, 0, 320 * 200);
325  switch (header & KMVC_METHOD) {
326  case 0:
327  case 1: // used in palette changed event
328  memcpy(ctx->cur, ctx->prev, 320 * 200);
329  break;
330  case 3:
331  kmvc_decode_intra_8x8(ctx, avctx->width, avctx->height);
332  break;
333  case 4:
334  kmvc_decode_inter_8x8(ctx, avctx->width, avctx->height);
335  break;
336  default:
337  av_log(avctx, AV_LOG_ERROR, "Unknown compression method %i\n", header & KMVC_METHOD);
338  return AVERROR_INVALIDDATA;
339  }
340 
341  out = frame->data[0];
342  src = ctx->cur;
343  for (i = 0; i < avctx->height; i++) {
344  memcpy(out, src, avctx->width);
345  src += 320;
346  out += frame->linesize[0];
347  }
348 
349  /* flip buffers */
350  if (ctx->cur == ctx->frm0) {
351  ctx->cur = ctx->frm1;
352  ctx->prev = ctx->frm0;
353  } else {
354  ctx->cur = ctx->frm0;
355  ctx->prev = ctx->frm1;
356  }
357 
358  *got_frame = 1;
359 
360  /* always report that the buffer was completely consumed */
361  return avpkt->size;
362 }
363 
364 
365 
366 /*
367  * Init kmvc decoder
368  */
370 {
371  KmvcContext *const c = avctx->priv_data;
372  int i;
373 
374  c->avctx = avctx;
375 
376  if (avctx->width > 320 || avctx->height > 200) {
377  av_log(avctx, AV_LOG_ERROR, "KMVC supports frames <= 320x200\n");
378  return AVERROR(EINVAL);
379  }
380 
381  c->frm0 = av_mallocz(320 * 200);
382  c->frm1 = av_mallocz(320 * 200);
383  c->cur = c->frm0;
384  c->prev = c->frm1;
385 
386  for (i = 0; i < 256; i++) {
387  c->pal[i] = 0xFFU << 24 | i * 0x10101;
388  }
389 
390  if (avctx->extradata_size < 12) {
391  av_log(avctx, AV_LOG_WARNING,
392  "Extradata missing, decoding may not work properly...\n");
393  c->palsize = 127;
394  } else {
395  c->palsize = AV_RL16(avctx->extradata + 10);
396  if (c->palsize >= (unsigned)MAX_PALSIZE) {
397  c->palsize = 127;
398  av_log(avctx, AV_LOG_ERROR, "KMVC palette too large\n");
399  return AVERROR_INVALIDDATA;
400  }
401  }
402 
403  if (avctx->extradata_size == 1036) { // palette in extradata
404  uint8_t *src = avctx->extradata + 12;
405  for (i = 0; i < 256; i++) {
406  c->pal[i] = AV_RL32(src);
407  src += 4;
408  }
409  c->setpal = 1;
410  }
411 
412  avctx->pix_fmt = AV_PIX_FMT_PAL8;
413 
414  return 0;
415 }
416 
417 
418 
419 /*
420  * Uninit kmvc decoder
421  */
423 {
424  KmvcContext *const c = avctx->priv_data;
425 
426  av_freep(&c->frm0);
427  av_freep(&c->frm1);
428 
429  return 0;
430 }
431 
433  .name = "kmvc",
434  .type = AVMEDIA_TYPE_VIDEO,
435  .id = AV_CODEC_ID_KMVC,
436  .priv_data_size = sizeof(KmvcContext),
437  .init = decode_init,
438  .close = decode_end,
439  .decode = decode_frame,
440  .capabilities = CODEC_CAP_DR1,
441  .long_name = NULL_IF_CONFIG_SMALL("Karl Morton's video codec"),
442 };
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
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
#define MAX_PALSIZE
Definition: kmvc.c:37
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
GetByteContext g
Definition: kmvc.c:50
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
#define AV_LOG_WARNING
Something somehow does not look correct.
Definition: log.h:154
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static av_always_inline void bytestream2_init(GetByteContext *g, const uint8_t *buf, int buf_size)
Definition: bytestream.h:130
#define AV_RL16
#define KMVC_PALETTE
Definition: kmvc.c:35
static int kmvc_decode_inter_8x8(KmvcContext *ctx, int w, int h)
Definition: kmvc.c:161
output residual component w
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
uint8_t * frm0
Definition: kmvc.c:49
#define BLK(data, x, y)
Definition: kmvc.c:58
uint8_t
#define av_cold
Definition: attributes.h:78
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
uint8_t * extradata
some codecs need / can use extradata like Huffman tables.
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
AVCodecContext * avctx
Definition: kmvc.c:43
frame
Definition: stft.m:14
#define U(x)
int palsize
Definition: kmvc.c:46
static int kmvc_decode_intra_8x8(KmvcContext *ctx, int w, int h)
Definition: kmvc.c:72
static av_always_inline void bytestream2_skip(GetByteContext *g, unsigned int size)
Definition: bytestream.h:159
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
int bitbuf
Definition: kmvc.c:55
Spectrum Plot time data
static av_always_inline unsigned int bytestream2_get_bytes_left(GetByteContext *g)
Definition: bytestream.h:149
struct KmvcContext KmvcContext
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
#define kmvc_init_getbits(bb, g)
Definition: kmvc.c:60
int bits
Definition: kmvc.c:54
external API header
AVCodec ff_kmvc_decoder
Definition: kmvc.c:432
enum AVPictureType pict_type
Picture type of the frame.
Definition: frame.h:144
ret
Definition: avfilter.c:821
int width
picture width / height.
#define kmvc_getbit(bb, g, res)
Definition: kmvc.c:62
static av_cold int decode_init(AVCodecContext *avctx)
Definition: kmvc.c:369
static int decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: kmvc.c:261
#define AV_RL32
#define KMVC_METHOD
Definition: kmvc.c:36
int setpal
Definition: kmvc.c:45
NULL
Definition: eval.c:55
AVS_Value src
Definition: avisynth_c.h:523
int linesize[AV_NUM_DATA_POINTERS]
For video, size in bytes of each picture line.
Definition: frame.h:101
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
synthesis window for stochastic i
Definition: kmvc.c:53
int palette_has_changed
Tell user application that palette has changed from previous frame.
Definition: frame.h:280
uint8_t * prev
Definition: kmvc.c:48
uint8_t * cur
Definition: kmvc.c:48
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
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
struct BitBuf BitBuf
common internal api header.
static double c[64]
uint8_t * frm1
Definition: kmvc.c:49
#define KMVC_KEYFRAME
Definition: kmvc.c:34
int key_frame
1 -> keyframe, 0-> not
Definition: frame.h:139
static av_always_inline int bytestream2_seek(GetByteContext *g, int offset, int whence)
Definition: bytestream.h:203
static av_cold int decode_end(AVCodecContext *avctx)
Definition: kmvc.c:422
uint8_t * av_packet_get_side_data(AVPacket *pkt, enum AVPacketSideDataType type, int *size)
Get side information from packet.
Definition: avpacket.c:289
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=av_sample_fmt_is_planar(in_fmt);out_planar=av_sample_fmt_is_planar(out_fmt);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_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)\n", len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt));return ff_convert_dither(ac-> out
static int decode(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: crystalhd.c:868
uint32_t pal[MAX_PALSIZE]
Definition: kmvc.c:47
This structure stores compressed data.
Predicted.
Definition: avutil.h:217