annotate mpc.c @ 3754:8d267b43eaba libavformat

Move malloc() down until after all initializations, so that the resource is only allocated if initialization worked. This means that on failure, we don't have to deallocate it.
author rbultje
date Sat, 23 Aug 2008 18:46:30 +0000
parents 7a0230981402
children 1d3d17de20ba
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
1 /*
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
2 * Musepack demuxer
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
3 * Copyright (c) 2006 Konstantin Shishkov
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
4 *
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
5 * This file is part of FFmpeg.
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
6 *
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
11 *
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
15 * Lesser General Public License for more details.
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
16 *
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
2217
06083249909c license header consistency cosmetics
diego
parents: 2001
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
20 */
3286
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 2771
diff changeset
21
6f61c3b36632 Use full path for #includes from another directory.
diego
parents: 2771
diff changeset
22 #include "libavcodec/bitstream.h"
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
23 #include "avformat.h"
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
24
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
25 #define MPC_FRAMESIZE 1152
1610
cde17266ad08 Decode previous 32 frames to avoid seeking artifacts in MPC
kostya
parents: 1609
diff changeset
26 #define DELAY_FRAMES 32
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
27
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
28 static const int mpc_rate[4] = { 44100, 48000, 37800, 32000 };
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
29 typedef struct {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
30 int64_t pos;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
31 int size, skip;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
32 }MPCFrame;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
33
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
34 typedef struct {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
35 int ver;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
36 uint32_t curframe, lastframe;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
37 uint32_t fcount;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
38 MPCFrame *frames;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
39 int curbits;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
40 int frames_noted;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
41 } MPCContext;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
42
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
43 static int mpc_probe(AVProbeData *p)
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
44 {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
45 const uint8_t *d = p->buf;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
46 if (d[0] == 'M' && d[1] == 'P' && d[2] == '+' && (d[3] == 0x17 || d[3] == 0x7))
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
47 return AVPROBE_SCORE_MAX;
1609
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
48 if (d[0] == 'I' && d[1] == 'D' && d[2] == '3')
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
49 return AVPROBE_SCORE_MAX / 2;
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
50 return 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
51 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
52
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
53 static int mpc_read_header(AVFormatContext *s, AVFormatParameters *ap)
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
54 {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
55 MPCContext *c = s->priv_data;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
56 AVStream *st;
1609
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
57 int t;
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
58
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
59 t = get_le24(s->pb);
1609
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
60 if(t != MKTAG('M', 'P', '+', 0)){
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
61 if(t != MKTAG('I', 'D', '3', 0)){
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
62 av_log(s, AV_LOG_ERROR, "Not a Musepack file\n");
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
63 return -1;
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
64 }
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
65 /* skip ID3 tags and try again */
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
66 url_fskip(s->pb, 3);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
67 t = get_byte(s->pb) << 21;
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
68 t |= get_byte(s->pb) << 14;
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
69 t |= get_byte(s->pb) << 7;
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
70 t |= get_byte(s->pb);
1609
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
71 av_log(s, AV_LOG_DEBUG, "Skipping %d(%X) bytes of ID3 data\n", t, t);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
72 url_fskip(s->pb, t);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
73 if(get_le24(s->pb) != MKTAG('M', 'P', '+', 0)){
1609
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
74 av_log(s, AV_LOG_ERROR, "Not a Musepack file\n");
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
75 return -1;
9adbec516265 Make MPC demuxer deal with ID3 tags at the beginning
kostya
parents: 1605
diff changeset
76 }
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
77 }
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
78 c->ver = get_byte(s->pb);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
79 if(c->ver != 0x07 && c->ver != 0x17){
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
80 av_log(s, AV_LOG_ERROR, "Can demux Musepack SV7, got version %02X\n", c->ver);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
81 return -1;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
82 }
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
83 c->fcount = get_le32(s->pb);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
84 if((int64_t)c->fcount * sizeof(MPCFrame) >= UINT_MAX){
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
85 av_log(s, AV_LOG_ERROR, "Too many frames, seeking is not possible\n");
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
86 return -1;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
87 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
88 c->frames = av_malloc(c->fcount * sizeof(MPCFrame));
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
89 c->curframe = 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
90 c->lastframe = -1;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
91 c->curbits = 8;
1605
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
92 c->frames_noted = 0;
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
93
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
94 st = av_new_stream(s, 0);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
95 if (!st)
2273
7eb456c4ed8a Replace all occurrences of AVERROR_NOMEM with AVERROR(ENOMEM).
takis
parents: 2217
diff changeset
96 return AVERROR(ENOMEM);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
97 st->codec->codec_type = CODEC_TYPE_AUDIO;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
98 st->codec->codec_id = CODEC_ID_MUSEPACK7;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
99 st->codec->channels = 2;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
100 st->codec->bits_per_sample = 16;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
101
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
102 st->codec->extradata_size = 16;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
103 st->codec->extradata = av_mallocz(st->codec->extradata_size+FF_INPUT_BUFFER_PADDING_SIZE);
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
104 get_buffer(s->pb, st->codec->extradata, 16);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
105 st->codec->sample_rate = mpc_rate[st->codec->extradata[2] & 3];
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
106 av_set_pts_info(st, 32, MPC_FRAMESIZE, st->codec->sample_rate);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
107 /* scan for seekpoints */
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
108 s->start_time = 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
109 s->duration = (int64_t)c->fcount * MPC_FRAMESIZE * AV_TIME_BASE / st->codec->sample_rate;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
110
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
111 return 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
112 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
113
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
114 static int mpc_read_packet(AVFormatContext *s, AVPacket *pkt)
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
115 {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
116 MPCContext *c = s->priv_data;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
117 int ret, size, size2, curbits, cur = c->curframe;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
118 int64_t tmp, pos;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
119
1645
9aa27a785d1f 10l, > vs. >= typo, caused crashes on last mpc frame
reimar
parents: 1610
diff changeset
120 if (c->curframe >= c->fcount)
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
121 return -1;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
122
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
123 if(c->curframe != c->lastframe + 1){
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
124 url_fseek(s->pb, c->frames[c->curframe].pos, SEEK_SET);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
125 c->curbits = c->frames[c->curframe].skip;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
126 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
127 c->lastframe = c->curframe;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
128 c->curframe++;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
129 curbits = c->curbits;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
130 pos = url_ftell(s->pb);
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
131 tmp = get_le32(s->pb);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
132 if(curbits <= 12){
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
133 size2 = (tmp >> (12 - curbits)) & 0xFFFFF;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
134 }else{
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
135 tmp = (tmp << 32) | get_le32(s->pb);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
136 size2 = (tmp >> (44 - curbits)) & 0xFFFFF;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
137 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
138 curbits += 20;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
139 url_fseek(s->pb, pos, SEEK_SET);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
140
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
141 size = ((size2 + curbits + 31) & ~31) >> 3;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
142 if(cur == c->frames_noted){
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
143 c->frames[cur].pos = pos;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
144 c->frames[cur].size = size;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
145 c->frames[cur].skip = curbits - 20;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
146 av_add_index_entry(s->streams[0], cur, cur, size, 0, AVINDEX_KEYFRAME);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
147 c->frames_noted++;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
148 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
149 c->curbits = (curbits + size2) & 0x1F;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
150
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
151 if (av_new_packet(pkt, size) < 0)
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
152 return AVERROR(EIO);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
153
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
154 pkt->data[0] = curbits;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
155 pkt->data[1] = (c->curframe > c->fcount);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
156
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
157 pkt->stream_index = 0;
1610
cde17266ad08 Decode previous 32 frames to avoid seeking artifacts in MPC
kostya
parents: 1609
diff changeset
158 pkt->pts = cur;
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
159 ret = get_buffer(s->pb, pkt->data + 4, size);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
160 if(c->curbits)
2771
d52c718e83f9 Use dynamically allocated ByteIOContext in AVFormatContext
andoma
parents: 2274
diff changeset
161 url_fseek(s->pb, -4, SEEK_CUR);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
162 if(ret < size){
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
163 av_free_packet(pkt);
2274
b21c2af60bc9 Replace all occurrences of AVERROR_IO with AVERROR(EIO).
takis
parents: 2273
diff changeset
164 return AVERROR(EIO);
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
165 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
166 pkt->size = ret + 4;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
167
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
168 return 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
169 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
170
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
171 static int mpc_read_close(AVFormatContext *s)
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
172 {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
173 MPCContext *c = s->priv_data;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
174
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
175 av_freep(&c->frames);
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
176 return 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
177 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
178
1605
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
179 /**
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
180 * Seek to the given position
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
181 * If position is unknown but is within the limits of file
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
182 * then packets are skipped unless desired position is reached
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
183 *
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
184 * Also this function makes use of the fact that timestamp == frameno
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
185 */
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
186 static int mpc_read_seek(AVFormatContext *s, int stream_index, int64_t timestamp, int flags)
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
187 {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
188 AVStream *st = s->streams[stream_index];
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
189 MPCContext *c = s->priv_data;
1605
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
190 AVPacket pkt1, *pkt = &pkt1;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
191 int ret;
1610
cde17266ad08 Decode previous 32 frames to avoid seeking artifacts in MPC
kostya
parents: 1609
diff changeset
192 int index = av_index_search_timestamp(st, timestamp - DELAY_FRAMES, flags);
1605
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
193 uint32_t lastframe;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
194
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
195 /* if found, seek there */
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
196 if (index >= 0){
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
197 c->curframe = st->index_entries[index].pos;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
198 return 0;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
199 }
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
200 /* if timestamp is out of bounds, return error */
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
201 if(timestamp < 0 || timestamp >= c->fcount)
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
202 return -1;
1610
cde17266ad08 Decode previous 32 frames to avoid seeking artifacts in MPC
kostya
parents: 1609
diff changeset
203 timestamp -= DELAY_FRAMES;
1605
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
204 /* seek to the furthest known position and read packets until
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
205 we reach desired position */
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
206 lastframe = c->curframe;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
207 if(c->frames_noted) c->curframe = c->frames_noted - 1;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
208 while(c->curframe < timestamp){
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
209 ret = av_read_frame(s, pkt);
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
210 if (ret < 0){
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
211 c->curframe = lastframe;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
212 return -1;
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
213 }
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
214 av_free_packet(pkt);
6d66c6325e0d Enable forward seek in Musepack demuxer
kostya
parents: 1602
diff changeset
215 }
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
216 return 0;
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
217 }
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
218
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
219
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
220 AVInputFormat mpc_demuxer = {
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
221 "mpc",
3424
7a0230981402 Make long_names in lavf/lavdev optional depending on CONFIG_SMALL.
diego
parents: 3286
diff changeset
222 NULL_IF_CONFIG_SMALL("Musepack"),
1602
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
223 sizeof(MPCContext),
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
224 mpc_probe,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
225 mpc_read_header,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
226 mpc_read_packet,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
227 mpc_read_close,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
228 mpc_read_seek,
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
229 .extensions = "mpc",
6238b40b7aef Musepack SV7 decoding support
kostya
parents:
diff changeset
230 };