cdgraphics.c
Go to the documentation of this file.
1 /*
2  * CD Graphics Video Decoder
3  * Copyright (c) 2009 Michael Tison
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 #include "avcodec.h"
23 #include "bytestream.h"
24 #include "internal.h"
25 
26 /**
27  * @file
28  * @brief CD Graphics Video Decoder
29  * @author Michael Tison
30  * @see http://wiki.multimedia.cx/index.php?title=CD_Graphics
31  * @see http://www.ccs.neu.edu/home/bchafy/cdb/info/cdg
32  */
33 
34 /// default screen sizes
35 #define CDG_FULL_WIDTH 300
36 #define CDG_FULL_HEIGHT 216
37 #define CDG_DISPLAY_WIDTH 294
38 #define CDG_DISPLAY_HEIGHT 204
39 #define CDG_BORDER_WIDTH 6
40 #define CDG_BORDER_HEIGHT 12
41 
42 /// masks
43 #define CDG_COMMAND 0x09
44 #define CDG_MASK 0x3F
45 
46 /// instruction codes
47 #define CDG_INST_MEMORY_PRESET 1
48 #define CDG_INST_BORDER_PRESET 2
49 #define CDG_INST_TILE_BLOCK 6
50 #define CDG_INST_SCROLL_PRESET 20
51 #define CDG_INST_SCROLL_COPY 24
52 #define CDG_INST_LOAD_PAL_LO 30
53 #define CDG_INST_LOAD_PAL_HIGH 31
54 #define CDG_INST_TILE_BLOCK_XOR 38
55 
56 /// data sizes
57 #define CDG_PACKET_SIZE 24
58 #define CDG_DATA_SIZE 16
59 #define CDG_TILE_HEIGHT 12
60 #define CDG_TILE_WIDTH 6
61 #define CDG_MINIMUM_PKT_SIZE 6
62 #define CDG_MINIMUM_SCROLL_SIZE 3
63 #define CDG_HEADER_SIZE 8
64 #define CDG_PALETTE_SIZE 16
65 
66 typedef struct CDGraphicsContext {
68  int hscroll;
69  int vscroll;
71 
73 {
74  CDGraphicsContext *cc = avctx->priv_data;
75 
76  cc->frame = av_frame_alloc();
77  if (!cc->frame)
78  return AVERROR(ENOMEM);
79 
80  avctx->width = CDG_FULL_WIDTH;
81  avctx->height = CDG_FULL_HEIGHT;
82  avctx->pix_fmt = AV_PIX_FMT_PAL8;
83 
84  return 0;
85 }
86 
88 {
89  int y;
90  int lsize = cc->frame->linesize[0];
91  uint8_t *buf = cc->frame->data[0];
92  int color = data[0] & 0x0F;
93 
94  if (!(data[1] & 0x0F)) {
95  /// fill the top and bottom borders
96  memset(buf, color, CDG_BORDER_HEIGHT * lsize);
97  memset(buf + (CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT) * lsize,
98  color, CDG_BORDER_HEIGHT * lsize);
99 
100  /// fill the side borders
101  for (y = CDG_BORDER_HEIGHT; y < CDG_FULL_HEIGHT - CDG_BORDER_HEIGHT; y++) {
102  memset(buf + y * lsize, color, CDG_BORDER_WIDTH);
103  memset(buf + CDG_FULL_WIDTH - CDG_BORDER_WIDTH + y * lsize,
104  color, CDG_BORDER_WIDTH);
105  }
106  }
107 }
108 
109 static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
110 {
111  uint8_t r, g, b;
112  uint16_t color;
113  int i;
114  int array_offset = low ? 0 : 8;
115  uint32_t *palette = (uint32_t *) cc->frame->data[1];
116 
117  for (i = 0; i < 8; i++) {
118  color = (data[2 * i] << 6) + (data[2 * i + 1] & 0x3F);
119  r = ((color >> 8) & 0x000F) * 17;
120  g = ((color >> 4) & 0x000F) * 17;
121  b = ((color ) & 0x000F) * 17;
122  palette[i + array_offset] = 0xFFU << 24 | r << 16 | g << 8 | b;
123  }
124  cc->frame->palette_has_changed = 1;
125 }
126 
128 {
129  unsigned ci, ri;
130  int color;
131  int x, y;
132  int ai;
133  int stride = cc->frame->linesize[0];
134  uint8_t *buf = cc->frame->data[0];
135 
136  ri = (data[2] & 0x1F) * CDG_TILE_HEIGHT + cc->vscroll;
137  ci = (data[3] & 0x3F) * CDG_TILE_WIDTH + cc->hscroll;
138 
139  if (ri > (CDG_FULL_HEIGHT - CDG_TILE_HEIGHT))
140  return AVERROR(EINVAL);
141  if (ci > (CDG_FULL_WIDTH - CDG_TILE_WIDTH))
142  return AVERROR(EINVAL);
143 
144  for (y = 0; y < CDG_TILE_HEIGHT; y++) {
145  for (x = 0; x < CDG_TILE_WIDTH; x++) {
146  if (!((data[4 + y] >> (5 - x)) & 0x01))
147  color = data[0] & 0x0F;
148  else
149  color = data[1] & 0x0F;
150 
151  ai = ci + x + (stride * (ri + y));
152  if (b)
153  color ^= buf[ai];
154  buf[ai] = color;
155  }
156  }
157 
158  return 0;
159 }
160 
161 #define UP 2
162 #define DOWN 1
163 #define LEFT 2
164 #define RIGHT 1
165 
166 static void cdg_copy_rect_buf(int out_tl_x, int out_tl_y, uint8_t *out,
167  int in_tl_x, int in_tl_y, uint8_t *in,
168  int w, int h, int stride)
169 {
170  int y;
171 
172  in += in_tl_x + in_tl_y * stride;
173  out += out_tl_x + out_tl_y * stride;
174  for (y = 0; y < h; y++)
175  memcpy(out + y * stride, in + y * stride, w);
176 }
177 
178 static void cdg_fill_rect_preset(int tl_x, int tl_y, uint8_t *out,
179  int color, int w, int h, int stride)
180 {
181  int y;
182 
183  for (y = tl_y; y < tl_y + h; y++)
184  memset(out + tl_x + y * stride, color, w);
185 }
186 
187 static void cdg_fill_wrapper(int out_tl_x, int out_tl_y, uint8_t *out,
188  int in_tl_x, int in_tl_y, uint8_t *in,
189  int color, int w, int h, int stride, int roll)
190 {
191  if (roll) {
192  cdg_copy_rect_buf(out_tl_x, out_tl_y, out, in_tl_x, in_tl_y,
193  in, w, h, stride);
194  } else {
195  cdg_fill_rect_preset(out_tl_x, out_tl_y, out, color, w, h, stride);
196  }
197 }
198 
200  AVFrame *new_frame, int roll_over)
201 {
202  int color;
203  int hscmd, h_off, hinc, vscmd, v_off, vinc;
204  int y;
205  int stride = cc->frame->linesize[0];
206  uint8_t *in = cc->frame->data[0];
207  uint8_t *out = new_frame->data[0];
208 
209  color = data[0] & 0x0F;
210  hscmd = (data[1] & 0x30) >> 4;
211  vscmd = (data[2] & 0x30) >> 4;
212 
213  h_off = FFMIN(data[1] & 0x07, CDG_BORDER_WIDTH - 1);
214  v_off = FFMIN(data[2] & 0x0F, CDG_BORDER_HEIGHT - 1);
215 
216  /// find the difference and save the offset for cdg_tile_block usage
217  hinc = h_off - cc->hscroll;
218  vinc = v_off - cc->vscroll;
219  cc->hscroll = h_off;
220  cc->vscroll = v_off;
221 
222  if (vscmd == UP)
223  vinc -= 12;
224  if (vscmd == DOWN)
225  vinc += 12;
226  if (hscmd == LEFT)
227  hinc -= 6;
228  if (hscmd == RIGHT)
229  hinc += 6;
230 
231  if (!hinc && !vinc)
232  return;
233 
234  memcpy(new_frame->data[1], cc->frame->data[1], CDG_PALETTE_SIZE * 4);
235 
236  for (y = FFMAX(0, vinc); y < FFMIN(CDG_FULL_HEIGHT + vinc, CDG_FULL_HEIGHT); y++)
237  memcpy(out + FFMAX(0, hinc) + stride * y,
238  in + FFMAX(0, hinc) - hinc + (y - vinc) * stride,
239  FFMIN(stride + hinc, stride));
240 
241  if (vinc > 0)
242  cdg_fill_wrapper(0, 0, out,
243  0, CDG_FULL_HEIGHT - vinc, in, color,
244  stride, vinc, stride, roll_over);
245  else if (vinc < 0)
246  cdg_fill_wrapper(0, CDG_FULL_HEIGHT + vinc, out,
247  0, 0, in, color,
248  stride, -1 * vinc, stride, roll_over);
249 
250  if (hinc > 0)
251  cdg_fill_wrapper(0, 0, out,
252  CDG_FULL_WIDTH - hinc, 0, in, color,
253  hinc, CDG_FULL_HEIGHT, stride, roll_over);
254  else if (hinc < 0)
255  cdg_fill_wrapper(CDG_FULL_WIDTH + hinc, 0, out,
256  0, 0, in, color,
257  -1 * hinc, CDG_FULL_HEIGHT, stride, roll_over);
258 
259 }
260 
262  void *data, int *got_frame, AVPacket *avpkt)
263 {
264  const uint8_t *buf = avpkt->data;
265  int buf_size = avpkt->size;
266  int ret;
267  uint8_t command, inst;
268  uint8_t cdg_data[CDG_DATA_SIZE];
269  AVFrame *frame = data;
270  CDGraphicsContext *cc = avctx->priv_data;
271 
272  if (buf_size < CDG_MINIMUM_PKT_SIZE) {
273  av_log(avctx, AV_LOG_ERROR, "buffer too small for decoder\n");
274  return AVERROR(EINVAL);
275  }
276  if (buf_size > CDG_HEADER_SIZE + CDG_DATA_SIZE) {
277  av_log(avctx, AV_LOG_ERROR, "buffer too big for decoder\n");
278  return AVERROR(EINVAL);
279  }
280 
281  if ((ret = ff_reget_buffer(avctx, cc->frame)) < 0)
282  return ret;
283  if (!avctx->frame_number) {
284  memset(cc->frame->data[0], 0, cc->frame->linesize[0] * avctx->height);
285  memset(cc->frame->data[1], 0, AVPALETTE_SIZE);
286  }
287 
288  command = bytestream_get_byte(&buf);
289  inst = bytestream_get_byte(&buf);
290  inst &= CDG_MASK;
291  buf += 2; /// skipping 2 unneeded bytes
292  bytestream_get_buffer(&buf, cdg_data, buf_size - CDG_HEADER_SIZE);
293 
294  if ((command & CDG_MASK) == CDG_COMMAND) {
295  switch (inst) {
297  if (!(cdg_data[1] & 0x0F))
298  memset(cc->frame->data[0], cdg_data[0] & 0x0F,
299  cc->frame->linesize[0] * CDG_FULL_HEIGHT);
300  break;
303  if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {
304  av_log(avctx, AV_LOG_ERROR, "buffer too small for loading palette\n");
305  return AVERROR(EINVAL);
306  }
307 
308  cdg_load_palette(cc, cdg_data, inst == CDG_INST_LOAD_PAL_LO);
309  break;
311  cdg_border_preset(cc, cdg_data);
312  break;
314  case CDG_INST_TILE_BLOCK:
315  if (buf_size - CDG_HEADER_SIZE < CDG_DATA_SIZE) {
316  av_log(avctx, AV_LOG_ERROR, "buffer too small for drawing tile\n");
317  return AVERROR(EINVAL);
318  }
319 
320  ret = cdg_tile_block(cc, cdg_data, inst == CDG_INST_TILE_BLOCK_XOR);
321  if (ret) {
322  av_log(avctx, AV_LOG_ERROR, "tile is out of range\n");
323  return ret;
324  }
325  break;
328  if (buf_size - CDG_HEADER_SIZE < CDG_MINIMUM_SCROLL_SIZE) {
329  av_log(avctx, AV_LOG_ERROR, "buffer too small for scrolling\n");
330  return AVERROR(EINVAL);
331  }
332 
333  if ((ret = ff_get_buffer(avctx, frame, AV_GET_BUFFER_FLAG_REF)) < 0)
334  return ret;
335 
336  cdg_scroll(cc, cdg_data, frame, inst == CDG_INST_SCROLL_COPY);
337  av_frame_unref(cc->frame);
338  ret = av_frame_ref(cc->frame, frame);
339  if (ret < 0)
340  return ret;
341  break;
342  default:
343  break;
344  }
345 
346  if (!frame->data[0]) {
347  ret = av_frame_ref(frame, cc->frame);
348  if (ret < 0)
349  return ret;
350  }
351  *got_frame = 1;
352  } else {
353  *got_frame = 0;
354  buf_size = 0;
355  }
356 
357  return buf_size;
358 }
359 
361 {
362  CDGraphicsContext *cc = avctx->priv_data;
363 
364  av_frame_free(&cc->frame);
365 
366  return 0;
367 }
368 
370  .name = "cdgraphics",
371  .type = AVMEDIA_TYPE_VIDEO,
373  .priv_data_size = sizeof(CDGraphicsContext),
377  .capabilities = CODEC_CAP_DR1,
378  .long_name = NULL_IF_CONFIG_SMALL("CD Graphics video"),
379 };
#define CDG_BORDER_HEIGHT
Definition: cdgraphics.c:40
This structure describes decoded (raw) audio or video data.
Definition: frame.h:76
#define CDG_TILE_WIDTH
Definition: cdgraphics.c:60
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
About Git write you should know how to use GIT properly Luckily Git comes with excellent documentation git help man git shows you the available git< command > help man git< command > shows information about the subcommand< command > The most comprehensive manual is the website Git Reference visit they are quite exhaustive You do not need a special username or password All you need is to provide a ssh public key to the Git server admin What follows now is a basic introduction to Git and some FFmpeg specific guidelines Read it at least if you are granted commit privileges to the FFmpeg project you are expected to be familiar with these rules I if not You can get git from etc no matter how small Every one of them has been saved from looking like a fool by this many times It s very easy for stray debug output or cosmetic modifications to slip in
Definition: git-howto.txt:5
enum AVPixelFormat pix_fmt
Pixel format, see AV_PIX_FMT_xxx.
static void cdg_border_preset(CDGraphicsContext *cc, uint8_t *data)
Definition: cdgraphics.c:87
#define CDG_INST_LOAD_PAL_HIGH
Definition: cdgraphics.c:53
int stride
Definition: mace.c:144
#define UP
Definition: cdgraphics.c:161
#define CDG_INST_SCROLL_PRESET
Definition: cdgraphics.c:50
output residual component w
static void cdg_fill_wrapper(int out_tl_x, int out_tl_y, uint8_t *out, int in_tl_x, int in_tl_y, uint8_t *in, int color, int w, int h, int stride, int roll)
Definition: cdgraphics.c:187
static int cdg_tile_block(CDGraphicsContext *cc, uint8_t *data, int b)
Definition: cdgraphics.c:127
uint8_t
#define av_cold
Definition: attributes.h:78
static void cdg_copy_rect_buf(int out_tl_x, int out_tl_y, uint8_t *out, int in_tl_x, int in_tl_y, uint8_t *in, int w, int h, int stride)
Definition: cdgraphics.c:166
8 bit with PIX_FMT_RGB32 palette
Definition: pixfmt.h:79
#define CDG_COMMAND
masks
Definition: cdgraphics.c:43
static const uint32_t color[16+AV_CLASS_CATEGORY_NB]
Definition: log.c:77
#define AVPALETTE_SIZE
Definition: pixfmt.h:33
#define b
Definition: input.c:42
#define CODEC_CAP_DR1
Codec uses get_buffer() for allocating buffers and supports custom allocators.
uint8_t * data
Discrete Time axis x
#define U(x)
#define CDG_HEADER_SIZE
Definition: cdgraphics.c:63
static av_cold int cdg_decode_init(AVCodecContext *avctx)
Definition: cdgraphics.c:72
#define CDG_MINIMUM_PKT_SIZE
Definition: cdgraphics.c:61
static void cdg_fill_rect_preset(int tl_x, int tl_y, uint8_t *out, int color, int w, int h, int stride)
Definition: cdgraphics.c:178
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
#define CDG_PALETTE_SIZE
Definition: cdgraphics.c:64
Spectrum Plot time data
const char * r
Definition: vf_curves.c:94
#define CDG_INST_BORDER_PRESET
Definition: cdgraphics.c:48
static av_cold int cdg_decode_end(AVCodecContext *avctx)
Definition: cdgraphics.c:360
#define CDG_INST_TILE_BLOCK
Definition: cdgraphics.c:49
void av_log(void *avcl, int level, const char *fmt,...)
Definition: log.c:246
const char * name
Name of the codec implementation.
#define FFMAX(a, b)
Definition: common.h:56
external API header
#define CDG_FULL_WIDTH
default screen sizes
Definition: cdgraphics.c:35
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...
FFT buffer for g
Definition: stft_peak.m:17
#define FFMIN(a, b)
Definition: common.h:58
static int cdg_decode_frame(AVCodecContext *avctx, void *data, int *got_frame, AVPacket *avpkt)
Definition: cdgraphics.c:261
ret
Definition: avfilter.c:821
int width
picture width / height.
#define CDG_INST_MEMORY_PRESET
instruction codes
Definition: cdgraphics.c:47
#define CDG_TILE_HEIGHT
Definition: cdgraphics.c:59
static void cdg_scroll(CDGraphicsContext *cc, uint8_t *data, AVFrame *new_frame, int roll_over)
Definition: cdgraphics.c:199
static av_always_inline unsigned int bytestream_get_buffer(const uint8_t **b, uint8_t *dst, unsigned int size)
Definition: bytestream.h:328
#define CDG_DATA_SIZE
Definition: cdgraphics.c:58
static void cdg_load_palette(CDGraphicsContext *cc, uint8_t *data, int low)
Definition: cdgraphics.c:109
AVFrame * frame
Definition: cdgraphics.c:67
AVCodec ff_cdgraphics_decoder
Definition: cdgraphics.c:369
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
#define CDG_INST_LOAD_PAL_LO
Definition: cdgraphics.c:52
static int command(AVFilterContext *ctx, const char *cmd, const char *arg, char *res, int res_len, int flags)
Definition: vf_drawtext.c:596
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
#define DOWN
Definition: cdgraphics.c:162
void * buf
Definition: avisynth_c.h:594
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
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition: frame.c:95
int av_frame_ref(AVFrame *dst, AVFrame *src)
Setup a new reference to the data described by an given frame.
Definition: frame.c:228
uint8_t * data[AV_NUM_DATA_POINTERS]
pointer to the picture/channel planes.
Definition: frame.h:87
#define CDG_INST_TILE_BLOCK_XOR
Definition: cdgraphics.c:54
int palette
Definition: v4l.c:61
#define CDG_BORDER_WIDTH
Definition: cdgraphics.c:39
common internal api header.
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition: frame.c:108
function y
Definition: D.m:1
struct CDGraphicsContext CDGraphicsContext
#define CDG_FULL_HEIGHT
Definition: cdgraphics.c:36
#define RIGHT
Definition: cdgraphics.c:164
int frame_number
Frame counter, set by libavcodec.
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
#define CDG_INST_SCROLL_COPY
Definition: cdgraphics.c:51
#define LEFT
Definition: cdgraphics.c:163
#define CDG_MASK
Definition: cdgraphics.c:44
This structure stores compressed data.
#define AV_GET_BUFFER_FLAG_REF
The decoder will keep a reference to the frame and may reuse it later.
for(j=16;j >0;--j)
#define CDG_MINIMUM_SCROLL_SIZE
Definition: cdgraphics.c:62