summaryrefslogtreecommitdiff
path: root/ffmpeg/libavformat/segafilm.c
diff options
context:
space:
mode:
Diffstat (limited to 'ffmpeg/libavformat/segafilm.c')
-rw-r--r--ffmpeg/libavformat/segafilm.c61
1 files changed, 9 insertions, 52 deletions
diff --git a/ffmpeg/libavformat/segafilm.c b/ffmpeg/libavformat/segafilm.c
index a33ad85..8a0e8bc 100644
--- a/ffmpeg/libavformat/segafilm.c
+++ b/ffmpeg/libavformat/segafilm.c
@@ -62,10 +62,6 @@ typedef struct FilmDemuxContext {
unsigned int base_clock;
unsigned int version;
-
- /* buffer used for interleaving stereo PCM data */
- unsigned char *stereo_buffer;
- int stereo_buffer_size;
} FilmDemuxContext;
static int film_probe(AVProbeData *p)
@@ -73,6 +69,9 @@ static int film_probe(AVProbeData *p)
if (AV_RB32(&p->buf[0]) != FILM_TAG)
return 0;
+ if (AV_RB32(&p->buf[16]) != FDSC_TAG)
+ return 0;
+
return AVPROBE_SCORE_MAX;
}
@@ -87,8 +86,6 @@ static int film_read_header(AVFormatContext *s)
unsigned int audio_frame_counter;
film->sample_table = NULL;
- film->stereo_buffer = NULL;
- film->stereo_buffer_size = 0;
/* load the main FILM header */
if (avio_read(pb, scratch, 16) != 16)
@@ -117,9 +114,9 @@ static int film_read_header(AVFormatContext *s)
film->audio_type = AV_CODEC_ID_ADPCM_ADX;
else if (film->audio_channels > 0) {
if (film->audio_bits == 8)
- film->audio_type = AV_CODEC_ID_PCM_S8;
+ film->audio_type = AV_CODEC_ID_PCM_S8_PLANAR;
else if (film->audio_bits == 16)
- film->audio_type = AV_CODEC_ID_PCM_S16BE;
+ film->audio_type = AV_CODEC_ID_PCM_S16BE_PLANAR;
else
film->audio_type = AV_CODEC_ID_NONE;
} else
@@ -209,12 +206,14 @@ static int film_read_header(AVFormatContext *s)
for (i = 0; i < film->sample_count; i++) {
/* load the next sample record and transfer it to an internal struct */
if (avio_read(pb, scratch, 16) != 16) {
- av_free(film->sample_table);
+ av_freep(&film->sample_table);
return AVERROR(EIO);
}
film->sample_table[i].sample_offset =
data_offset + AV_RB32(&scratch[0]);
film->sample_table[i].sample_size = AV_RB32(&scratch[4]);
+ if (film->sample_table[i].sample_size > INT_MAX / 4)
+ return AVERROR_INVALIDDATA;
if (AV_RB32(&scratch[8]) == 0xFFFFFFFF) {
film->sample_table[i].stream = film->audio_stream_index;
film->sample_table[i].pts = audio_frame_counter;
@@ -244,8 +243,6 @@ static int film_read_packet(AVFormatContext *s,
AVIOContext *pb = s->pb;
film_sample *sample;
int ret = 0;
- int i;
- int left, right;
if (film->current_sample >= film->sample_count)
return AVERROR_EOF;
@@ -262,45 +259,6 @@ static int film_read_packet(AVFormatContext *s,
if (av_new_packet(pkt, sample->sample_size))
return AVERROR(ENOMEM);
avio_read(pb, pkt->data, sample->sample_size);
- } else if ((sample->stream == film->audio_stream_index) &&
- (film->audio_channels == 2) &&
- (film->audio_type != AV_CODEC_ID_ADPCM_ADX)) {
- /* stereo PCM needs to be interleaved */
-
- if (ffio_limit(pb, sample->sample_size) != sample->sample_size)
- return AVERROR(EIO);
- if (av_new_packet(pkt, sample->sample_size))
- return AVERROR(ENOMEM);
-
- /* make sure the interleave buffer is large enough */
- if (sample->sample_size > film->stereo_buffer_size) {
- av_free(film->stereo_buffer);
- film->stereo_buffer_size = sample->sample_size;
- film->stereo_buffer = av_malloc(film->stereo_buffer_size);
- if (!film->stereo_buffer) {
- film->stereo_buffer_size = 0;
- return AVERROR(ENOMEM);
- }
- }
-
- pkt->pos= avio_tell(pb);
- ret = avio_read(pb, film->stereo_buffer, sample->sample_size);
- if (ret != sample->sample_size)
- ret = AVERROR(EIO);
-
- left = 0;
- right = sample->sample_size / 2;
- for (i = 0; i + 1 + 2*(film->audio_bits != 8) < sample->sample_size; ) {
- if (film->audio_bits == 8) {
- pkt->data[i++] = film->stereo_buffer[left++];
- pkt->data[i++] = film->stereo_buffer[right++];
- } else {
- pkt->data[i++] = film->stereo_buffer[left++];
- pkt->data[i++] = film->stereo_buffer[left++];
- pkt->data[i++] = film->stereo_buffer[right++];
- pkt->data[i++] = film->stereo_buffer[right++];
- }
- }
} else {
ret= av_get_packet(pb, pkt, sample->sample_size);
if (ret != sample->sample_size)
@@ -319,8 +277,7 @@ static int film_read_close(AVFormatContext *s)
{
FilmDemuxContext *film = s->priv_data;
- av_free(film->sample_table);
- av_free(film->stereo_buffer);
+ av_freep(&film->sample_table);
return 0;
}