~ubuntu-branches/ubuntu/precise/mplayer2/precise-proposed

« back to all changes in this revision

Viewing changes to ffmpeg-mt/libavformat/mpc8.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2011-04-21 09:21:39 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20110421092139-7a21foqroxvir3wr
Tags: 2.0-54-gd33877a-1
* New upstream version
* Bug fix: "internal MP3 decoder miscompiles with gcc 4.6", thanks to
  Norbert Preining (Closes: #623279). Fixed by no longer using internal
  mp3lib copy.
* drop build host specific optimizations

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * Musepack SV8 demuxer
3
3
 * Copyright (c) 2007 Konstantin Shishkov
4
4
 *
5
 
 * This file is part of FFmpeg.
 
5
 * This file is part of Libav.
6
6
 *
7
 
 * FFmpeg is free software; you can redistribute it and/or
 
7
 * Libav is free software; you can redistribute it and/or
8
8
 * modify it under the terms of the GNU Lesser General Public
9
9
 * License as published by the Free Software Foundation; either
10
10
 * version 2.1 of the License, or (at your option) any later version.
11
11
 *
12
 
 * FFmpeg is distributed in the hope that it will be useful,
 
12
 * Libav is distributed in the hope that it will be useful,
13
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15
15
 * Lesser General Public License for more details.
16
16
 *
17
17
 * You should have received a copy of the GNU Lesser General Public
18
 
 * License along with FFmpeg; if not, write to the Free Software
 
18
 * License along with Libav; if not, write to the Free Software
19
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
20
 */
21
21
 
22
22
#include "libavcodec/get_bits.h"
23
23
#include "libavcodec/unary.h"
24
24
#include "avformat.h"
 
25
#include "avio_internal.h"
25
26
 
26
27
/// Two-byte MPC tag
27
28
#define MKMPCTAG(a, b) (a | (b << 8))
117
118
    return v;
118
119
}
119
120
 
120
 
static void mpc8_get_chunk_header(ByteIOContext *pb, int *tag, int64_t *size)
 
121
static void mpc8_get_chunk_header(AVIOContext *pb, int *tag, int64_t *size)
121
122
{
122
123
    int64_t pos;
123
 
    pos = url_ftell(pb);
124
 
    *tag = get_le16(pb);
125
 
    *size = ff_get_v(pb);
126
 
    *size -= url_ftell(pb) - pos;
 
124
    pos = avio_tell(pb);
 
125
    *tag = avio_rl16(pb);
 
126
    *size = ffio_read_varlen(pb);
 
127
    *size -= avio_tell(pb) - pos;
127
128
}
128
129
 
129
130
static void mpc8_parse_seektable(AVFormatContext *s, int64_t off)
135
136
    int i, t, seekd;
136
137
    GetBitContext gb;
137
138
 
138
 
    url_fseek(s->pb, off, SEEK_SET);
 
139
    avio_seek(s->pb, off, SEEK_SET);
139
140
    mpc8_get_chunk_header(s->pb, &tag, &size);
140
141
    if(tag != TAG_SEEKTABLE){
141
142
        av_log(s, AV_LOG_ERROR, "No seek table at given position\n");
143
144
    }
144
145
    if(!(buf = av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE)))
145
146
        return;
146
 
    get_buffer(s->pb, buf, size);
 
147
    avio_read(s->pb, buf, size);
147
148
    init_get_bits(&gb, buf, size * 8);
148
149
    size = gb_get_v(&gb);
