Mercurial > mplayer.hg
annotate libmpcodecs/ad_mpc.c @ 25194:e816d546c4fe
ao_null: Make duration of "buffered" audio constant
Choose the "buffer size" for the amount of audio the driver accepts so
that it corresponds to about 0.2 seconds of playback based on the
number of channels, sample size and samplerate.
author | uau |
---|---|
date | Sat, 01 Dec 2007 01:39:39 +0000 |
parents | acfe034e5386 |
children | 0f1b5b68af32 |
rev | line source |
---|---|
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
1 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
2 * Musepack audio files decoder for MPlayer |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
3 * by Reza Jelveh <reza.jelveh@tuhh.de> and |
23734 | 4 * Reimar Döffinger <Reimar.Doeffinger@stud.uni-karlsruhe.de> |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
5 * License: GPL |
16074
f482bbb5fad9
Allow the ffmpeg people to use this code if they want.
reimar
parents:
16047
diff
changeset
|
6 * This code may be be relicensed under the terms of the GNU LGPL when it |
16093 | 7 * becomes part of the FFmpeg project (ffmpeg.org) |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
8 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
9 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
10 #include <stdio.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
11 #include <stdlib.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
12 #include <unistd.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
13 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
14 #include "config.h" |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
15 #include "ad_internal.h" |
17012 | 16 #include "libaf/af_format.h" |
17 #include "libvo/fastmemcpy.h" | |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
18 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
19 static ad_info_t info = |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
20 { |
15960 | 21 "Musepack audio decoder", |
22 "mpcdec", | |
23734 | 23 "Reza Jelveh and Reimar Döffinger", |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
24 "", |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
25 "" |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
26 }; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
27 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
28 LIBAD_EXTERN(libmusepack) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
29 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
30 #include <mpcdec/mpcdec.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
31 |
16468
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
32 // BUFFER_LENGTH is in MPC_SAMPLE_FORMAT units |
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
33 #define MAX_FRAMESIZE (4 * MPC_DECODER_BUFFER_LENGTH) |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
34 //! this many frames should decode good after seeking |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
35 #define MIN_SEEK_GOOD 5 |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
36 //! how many frames to discard at most after seeking |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
37 #define MAX_SEEK_DISCARD 50 |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
38 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
39 typedef struct context_s { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
40 char *header; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
41 int header_len; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
42 sh_audio_t *sh; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
43 uint32_t pos; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
44 mpc_decoder decoder; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
45 } context_t; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
46 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
47 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
48 * \brief mpc_reader callback function for reading the header |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
49 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
50 static mpc_int32_t cb_read(void *data, void *buf, mpc_int32_t size) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
51 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
52 char *p = (char *)buf; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
53 int s = size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
54 if (d->pos < d->header_len) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
55 if (s > d->header_len - d->pos) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
56 s = d->header_len - d->pos; |
23457
a124f3abc1ec
Replace implicit use of fast_memcpy via macro by explicit use to allow
reimar
parents:
18879
diff
changeset
|
57 fast_memcpy(p, &d->header[d->pos], s); |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
58 } else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
59 s = 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
60 memset(&p[s], 0, size - s); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
61 d->pos += size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
62 return size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
63 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
64 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
65 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
66 * \brief dummy mpc_reader callback function for seeking |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
67 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
68 static mpc_bool_t cb_seek(void *data, mpc_int32_t offset ) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
69 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
70 d->pos = offset; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
71 return 1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
72 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
73 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
74 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
75 * \brief dummy mpc_reader callback function for getting stream position |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
76 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
77 static mpc_int32_t cb_tell(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
78 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
79 return d->pos; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
80 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
81 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
82 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
83 * \brief dummy mpc_reader callback function for getting stream length |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
84 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
85 static mpc_int32_t cb_get_size(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
86 return 1 << 30; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
87 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
88 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
89 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
90 * \brief mpc_reader callback function, we cannot seek. |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
91 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
92 static mpc_bool_t cb_canseek(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
93 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
94 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
95 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
96 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
97 mpc_reader header_reader = { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
98 .read = cb_read, .seek = cb_seek, .tell = cb_tell, |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
99 .get_size = cb_get_size, .canseek = cb_canseek |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
100 }; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
101 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
102 static int preinit(sh_audio_t *sh) { |
18159 | 103 sh->audio_out_minsize = MAX_FRAMESIZE; |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
104 return 1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
105 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
106 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
107 static void uninit(sh_audio_t *sh) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
108 if (sh->context) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
109 free(sh->context); |
16047
7b8870739cc7
guard against double uninit (reportedly can happen on STRG+C)
reimar
parents:
15960
diff
changeset
|
110 sh->context = NULL; |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
111 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
112 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
113 static int init(sh_audio_t *sh) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
114 mpc_streaminfo info; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
115 context_t *cd = malloc(sizeof(context_t)); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
116 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
117 if (!sh->wf || (sh->wf->cbSize < 6 * 4)) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
118 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n"); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
119 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
120 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
121 cd->header = (char *)sh->wf; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
122 cd->header = &cd->header[sizeof(WAVEFORMATEX)]; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
123 cd->header_len = sh->wf->cbSize; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
124 cd->sh = sh; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
125 cd->pos = 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
126 sh->context = (char *)cd; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
127 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
128 /* read file's streaminfo data */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
129 mpc_streaminfo_init(&info); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
130 header_reader.data = cd; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
131 if (mpc_streaminfo_read(&info, &header_reader) != ERROR_CODE_OK) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
132 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Not a valid musepack file.\n"); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
133 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
134 } |
16415 | 135 // this value is nonsense, since it relies on the get_size function. |
136 // use the value from the demuxer instead. | |
137 // sh->i_bps = info.average_bitrate / 8; | |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
138 sh->channels = info.channels; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
139 sh->samplerate = info.sample_freq; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
140 sh->samplesize = 4; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
141 sh->sample_format = |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
142 #if MPC_SAMPLE_FORMAT == float |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
143 AF_FORMAT_FLOAT_NE; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
144 #elif MPC_SAMPLE_FORMAT == mpc_int32_t |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
145 AF_FORMAT_S32_NE; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
146 #else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
147 #error musepack lib must use either float or mpc_int32_t sample format |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
148 #endif |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
149 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
150 mpc_decoder_setup(&cd->decoder, NULL); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
151 mpc_decoder_set_streaminfo(&cd->decoder, &info); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
152 return 1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
153 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
154 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
155 // FIXME: minlen is currently ignored |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
156 static int decode_audio(sh_audio_t *sh, unsigned char *buf, |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
157 int minlen, int maxlen) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
158 int status, len; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
159 MPC_SAMPLE_FORMAT *sample_buffer = (MPC_SAMPLE_FORMAT *)buf; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
160 mpc_uint32_t *packet = NULL; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
161 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
162 context_t *cd = (context_t *) sh->context; |
16468
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
163 if (maxlen < MAX_FRAMESIZE) { |
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
164 mp_msg(MSGT_DECAUDIO, MSGL_V, "maxlen too small in decode_audio\n"); |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
165 return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
166 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
167 len = ds_get_packet(sh->ds, (unsigned char **)&packet); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
168 if (len <= 0) return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
169 status = mpc_decoder_decode_frame(&cd->decoder, packet, len, sample_buffer); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
170 if (status == -1) // decode error |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
171 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Error decoding file.\n"); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
172 if (status <= 0) // error or EOF |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
173 return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
174 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
175 status = MPC_FRAME_LENGTH * sh->channels; // one sample per channel |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
176 #if MPC_SAMPLE_FORMAT == float || MPC_SAMPLE_FORMAT == mpc_int32_t |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
177 status *= 4; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
178 #else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
179 // should not happen |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
180 status *= 2; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
181 #endif |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
182 return status; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
183 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
184 |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
185 /** |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
186 * \brief check if the decoded values are in a sane range |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
187 * \param buf decoded buffer |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
188 * \param len length of buffer in bytes |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
189 * \return 1 if all values are in (-1.01, 1.01) range, 0 otherwise |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
190 */ |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
191 static int check_clip(void *buf, int len) { |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
192 #if MPC_SAMPLE_FORMAT == float |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
193 float *p = buf; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
194 if (len < 4) return 1; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
195 len = -len / 4; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
196 p = &p[-len]; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
197 do { |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
198 if (p[len] < -1 || p[len] > 1) return 0; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
199 } while (++len); |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
200 #endif |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
201 return 1; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
202 } |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
203 |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
204 static int control(sh_audio_t *sh, int cmd, void* arg, ...) { |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
205 if (cmd == ADCTRL_RESYNC_STREAM) { |
18879 | 206 unsigned char *buf = malloc(MAX_FRAMESIZE); |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
207 int i; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
208 int nr_ok = 0; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
209 for (i = 0; i < MAX_SEEK_DISCARD; i++) { |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
210 int len = decode_audio(sh, buf, 0, MAX_FRAMESIZE); |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
211 if (check_clip(buf, len)) nr_ok++; else nr_ok = 0; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
212 if (nr_ok > MIN_SEEK_GOOD) break; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
213 } |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
214 free(buf); |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
215 } |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
216 return CONTROL_UNKNOWN; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
217 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
218 |