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"
26 #include "libavutil/internal.h"
27 #include "avformat.h"
28 #include "demux.h"
29 #include "internal.h"
30 #include "avio_internal.h"
31 
32 #define SEGA_CD_PCM_NUM 12500000
33 #define SEGA_CD_PCM_DEN 786432
34 
35 typedef struct SGADemuxContext {
38 
39  uint8_t sector[65536 * 2];
45  int flags;
46  int idx;
47  int left;
50 
51 static int sga_probe(const AVProbeData *p)
52 {
53  const uint8_t *src = p->buf;
54  int score = 0, sectors = 1;
55  int last_left = 0;
56  int sample_rate = -1;
57 
58  if (p->buf_size < 2048)
59  return 0;
60 
61  for (int i = 0; i + 2 < p->buf_size; i += 2048) {
62  int header = AV_RB16(src + i);
63 
64  if ((header > 0x07FE && header < 0x8100) ||
65  (header > 0x8200 && header < 0xA100) ||
66  (header > 0xA200 && header < 0xC100)) {
67  sectors = 0;
68  break;
69  }
70  }
71 
72  for (int i = 0; i + 4 < p->buf_size;) {
73  int header = AV_RB16(src + i);
74  int left = AV_RB16(src + i + 2);
75  int offset, type, size;
76 
77  if (last_left < 0)
78  return 0;
79  if (sectors && header && last_left == 0) {
80  if (header >> 12) {
81  last_left = left;
82  } else {
83  last_left = left = header;
84  }
85  } else if (sectors && header) {
86  left = header;
87  last_left -= left;
88  if (header != 0x7FE && left < 7)
89  return 0;
90  } else if (sectors) {
91  if (left <= 8)
92  return 0;
93  i += sectors ? 2048 : left + 4;
94  last_left = 0;
95  continue;
96  }
97 
98  if (sectors && (i > 0 && left < 0x7fe) &&
99  (i + left + 14 < p->buf_size)) {
100  offset = i + left + 2;
101  } else if (sectors && i > 0) {
102  i += 2048;
103  last_left -= FFMIN(last_left, 2046);
104  continue;
105  } else {
106  offset = 0;
107  last_left = left;
108  }
109 
110  header = AV_RB16(src + offset);
111  size = AV_RB16(src + offset + 2) + 4;
112 
113  while ((header & 0xFF00) == 0) {
114  offset++;
115  if (offset + 4 >= p->buf_size)
116  break;
117  header = AV_RB16(src + offset);
118  size = AV_RB16(src + offset + 2) + 4;
119  }
120 
121  if (offset + 12 >= p->buf_size)
122  break;
123  if ((header & 0xFF) > 1)
124  return 0;
125  type = header >> 8;
126 
127  if (type == 0xAA ||
128  type == 0xA1 ||
129  type == 0xA2 ||
130  type == 0xA3) {
131  int new_rate;
132 
133  if (size <= 12)
134  return 0;
135  new_rate = AV_RB16(src + offset + 8);
136  if (sample_rate < 0)
137  sample_rate = new_rate;
138  if (sample_rate == 0 || new_rate != sample_rate)
139  return 0;
140  if (src[offset + 10] != 1)
141  return 0;
142 
143  score += 10;
144  } else if (type == 0xC1 ||
145  type == 0xC6 ||
146  type == 0xC7 ||
147  type == 0xC8 ||
148  type == 0xC9 ||
149  type == 0xCB ||
150  type == 0xCD ||
151  type == 0xE7) {
152  int nb_pals = src[offset + 9];
153  int tiles_w = src[offset + 10];
154  int tiles_h = src[offset + 11];
155 
156  if (size <= 12)
157  return 0;
158  if (nb_pals == 0 || nb_pals > 4)
159  return 0;
160  if (tiles_w == 0 || tiles_w > 80)
161  return 0;
162  if (tiles_h == 0 || tiles_h > 60)
163  return 0;
164 
165  score += 10;
166  } else if (header == 0x7FE) {
167  ;
168  } else {
169  return 0;
170  }
171 
172  i += sectors ? 2048 : size + 4;
173  last_left -= FFMIN(last_left, 2046);
174 
175  if (score < 0)
176  break;
177  }
178 
179  return av_clip(score, 0, AVPROBE_SCORE_MAX);
180 }
181 
183 {
184  SGADemuxContext *sga = s->priv_data;
185  AVIOContext *pb = s->pb;
186 
187  sga->sector_headers = 1;
188  sga->first_audio_size = 0;
189  sga->video_stream_index = -1;
190  sga->audio_stream_index = -1;
191  sga->left = 2048;
192  sga->idx = 0;
193 
194  s->ctx_flags |= AVFMTCTX_NOHEADER;
195 
196  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
197  while (!avio_feof(pb)) {
198  int header = avio_rb16(pb);
199  int type = header >> 8;
200  int skip = 2046;
201  int clock;
202 
203  if (!sga->first_audio_size &&
204  (type == 0xAA ||
205  type == 0xA1 ||
206  type == 0xA2 ||
207  type == 0xA3)) {
208  sga->first_audio_size = avio_rb16(pb);
209  avio_skip(pb, 4);
210  clock = avio_rb16(pb);
211  sga->sample_rate = av_rescale(clock,
214  skip -= 8;
215  }
216  if ((header > 0x07FE && header < 0x8100) ||
217  (header > 0x8200 && header < 0xA100) ||
218  (header > 0xA200 && header < 0xC100)) {
219  sga->sector_headers = 0;
220  break;
221  }
222 
223  avio_skip(pb, skip);
224  }
225 
226  avio_seek(pb, 0, SEEK_SET);
227  }
228 
229  return 0;
230 }
231 
232 static void print_stats(AVFormatContext *s, const char *where)
233 {
234  SGADemuxContext *sga = s->priv_data;
235 
236  av_log(s, AV_LOG_DEBUG, "START %s\n", where);
237  av_log(s, AV_LOG_DEBUG, "pos: %"PRIX64"\n", avio_tell(s->pb));
238  av_log(s, AV_LOG_DEBUG, "idx: %X\n", sga->idx);
239  av_log(s, AV_LOG_DEBUG, "packet_type: %X\n", sga->packet_type);
240  av_log(s, AV_LOG_DEBUG, "payload_size: %X\n", sga->payload_size);
241  av_log(s, AV_LOG_DEBUG, "SECTOR: %016"PRIX64"\n", AV_RB64(sga->sector));
242  av_log(s, AV_LOG_DEBUG, "stream: %X\n", sga->sector[1]);
243  av_log(s, AV_LOG_DEBUG, "END %s\n", where);
244 }
245 
247 {
248  SGADemuxContext *sga = s->priv_data;
249 
250  if (sga->idx >= 4) {
251  sga->packet_type = sga->sector[0];
252  sga->payload_size = AV_RB16(sga->sector + 2);
253  } else {
254  sga->packet_type = 0;
255  sga->payload_size = 0;
256  }
257 }
258 
260 {
261  SGADemuxContext *sga = s->priv_data;
262  int ret;
263 
264  if (sga->payload_size <= 8)
265  return AVERROR_INVALIDDATA;
266 
267  if (sga->video_stream_index == -1) {
268  AVRational frame_rate;
269 
271  if (!st)
272  return AVERROR(ENOMEM);
273 
274  st->start_time = 0;
276  st->codecpar->codec_tag = 0;
278  sga->video_stream_index = st->index;
279 
280  if (sga->first_audio_size > 0 && sga->sample_rate > 0) {
281  frame_rate.num = sga->sample_rate;
282  frame_rate.den = sga->first_audio_size;
283  } else {
284  frame_rate.num = 15;
285  frame_rate.den = 1;
286  }
287  avpriv_set_pts_info(st, 64, frame_rate.den, frame_rate.num);
288  }
289 
290  ret = av_new_packet(pkt, sga->payload_size + 4);
291  if (ret < 0)
292  return AVERROR(ENOMEM);
293  memcpy(pkt->data, sga->sector, sga->payload_size + 4);
294  av_assert0(sga->idx >= sga->payload_size + 4);
295  memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4);
296 
298  pkt->duration = 1;
299  pkt->pos = sga->pkt_pos;
300  pkt->flags |= sga->flags;
301  sga->idx -= sga->payload_size + 4;
302  sga->flags = 0;
304 
305  av_log(s, AV_LOG_DEBUG, "VIDEO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx);
306 
307  return 0;
308 }
309 
311 {
312  SGADemuxContext *sga = s->priv_data;
313  int ret;
314 
315  if (sga->payload_size <= 8)
316  return AVERROR_INVALIDDATA;
317 
318  if (sga->audio_stream_index == -1) {
320  if (!st)
321  return AVERROR(ENOMEM);
322 
323  st->start_time = 0;
325  st->codecpar->codec_tag = 0;
328  st->codecpar->sample_rate = av_rescale(AV_RB16(sga->sector + 8),
331  sga->audio_stream_index = st->index;
332 
333  avpriv_set_pts_info(st, 64, 1, st->codecpar->sample_rate);
334  }
335 
336  ret = av_new_packet(pkt, sga->payload_size - 8);
337  if (ret < 0)
338  return AVERROR(ENOMEM);
339  memcpy(pkt->data, sga->sector + 12, sga->payload_size - 8);
340  av_assert0(sga->idx >= sga->payload_size + 4);
341  memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4);
342 
344  pkt->duration = pkt->size;
345  pkt->pos = sga->pkt_pos;
346  pkt->flags |= sga->flags;
347  sga->idx -= sga->payload_size + 4;
348  sga->flags = 0;
350 
351  av_log(s, AV_LOG_DEBUG, "AUDIO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx);
352 
353  return 0;
354 }
355 
357 {
358  SGADemuxContext *sga = s->priv_data;
359  int ret = 0;
360 
361  if (sga->packet_type == 0xCD ||
362  sga->packet_type == 0xCB ||
363  sga->packet_type == 0xC9 ||
364  sga->packet_type == 0xC8 ||
365  sga->packet_type == 0xC7 ||
366  sga->packet_type == 0xC6 ||
367  sga->packet_type == 0xC1 ||
368  sga->packet_type == 0xE7) {
370  } else if (sga->packet_type == 0xA1 ||
371  sga->packet_type == 0xA2 ||
372  sga->packet_type == 0xA3 ||
373  sga->packet_type == 0xAA) {
375  } else {
376  if (sga->idx == 0)
377  return AVERROR_EOF;
378  if (sga->sector[0])
379  return AVERROR_INVALIDDATA;
380  memmove(sga->sector, sga->sector + 1, sga->idx - 1);
381  sga->idx--;
382  return AVERROR(EAGAIN);
383  }
384 
385  return ret;
386 }
387 
389 {
390  SGADemuxContext *sga = s->priv_data;
391  int ret = AVERROR(EAGAIN);
392 
394  if (sga->idx >= sga->payload_size + 4) {
395  print_stats(s, "before sga_packet");
396  ret = sga_packet(s, pkt);
397  print_stats(s, "after sga_packet");
398  if (ret != AVERROR(EAGAIN))
399  return ret;
400  }
401 
402  return sga->idx < sga->payload_size + 4 ? AVERROR(EAGAIN) : ret;
403 }
404 
406 {
407  SGADemuxContext *sga = s->priv_data;
408  AVIOContext *pb = s->pb;
409  int header, ret = 0;
410 
411  sga->pkt_pos = avio_tell(pb);
412 
413 retry:
415 
416  print_stats(s, "start");
417  if (avio_feof(pb) &&
418  (!sga->payload_size || sga->idx < sga->payload_size + 4))
419  return AVERROR_EOF;
420 
421  if (sga->idx < sga->payload_size + 4) {
422  ret = ffio_ensure_seekback(pb, 2);
423  if (ret < 0)
424  return ret;
425 
426  print_stats(s, "before read header");
427  header = avio_rb16(pb);
428  if (!header) {
429  avio_skip(pb, 2046);
430  sga->left = 0;
431  } else if (!avio_feof(pb) &&
432  ((header >> 15) ||
433  !sga->sector_headers)) {
434  avio_seek(pb, -2, SEEK_CUR);
435  sga->flags = AV_PKT_FLAG_KEY;
436  sga->left = 2048;
437  } else {
438  sga->left = 2046;
439  }
440 
441  av_assert0(sga->idx + sga->left < sizeof(sga->sector));
442  ret = avio_read(pb, sga->sector + sga->idx, sga->left);
443  if (ret > 0)
444  sga->idx += ret;
445  else if (ret != AVERROR_EOF && ret)
446  return ret;
447  print_stats(s, "after read header");
448 
450  }
451 
452  ret = try_packet(s, pkt);
453  if (ret == AVERROR(EAGAIN))
454  goto retry;
455 
456  return ret;
457 }
458 
459 static int sga_seek(AVFormatContext *s, int stream_index,
460  int64_t timestamp, int flags)
461 {
462  SGADemuxContext *sga = s->priv_data;
463 
464  sga->packet_type = sga->payload_size = sga->idx = 0;
465  memset(sga->sector, 0, sizeof(sga->sector));
466 
467  return -1;
468 }
469 
471  .p.name = "sga",
472  .p.long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA"),
473  .p.extensions = "sga",
474  .p.flags = AVFMT_GENERIC_INDEX,
475  .priv_data_size = sizeof(SGADemuxContext),
479  .read_seek = sga_seek,
480 };
av_clip
#define av_clip
Definition: common.h:98
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
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:51
SGADemuxContext::idx
int idx
Definition: sga.c:46
avformat_new_stream
AVStream * avformat_new_stream(AVFormatContext *s, const struct AVCodec *c)
Add a new stream to a media file.
AVERROR_EOF
#define AVERROR_EOF
End of file.
Definition: error.h:57
try_packet
static int try_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:388
int64_t
long long int64_t
Definition: coverity.c:34
sga_packet
static int sga_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:356
print_stats
static void print_stats(AVFormatContext *s, const char *where)
Definition: sga.c:232
AVPacket::data
uint8_t * data
Definition: packet.h:522
sga_video_packet
static int sga_video_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:259
AV_CODEC_ID_PCM_SGA
@ AV_CODEC_ID_PCM_SGA
Definition: codec_id.h:364
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:540
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:59
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:454
SGADemuxContext
Definition: sga.c:35
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:577
sample_rate
sample_rate
Definition: ffmpeg_filter.c:409
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:463
avpriv_set_pts_info
void avpriv_set_pts_info(AVStream *st, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: avformat.c:853
SGADemuxContext::sector_headers
int sector_headers
Definition: sga.c:40
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:151
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:494
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:480
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:36
AVRational::num
int num
Numerator.
Definition: rational.h:59
SGADemuxContext::first_audio_size
int first_audio_size
Definition: sga.c:42
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
read_packet
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
Definition: avio_read_callback.c:41
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:198
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:98
SGADemuxContext::flags
int flags
Definition: sga.c:45
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:553
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:453
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
AV_CODEC_ID_SGA_VIDEO
@ AV_CODEC_ID_SGA_VIDEO
Definition: codec_id.h:310
sga_audio_packet
static int sga_audio_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:310
av_assert0
#define av_assert0(cond)
assert() equivalent, that is always enabled.
Definition: avassert.h:40
AV_LOG_DEBUG
#define AV_LOG_DEBUG
Stuff which is only useful for libav* developers.
Definition: log.h:201
sga_read_packet
static int sga_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:405
AVFormatContext
Format I/O context.
Definition: avformat.h:1255
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:766
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:550
NULL
#define NULL
Definition: coverity.c:32
SEGA_CD_PCM_DEN
#define SEGA_CD_PCM_DEN
Definition: sga.c:33
AVFMTCTX_NOHEADER
#define AVFMTCTX_NOHEADER
signal that no header is present (streams are added dynamically)
Definition: avformat.h:1206
AVRational
Rational number (pair of numerator and denominator).
Definition: rational.h:58
AVProbeData
This structure contains the data a format has to probe a file.
Definition: avformat.h:451
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:180
SGADemuxContext::pkt_pos
int64_t pkt_pos
Definition: sga.c:48
SGADemuxContext::sample_rate
int sample_rate
Definition: sga.c:41
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:184
SGADemuxContext::audio_stream_index
int audio_stream_index
Definition: sga.c:37
AVIOContext
Bytestream IO Context.
Definition: avio.h:160
SGADemuxContext::left
int left
Definition: sga.c:47
sga_read_header
static int sga_read_header(AVFormatContext *s)
Definition: sga.c:182
SGADemuxContext::sector
uint8_t sector[65536 *2]
Definition: sga.c:39
AVPacket::size
int size
Definition: packet.h:523
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:106
AVIOContext::seekable
int seekable
A combination of AVIO_SEEKABLE_ flags or 0 when the stream is not seekable.
Definition: avio.h:261
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:303
sga_probe
static int sga_probe(const AVProbeData *p)
Definition: sga.c:51
size
int size
Definition: twinvq_data.h:10344
ff_sga_demuxer
const FFInputFormat ff_sga_demuxer
Definition: sga.c:470
FFInputFormat::p
AVInputFormat p
The public AVInputFormat.
Definition: demux.h:41
header
static const uint8_t header[24]
Definition: sdr2.c:68
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:1022
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:528
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:255
avio_internal.h
internal.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
demux.h
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:43
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:743
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:230
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:745
avformat.h
update_type_size
static void update_type_size(AVFormatContext *s)
Definition: sga.c:246
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:749
channel_layout.h
AVIO_SEEKABLE_NORMAL
#define AVIO_SEEKABLE_NORMAL
Seeking works like for a local file.
Definition: avio.h:41
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:611
AVPacket::stream_index
int stream_index
Definition: packet.h:524
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:317
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
read_probe
static int read_probe(const AVProbeData *p)
Definition: cdg.c:30
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:378
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: codec_par.h:55
AVPacket
This structure stores compressed data.
Definition: packet.h:499
src
INIT_CLIP pixel * src
Definition: h264pred_template.c:418
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:542
FFInputFormat
Definition: demux.h:37
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:482
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
SEGA_CD_PCM_NUM
#define SEGA_CD_PCM_NUM
Definition: sga.c:32
AVERROR_INVALIDDATA
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:61
sga_seek
static int sga_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: sga.c:459
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:792
SGADemuxContext::packet_type
int packet_type
Definition: sga.c:44
skip
static void BS_FUNC() skip(BSCTX *bc, unsigned int n)
Skip n bits in the buffer.
Definition: bitstream_template.h:375
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:345