Libav
segafilm.c
Go to the documentation of this file.
1 /*
2  * Sega FILM Format (CPK) Demuxer
3  * Copyright (c) 2003 The FFmpeg project
4  *
5  * This file is part of Libav.
6  *
7  * Libav is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2.1 of the License, or (at your option) any later version.
11  *
12  * Libav is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with Libav; if not, write to the Free Software
19  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20  */
21 
30 #include "libavutil/intreadwrite.h"
31 #include "avformat.h"
32 #include "internal.h"
33 
34 #define FILM_TAG MKBETAG('F', 'I', 'L', 'M')
35 #define FDSC_TAG MKBETAG('F', 'D', 'S', 'C')
36 #define STAB_TAG MKBETAG('S', 'T', 'A', 'B')
37 #define CVID_TAG MKBETAG('c', 'v', 'i', 'd')
38 #define RAW_TAG MKBETAG('r', 'a', 'w', ' ')
39 
40 typedef struct film_sample {
41  int stream;
42  int64_t sample_offset;
43  unsigned int sample_size;
44  int64_t pts;
45  int keyframe;
46 } film_sample;
47 
48 typedef struct FilmDemuxContext {
51 
52  enum AVCodecID audio_type;
53  unsigned int audio_samplerate;
54  unsigned int audio_bits;
55  unsigned int audio_channels;
56 
57  enum AVCodecID video_type;
58  unsigned int sample_count;
60  unsigned int current_sample;
61 
62  unsigned int base_clock;
63  unsigned int version;
65 
66 static int film_probe(AVProbeData *p)
67 {
68  if (AV_RB32(&p->buf[0]) != FILM_TAG)
69  return 0;
70 
71  return AVPROBE_SCORE_MAX;
72 }
73 
75 {
76  FilmDemuxContext *film = s->priv_data;
77 
78  av_freep(&film->sample_table);
79 
80  return 0;
81 }
82 
84 {
85  FilmDemuxContext *film = s->priv_data;
86  AVIOContext *pb = s->pb;
87  AVStream *st;
88  unsigned char scratch[256];
89  int i, ret;
90  unsigned int data_offset;
91  unsigned int audio_frame_counter;
92  unsigned int video_frame_counter;
93 
94  film->sample_table = NULL;
95 
96  /* load the main FILM header */
97  if (avio_read(pb, scratch, 16) != 16)
98  return AVERROR(EIO);
99  data_offset = AV_RB32(&scratch[4]);
100  film->version = AV_RB32(&scratch[8]);
101 
102  /* load the FDSC chunk */
103  if (film->version == 0) {
104  /* special case for Lemmings .film files; 20-byte header */
105  if (avio_read(pb, scratch, 20) != 20)
106  return AVERROR(EIO);
107  /* make some assumptions about the audio parameters */
109  film->audio_samplerate = 22050;
110  film->audio_channels = 1;
111  film->audio_bits = 8;
112  } else {
113  /* normal Saturn .cpk files; 32-byte header */
114  if (avio_read(pb, scratch, 32) != 32)
115  return AVERROR(EIO);
116  film->audio_samplerate = AV_RB16(&scratch[24]);
117  film->audio_channels = scratch[21];
118  if (!film->audio_channels || film->audio_channels > 2) {
119  av_log(s, AV_LOG_ERROR,
120  "Invalid number of channels: %d\n", film->audio_channels);
121  return AVERROR_INVALIDDATA;
122  }
123  film->audio_bits = scratch[22];
124  if (scratch[23] == 2)
126  else if (film->audio_channels > 0) {
127  if (film->audio_bits == 8)
129  else if (film->audio_bits == 16)
131  else
133  } else
135  }
136 
137  if (AV_RB32(&scratch[0]) != FDSC_TAG)
138  return AVERROR_INVALIDDATA;
139 
140  if (AV_RB32(&scratch[8]) == CVID_TAG) {
142  } else if (AV_RB32(&scratch[8]) == RAW_TAG) {
144  } else {
146  }
147 
148  /* initialize the decoder streams */
149  if (film->video_type) {
150  st = avformat_new_stream(s, NULL);
151  if (!st)
152  return AVERROR(ENOMEM);
153  film->video_stream_index = st->index;
155  st->codecpar->codec_id = film->video_type;
156  st->codecpar->codec_tag = 0; /* no fourcc */
157  st->codecpar->width = AV_RB32(&scratch[16]);
158  st->codecpar->height = AV_RB32(&scratch[12]);
159 
160  if (film->video_type == AV_CODEC_ID_RAWVIDEO) {
161  if (scratch[20] == 24) {
163  } else {
164  av_log(s, AV_LOG_ERROR, "raw video is using unhandled %dbpp\n", scratch[20]);
165  return -1;
166  }
167  }
168  }
169 
170  if (film->audio_type) {
171  st = avformat_new_stream(s, NULL);
172  if (!st)
173  return AVERROR(ENOMEM);
174  film->audio_stream_index = st->index;
176  st->codecpar->codec_id = film->audio_type;
177  st->codecpar->codec_tag = 1;
178  st->codecpar->channels = film->audio_channels;
180 
181  if (film->audio_type == AV_CODEC_ID_ADPCM_ADX) {
182  st->codecpar->bits_per_coded_sample = 18 * 8 / 32;
183  st->codecpar->block_align = st->codecpar->channels * 18;
185  } else {
187  st->codecpar->block_align = st->codecpar->channels *
189  }
190 
193  }
194 
195  /* load the sample table */
196  if (avio_read(pb, scratch, 16) != 16)
197  return AVERROR(EIO);
198  if (AV_RB32(&scratch[0]) != STAB_TAG)
199  return AVERROR_INVALIDDATA;
200  film->base_clock = AV_RB32(&scratch[8]);
201  film->sample_count = AV_RB32(&scratch[12]);
202  if(film->sample_count >= UINT_MAX / sizeof(film_sample))
203  return -1;
204  film->sample_table = av_malloc(film->sample_count * sizeof(film_sample));
205  if (!film->sample_table)
206  return AVERROR(ENOMEM);
207 
208  for (i = 0; i < s->nb_streams; i++) {
209  st = s->streams[i];
211  avpriv_set_pts_info(st, 33, 1, film->base_clock);
212  else
213  avpriv_set_pts_info(st, 64, 1, film->audio_samplerate);
214  }
215 
216  audio_frame_counter = video_frame_counter = 0;
217  for (i = 0; i < film->sample_count; i++) {
218  /* load the next sample record and transfer it to an internal struct */
219  if (avio_read(pb, scratch, 16) != 16) {
220  ret = AVERROR(EIO);
221  goto fail;
222  }
223  film->sample_table[i].sample_offset =
224  data_offset + AV_RB32(&scratch[0]);
225  film->sample_table[i].sample_size = AV_RB32(&scratch[4]);
226  if (film->sample_table[i].sample_size > INT_MAX / 4) {
227  ret = AVERROR_INVALIDDATA;
228  goto fail;
229  }
230  if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) {
231  film->sample_table[i].stream = film->audio_stream_index;
232  film->sample_table[i].pts = audio_frame_counter;
233 
234  if (film->audio_type == AV_CODEC_ID_ADPCM_ADX)
235  audio_frame_counter += (film->sample_table[i].sample_size * 32 /
236  (18 * film->audio_channels));
237  else if (film->audio_type != AV_CODEC_ID_NONE)
238  audio_frame_counter += (film->sample_table[i].sample_size /
239  (film->audio_channels * film->audio_bits / 8));
240  } else {
241  film->sample_table[i].stream = film->video_stream_index;
242  film->sample_table[i].pts = AV_RB32(&scratch[8]) & 0x7FFFFFFF;
243  film->sample_table[i].keyframe = (scratch[8] & 0x80) ? 0 : 1;
244  video_frame_counter++;
246  film->sample_table[i].sample_offset,
247  film->sample_table[i].pts,
248  film->sample_table[i].sample_size, 0,
249  film->sample_table[i].keyframe);
250  }
251  }
252 
253  if (film->audio_type)
254  s->streams[film->audio_stream_index]->duration = audio_frame_counter;
255 
256  if (film->video_type)
257  s->streams[film->video_stream_index]->duration = video_frame_counter;
258 
259  film->current_sample = 0;
260 
261  return 0;
262 fail:
263  film_read_close(s);
264  return ret;
265 }
266 
268  AVPacket *pkt)
269 {
270  FilmDemuxContext *film = s->priv_data;
271  AVIOContext *pb = s->pb;
273  int ret = 0;
274 
275  if (film->current_sample >= film->sample_count)
276  return AVERROR(EIO);
277 
278  sample = &film->sample_table[film->current_sample];
279 
280  /* position the stream (will probably be there anyway) */
281  avio_seek(pb, sample->sample_offset, SEEK_SET);
282 
283  ret = av_get_packet(pb, pkt, sample->sample_size);
284  if (ret < 0)
285  return ret;
286 
287  pkt->stream_index = sample->stream;
288  pkt->pts = sample->pts;
289 
290  film->current_sample++;
291 
292  return ret;
293 }
294 
295 static int film_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
296 {
297  FilmDemuxContext *film = s->priv_data;
298  AVStream *st = s->streams[stream_index];
299  int64_t pos;
300  int ret = av_index_search_timestamp(st, timestamp, flags);
301  if (ret < 0)
302  return ret;
303 
304  pos = avio_seek(s->pb, st->index_entries[ret].pos, SEEK_SET);
305  if (pos < 0)
306  return pos;
307 
308  film->current_sample = ret;
309 
310  return 0;
311 }
312 
314  .name = "film_cpk",
315  .long_name = NULL_IF_CONFIG_SMALL("Sega FILM / CPK"),
316  .priv_data_size = sizeof(FilmDemuxContext),
322 };
void * av_malloc(size_t size)
Allocate a block of size bytes with alignment suitable for all memory accesses (including vectors if ...
Definition: mem.c:62
Bytestream IO Context.
Definition: avio.h:104
#define AVERROR_INVALIDDATA
Invalid data found when processing input.
Definition: error.h:54
int av_add_index_entry(AVStream *st, int64_t pos, int64_t timestamp, int size, int distance, int flags)
Add an index entry into a sorted list.
Definition: utils.c:1214
packed RGB 8:8:8, 24bpp, RGBRGB...
Definition: pixfmt.h:61
void avpriv_set_pts_info(AVStream *s, int pts_wrap_bits, unsigned int pts_num, unsigned int pts_den)
Set the time base and wrapping info for a given stream.
Definition: utils.c:2986
int64_t pos
Definition: avformat.h:664
static int film_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
Definition: segafilm.c:295
#define FILM_TAG
Definition: segafilm.c:34
static int read_seek(AVFormatContext *ctx, int stream_index, int64_t timestamp, int flags)
Definition: libcdio.c:153
enum AVCodecID codec_id
Specific type of the encoded data (the codec used).
Definition: avcodec.h:3483
int index
stream index in AVFormatContext
Definition: avformat.h:706
unsigned int sample_count
Definition: segafilm.c:58
av_log(ac->avr, AV_LOG_TRACE, "%d samples - audio_convert: %s to %s (%s)\, len, av_get_sample_fmt_name(ac->in_fmt), av_get_sample_fmt_name(ac->out_fmt), use_generic ? ac->func_descr_generic :ac->func_descr)
int64_t avio_seek(AVIOContext *s, int64_t offset, int whence)
fseek() equivalent for AVIOContext.
Definition: aviobuf.c:242
AVIndexEntry * index_entries
Only used if the format does not support seeking natively.
Definition: avformat.h:890
static int film_read_close(AVFormatContext *s)
Definition: segafilm.c:74
#define sample
void av_freep(void *arg)
Free a memory block which has been allocated with av_malloc(z)() or av_realloc() and set the pointer ...
Definition: mem.c:202
Format I/O context.
Definition: avformat.h:940
unsigned int audio_channels
Definition: segafilm.c:55
int width
Video only.
Definition: avcodec.h:3525
unsigned int base_clock
Definition: segafilm.c:62
#define AV_RB32
Definition: intreadwrite.h:130
enum AVStreamParseType need_parsing
Definition: avformat.h:879
AVStream * avformat_new_stream(AVFormatContext *s, const AVCodec *c)
Add a new stream to a media file.
Definition: utils.c:2648
AVStream ** streams
A list of all streams in the file.
Definition: avformat.h:1008
static int flags
Definition: log.c:50
static av_cold int read_close(AVFormatContext *ctx)
Definition: libcdio.c:145
int av_get_packet(AVIOContext *s, AVPacket *pkt, int size)
Allocate and read the payload of a packet and initialize its fields with default values.
Definition: utils.c:117
#define STAB_TAG
Definition: segafilm.c:36
int stream
Definition: segafilm.c:41
unsigned int sample_size
Definition: segafilm.c:43
unsigned int audio_samplerate
Definition: segafilm.c:53
int avio_read(AVIOContext *s, unsigned char *buf, int size)
Read size bytes from AVIOContext into buf.
Definition: aviobuf.c:545
int video_stream_index
Definition: segafilm.c:49
AVCodecID
Identify the syntax and semantics of the bitstream.
Definition: avcodec.h:193
#define AV_LOG_ERROR
Something went wrong and cannot losslessly be recovered.
Definition: log.h:124
int av_index_search_timestamp(AVStream *st, int64_t timestamp, int flags)
Get the index for a specific timestamp.
Definition: utils.c:1255
#define AV_RB16
Definition: intreadwrite.h:53
#define AVERROR(e)
Definition: error.h:43
#define NULL_IF_CONFIG_SMALL(x)
Return NULL if CONFIG_SMALL is true, otherwise the argument without modification. ...
Definition: internal.h:148
enum AVMediaType codec_type
General type of the encoded data.
Definition: avcodec.h:3479
unsigned int current_sample
Definition: segafilm.c:60
unsigned int version
Definition: segafilm.c:63
#define fail()
Definition: checkasm.h:80
int bit_rate
The average bitrate of the encoded data (in bits per second).
Definition: avcodec.h:3512
unsigned char * buf
Buffer must have AVPROBE_PADDING_SIZE of extra allocated bytes filled with zero.
Definition: avformat.h:400
int keyframe
Definition: segafilm.c:45
unsigned int nb_streams
Number of elements in AVFormatContext.streams.
Definition: avformat.h:996
int block_align
Audio only.
Definition: avcodec.h:3571
static int read_probe(AVProbeData *pd)
Definition: jvdec.c:55
film_sample * sample_table
Definition: segafilm.c:59
unsigned int audio_bits
Definition: segafilm.c:54
#define RAW_TAG
Definition: segafilm.c:38
#define CVID_TAG
Definition: segafilm.c:37
int64_t pts
Definition: segafilm.c:44
enum AVCodecID video_type
Definition: segafilm.c:57
static int film_read_header(AVFormatContext *s)
Definition: segafilm.c:83
int64_t sample_offset
Definition: segafilm.c:42
static int read_header(FFV1Context *f)
Definition: ffv1dec.c:546
Stream structure.
Definition: avformat.h:705
NULL
Definition: eval.c:55
AVIOContext * pb
I/O context.
Definition: avformat.h:982
static int read_packet(AVFormatContext *ctx, AVPacket *pkt)
Definition: libcdio.c:114
static int film_probe(AVProbeData *p)
Definition: segafilm.c:66
#define FDSC_TAG
Definition: segafilm.c:35
This structure contains the data a format has to probe a file.
Definition: avformat.h:398
AVInputFormat ff_segafilm_demuxer
Definition: segafilm.c:313
int64_t duration
Decoding: duration of the stream, in stream time base.
Definition: avformat.h:757
int sample_rate
Audio only.
Definition: avcodec.h:3564
#define AVPROBE_SCORE_MAX
maximum score
Definition: avformat.h:407
full parsing and repack
Definition: avformat.h:657
Main libavformat public API header.
int audio_stream_index
Definition: segafilm.c:50
static int film_read_packet(AVFormatContext *s, AVPacket *pkt)
Definition: segafilm.c:267
void * priv_data
Format private data.
Definition: avformat.h:968
int bits_per_coded_sample
Definition: avcodec.h:3514
int channels
Audio only.
Definition: avcodec.h:3560
enum AVCodecID audio_type
Definition: segafilm.c:52
const char * name
A comma separated list of short names for the format.
Definition: avformat.h:529
AVCodecParameters * codecpar
Definition: avformat.h:831
uint32_t codec_tag
Additional information about the codec (corresponds to the AVI FOURCC).
Definition: avcodec.h:3487
int stream_index
Definition: avcodec.h:1348
This structure stores compressed data.
Definition: avcodec.h:1323
int64_t pts
Presentation timestamp in AVStream->time_base units; the time at which the decompressed packet will b...
Definition: avcodec.h:1339