FFmpeg
segafilmenc.c
Go to the documentation of this file.
1 /*
2  * Sega FILM Format (CPK) Muxer
3  * Copyright (C) 2003 The FFmpeg project
4  * Copyright (C) 2018 Misty De Meo
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 /**
24  * @file
25  * Sega FILM (.cpk) file muxer
26  * @author Misty De Meo <misty@brew.sh>
27  *
28  * @see For more information regarding the Sega FILM file format, visit:
29  * http://wiki.multimedia.cx/index.php?title=Sega_FILM
30  */
31 
32 #include "libavutil/intreadwrite.h"
33 #include "avformat.h"
34 #include "internal.h"
35 #include "avio_internal.h"
36 
37 typedef struct FILMPacket {
38  int audio;
39  int keyframe;
44  struct FILMPacket *next;
45 } FILMPacket;
46 
47 typedef struct FILMOutputContext {
48  const AVClass *class;
51  int64_t stab_pos;
54  int64_t packet_count;
56 
58 {
59  AVIOContext *pb = format_context->pb;
60  /* The bits in these two 32-bit integers contain info about the contents of this sample */
61  int32_t info1 = 0;
62  int32_t info2 = 0;
63 
64  if (pkt->audio) {
65  /* Always the same, carries no more information than "this is audio" */
66  info1 = 0xFFFFFFFF;
67  info2 = 1;
68  } else {
69  info1 = pkt->pts;
70  info2 = pkt->duration;
71  /* The top bit being set indicates a key frame */
72  if (!pkt->keyframe)
73  info1 |= 1U << 31;
74  }
75 
76  /* Write the 16-byte sample info packet to the STAB chunk in the header */
77  avio_wb32(pb, pkt->index);
78  avio_wb32(pb, pkt->size);
79  avio_wb32(pb, info1);
80  avio_wb32(pb, info2);
81 
82  return 0;
83 }
84 
85 static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt)
86 {
87  FILMPacket *metadata;
88  AVIOContext *pb = format_context->pb;
89  FILMOutputContext *film = format_context->priv_data;
90  int encoded_buf_size = 0;
91  enum AVCodecID codec_id;
92 
93  /* Track the metadata used to write the header and add it to the linked list */
94  metadata = av_mallocz(sizeof(FILMPacket));
95  if (!metadata)
96  return AVERROR(ENOMEM);
97  metadata->audio = pkt->stream_index == film->audio_index;
98  metadata->keyframe = pkt->flags & AV_PKT_FLAG_KEY;
99  metadata->pts = pkt->pts;
100  metadata->duration = pkt->duration;
101  metadata->size = pkt->size;
102  if (film->last == NULL) {
103  metadata->index = 0;
104  } else {
105  metadata->index = film->last->index + film->last->size;
106  film->last->next = metadata;
107  }
108  metadata->next = NULL;
109  if (film->start == NULL)
110  film->start = metadata;
111  film->packet_count++;
112  film->last = metadata;
113 
114  codec_id = format_context->streams[pkt->stream_index]->codecpar->codec_id;
115 
116  /* Sega Cinepak has an extra two-byte header; write dummy data there,
117  * then adjust the cvid header to accommodate for the extra size */
118  if (codec_id == AV_CODEC_ID_CINEPAK) {
119  encoded_buf_size = AV_RB24(&pkt->data[1]);
120  /* Already Sega Cinepak, so no need to reformat the packets */
121  if (encoded_buf_size != pkt->size && (pkt->size % encoded_buf_size) != 0) {
122  avio_write(pb, pkt->data, pkt->size);
123  } else {
124  uint8_t padding[2] = {0, 0};
125  /* In Sega Cinepak, the reported size in the Cinepak header is
126  * 8 bytes too short. However, the size in the STAB section of the header
127  * is correct, taking into account the extra two bytes. */
128  AV_WB24(&pkt->data[1], pkt->size - 8 + 2);
129  metadata->size += 2;
130 
131  avio_write(pb, pkt->data, 10);
132  avio_write(pb, padding, 2);
133  avio_write(pb, &pkt->data[10], pkt->size - 10);
134  }
135  } else {
136  /* Other formats can just be written as-is */
137  avio_write(pb, pkt->data, pkt->size);
138  }
139 
140  return 0;
141 }
142 
144 {
145  /* 0 (PCM) and 2 (ADX) are the only known values */
146  switch (codec_id) {
149  return 0;
150  break;
152  return 2;
153  break;
154  default:
155  return -1;
156  }
157 }
158 
159 static int film_init(AVFormatContext *format_context)
160 {
161  AVStream *audio = NULL;
162  FILMOutputContext *film = format_context->priv_data;
163  film->audio_index = -1;
164  film->video_index = -1;
165  film->stab_pos = 0;
166  film->packet_count = 0;
167  film->start = NULL;
168  film->last = NULL;
169 
170  for (int i = 0; i < format_context->nb_streams; i++) {
171  AVStream *st = format_context->streams[i];
172  if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
173  if (film->audio_index > -1) {
174  av_log(format_context, AV_LOG_ERROR, "Sega FILM allows a maximum of one audio stream.\n");
175  return AVERROR(EINVAL);
176  }
177  film->audio_index = i;
178  audio = st;
179  }
180 
181  if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
182  if (film->video_index > -1) {
183  av_log(format_context, AV_LOG_ERROR, "Sega FILM allows a maximum of one video stream.\n");
184  return AVERROR(EINVAL);
185  }
186  film->video_index = i;
187  }
188 
189  if (film->video_index == -1) {
190  av_log(format_context, AV_LOG_ERROR, "No video stream present.\n");
191  return AVERROR(EINVAL);
192  }
193  }
194 
195  if (audio != NULL && get_audio_codec_id(audio->codecpar->codec_id) < 0) {
196  av_log(format_context, AV_LOG_ERROR, "Incompatible audio stream format.\n");
197  return AVERROR(EINVAL);
198  }
199 
200  return 0;
201 }
202 
203 static int shift_data(AVFormatContext *format_context, int64_t shift_size)
204 {
205  int ret = 0;
206  int64_t pos, pos_end = avio_tell(format_context->pb);
207  uint8_t *buf, *read_buf[2];
208  int read_buf_id = 0;
209  int read_size[2];
210  AVIOContext *read_pb;
211 
212  buf = av_malloc(shift_size * 2);
213  if (!buf)
214  return AVERROR(ENOMEM);
215  read_buf[0] = buf;
216  read_buf[1] = buf + shift_size;
217 
218  /* Write the header at the beginning of the file, shifting all content as necessary;
219  * based on the approach used by MOV faststart. */
220  avio_flush(format_context->pb);
221  ret = format_context->io_open(format_context, &read_pb, format_context->url, AVIO_FLAG_READ, NULL);
222  if (ret < 0) {
223  av_log(format_context, AV_LOG_ERROR, "Unable to re-open %s output file to "
224  "write the header\n", format_context->url);
225  av_free(buf);
226  return ret;
227  }
228 
229  /* mark the end of the shift to up to the last data we wrote, and get ready
230  * for writing */
231  pos_end = avio_tell(format_context->pb);
232  avio_seek(format_context->pb, shift_size, SEEK_SET);
233 
234  /* start reading at where the new header will be placed */
235  avio_seek(read_pb, 0, SEEK_SET);
236  pos = avio_tell(read_pb);
237 
238 #define READ_BLOCK do { \
239  read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], shift_size); \
240  read_buf_id ^= 1; \
241 } while (0)
242 
243  /* shift data by chunk of at most shift_size */
244  READ_BLOCK;
245  do {
246  int n;
247  READ_BLOCK;
248  n = read_size[read_buf_id];
249  if (n <= 0)
250  break;
251  avio_write(format_context->pb, read_buf[read_buf_id], n);
252  pos += n;
253  } while (pos < pos_end);
254  ff_format_io_close(format_context, &read_pb);
255 
256  av_free(buf);
257  return 0;
258 }
259 
260 static int film_write_header(AVFormatContext *format_context)
261 {
262  int ret = 0;
263  int64_t sample_table_size, stabsize, headersize;
264  int8_t audio_codec;
265  AVIOContext *pb = format_context->pb;
266  FILMOutputContext *film = format_context->priv_data;
267  FILMPacket *prev, *packet;
268  AVStream *audio = NULL;
269  AVStream *video = NULL;
270 
271  /* Calculate how much we need to reserve for the header;
272  * this is the amount the rest of the data will be shifted up by. */
273  sample_table_size = film->packet_count * 16;
274  stabsize = 16 + sample_table_size;
275  headersize = 16 + /* FILM header base */
276  32 + /* FDSC chunk */
277  stabsize;
278 
279  ret = shift_data(format_context, headersize);
280  if (ret < 0)
281  return ret;
282  /* Seek back to the beginning to start writing the header now */
283  avio_seek(pb, 0, SEEK_SET);
284 
285  if (film->audio_index > -1)
286  audio = format_context->streams[film->audio_index];
287  if (film->video_index > -1)
288  video = format_context->streams[film->video_index];
289 
290  if (audio != NULL) {
291  audio_codec = get_audio_codec_id(audio->codecpar->codec_id);
292  if (audio_codec < 0) {
293  av_log(format_context, AV_LOG_ERROR, "Incompatible audio stream format.\n");
294  return AVERROR(EINVAL);
295  }
296  }
297 
298  if (video->codecpar->format != AV_PIX_FMT_RGB24) {
299  av_log(format_context, AV_LOG_ERROR, "Pixel format must be rgb24.\n");
300  return AVERROR(EINVAL);
301  }
302 
303  /* First, write the FILM header; this is very simple */
304 
305  ffio_wfourcc(pb, "FILM");
306  avio_wb32(pb, 48 + stabsize);
307  /* This seems to be okay to hardcode, since this muxer targets 1.09 features;
308  * videos produced by this muxer are readable by 1.08 and lower players. */
309  ffio_wfourcc(pb, "1.09");
310  /* I have no idea what this field does, might be reserved */
311  avio_wb32(pb, 0);
312 
313  /* Next write the FDSC (file description) chunk */
314  ffio_wfourcc(pb, "FDSC");
315  avio_wb32(pb, 0x20); /* Size of FDSC chunk */
316 
317  /* The only two supported codecs; raw video is rare */
318  switch (video->codecpar->codec_id) {
319  case AV_CODEC_ID_CINEPAK:
320  ffio_wfourcc(pb, "cvid");
321  break;
323  ffio_wfourcc(pb, "raw ");
324  break;
325  default:
326  av_log(format_context, AV_LOG_ERROR, "Incompatible video stream format.\n");
327  return AVERROR(EINVAL);
328  }
329 
330  avio_wb32(pb, video->codecpar->height);
331  avio_wb32(pb, video->codecpar->width);
332  avio_w8(pb, 24); /* Bits per pixel - observed to always be 24 */
333 
334  if (audio != NULL) {
335  avio_w8(pb, audio->codecpar->channels); /* Audio channels */
336  avio_w8(pb, audio->codecpar->bits_per_coded_sample); /* Audio bit depth */
337  avio_w8(pb, audio_codec); /* Compression - 0 is PCM, 2 is ADX */
338  avio_wb16(pb, audio->codecpar->sample_rate); /* Audio sampling rate */
339  } else {
340  /* Set all these fields to 0 if there's no audio */
341  avio_w8(pb, 0);
342  avio_w8(pb, 0);
343  avio_w8(pb, 0);
344  avio_wb16(pb, 0);
345  }
346 
347  /* I have no idea what this pair of fields does either, might be reserved */
348  avio_wb32(pb, 0);
349  avio_wb16(pb, 0);
350 
351  /* Finally, write the STAB (sample table) chunk */
352  ffio_wfourcc(pb, "STAB");
353  avio_wb32(pb, 16 + (film->packet_count * 16));
354  /* Framerate base frequency. Here we're assuming that the frame rate is even.
355  * In real world Sega FILM files, there are usually a couple of approaches:
356  * a) framerate base frequency is the same as the framerate, and ticks
357  * increment by 1 every frame, or
358  * b) framerate base frequency is a much larger number, and ticks
359  * increment by larger steps every frame.
360  * The latter occurs even in cases where the frame rate is even; for example, in
361  * Lunar: Silver Star Story, the base frequency is 600 and each frame, the ticks
362  * are incremented by 25 for an evenly spaced framerate of 24fps. */
363  avio_wb32(pb, av_q2d(av_inv_q(video->time_base)));
364 
365  avio_wb32(pb, film->packet_count);
366 
367  avio_flush(pb);
368 
369  /* Finally, write out each packet's data to the header */
370  packet = film->start;
371  while (packet != NULL) {
372  film_write_packet_to_header(format_context, packet);
373  prev = packet;
374  packet = packet->next;
375  av_freep(&prev);
376  }
377 
378  return 0;
379 }
380 
381 static const AVClass film_muxer_class = {
382  .class_name = "Sega FILM muxer",
383  .item_name = av_default_item_name,
384  .version = LIBAVUTIL_VERSION_INT,
385 };
386 
388  .name = "film_cpk",
389  .long_name = NULL_IF_CONFIG_SMALL("Sega FILM / CPK"),
390  .extensions = "cpk",
391  .priv_data_size = sizeof(FILMOutputContext),
392  .audio_codec = AV_CODEC_ID_PCM_S16BE_PLANAR,
393  .video_codec = AV_CODEC_ID_CINEPAK,
394  .init = film_init,
397  .priv_class = &film_muxer_class,
398 };
init
static av_cold int init(AVCodecContext *avctx)
Definition: avrndec.c:35
AVOutputFormat::name
const char * name
Definition: avformat.h:496
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
FILMPacket::keyframe
int keyframe
Definition: segafilmenc.c:39
FILMOutputContext::stab_pos
int64_t stab_pos
Definition: segafilmenc.c:51
AVCodecParameters::codec_type
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3953
codec_id
enum AVCodecID codec_id
Definition: qsv.c:72
ffio_wfourcc
static av_always_inline void ffio_wfourcc(AVIOContext *pb, const uint8_t *s)
Definition: avio_internal.h:58
n
int n
Definition: avisynth_c.h:760
AV_CODEC_ID_RAWVIDEO
@ AV_CODEC_ID_RAWVIDEO
Definition: avcodec.h:231
film_init
static int film_init(AVFormatContext *format_context)
Definition: segafilmenc.c:159
AVFormatContext::streams
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1410
film_write_packet_to_header
static int film_write_packet_to_header(AVFormatContext *format_context, FILMPacket *pkt)
Definition: segafilmenc.c:57
AVPacket::data
uint8_t * data
Definition: avcodec.h:1477
AV_CODEC_ID_PCM_S16BE_PLANAR
@ AV_CODEC_ID_PCM_S16BE_PLANAR
Definition: avcodec.h:493
AVPacket::duration
int64_t duration
Duration of this packet in AVStream->time_base units, 0 if unknown.
Definition: avcodec.h:1495
film_write_packet
static int film_write_packet(AVFormatContext *format_context, AVPacket *pkt)
Definition: segafilmenc.c:85
AV_PKT_FLAG_KEY
#define AV_PKT_FLAG_KEY
The packet contains a keyframe.
Definition: avcodec.h:1509
av_malloc
#define av_malloc(s)
Definition: tableprint_vlc.h:31
FILMPacket::index
int32_t index
Definition: segafilmenc.c:43
FILMOutputContext::video_index
int video_index
Definition: segafilmenc.c:50
AVCodecParameters::channels
int channels
Audio only.
Definition: avcodec.h:4063
FILMOutputContext
Definition: segafilmenc.c:47
U
#define U(x)
Definition: vp56_arith.h:37
avio_tell
static av_always_inline int64_t avio_tell(AVIOContext *s)
ftell() equivalent for AVIOContext.
Definition: avio.h:557
shift_data
static int shift_data(AVFormatContext *format_context, int64_t shift_size)
Definition: segafilmenc.c:203
get_audio_codec_id
static int get_audio_codec_id(enum AVCodecID codec_id)
Definition: segafilmenc.c:143
AV_LOG_ERROR
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:176
buf
void * buf
Definition: avisynth_c.h:766
FILMPacket::size
int32_t size
Definition: segafilmenc.c:42
intreadwrite.h
AVMEDIA_TYPE_AUDIO
@ AVMEDIA_TYPE_AUDIO
Definition: avutil.h:202
av_q2d
static double av_q2d(AVRational a)
Convert an AVRational to a double.
Definition: rational.h:104
int32_t
int32_t
Definition: audio_convert.c:194
FILMPacket::next
struct FILMPacket * next
Definition: segafilmenc.c:44
AVFormatContext
Format I/O context.
Definition: avformat.h:1342
internal.h
AVStream::codecpar
AVCodecParameters * codecpar
Codec parameters associated with this stream.
Definition: avformat.h:1017
LIBAVUTIL_VERSION_INT
#define LIBAVUTIL_VERSION_INT
Definition: version.h:85
AVClass
Describe the class of an AVClass context structure.
Definition: log.h:67
NULL
#define NULL
Definition: coverity.c:32
write_trailer
static int write_trailer(AVFormatContext *s1)
Definition: v4l2enc.c:94
AV_CODEC_ID_CINEPAK
@ AV_CODEC_ID_CINEPAK
Definition: avcodec.h:261
av_default_item_name
const char * av_default_item_name(void *ptr)
Return the context name.
Definition: log.c:191
AVFormatContext::pb
AVIOContext * pb
I/O context.
Definition: avformat.h:1384
avio_w8
void avio_w8(AVIOContext *s, int b)
Definition: aviobuf.c:196
AVCodecParameters::sample_rate
int sample_rate
Audio only.
Definition: avcodec.h:4067
AVCodecID
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:215
FILMPacket::duration
int32_t duration
Definition: segafilmenc.c:41
AVFormatContext::nb_streams
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:1398
FILMPacket::pts
int32_t pts
Definition: segafilmenc.c:40
film_muxer_class
static const AVClass film_muxer_class
Definition: segafilmenc.c:381
AVIOContext
Bytestream IO Context.
Definition: avio.h:161
AV_PIX_FMT_RGB24
@ AV_PIX_FMT_RGB24
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:68
AV_CODEC_ID_ADPCM_ADX
@ AV_CODEC_ID_ADPCM_ADX
Definition: avcodec.h:511
AVPacket::size
int size
Definition: avcodec.h:1478
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:188
AVFormatContext::url
char * url
input or output URL.
Definition: avformat.h:1438
FILMOutputContext::packet_count
int64_t packet_count
Definition: segafilmenc.c:54
AV_WB24
#define AV_WB24(p, d)
Definition: intreadwrite.h:450
FILMPacket
Definition: segafilmenc.c:37
avio_write
void avio_write(AVIOContext *s, const unsigned char *buf, int size)
Definition: aviobuf.c:218
avio_wb32
void avio_wb32(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:377
FILMOutputContext::last
FILMPacket * last
Definition: segafilmenc.c:53
AVPacket::flags
int flags
A combination of AV_PKT_FLAG values.
Definition: avcodec.h:1483
write_packet
static void write_packet(OutputFile *of, AVPacket *pkt, OutputStream *ost, int unqueue)
Definition: ffmpeg.c:690
FILMPacket::audio
int audio
Definition: segafilmenc.c:38
AVOutputFormat
Definition: avformat.h:495
i
#define i(width, name, range_min, range_max)
Definition: cbs_h2645.c:259
AVPacket::pts
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1470
avio_internal.h
ff_segafilm_muxer
AVOutputFormat ff_segafilm_muxer
Definition: segafilmenc.c:387
uint8_t
uint8_t
Definition: audio_convert.c:194
av_mallocz
void * av_mallocz(size_t size)
Allocate a memory block with alignment suitable for all memory accesses (including vectors if availab...
Definition: mem.c:236
av_inv_q
static av_always_inline AVRational av_inv_q(AVRational q)
Invert a rational.
Definition: rational.h:159
ret
ret
Definition: filter_design.txt:187
AVStream
Stream structure.
Definition: avformat.h:870
avio_seek
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:246
AVClass::class_name
const char * class_name
The name of the class; usually it is the same name as the context structure type to which the AVClass...
Definition: log.h:72
avformat.h
FILMOutputContext::audio_index
int audio_index
Definition: segafilmenc.c:49
pkt
static AVPacket pkt
Definition: demuxing_decoding.c:54
video
A Quick Description Of Rate Distortion Theory We want to encode a video
Definition: rate_distortion.txt:3
AVFormatContext::io_open
int(* io_open)(struct AVFormatContext *s, AVIOContext **pb, const char *url, int flags, AVDictionary **options)
A callback for opening new IO streams.
Definition: avformat.h:1924
AVPacket::stream_index
int stream_index
Definition: avcodec.h:1479
ff_format_io_close
void ff_format_io_close(AVFormatContext *s, AVIOContext **pb)
Definition: utils.c:5665
AVIO_FLAG_READ
#define AVIO_FLAG_READ
read-only
Definition: avio.h:654
AVMEDIA_TYPE_VIDEO
@ AVMEDIA_TYPE_VIDEO
Definition: avutil.h:201
AVCodecParameters::bits_per_coded_sample
int bits_per_coded_sample
The number of bits per sample in the codedwords.
Definition: avcodec.h:3999
avio_flush
int void avio_flush(AVIOContext *s)
Force flushing of buffered data.
Definition: aviobuf.c:238
av_free
#define av_free(p)
Definition: tableprint_vlc.h:34
AVCodecParameters::codec_id
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3957
AVPacket
This structure stores compressed data.
Definition: avcodec.h:1454
av_freep
#define av_freep(p)
Definition: tableprint_vlc.h:35
AV_CODEC_ID_PCM_S8_PLANAR
@ AV_CODEC_ID_PCM_S8_PLANAR
Definition: avcodec.h:490
film_write_header
static int film_write_header(AVFormatContext *format_context)
Definition: segafilmenc.c:260
avio_wb16
void avio_wb16(AVIOContext *s, unsigned int val)
Definition: aviobuf.c:475
av_log
#define av_log(a,...)
Definition: tableprint_vlc.h:28
AV_RB24
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_RB24
Definition: bytestream.h:93
AVFormatContext::priv_data
void * priv_data
Format private data.
Definition: avformat.h:1370
READ_BLOCK
#define READ_BLOCK
FILMOutputContext::start
FILMPacket * start
Definition: segafilmenc.c:52