149
150
    if(size > UINT_MAX/4 || size > c->samples/1152){
171
172
 
172
173
static void mpc8_handle_chunk(AVFormatContext *s, int tag, int64_t chunk_pos, int64_t size)
173
174
{
174
 
    ByteIOContext *pb = s->pb;
 
175
    AVIOContext *pb = s->pb;
175
176
    int64_t pos, off;
176
177
 
177
178
    switch(tag){
178
179
    case TAG_SEEKTBLOFF:
179
 
        pos = url_ftell(pb) + size;
180
 
        off = ff_get_v(pb);
 
180
        pos = avio_tell(pb) + size;
 
181
        off = ffio_read_varlen(pb);
181
182
        mpc8_parse_seektable(s, chunk_pos + off);
182
 
        url_fseek(pb, pos, SEEK_SET);
 
183
        avio_seek(pb, pos, SEEK_SET);
183
184
        break;
184
185
    default:
185
 
        url_fskip(pb, size);
 
186
        avio_skip(pb, size);
186
187
    }
187
188
}
188
189
 
189
190
static int mpc8_read_header(AVFormatContext *s, AVFormatParameters *ap)
190
191
{
191
192
    MPCContext *c = s->priv_data;
192
 
    ByteIOContext *pb = s->pb;
 
193
    AVIOContext *pb = s->pb;
193
194
    AVStream *st;
194
195
    int tag = 0;
195
196
    int64_t size, pos;
196
197
 
197
 
    c->header_pos = url_ftell(pb);
198
 
    if(get_le32(pb) != TAG_MPCK){
 
198
    c->header_pos = avio_tell(pb);
 
199
    if(avio_rl32(pb) != TAG_MPCK){
199
200
        av_log(s, AV_LOG_ERROR, "Not a Musepack8 file\n");
200
201
        return -1;
201
202
    }
202
203
 
203
 
    while(!url_feof(pb)){
204
 
        pos = url_ftell(pb);
 
204
    while(!pb->eof_reached){
 
205
        pos = avio_tell(pb);
205
206
        mpc8_get_chunk_header(pb, &tag, &size);
206
207
        if(tag == TAG_STREAMHDR)
207
208
            break;
211
212
        av_log(s, AV_LOG_ERROR, "Stream header not found\n");
212
213
        return -1;
213
214
    }
214
 
    pos = url_ftell(pb);
215
 
    url_fskip(pb, 4); //CRC
216
 
    c->ver = get_byte(pb);
 
215
    pos = avio_tell(pb);
 
216
    avio_skip(pb, 4); //CRC
 
217
    c->ver = avio_r8(pb);
217
218
    if(c->ver != 8){
218
219
        av_log(s, AV_LOG_ERROR, "Unknown stream version %d\n", c->ver);
219
220
        return -1;
220
221
    }
221
 
    c->samples = ff_get_v(pb);
222
 
    ff_get_v(pb); //silence samples at the beginning
 
222
    c->samples = ffio_read_varlen(pb);
 
223
    ffio_read_varlen(pb); //silence samples at the beginning
223
224
 
224
225
    st = av_new_stream(s, 0);
225
226
    if (!st)
230
231
 
231
232
    st->codec->extradata_size = 2;
232
233
    st->codec->extradata = av_mallocz(st->codec->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
233
 
    get_buffer(pb, st->codec->extradata, st->codec->extradata_size);
 
234
    avio_read(pb, st->codec->extradata, st->codec->extradata_size);
234
235
 
235
236
    st->codec->channels = (st->codec->extradata[1] >> 4) + 1;
236
237
    st->codec->sample_rate = mpc8_rate[st->codec->extradata[0] >> 5];
237
238
    av_set_pts_info(st, 32, 1152  << (st->codec->extradata[1]&3)*2, st->codec->sample_rate);
238
239
    st->duration = c->samples / (1152 << (st->codec->extradata[1]&3)*2);
239
 
    size -= url_ftell(pb) - pos;
 
240
    size -= avio_tell(pb) - pos;
240
241
 
241
242
    return 0;
242
243
}
247
248
    int tag;
248
249
    int64_t pos, size;
249
250
 
250
 
    while(!url_feof(s->pb)){
251
 
        pos = url_ftell(s->pb);
 
251
    while(!s->pb->eof_reached){
 
252
        pos = avio_tell(s->pb);
252
253
        mpc8_get_chunk_header(s->pb, &tag, &size);
253
254
        if (size < 0)
254
255
            return -1;
273
274
    int index = av_index_search_timestamp(st, timestamp, flags);
274
275
 
275
276
    if(index < 0) return -1;
276
 
    url_fseek(s->pb, st->index_entries[index].pos, SEEK_SET);
 
277
    avio_seek(s->pb, st->index_entries[index].pos, SEEK_SET);
277
278
    c->frame = st->index_entries[index].timestamp;
278
279
    return 0;
279
280
}
280
281
 
281
282
 
282
 
AVInputFormat mpc8_demuxer = {
 
283
AVInputFormat ff_mpc8_demuxer = {
283
284
    "mpc8",
284
285
    NULL_IF_CONFIG_SMALL("Musepack SV8"),
285
286
    sizeof(MPCContext),