Mercurial > mplayer.hg
annotate libmpcodecs/ad_mpc.c @ 32282:606e4157cd4c
Split alloc and init of context so that parameters can be set in the context
instead of requireing being passed through function parameters. This also
makes sws work with AVOptions.
author | michael |
---|---|
date | Sun, 26 Sep 2010 19:33:57 +0000 |
parents | d332ea379205 |
children | 8fa2f43cb760 |
rev | line source |
---|---|
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
1 /* |
15958
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> |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
5 * |
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) |
30421
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
8 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
9 * This file is part of MPlayer. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
10 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
11 * MPlayer is free software; you can redistribute it and/or modify |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
12 * it under the terms of the GNU General Public License as published by |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
13 * the Free Software Foundation; either version 2 of the License, or |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
14 * (at your option) any later version. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
15 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
16 * MPlayer is distributed in the hope that it will be useful, |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
19 * GNU General Public License for more details. |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
20 * |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
21 * You should have received a copy of the GNU General Public License along |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
22 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
bbb6ebec87a0
Add missing license headers to all files in the libmpcodecs directory.
diego
parents:
29263
diff
changeset
|
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
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 #include <stdio.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
27 #include <stdlib.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
28 #include <unistd.h> |
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 "config.h" |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
31 #include "ad_internal.h" |
17012 | 32 #include "libaf/af_format.h" |
33 #include "libvo/fastmemcpy.h" | |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
34 |
30504
cc27da5d7286
Mark all ad_info_t/vd_info_t structure declarations as const.
diego
parents:
30421
diff
changeset
|
35 static const ad_info_t info = |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
36 { |
15960 | 37 "Musepack audio decoder", |
38 "mpcdec", | |
23734 | 39 "Reza Jelveh and Reimar Döffinger", |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
40 "", |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
41 "" |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
42 }; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
43 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
44 LIBAD_EXTERN(libmusepack) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
45 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
46 #include <mpcdec/mpcdec.h> |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
47 |
16468
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
48 // 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
|
49 #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
|
50 //! 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
|
51 #define MIN_SEEK_GOOD 5 |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
52 //! 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
|
53 #define MAX_SEEK_DISCARD 50 |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
54 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
55 typedef struct context_s { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
56 char *header; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
57 int header_len; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
58 sh_audio_t *sh; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
59 uint32_t pos; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
60 mpc_decoder decoder; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
61 } context_t; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
62 |
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 * \brief mpc_reader callback function for reading the header |
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 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
|
67 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
68 char *p = (char *)buf; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
69 int s = size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
70 if (d->pos < d->header_len) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
71 if (s > d->header_len - d->pos) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
72 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
|
73 fast_memcpy(p, &d->header[d->pos], s); |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
74 } else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
75 s = 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
76 memset(&p[s], 0, size - s); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
77 d->pos += size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
78 return size; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
79 } |
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 * \brief dummy mpc_reader callback function for seeking |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
83 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
84 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
|
85 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
86 d->pos = offset; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
87 return 1; |
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 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
91 * \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
|
92 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
93 static mpc_int32_t cb_tell(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
94 context_t *d = (context_t *)data; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
95 return d->pos; |
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 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
98 /** |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
99 * \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
|
100 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
101 static mpc_int32_t cb_get_size(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
102 return 1 << 30; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
103 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
104 |
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 * \brief mpc_reader callback function, we cannot seek. |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
107 */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
108 static mpc_bool_t cb_canseek(void *data) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
109 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
110 } |
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 mpc_reader header_reader = { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
114 .read = cb_read, .seek = cb_seek, .tell = cb_tell, |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
115 .get_size = cb_get_size, .canseek = cb_canseek |
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 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
118 static int preinit(sh_audio_t *sh) { |
18159 | 119 sh->audio_out_minsize = MAX_FRAMESIZE; |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
120 return 1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
121 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
122 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
123 static void uninit(sh_audio_t *sh) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
124 if (sh->context) |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
125 free(sh->context); |
16047
7b8870739cc7
guard against double uninit (reportedly can happen on STRG+C)
reimar
parents:
15960
diff
changeset
|
126 sh->context = NULL; |
15958
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 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
129 static int init(sh_audio_t *sh) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
130 mpc_streaminfo info; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
131 context_t *cd = malloc(sizeof(context_t)); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
132 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
133 if (!sh->wf || (sh->wf->cbSize < 6 * 4)) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
134 mp_msg(MSGT_DECAUDIO, MSGL_FATAL, "Missing extradata!\n"); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
135 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
136 } |
32121 | 137 cd->header = (char *)(sh->wf + 1); |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
138 cd->header_len = sh->wf->cbSize; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
139 cd->sh = sh; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
140 cd->pos = 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
141 sh->context = (char *)cd; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
142 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
143 /* read file's streaminfo data */ |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
144 mpc_streaminfo_init(&info); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
145 header_reader.data = cd; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
146 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
|
147 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
|
148 return 0; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
149 } |
16415 | 150 // this value is nonsense, since it relies on the get_size function. |
151 // use the value from the demuxer instead. | |
152 // sh->i_bps = info.average_bitrate / 8; | |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
153 sh->channels = info.channels; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
154 sh->samplerate = info.sample_freq; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
155 sh->samplesize = 4; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
156 sh->sample_format = |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
157 #if MPC_SAMPLE_FORMAT == float |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
158 AF_FORMAT_FLOAT_NE; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
159 #elif MPC_SAMPLE_FORMAT == mpc_int32_t |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
160 AF_FORMAT_S32_NE; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
161 #else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
162 #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
|
163 #endif |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
164 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
165 mpc_decoder_setup(&cd->decoder, NULL); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
166 mpc_decoder_set_streaminfo(&cd->decoder, &info); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
167 return 1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
168 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
169 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
170 // FIXME: minlen is currently ignored |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
171 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
|
172 int minlen, int maxlen) { |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
173 int status, len; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
174 MPC_SAMPLE_FORMAT *sample_buffer = (MPC_SAMPLE_FORMAT *)buf; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
175 mpc_uint32_t *packet = NULL; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
23734
diff
changeset
|
176 |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
177 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
|
178 if (maxlen < MAX_FRAMESIZE) { |
0c22fbbbc2c7
Fix maximum frame size, could lead to crashes when changing playback speed.
reimar
parents:
16415
diff
changeset
|
179 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
|
180 return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
181 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
182 len = ds_get_packet(sh->ds, (unsigned char **)&packet); |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
183 if (len <= 0) return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
184 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
|
185 if (status == -1) // decode error |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
186 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
|
187 if (status <= 0) // error or EOF |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
188 return -1; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
189 |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
190 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
|
191 #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
|
192 status *= 4; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
193 #else |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
194 // should not happen |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
195 status *= 2; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
196 #endif |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
197 return status; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
198 } |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
199 |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
200 /** |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
201 * \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
|
202 * \param buf decoded buffer |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
203 * \param len length of buffer in bytes |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
204 * \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
|
205 */ |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
206 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
|
207 #if MPC_SAMPLE_FORMAT == float |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
208 float *p = buf; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
209 if (len < 4) return 1; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
210 len = -len / 4; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
211 p = &p[-len]; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
212 do { |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
213 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
|
214 } while (++len); |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
215 #endif |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
216 return 1; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
217 } |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
218 |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
219 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
|
220 if (cmd == ADCTRL_RESYNC_STREAM) { |
18879 | 221 unsigned char *buf = malloc(MAX_FRAMESIZE); |
16744
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
222 int i; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
223 int nr_ok = 0; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
224 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
|
225 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
|
226 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
|
227 if (nr_ok > MIN_SEEK_GOOD) break; |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
228 } |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
229 free(buf); |
65fb32defee5
implement ADCTRL_RESYNC_STREAM, it tries to detect when decoding is
reimar
parents:
16468
diff
changeset
|
230 } |
15958
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
231 return CONTROL_UNKNOWN; |
087142ef3a2d
musepack demuxing and decoding support (demuxing is v7 bitstream only).
reimar
parents:
diff
changeset
|
232 } |