2 * Demuxer for Musepack v7 bitstream
3 * by Reimar Döffinger <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)
20 #define HDR_SIZE (6 * 4)
22 typedef struct da_priv
{
30 extern void free_sh_audio(sh_audio_t
* sh
);
32 static uint32_t get_bits(da_priv_t
* priv
, stream_t
* s
, int bits
) {
33 uint32_t out
= priv
->dword
;
34 uint32_t mask
= (1 << bits
) - 1;
37 out
>>= (32 - priv
->pos
);
40 stream_read(s
, (void *)&priv
->dword
, 4);
41 priv
->dword
= le2me_32(priv
->dword
);
45 out
|= priv
->dword
>> (32 - priv
->pos
);
51 static int demux_mpc_check(demuxer_t
* demuxer
) {
52 stream_t
*s
= demuxer
->stream
;
53 uint8_t hdr
[HDR_SIZE
];
56 if (stream_read(s
, hdr
, HDR_SIZE
) != HDR_SIZE
)
58 for (i
= 0; i
< 30000 && !s
->eof
; i
++) {
59 if (hdr
[0] == 'M' && hdr
[1] == 'P' && hdr
[2] == '+')
61 memmove(hdr
, &hdr
[1], HDR_SIZE
- 1);
62 stream_read(s
, &hdr
[HDR_SIZE
- 1], 1);
65 if (hdr
[0] != 'M' || hdr
[1] != 'P' || hdr
[2] != '+')
67 demuxer
->movi_start
= stream_tell(s
) - HDR_SIZE
;
68 demuxer
->movi_end
= s
->end_pos
;
69 demuxer
->priv
= malloc(HDR_SIZE
);
70 memcpy(demuxer
->priv
, hdr
, HDR_SIZE
);
71 return DEMUXER_TYPE_MPC
;
74 static demuxer_t
*demux_mpc_open(demuxer_t
* demuxer
) {
76 stream_t
*s
= demuxer
->stream
;
78 da_priv_t
* priv
= demuxer
->priv
;
80 sh_audio
= new_sh_audio(demuxer
,0);
83 char *wf
= (char *)calloc(1, sizeof(WAVEFORMATEX
) + HDR_SIZE
);
84 char *header
= &wf
[sizeof(WAVEFORMATEX
)];
85 const int freqs
[4] = {44100, 48000, 37800, 32000};
87 sh_audio
->format
= mmioFOURCC('M', 'P', 'C', ' ');
88 memcpy(header
, priv
, HDR_SIZE
);
90 frames
= header
[4] | header
[5] << 8 | header
[6] << 16 | header
[7] << 24;
91 sh_audio
->wf
= (WAVEFORMATEX
*)wf
;
92 sh_audio
->wf
->wFormatTag
= sh_audio
->format
;
93 sh_audio
->wf
->nChannels
= 2;
94 sh_audio
->wf
->nSamplesPerSec
= freqs
[header
[10] & 3];
95 sh_audio
->wf
->nBlockAlign
= 32 * 36;
96 sh_audio
->wf
->wBitsPerSample
= 16;
97 seconds
= 1152 * frames
/ (float)sh_audio
->wf
->nSamplesPerSec
;
98 if (demuxer
->movi_end
> demuxer
->movi_start
&& seconds
> 1)
99 sh_audio
->wf
->nAvgBytesPerSec
= (demuxer
->movi_end
- demuxer
->movi_start
) / seconds
;
101 sh_audio
->wf
->nAvgBytesPerSec
= 32 * 1024; // dummy to make mencoder not hang
102 sh_audio
->wf
->cbSize
= HDR_SIZE
;
103 demuxer
->movi_start
= stream_tell(s
);
104 demuxer
->movi_end
= s
->end_pos
;
107 priv
= (da_priv_t
*)malloc(sizeof(da_priv_t
));
109 priv
->pts_per_packet
= (32 * 36) / (float)sh_audio
->wf
->nSamplesPerSec
;
110 priv
->length
= seconds
;
112 priv
->pos
= 32; // empty bit buffer
113 get_bits(priv
, s
, 8); // discard first 8 bits
114 demuxer
->priv
= priv
;
115 demuxer
->audio
->id
= 0;
116 demuxer
->audio
->sh
= sh_audio
;
117 sh_audio
->ds
= demuxer
->audio
;
118 sh_audio
->samplerate
= sh_audio
->wf
->nSamplesPerSec
;
119 sh_audio
->i_bps
= sh_audio
->wf
->nAvgBytesPerSec
;
120 sh_audio
->audio
.dwSampleSize
= 0;
121 sh_audio
->audio
.dwScale
= 32 * 36;
122 sh_audio
->audio
.dwRate
= sh_audio
->samplerate
;
127 static int demux_mpc_fill_buffer(demuxer_t
*demux
, demux_stream_t
*ds
) {
131 sh_audio_t
* sh_audio
= ds
->sh
;
132 da_priv_t
* priv
= demux
->priv
;
133 stream_t
* s
= demux
->stream
;
139 bit_len
= get_bits(priv
, s
, 20);
140 dp
= new_demux_packet((bit_len
+ 7) / 8);
141 for (l
= 0; l
< (bit_len
/ 8); l
++)
142 dp
->buffer
[l
] = get_bits(priv
, s
, 8);
145 dp
->buffer
[l
] = get_bits(priv
, s
, bit_len
) << (8 - bit_len
);
146 if (priv
->last_pts
< 0)
149 priv
->last_pts
+= priv
->pts_per_packet
;
150 ds
->pts
= priv
->last_pts
- (ds_tell_pts(demux
->audio
) -
151 sh_audio
->a_in_buffer_len
)/(float)sh_audio
->i_bps
;
152 ds_add_packet(ds
, dp
);
156 static void demux_mpc_seek(demuxer_t
*demuxer
,float rel_seek_secs
,float audio_delay
,int flags
){
157 sh_audio_t
* sh_audio
= demuxer
->audio
->sh
;
158 da_priv_t
* priv
= demuxer
->priv
;
159 stream_t
* s
= demuxer
->stream
;
160 float target
= rel_seek_secs
;
162 target
*= priv
->length
;
164 target
+= priv
->last_pts
;
165 if (target
< priv
->last_pts
) {
166 stream_seek(s
, demuxer
->movi_start
);
167 priv
->pos
= 32; // empty bit buffer
168 get_bits(priv
, s
, 8); // discard first 8 bits
171 while (target
> priv
->last_pts
) {
172 int bit_len
= get_bits(priv
, s
, 20);
174 stream_skip(s
, bit_len
/ 32 * 4 - 4);
175 get_bits(priv
, s
, 32); // make sure dword is reloaded
177 get_bits(priv
, s
, bit_len
% 32);
178 priv
->last_pts
+= priv
->pts_per_packet
;
181 if (!sh_audio
) return;
182 sh_audio
->delay
= priv
->last_pts
- (ds_tell_pts(demuxer
->audio
) -
183 sh_audio
->a_in_buffer_len
)/(float)sh_audio
->i_bps
;
186 static void demux_close_mpc(demuxer_t
* demuxer
) {
187 da_priv_t
* priv
= demuxer
->priv
;
194 static int demux_mpc_control(demuxer_t
*demuxer
,int cmd
, void *arg
){
195 da_priv_t
* priv
= demuxer
->priv
;
197 case DEMUXER_CTRL_GET_TIME_LENGTH
:
198 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
199 *((double *)arg
) = priv
->length
;
200 return DEMUXER_CTRL_OK
;
201 case DEMUXER_CTRL_GET_PERCENT_POS
:
202 if (priv
->length
< 1) return DEMUXER_CTRL_DONTKNOW
;
203 *((int *)arg
) = priv
->last_pts
* 100 / priv
->length
;
204 return DEMUXER_CTRL_OK
;
206 return DEMUXER_CTRL_NOTIMPL
;
210 demuxer_desc_t demuxer_desc_mpc
= {
214 "Reza Jelveh, Reimar Doeffinger",
215 "supports v7 bitstream only",
217 0, // unsafe autodetect
219 demux_mpc_fill_buffer
,