2
* Discworld II BMV demuxer
3
* Copyright (c) 2011 Konstantin Shishkov.
5
* This file is part of Libav.
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.
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.
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
34
typedef struct BMVContext {
41
static int bmv_read_header(AVFormatContext *s, AVFormatParameters *ap)
44
BMVContext *c = s->priv_data;
46
st = avformat_new_stream(s, 0);
48
return AVERROR(ENOMEM);
49
st->codec->codec_type = AVMEDIA_TYPE_VIDEO;
50
st->codec->codec_id = CODEC_ID_BMV_VIDEO;
51
st->codec->width = 640;
52
st->codec->height = 429;
53
st->codec->pix_fmt = PIX_FMT_PAL8;
54
avpriv_set_pts_info(st, 16, 1, 12);
55
ast = avformat_new_stream(s, 0);
57
return AVERROR(ENOMEM);
58
ast->codec->codec_type = AVMEDIA_TYPE_AUDIO;
59
ast->codec->codec_id = CODEC_ID_BMV_AUDIO;
60
ast->codec->channels = 2;
61
ast->codec->sample_rate = 22050;
62
avpriv_set_pts_info(ast, 16, 1, 22050);
69
static int bmv_read_packet(AVFormatContext *s, AVPacket *pkt)
71
BMVContext *c = s->priv_data;
76
if (s->pb->eof_reached)
78
type = avio_r8(s->pb);
83
c->size = avio_rl24(s->pb);
85
return AVERROR_INVALIDDATA;
86
tmp = av_realloc(c->packet, c->size + 1);
88
return AVERROR(ENOMEM);
91
if (avio_read(s->pb, c->packet + 1, c->size) != c->size)
93
if (type & BMV_AUDIO) {
94
int audio_size = c->packet[1] * 65 + 1;
95
if (audio_size >= c->size) {
96
av_log(s, AV_LOG_ERROR, "Reported audio size %d is bigger than packet size (%d)\n",
98
return AVERROR_INVALIDDATA;
100
if (av_new_packet(pkt, audio_size) < 0)
101
return AVERROR(ENOMEM);
102
memcpy(pkt->data, c->packet + 1, pkt->size);
103
pkt->stream_index = 1;
104
pkt->pts = c->audio_pos;
105
pkt->duration = c->packet[1] * 32;
106
c->audio_pos += pkt->duration;
112
if (av_new_packet(pkt, c->size + 1) < 0)
113
return AVERROR(ENOMEM);
114
pkt->stream_index = 0;
116
memcpy(pkt->data, c->packet, pkt->size);
120
static int bmv_read_close(AVFormatContext *s)
122
BMVContext *c = s->priv_data;
124
av_freep(&c->packet);
129
AVInputFormat ff_bmv_demuxer = {
131
.long_name = NULL_IF_CONFIG_SMALL("Discworld II BMV"),
132
.priv_data_size = sizeof(BMVContext),
133
.read_header = bmv_read_header,
134
.read_packet = bmv_read_packet,
135
.read_close = bmv_read_close,