FFmpeg
sga.c
Go to the documentation of this file.
1 /*
2  * Digital Pictures SGA game demuxer
3  *
4  * Copyright (C) 2021 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 #include "libavutil/intreadwrite.h"
24 #include "libavutil/avassert.h"
25 #include "libavutil/internal.h"
26 #include "avformat.h"
27 #include "internal.h"
28 #include "avio_internal.h"
29 
30 #define SEGA_CD_PCM_NUM 12500000
31 #define SEGA_CD_PCM_DEN 786432
32 
33 typedef struct SGADemuxContext {
36 
37  uint8_t sector[65536 * 2];
43  int flags;
44  int idx;
45  int left;
46  int64_t pkt_pos;
48 
49 static int sga_probe(const AVProbeData *p)
50 {
51  const uint8_t *src = p->buf;
52  int score = 0, sectors = 1;
53  int last_left = 0;
54  int sample_rate = -1;
55 
56  if (p->buf_size < 2048)
57  return 0;
58 
59  for (int i = 0; i + 2 < p->buf_size; i += 2048) {
60  int header = AV_RB16(src + i);
61 
62  if ((header > 0x07FE && header < 0x8100) ||
63  (header > 0x8200 && header < 0xA100) ||
64  (header > 0xA200 && header < 0xC100)) {
65  sectors = 0;
66  break;
67  }
68  }
69 
70  for (int i = 0; i + 4 < p->buf_size;) {
71  int header = AV_RB16(src + i);
72  int left = AV_RB16(src + i + 2);
73  int offset, type, size;
74 
75  if (last_left < 0)
76  return 0;
77  if (sectors && header && last_left == 0) {
78  if (header >> 12) {
79  last_left = left;
80  } else {
81  last_left = left = header;
82  }
83  } else if (sectors && header) {
84  left = header;
85  last_left -= left;
86  if (header != 0x7FE && left < 7)
87  return 0;
88  } else if (sectors) {
89  if (left <= 8)
90  return 0;
91  i += sectors ? 2048 : left + 4;
92  last_left = 0;
93  continue;
94  }
95 
96  if (sectors && (i > 0 && left < 0x7fe) &&
97  (i + left + 14 < p->buf_size)) {
98  offset = i + left + 2;
99  } else if (sectors && i > 0) {
100  i += 2048;
101  last_left -= FFMIN(last_left, 2046);
102  continue;
103  } else {
104  offset = 0;
105  last_left = left;
106  }
107 
108  header = AV_RB16(src + offset);
109  size = AV_RB16(src + offset + 2) + 4;
110 
111  while ((header & 0xFF00) == 0) {
112  offset++;
113  if (offset + 4 >= p->buf_size)
114  break;
115  header = AV_RB16(src + offset);
116  size = AV_RB16(src + offset + 2) + 4;
117  }
118 
119  if (offset + 12 >= p->buf_size)
120  break;
121  if ((header & 0xFF) > 1)
122  return 0;
123  type = header >> 8;
124 
125  if (type == 0xAA ||
126  type == 0xA1 ||
127  type == 0xA2 ||
128  type == 0xA3) {
129  int new_rate;
130 
131  if (size <= 12)
132  return 0;
133  new_rate = AV_RB16(src + offset + 8);
134  if (sample_rate < 0)
135  sample_rate = new_rate;
136  if (sample_rate == 0 || new_rate != sample_rate)
137  return 0;
138  if (src[offset + 10] != 1)
139  return 0;
140 
141  score += 10;
142  } else if (type == 0xC1 ||
143  type == 0xC6 ||
144  type == 0xC7 ||
145  type == 0xC8 ||
146  type == 0xC9 ||
147  type == 0xCB ||
148  type == 0xCD ||
149  type == 0xE7) {
150  int nb_pals = src[offset + 9];
151  int tiles_w = src[offset + 10];
152  int tiles_h = src[offset + 11];
153 
154  if (size <= 12)
155  return 0;
156  if (nb_pals == 0 || nb_pals > 4)
157  return 0;
158  if (tiles_w == 0 || tiles_w > 80)
159  return 0;
160  if (tiles_h == 0 || tiles_h > 60)
161  return 0;
162 
163  score += 10;
164  } else if (header == 0x7FE) {
165  ;
166  } else {
167  return 0;
168  }
169 
170  i += sectors ? 2048 : size + 4;
171  last_left -= FFMIN(last_left, 2046);
172 
173  if (score < 0)
174  break;
175  }
176 
177  return av_clip(score, 0, AVPROBE_SCORE_MAX);
178 }
179 
181 {
182  SGADemuxContext *sga = s->priv_data;
183  AVIOContext *pb = s->pb;
184 
185  sga->sector_headers = 1;
186  sga->first_audio_size = 0;
187  sga->video_stream_index = -1;
188  sga->audio_stream_index = -1;
189  sga->left = 2048;
190  sga->idx = 0;
191 
192  s->ctx_flags |= AVFMTCTX_NOHEADER;
193 
194  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
195  while (!avio_feof(pb)) {
196  int header = avio_rb16(pb);
197  int type = header >> 8;
198  int skip = 2046;
199  int clock;
200 
201  if (!sga->first_audio_size &&
202  (type == 0xAA ||
203  type == 0xA1 ||
204  type == 0xA2 ||
205  type == 0xA3)) {
206  sga->first_audio_size = avio_rb16(pb);
207  avio_skip(pb, 4);
208  clock = avio_rb16(pb);
209  sga->sample_rate = av_rescale(clock,
212  skip -= 8;
213  }
214  if ((header > 0x07FE && header < 0x8100) ||
215  (header > 0x8200 && header < 0xA100) ||
216  (header > 0xA200 && header < 0xC100)) {
217  sga->sector_headers = 0;
218  break;
219  }
220 
221  avio_skip(pb, skip);
222  }
223 
224  avio_seek(pb, 0, SEEK_SET);
225  }
226 
227  return 0;
228 }
229 
230 static void print_stats(AVFormatContext *s, const char *where)
231 {
232  SGADemuxContext *sga = s->priv_data;
233 
234  av_log(s, AV_LOG_DEBUG, "START %s\n", where);
235  av_log(s, AV_LOG_DEBUG, "pos: %"PRIX64"\n", avio_tell(s->pb));
236  av_log(s, AV_LOG_DEBUG, "idx: %X\n", sga->idx);
237  av_log(s, AV_LOG_DEBUG, "packet_type: %X\n", sga->packet_type);
238  av_log(s, AV_LOG_DEBUG, "payload_size: %X\n", sga->payload_size);
239  av_log(s, AV_LOG_DEBUG, "SECTOR: %016"PRIX64"\n", AV_RB64(sga->sector));
240  av_log(s, AV_LOG_DEBUG, "stream: %X\n", sga->sector[1]);
241  av_log(s, AV_LOG_DEBUG, "END %s\n", where);
242 }
243 
245 {
246  SGADemuxContext *sga = s->priv_data;
247 
248  if (sga->idx >= 4) {
249  sga->packet_type = sga->sector[0];
250  sga->payload_size = AV_RB16(sga->sector + 2);
251  } else {
252  sga->packet_type = 0;
253  sga->payload_size = 0;
254  }
255 }
256 
258 {
259  SGADemuxContext *sga = s->priv_data;
260  int ret;
261 
262  if (sga->payload_size <= 8)
263  return AVERROR_INVALIDDATA;
264 
265  if (sga->video_stream_index == -1) {
266  AVRational frame_rate;
267 
269  if (!st)
270  return AVERROR(ENOMEM);
271 
272  st->start_time = 0;
274  st->codecpar->codec_tag = 0;
276  sga->video_stream_index = st->index;
277 
278  if (sga->first_audio_size > 0 && sga->sample_rate > 0) {
279  frame_rate.num = sga->sample_rate;
280  frame_rate.den = sga->first_audio_size;
281  } else {
282  frame_rate.num = 15;
283  frame_rate.den = 1;
284  }
285  avpriv_set_pts_info(st, 64, frame_rate.den, frame_rate.num);
286  }
287 
288  ret = av_new_packet(pkt, sga->payload_size + 4);
289  if (ret < 0)
290  return AVERROR(ENOMEM);
291  memcpy(pkt->data, sga->sector, sga->payload_size + 4);
292  av_assert0(sga->idx >= sga->payload_size + 4);
293  memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4);
294 
296  pkt->duration = 1;
297  pkt->pos = sga->pkt_pos;
298  pkt->flags |= sga->flags;
299  sga->idx -= sga->payload_size + 4;
300  sga->flags = 0;
302 
303  av_log(s, AV_LOG_DEBUG, "VIDEO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx);
304 
305  return 0;
306 }
307 
309 {
310  SGADemuxContext *sga = s->priv_data;
311  int ret;
312 
313  if (sga->payload_size <= 8)
314  return AVERROR_INVALIDDATA;
315 
316  if (sga->audio_stream_index == -1) {
318  if (!st)
319  return AVERROR(ENOMEM);
320 
321  st->start_time = 0;
323  st->codecpar->codec_tag = 0;
325  st->codecpar->channels = 1;
327  st->codecpar->sample_rate = av_rescale(AV_RB16(sga->sector + 8),
330  sga->audio_stream_index = st->index;
331 
332  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
333  }
334 
335  ret = av_new_packet(pkt, sga->payload_size - 8);
336  if (ret < 0)
337  return AVERROR(ENOMEM);
338  memcpy(pkt->data, sga->sector + 12, sga->payload_size - 8);
339  av_assert0(sga->idx >= sga->payload_size + 4);
340  memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4);
341 
343  pkt->duration = pkt->size;
344  pkt->pos = sga->pkt_pos;
345  pkt->flags |= sga->flags;
346  sga->idx -= sga->payload_size + 4;
347  sga->flags = 0;
349 
350  av_log(s, AV_LOG_DEBUG, "AUDIO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx);
351 
352  return 0;
353 }
354 
356 {
357  SGADemuxContext *sga = s->priv_data;
358  int ret = 0;
359 
360  if (sga->packet_type == 0xCD ||
361  sga->packet_type == 0xCB ||
362  sga->packet_type == 0xC9 ||
363  sga->packet_type == 0xC8 ||
364  sga->packet_type == 0xC7 ||
365  sga->packet_type == 0xC6 ||
366  sga->packet_type == 0xC1 ||
367  sga->packet_type == 0xE7) {
369  } else if (sga->packet_type == 0xA1 ||
370  sga->packet_type == 0xA2 ||
371  sga->packet_type == 0xA3 ||
372  sga->packet_type == 0xAA) {
374  } else {
375  if (sga->idx == 0)
376  return AVERROR_EOF;
377  if (sga->sector[0])
378  return AVERROR_INVALIDDATA;
379  memmove(sga->sector, sga->sector + 1, sga->idx - 1);
380  sga->idx--;
381  return AVERROR(EAGAIN);
382  }
383 
384  return ret;
385 }
386 
388 {
389  SGADemuxContext *sga = s->priv_data;
390  int ret = AVERROR(EAGAIN);
391 
393  if (sga->idx >= sga->payload_size + 4) {
394  print_stats(s, "before sga_packet");
395  ret = sga_packet(s, pkt);
396  print_stats(s, "after sga_packet");
397  if (ret != AVERROR(EAGAIN))
398  return ret;
399  }
400 
401  return sga->idx < sga->payload_size + 4 ? AVERROR(EAGAIN) : ret;
402 }
403 
405 {
406  SGADemuxContext *sga = s->priv_data;
407  AVIOContext *pb = s->pb;
408  int header, ret = 0;
409 
410  sga->pkt_pos = avio_tell(pb);
411 
412 retry:
414 
415  print_stats(s, "start");
416  if (avio_feof(pb) &&
417  (!sga->payload_size || sga->idx < sga->payload_size + 4))
418  return AVERROR_EOF;
419 
420  if (sga->idx < sga->payload_size + 4) {
421  ret = ffio_ensure_seekback(pb, 2);
422  if (ret < 0)
423  return ret;
424 
425  print_stats(s, "before read header");
426  header = avio_rb16(pb);
427  if (!header) {
428  avio_skip(pb, 2046);
429  sga->left = 0;
430  } else if (!avio_feof(pb) &&
431  ((header >> 15) ||
432  !sga->sector_headers)) {
433  avio_seek(pb, -2, SEEK_CUR);
434  sga->flags = AV_PKT_FLAG_KEY;
435  sga->left = 2048;
436  } else {
437  sga->left = 2046;
438  }
439 
440  av_assert0(sga->idx + sga->left < sizeof(sga->sector));
441  ret = avio_read(pb, sga->sector + sga->idx, sga->left);
442  if (ret > 0)
443  sga->idx += ret;
444  else if (ret != AVERROR_EOF && ret)
445  return ret;
446  print_stats(s, "after read header");
447 
449  }
450 
451  ret = try_packet(s, pkt);
452  if (ret == AVERROR(EAGAIN))
453  goto retry;
454 
455  return ret;
456 }
457 
458 static int sga_seek(AVFormatContext *s, int stream_index,
459  int64_t timestamp, int flags)
460 {
461  SGADemuxContext *sga = s->priv_data;
462 
463  sga->packet_type = sga->payload_size = sga->idx = 0;
464  memset(sga->sector, 0, sizeof(sga->sector));
465 
466  return -1;
467 }
468 
470  .name = "sga",
471  .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA"),
472  .priv_data_size = sizeof(SGADemuxContext),
476  .read_seek = sga_seek,
477  .extensions = "sga",
479 };
av_clip
#define av_clip
Definition: common.h:122
AVERROR
Filter the word “frame” indicates either a video frame or a group of audio as stored in an AVFrame 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. Frame references ownership and permissions
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:4547
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:56
SGADemuxContext::idx
int idx
Definition: sga.c:44
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:55
try_packet
static int try_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:387
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:90
sga_packet
static int sga_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:355
print_stats
static void print_stats(AVFormatContext *s, const char *where)
Definition: sga.c:230
AVPacket::data
uint8_t * data
Definition: packet.h:369
sga_video_packet
static int sga_video_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:257
AV_CODEC_ID_PCM_SGA
@ AV_CODEC_ID_PCM_SGA
Definition: codec_id.h:350
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:387
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:64
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:444
SGADemuxContext
Definition: sga.c:33
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:410
sample_rate
sample_rate
Definition: ffmpeg_filter.c:158
ff_sga_demuxer
AVInputFormat ff_sga_demuxer
Definition: sga.c:469
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:453
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
SGADemuxContext::sector_headers
int sector_headers
Definition: sga.c:38
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:463
type
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf type
Definition: writing_filters.txt:86
SGADemuxContext::video_stream_index
int video_stream_index
Definition: sga.c:34
AVRational::num
int num
Numerator.
Definition: rational.h:59
SGADemuxContext::first_audio_size
int first_audio_size
Definition: sga.c:40
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AVInputFormat
Definition: avformat.h:640
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:257
av_new_packet
int av_new_packet(AVPacket *pkt, int size)
Allocate the payload of a packet and initialize its fields with default values.
Definition: avpacket.c:99
SGADemuxContext::flags
int flags
Definition: sga.c:43
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:645
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:443
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_SGA_VIDEO
@ AV_CODEC_ID_SGA_VIDEO
Definition: codec_id.h:309
sga_audio_packet
static int sga_audio_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:308
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:37
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:215
sga_read_packet
static int sga_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:404
AVFormatContext
Format I/O context.
Definition: avformat.h:1231
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1038
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:527
NULL
#define NULL
Definition: coverity.c:32
SEGA_CD_PCM_DEN
#define SEGA_CD_PCM_DEN
Definition: sga.c:31
read_probe
static int read_probe(const AVProbeData *pd)
Definition: jvdec.c:55
AVFMTCTX_NOHEADER
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:1176
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
src
#define src
Definition: vp8dsp.c:255
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:441
SGADemuxContext::pkt_pos
int64_t pkt_pos
Definition: sga.c:46
SGADemuxContext::sample_rate
int sample_rate
Definition: sga.c:39
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
SGADemuxContext::audio_stream_index
int audio_stream_index
Definition: sga.c:35
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
SGADemuxContext::left
int left
Definition: sga.c:45
sga_read_header
static int sga_read_header(AVFormatContext *s)
Definition: sga.c:180
SGADemuxContext::sector
uint8_t sector[65536 *2]
Definition: sga.c:37
AVPacket::size
int size
Definition: packet.h:370
NULL_IF_CONFIG_SMALL
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification.
Definition: internal.h:117
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:260
sga_probe
static int sga_probe(const AVProbeData *p)
Definition: sga.c:49
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:4993
size
int size
Definition: twinvq_data.h:10344
header
static const uint8_t header[24]
Definition: sdr2.c:67
FFMIN
#define FFMIN(a, b)
Definition: common.h:105
ffio_ensure_seekback
int ffio_ensure_seekback(AVIOContext *s, int64_t buf_size)
Ensures that the requested seekback buffer size will be available.
Definition: aviobuf.c:998
offset
it s the only field you need to keep assuming you have a context There is some magic you don t need to care about around this just let it vf offset
Definition: writing_filters.txt:86
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: packet.h:375
i
int i
Definition: input.c:407
avio_internal.h
internal.h
uint8_t
uint8_t
Definition: audio_convert.c:194
av_rescale
int64_t av_rescale(int64_t a, int64_t b, int64_t c)
Rescale a 64-bit integer with rounding to nearest.
Definition: mathematics.c:129
SGADemuxContext::payload_size
int payload_size
Definition: sga.c:41
ret
ret
Definition: filter_design.txt:187
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_reading.c:42
AVStream
Stream structure.
Definition: avformat.h:873
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:253
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:766
avformat.h
update_type_size
static void update_type_size(AVFormatContext *s)
Definition: sga.c:244
left
Tag MUST be and< 10hcoeff half pel interpolation filter coefficients, hcoeff[0] are the 2 middle coefficients[1] are the next outer ones and so on, resulting in a filter like:...eff[2], hcoeff[1], hcoeff[0], hcoeff[0], hcoeff[1], hcoeff[2] ... the sign of the coefficients is not explicitly stored but alternates after each coeff and coeff[0] is positive, so ...,+,-,+,-,+,+,-,+,-,+,... hcoeff[0] is not explicitly stored but found by subtracting the sum of all stored coefficients with signs from 32 hcoeff[0]=32 - hcoeff[1] - hcoeff[2] - ... a good choice for hcoeff and htaps is htaps=6 hcoeff={40,-10, 2} an alternative which requires more computations at both encoder and decoder side and may or may not be better is htaps=8 hcoeff={42,-14, 6,-2}ref_frames minimum of the number of available reference frames and max_ref_frames for example the first frame after a key frame always has ref_frames=1spatial_decomposition_type wavelet type 0 is a 9/7 symmetric compact integer wavelet 1 is a 5/3 symmetric compact integer wavelet others are reserved stored as delta from last, last is reset to 0 if always_reset||keyframeqlog quality(logarithmic quantizer scale) stored as delta from last, last is reset to 0 if always_reset||keyframemv_scale stored as delta from last, last is reset to 0 if always_reset||keyframe FIXME check that everything works fine if this changes between framesqbias dequantization bias stored as delta from last, last is reset to 0 if always_reset||keyframeblock_max_depth maximum depth of the block tree stored as delta from last, last is reset to 0 if always_reset||keyframequant_table quantization tableHighlevel bitstream structure:==============================--------------------------------------------|Header|--------------------------------------------|------------------------------------|||Block0||||split?||||yes no||||......... intra?||||:Block01 :yes no||||:Block02 :....... ..........||||:Block03 ::y DC ::ref index:||||:Block04 ::cb DC ::motion x :||||......... :cr DC ::motion y :||||....... ..........|||------------------------------------||------------------------------------|||Block1|||...|--------------------------------------------|------------ ------------ ------------|||Y subbands||Cb subbands||Cr subbands||||--- ---||--- ---||--- ---|||||LL0||HL0||||LL0||HL0||||LL0||HL0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||LH0||HH0||||LH0||HH0||||LH0||HH0|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HL1||LH1||||HL1||LH1||||HL1||LH1|||||--- ---||--- ---||--- ---||||--- ---||--- ---||--- ---|||||HH1||HL2||||HH1||HL2||||HH1||HL2|||||...||...||...|||------------ ------------ ------------|--------------------------------------------Decoding process:=================------------|||Subbands|------------||||------------|Intra DC||||LL0 subband prediction ------------|\ Dequantization ------------------- \||Reference frames|\ IDWT|------- -------|Motion \|||Frame 0||Frame 1||Compensation . OBMC v -------|------- -------|--------------. \------> Frame n output Frame Frame<----------------------------------/|...|------------------- Range Coder:============Binary Range Coder:------------------- The implemented range coder is an adapted version based upon "Range encoding: an algorithm for removing redundancy from a digitised message." by G. N. N. Martin. The symbols encoded by the Snow range coder are bits(0|1). The associated probabilities are not fix but change depending on the symbol mix seen so far. bit seen|new state ---------+----------------------------------------------- 0|256 - state_transition_table[256 - old_state];1|state_transition_table[old_state];state_transition_table={ 0, 0, 0, 0, 0, 0, 0, 0, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 190, 191, 192, 194, 194, 195, 196, 197, 198, 199, 200, 201, 202, 202, 204, 205, 206, 207, 208, 209, 209, 210, 211, 212, 213, 215, 215, 216, 217, 218, 219, 220, 220, 222, 223, 224, 225, 226, 227, 227, 229, 229, 230, 231, 232, 234, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 248, 0, 0, 0, 0, 0, 0, 0};FIXME Range Coding of integers:------------------------- FIXME Neighboring Blocks:===================left and top are set to the respective blocks unless they are outside of the image in which case they are set to the Null block top-left is set to the top left block unless it is outside of the image in which case it is set to the left block if this block has no larger parent block or it is at the left side of its parent block and the top right block is not outside of the image then the top right block is used for top-right else the top-left block is used Null block y, cb, cr are 128 level, ref, mx and my are 0 Motion Vector Prediction:=========================1. the motion vectors of all the neighboring blocks are scaled to compensate for the difference of reference frames scaled_mv=(mv *(256 *(current_reference+1)/(mv.reference+1))+128)> the median of the scaled left
Definition: snow.txt:386
AVStream::index
int index
stream index in AVFormatContext
Definition: avformat.h:874
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:40
AVRational::den
int den
Denominator.
Definition: rational.h:60
avio_read
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:633
AVPacket::stream_index
int stream_index
Definition: packet.h:371
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:337
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:60
AVPacket
This structure stores compressed data.
Definition: packet.h:346
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:389
AVCodecParameters::channel_layout
uint64_t channel_layout
Audio only.
Definition: codec_par.h:162
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
SEGA_CD_PCM_NUM
#define SEGA_CD_PCM_NUM
Definition: sga.c:30
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:59
sga_seek
static int sga_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: sga.c:458
AVStream::start_time
int64_t start_time
Decoding: pts of the first frame of the stream in presentation order, in stream time base.
Definition: avformat.h:912
SGADemuxContext::packet_type
int packet_type
Definition: sga.c:42
AV_RB64
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_RB64
Definition: bytestream.h:95
AV_RB16
uint64_t_TMPL AV_WL64 unsigned int_TMPL AV_WL32 unsigned int_TMPL AV_WL24 unsigned int_TMPL AV_WL16 uint64_t_TMPL AV_WB64 unsigned int_TMPL AV_WB32 unsigned int_TMPL AV_WB24 unsigned int_TMPL AV_RB16
Definition: bytestream.h:98
avio_feof
int avio_feof(AVIOContext *s)
Similar to feof() but also returns nonzero on read errors.
Definition: aviobuf.c:364