2 * Demuxer for Musepack v7 bitstream
3 * by Reimar Doeffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de>
4 * This code may be be relicensed under the terms of the GNU LGPL when it
5 * becomes part of the FFmpeg project (ffmpeg.org)
14 #include "libavutil/common.h"
16 #include "stream/stream.h"
21 #define HDR_SIZE (6 * 4)
23 typedef struct da_priv
{
31 static uint32_t get_bits(da_priv_t
* priv
, stream_t
* s
, int bits
) {
32 uint32_t out
= priv
->dword
;
33 uint32_t mask
= (1 << bits
) - 1;
36 out
>>= (32 - priv
->pos
);
39 stream_read(s
, (void *)&priv
->dword
, 4);
40 priv
->dword
= le2me_32(priv
->dword
);
44 out
|= priv
->dword
>> (32 - priv
->pos
);
50 static int demux_mpc_check(demuxer_t
* demuxer
) {
51 stream_t
*s
= demuxer
->stream
;
52 uint8_t hdr
[HDR_SIZE
];
55 if (stream_read(s
, hdr
, HDR_SIZE
) != HDR_SIZE
)
57 for (i
= 0; i
< 30000 && !s
->eof
; i
++) {
58 if (hdr
[0] == 'M' && hdr
[1] == 'P' && hdr
[2] == '+')
60 memmove(hdr
, &hdr
[1], HDR_SIZE
- 1);
61 stream_read(s
, &hdr
[HDR_SIZE
- 1], 1);
64 if (hdr
[0] != 'M' || hdr
[1] != 'P' || hdr
[2] != '+')
66 demuxer
->movi_start
= stream_tell(s
) - HDR_SIZE
;
67 demuxer
->movi_end
= s
->end_pos
;
68 demuxer
->priv
= malloc(HDR_SIZE
);
69 memcpy(demuxer
->priv
, hdr
, HDR_SIZE
);
70 return DEMUXER_TYPE_MPC
;
73 static demuxer_t
*demux_mpc_open(demuxer_t
* demuxer
) {
75 stream_t
*s
= demuxer
->stream
;
77 da_priv_t
* priv
= demuxer
->priv
;
79 sh_audio
= new_sh_audio(demuxer
,0);
82 char *wf
= calloc(1, sizeof(WAVEFORMATEX
) + HDR_SIZE
);
83 char *header
= &wf
[sizeof(WAVEFORMATEX
)];
84 const int freqs
[4] = {44100, 48000, 37800, 32000};
86 sh_audio
->format
= mmioFOURCC('M', 'P', 'C', ' ');
87 memcpy(header
, priv
, HDR_SIZE
);
89 frames
= header
[4] | header
[5] << 8 | header
[6] << 16 | header
[7] << 24;
90 sh_audio
->wf
= (WAVEFORMATEX
*)wf
;
91 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
92 sh_audio
->wf
->nChannels
= 2;
93 sh_audio
->wf
->nSamplesPerSec
= freqs
[header
[10] & 3];
94 sh_audio
->wf
->nBlockAlign
= 32 * 36;
95 sh_audio
->wf
->wBitsPerSample
= 16;
96 seconds
= 1152 * frames
/ (float)sh_audio
->wf
->nSamplesPerSec
;
97 if (demuxer
->movi_end
> demuxer
->movi_start
&& seconds
> 1)
98 sh_audio
->wf
->nAvgBytesPerSec
= (demuxer
->movi_end
- demuxer
->movi_start
) / seconds
;
100 sh_audio
->wf
->nAvgBytesPerSec
= 32 * 1024; // dummy to make mencoder not hang
101 sh_audio
->wf
->cbSize
= HDR_SIZE
;
102 demuxer
->movi_start
= stream_tell(s
);
103 demuxer
->movi_end
= s
->end_pos
;
106 priv
= malloc(sizeof(da_priv_t
));
108 priv
->pts_per_packet
= (32 * 36) / (float)sh_audio
->wf
->nSamplesPerSec
;
109 priv
->length
= seconds
;
111 priv
->pos
= 32; // empty bit buffer
112 get_bits(priv
, s
, 8); // discard first 8 bits
113 demuxer
->priv
= priv
;
114 demuxer
->audio
->id
= 0;
115 demuxer
->audio
->sh
= sh_audio
;
116 sh_audio
->ds
= demuxer
->audio
;
117 sh_audio
->samplerate
= sh_audio
->wf
->nSamplesPerSec
;
118 sh_audio
->i_bps
= sh_audio
->wf
->nAvgBytesPerSec
;
119 sh_audio
->audio
.dwSampleSize
= 0;
120 sh_audio
->audio
.dwScale
= 32 * 36;
121 sh_audio
->audio
.dwRate
= sh_audio
->samplerate
;
126 static int demux_mpc_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
) {
130 sh_audio_t
* sh_audio
= ds
->sh
;
131 da_priv_t
* priv
= demux
->priv
;
132 stream_t
* s
= demux
->stream
;
138 bit_len
= get_bits(priv
, s
, 20);
139 dp
= new_demux_packet((bit_len
+ 7) / 8);
140 for (l
= 0; l
< (bit_len
/ 8); l
++)
141 dp
->buffer
[l
] = get_bits(priv
, s
, 8);
144 dp
->buffer
[l
] = get_bits(priv
, s
, bit_len
) << (8 - bit_len
);
145 if (priv
->last_pts
< 0)
148 priv
->last_pts
+= priv
->pts_per_packet
;
149 dp
->pts
= priv
->last_pts
;
150 ds_add_packet(ds
, dp
);
154 static void demux_mpc_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
155 sh_audio_t
* sh_audio
= demuxer
->audio
->sh
;
156 da_priv_t
* priv
= demuxer
->priv
;
157 stream_t
* s
= demuxer
->stream
;
158 float target
= rel_seek_secs
;
160 target
*= priv
->length
;
162 target
+= priv
->last_pts
;
163 if (target
< priv
->last_pts
) {
164 stream_seek(s
, demuxer
->movi_start
);
165 priv
->pos
= 32; // empty bit buffer
166 get_bits(priv
, s
, 8); // discard first 8 bits
169 while (target
> priv
->last_pts
) {
170 int bit_len
= get_bits(priv
, s
, 20);
172 stream_skip(s
, bit_len
/ 32 * 4 - 4);
173 get_bits(priv
, s
, 32); // make sure dword is reloaded
175 get_bits(priv
, s
, bit_len
% 32);
176 priv
->last_pts
+= priv
->pts_per_packet
;
179 if (!sh_audio
) return;
182 static void demux_close_mpc(demuxer_t
* demuxer
) {
183 da_priv_t
* priv
= demuxer
->priv
;
190 static int demux_mpc_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
191 da_priv_t
* priv
= demuxer
->priv
;
193 case DEMUXER_CTRL_GET_TIME_LENGTH
:
194 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
195 *((double *)arg
) = priv
->length
;
196 return DEMUXER_CTRL_OK
;
197 case DEMUXER_CTRL_GET_PERCENT_POS
:
198 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
199 *((int *)arg
) = priv
->last_pts
* 100 / priv
->length
;
200 return DEMUXER_CTRL_OK
;
202 return DEMUXER_CTRL_NOTIMPL
;
206 demuxer_desc_t demuxer_desc_mpc
= {
210 "Reza Jelveh, Reimar Doeffinger",
211 "supports v7 bitstream only",
213 0, // unsafe autodetect
215 demux_mpc_fill_buffer
,