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;
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:95
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: options.c:237
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: codec_par.h:57
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:387
ff_sga_demuxer
const AVInputFormat ff_sga_demuxer
Definition: sga.c:469
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:231
AVPacket::data
uint8_t * data
Definition: packet.h:374
sga_video_packet
static int sga_video_packet(AVFormatContext *s, AVPacket *pkt)
Definition: sga.c:258
AV_CHANNEL_LAYOUT_MONO
#define AV_CHANNEL_LAYOUT_MONO
Definition: channel_layout.h:353
AV_CODEC_ID_PCM_SGA
@ AV_CODEC_ID_PCM_SGA
Definition: codec_id.h:354
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: packet.h:392
AVCodecParameters::codec_tag
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: codec_par.h:65
AVProbeData::buf_size
int buf_size
Size of buf except extra allocated bytes.
Definition: avformat.h:456
SGADemuxContext
Definition: sga.c:34
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: packet.h:429
sample_rate
sample_rate
Definition: ffmpeg_filter.c:153
AVPROBE_SCORE_MAX
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:465
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:697
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:151
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:505
AVFMT_GENERIC_INDEX
#define AVFMT_GENERIC_INDEX
Use generic index building code.
Definition: avformat.h:482
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:656
intreadwrite.h
s
#define s(width, name)
Definition: cbs_vp9.c:256
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:97
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:661
AVProbeData::buf
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:455
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:404
AVFormatContext
Format I/O context.
Definition: avformat.h:1213
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1108
read_header
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:532
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:1164
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:453
AVCodecParameters::ch_layout
AVChannelLayout ch_layout
Audio only.
Definition: codec_par.h:212
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:177
SGADemuxContext::audio_stream_index
int audio_stream_index
Definition: sga.c:36
AVIOContext
Bytestream IO Context.
Definition: avio.h:162
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:375
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:263
AVChannelLayout
An AVChannelLayout holds information about the channel layout of audio data.
Definition: channel_layout.h:290
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:380
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:269
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:129
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:948
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:956
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:641
AVPacket::stream_index
int stream_index
Definition: packet.h:376
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:61
AVPacket
This structure stores compressed data.
Definition: packet.h:351
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:394
flags
#define flags(name, subs,...)
Definition: cbs_av1.c:561
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:27
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: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:988
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