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 "internal.h"
29 #include "avio_internal.h"
30 
31 #define SEGA_CD_PCM_NUM 12500000
32 #define SEGA_CD_PCM_DEN 786432
33 
34 typedef struct SGADemuxContext {
37 
38  uint8_t sector[65536 * 2];
44  int flags;
45  int idx;
46  int left;
47  int64_t pkt_pos;
49 
50 static int sga_probe(const AVProbeData *p)
51 {
52  const uint8_t *src = p->buf;
53  int score = 0, sectors = 1;
54  int last_left = 0;
55  int sample_rate = -1;
56 
57  if (p->buf_size < 2048)
58  return 0;
59 
60  for (int i = 0; i + 2 < p->buf_size; i += 2048) {
61  int header = AV_RB16(src + i);
62 
63  if ((header > 0x07FE && header < 0x8100) ||
64  (header > 0x8200 && header < 0xA100) ||
65  (header > 0xA200 && header < 0xC100)) {
66  sectors = 0;
67  break;
68  }
69  }
70 
71  for (int i = 0; i + 4 < p->buf_size;) {
72  int header = AV_RB16(src + i);
73  int left = AV_RB16(src + i + 2);
74  int offset, type, size;
75 
76  if (last_left < 0)
77  return 0;
78  if (sectors && header && last_left == 0) {
79  if (header >> 12) {
80  last_left = left;
81  } else {
82  last_left = left = header;
83  }
84  } else if (sectors && header) {
85  left = header;
86  last_left -= left;
87  if (header != 0x7FE && left < 7)
88  return 0;
89  } else if (sectors) {
90  if (left <= 8)
91  return 0;
92  i += sectors ? 2048 : left + 4;
93  last_left = 0;
94  continue;
95  }
96 
97  if (sectors && (i > 0 && left < 0x7fe) &&
98  (i + left + 14 < p->buf_size)) {
99  offset = i + left + 2;
100  } else if (sectors && i > 0) {
101  i += 2048;
102  last_left -= FFMIN(last_left, 2046);
103  continue;
104  } else {
105  offset = 0;
106  last_left = left;
107  }
108 
109  header = AV_RB16(src + offset);
110  size = AV_RB16(src + offset + 2) + 4;
111 
112  while ((header & 0xFF00) == 0) {
113  offset++;
114  if (offset + 4 >= p->buf_size)
115  break;
116  header = AV_RB16(src + offset);
117  size = AV_RB16(src + offset + 2) + 4;
118  }
119 
120  if (offset + 12 >= p->buf_size)
121  break;
122  if ((header & 0xFF) > 1)
123  return 0;
124  type = header >> 8;
125 
126  if (type == 0xAA ||
127  type == 0xA1 ||
128  type == 0xA2 ||
129  type == 0xA3) {
130  int new_rate;
131 
132  if (size <= 12)
133  return 0;
134  new_rate = AV_RB16(src + offset + 8);
135  if (sample_rate < 0)
136  sample_rate = new_rate;
137  if (sample_rate == 0 || new_rate != sample_rate)
138  return 0;
139  if (src[offset + 10] != 1)
140  return 0;
141 
142  score += 10;
143  } else if (type == 0xC1 ||
144  type == 0xC6 ||
145  type == 0xC7 ||
146  type == 0xC8 ||
147  type == 0xC9 ||
148  type == 0xCB ||
149  type == 0xCD ||
150  type == 0xE7) {
151  int nb_pals = src[offset + 9];
152  int tiles_w = src[offset + 10];
153  int tiles_h = src[offset + 11];
154 
155  if (size <= 12)
156  return 0;
157  if (nb_pals == 0 || nb_pals > 4)
158  return 0;
159  if (tiles_w == 0 || tiles_w > 80)
160  return 0;
161  if (tiles_h == 0 || tiles_h > 60)
162  return 0;
163 
164  score += 10;
165  } else if (header == 0x7FE) {
166  ;
167  } else {
168  return 0;
169  }
170 
171  i += sectors ? 2048 : size + 4;
172  last_left -= FFMIN(last_left, 2046);
173 
174  if (score < 0)
175  break;
176  }
177 
178  return av_clip(score, 0, AVPROBE_SCORE_MAX);
179 }
180 
182 {
183  SGADemuxContext *sga = s->priv_data;
184  AVIOContext *pb = s->pb;
185 
186  sga->sector_headers = 1;
187  sga->first_audio_size = 0;
188  sga->video_stream_index = -1;
189  sga->audio_stream_index = -1;
190  sga->left = 2048;
191  sga->idx = 0;
192 
193  s->ctx_flags |= AVFMTCTX_NOHEADER;
194 
195  if (pb->seekable & AVIO_SEEKABLE_NORMAL) {
196  while (!avio_feof(pb)) {
197  int header = avio_rb16(pb);
198  int type = header >> 8;
199  int skip = 2046;
200  int clock;
201 
202  if (!sga->first_audio_size &&
203  (type == 0xAA ||
204  type == 0xA1 ||
205  type == 0xA2 ||
206  type == 0xA3)) {
207  sga->first_audio_size = avio_rb16(pb);
208  avio_skip(pb, 4);
209  clock = avio_rb16(pb);
210  sga->sample_rate = av_rescale(clock,
213  skip -= 8;
214  }
215  if ((header > 0x07FE && header < 0x8100) ||
216  (header > 0x8200 && header < 0xA100) ||
217  (header > 0xA200 && header < 0xC100)) {
218  sga->sector_headers = 0;
219  break;
220  }
221 
222  avio_skip(pb, skip);
223  }
224 
225  avio_seek(pb, 0, SEEK_SET);
226  }
227 
228  return 0;
229 }
230 
231 static void print_stats(AVFormatContext *s, const char *where)
232 {
233  SGADemuxContext *sga = s->priv_data;
234 
235  av_log(s, AV_LOG_DEBUG, "START %s\n", where);
236  av_log(s, AV_LOG_DEBUG, "pos: %"PRIX64"\n", avio_tell(s->pb));
237  av_log(s, AV_LOG_DEBUG, "idx: %X\n", sga->idx);
238  av_log(s, AV_LOG_DEBUG, "packet_type: %X\n", sga->packet_type);
239  av_log(s, AV_LOG_DEBUG, "payload_size: %X\n", sga->payload_size);
240  av_log(s, AV_LOG_DEBUG, "SECTOR: %016"PRIX64"\n", AV_RB64(sga->sector));
241  av_log(s, AV_LOG_DEBUG, "stream: %X\n", sga->sector[1]);
242  av_log(s, AV_LOG_DEBUG, "END %s\n", where);
243 }
244 
246 {
247  SGADemuxContext *sga = s->priv_data;
248 
249  if (sga->idx >= 4) {
250  sga->packet_type = sga->sector[0];
251  sga->payload_size = AV_RB16(sga->sector + 2);
252  } else {
253  sga->packet_type = 0;
254  sga->payload_size = 0;
255  }
256 }
257 
259 {
260  SGADemuxContext *sga = s->priv_data;
261  int ret;
262 
263  if (sga->payload_size <= 8)
264  return AVERROR_INVALIDDATA;
265 
266  if (sga->video_stream_index == -1) {
267  AVRational frame_rate;
268 
270  if (!st)
271  return AVERROR(ENOMEM);
272 
273  st->start_time = 0;
275  st->codecpar->codec_tag = 0;
277  sga->video_stream_index = st->index;
278 
279  if (sga->first_audio_size > 0 && sga->sample_rate > 0) {
280  frame_rate.num = sga->sample_rate;
281  frame_rate.den = sga->first_audio_size;
282  } else {
283  frame_rate.num = 15;
284  frame_rate.den = 1;
285  }
286  avpriv_set_pts_info(st, 64, frame_rate.den, frame_rate.num);
287  }
288 
289  ret = av_new_packet(pkt, sga->payload_size + 4);
290  if (ret < 0)
291  return AVERROR(ENOMEM);
292  memcpy(pkt->data, sga->sector, sga->payload_size + 4);
293  av_assert0(sga->idx >= sga->payload_size + 4);
294  memmove(sga->sector, sga->sector + sga->payload_size + 4, sga->idx - sga->payload_size - 4);
295 
297  pkt->duration = 1;
298  pkt->pos = sga->pkt_pos;
299  pkt->flags |= sga->flags;
300  sga->idx -= sga->payload_size + 4;
301  sga->flags = 0;
303 
304  av_log(s, AV_LOG_DEBUG, "VIDEO PACKET: %d:%016"PRIX64" i:%X\n", pkt->size, AV_RB64(sga->sector), sga->idx);
305 
306  return 0;
307 }
308 
310 {
311  SGADemuxContext *sga = s->priv_data;
312  int ret;
313 
314  if (sga->payload_size <= 8)
315  return AVERROR_INVALIDDATA;
316 
317  if (sga->audio_stream_index == -1) {
319  if (!st)
320  return AVERROR(ENOMEM);
321 
322  st->start_time = 0;
324  st->codecpar->codec_tag = 0;
326  st->codecpar->channels = 1;
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  .name = "sga",
472  .long_name = NULL_IF_CONFIG_SMALL("Digital Pictures SGA"),
473  .priv_data_size = sizeof(SGADemuxContext),
477  .read_seek = sga_seek,
478  .extensions = "sga",
480 };
av_clip
#define av_clip
Definition: common.h:96
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:768
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:45
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
AV_CH_LAYOUT_MONO
#define AV_CH_LAYOUT_MONO
Definition: channel_layout.h:90
ff_sga_demuxer
const AVInputFormat ff_sga_demuxer
Definition: sga.c:470
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:231
AVPacket::data
uint8_t * data
Definition: packet.h:373
sga_video_packet
static int sga_video_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:258
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:391
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:450
SGADemuxContext
Definition: sga.c:34
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:428
sample_rate
sample_rate
Definition: ffmpeg_filter.c:153
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:459
AVCodecParameters::channels
int channels
Audio only.
Definition: codec_par.h:166
SGADemuxContext::sector_headers
int sector_headers
Definition: sga.c:39
read_seek
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:149
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:504
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:476
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:35
AVRational::num
int num
Numerator.
Definition: rational.h:59
SGADemuxContext::first_audio_size
int first_audio_size
Definition: sga.c:41
avassert.h
pkt
AVPacket * pkt
Definition: movenc.c:59
AVInputFormat
Definition: avformat.h:650
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:44
AVInputFormat::name
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:655
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:449
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:309
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: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:1200
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1095
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:32
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:1151
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:447
SGADemuxContext::pkt_pos
int64_t pkt_pos
Definition: sga.c:47
SGADemuxContext::sample_rate
int sample_rate
Definition: sga.c:40
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: codec_par.h:170
SGADemuxContext::audio_stream_index
int audio_stream_index
Definition: sga.c:36
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
SGADemuxContext::left
int left
Definition: sga.c:46
sga_read_header
static int sga_read_header(AVFormatContext *s)
Definition: sga.c:181
SGADemuxContext::sector
uint8_t sector[65536 *2]
Definition: sga.c:38
AVPacket::size
int size
Definition: packet.h:374
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:262
sga_probe
static int sga_probe(const AVProbeData *p)
Definition: sga.c:50
size
int size
Definition: twinvq_data.h:10344
header
static const uint8_t header[24]
Definition: sdr2.c:67
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:1055
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:379
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:271
avio_internal.h
internal.h
FFMIN
#define FFMIN(a, b)
Definition: macros.h:49
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:128
SGADemuxContext::payload_size
int payload_size
Definition: sga.c:42
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:935
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:260
avio_rb16
unsigned int avio_rb16(AVIOContext *s)
Definition: aviobuf.c:775
avformat.h
update_type_size
static void update_type_size(AVFormatContext *s)
Definition: sga.c:245
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:943
channel_layout.h
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:641
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: utils.c:1196
AVPacket::stream_index
int stream_index
Definition: packet.h:375
avio_skip
int64_t avio_skip(AVIOContext *s, int64_t offset)
Skip given number of bytes forward.
Definition: aviobuf.c:347
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:350
AVPacket::pos
int64_t pos
byte position in stream, -1 if unknown
Definition: packet.h:393
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:31
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:975
SGADemuxContext::packet_type
int packet_type
Definition: sga.c:43
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:375