2 * demuxer for Musepack v7 bitstream
3 * copyright (c) 2005 Reimar Doeffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
5 * This code may be be relicensed under the terms of the GNU LGPL when it
6 * becomes part of the FFmpeg project (ffmpeg.org)
8 * This file is part of MPlayer.
10 * MPlayer is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * MPlayer is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License along
21 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
31 #include "libavutil/common.h"
33 #include "stream/stream.h"
38 #define HDR_SIZE (6 * 4)
40 typedef struct da_priv
{
48 static uint32_t get_bits(da_priv_t
* priv
, stream_t
* s
, int bits
) {
49 uint32_t out
= priv
->dword
;
50 uint32_t mask
= (1 << bits
) - 1;
53 out
>>= (32 - priv
->pos
);
56 stream_read(s
, (void *)&priv
->dword
, 4);
57 priv
->dword
= le2me_32(priv
->dword
);
61 out
|= priv
->dword
>> (32 - priv
->pos
);
67 static int demux_mpc_check(demuxer_t
* demuxer
) {
68 stream_t
*s
= demuxer
->stream
;
69 uint8_t hdr
[HDR_SIZE
];
72 if (stream_read(s
, hdr
, HDR_SIZE
) != HDR_SIZE
)
74 for (i
= 0; i
< 30000 && !s
->eof
; i
++) {
75 if (hdr
[0] == 'M' && hdr
[1] == 'P' && hdr
[2] == '+')
77 memmove(hdr
, &hdr
[1], HDR_SIZE
- 1);
78 stream_read(s
, &hdr
[HDR_SIZE
- 1], 1);
81 if (hdr
[0] != 'M' || hdr
[1] != 'P' || hdr
[2] != '+')
83 demuxer
->movi_start
= stream_tell(s
) - HDR_SIZE
;
84 demuxer
->movi_end
= s
->end_pos
;
85 demuxer
->priv
= malloc(HDR_SIZE
);
86 memcpy(demuxer
->priv
, hdr
, HDR_SIZE
);
87 return DEMUXER_TYPE_MPC
;
90 static demuxer_t
*demux_mpc_open(demuxer_t
* demuxer
) {
92 stream_t
*s
= demuxer
->stream
;
94 da_priv_t
* priv
= demuxer
->priv
;
96 sh_audio
= new_sh_audio(demuxer
,0);
99 char *wf
= calloc(1, sizeof(WAVEFORMATEX
) + HDR_SIZE
);
100 char *header
= &wf
[sizeof(WAVEFORMATEX
)];
101 const int freqs
[4] = {44100, 48000, 37800, 32000};
103 sh_audio
->format
= mmioFOURCC('M', 'P', 'C', ' ');
104 memcpy(header
, priv
, HDR_SIZE
);
106 frames
= header
[4] | header
[5] << 8 | header
[6] << 16 | header
[7] << 24;
107 sh_audio
->wf
= (WAVEFORMATEX
*)wf
;
108 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
109 sh_audio
->wf
->nChannels
= 2;
110 sh_audio
->wf
->nSamplesPerSec
= freqs
[header
[10] & 3];
111 sh_audio
->wf
->nBlockAlign
= 32 * 36;
112 sh_audio
->wf
->wBitsPerSample
= 16;
113 seconds
= 1152 * frames
/ (float)sh_audio
->wf
->nSamplesPerSec
;
114 if (demuxer
->movi_end
> demuxer
->movi_start
&& seconds
> 1)
115 sh_audio
->wf
->nAvgBytesPerSec
= (demuxer
->movi_end
- demuxer
->movi_start
) / seconds
;
117 sh_audio
->wf
->nAvgBytesPerSec
= 32 * 1024; // dummy to make mencoder not hang
118 sh_audio
->wf
->cbSize
= HDR_SIZE
;
119 demuxer
->movi_start
= stream_tell(s
);
120 demuxer
->movi_end
= s
->end_pos
;
123 priv
= malloc(sizeof(da_priv_t
));
125 priv
->pts_per_packet
= (32 * 36) / (float)sh_audio
->wf
->nSamplesPerSec
;
126 priv
->length
= seconds
;
128 priv
->pos
= 32; // empty bit buffer
129 get_bits(priv
, s
, 8); // discard first 8 bits
130 demuxer
->priv
= priv
;
131 demuxer
->audio
->id
= 0;
132 demuxer
->audio
->sh
= sh_audio
;
133 sh_audio
->ds
= demuxer
->audio
;
134 sh_audio
->samplerate
= sh_audio
->wf
->nSamplesPerSec
;
135 sh_audio
->i_bps
= sh_audio
->wf
->nAvgBytesPerSec
;
136 sh_audio
->audio
.dwSampleSize
= 0;
137 sh_audio
->audio
.dwScale
= 32 * 36;
138 sh_audio
->audio
.dwRate
= sh_audio
->samplerate
;
143 static int demux_mpc_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
) {
147 sh_audio_t
* sh_audio
= ds
->sh
;
148 da_priv_t
* priv
= demux
->priv
;
149 stream_t
* s
= demux
->stream
;
155 bit_len
= get_bits(priv
, s
, 20);
156 dp
= new_demux_packet((bit_len
+ 7) / 8);
157 for (l
= 0; l
< (bit_len
/ 8); l
++)
158 dp
->buffer
[l
] = get_bits(priv
, s
, 8);
161 dp
->buffer
[l
] = get_bits(priv
, s
, bit_len
) << (8 - bit_len
);
162 if (priv
->last_pts
< 0)
165 priv
->last_pts
+= priv
->pts_per_packet
;
166 dp
->pts
= priv
->last_pts
;
167 ds_add_packet(ds
, dp
);
171 static void demux_mpc_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
172 sh_audio_t
* sh_audio
= demuxer
->audio
->sh
;
173 da_priv_t
* priv
= demuxer
->priv
;
174 stream_t
* s
= demuxer
->stream
;
175 float target
= rel_seek_secs
;
176 if (flags
& SEEK_FACTOR
)
177 target
*= priv
->length
;
178 if (!(flags
& SEEK_ABSOLUTE
))
179 target
+= priv
->last_pts
;
180 if (target
< priv
->last_pts
) {
181 stream_seek(s
, demuxer
->movi_start
);
182 priv
->pos
= 32; // empty bit buffer
183 get_bits(priv
, s
, 8); // discard first 8 bits
186 while (target
> priv
->last_pts
) {
187 int bit_len
= get_bits(priv
, s
, 20);
189 stream_skip(s
, bit_len
/ 32 * 4 - 4);
190 get_bits(priv
, s
, 32); // make sure dword is reloaded
192 get_bits(priv
, s
, bit_len
% 32);
193 priv
->last_pts
+= priv
->pts_per_packet
;
196 if (!sh_audio
) return;
199 static void demux_close_mpc(demuxer_t
* demuxer
) {
200 da_priv_t
* priv
= demuxer
->priv
;
207 static int demux_mpc_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
208 da_priv_t
* priv
= demuxer
->priv
;
210 case DEMUXER_CTRL_GET_TIME_LENGTH
:
211 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
212 *((double *)arg
) = priv
->length
;
213 return DEMUXER_CTRL_OK
;
214 case DEMUXER_CTRL_GET_PERCENT_POS
:
215 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
216 *((int *)arg
) = priv
->last_pts
* 100 / priv
->length
;
217 return DEMUXER_CTRL_OK
;
219 return DEMUXER_CTRL_NOTIMPL
;
223 const demuxer_desc_t demuxer_desc_mpc
= {
227 "Reza Jelveh, Reimar Doeffinger",
228 "supports v7 bitstream only",
230 0, // unsafe autodetect
232 demux_mpc_fill_buffer
,