Mercurial > mplayer.hg
annotate libmpcodecs/ad_spdif.c @ 34205:332fa33a47c4
Cosmetics: Remove empty statement.
Patch by Naoya OYAMA, naoya D oyama gmail
author | cehoyos |
---|---|
date | Thu, 03 Nov 2011 18:51:56 +0000 |
parents | c1b5018b5edb |
children | 92841858c5cb |
rev | line source |
---|---|
34103 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
18 | |
19 #include <string.h> | |
20 | |
21 #include "config.h" | |
22 #include "mp_msg.h" | |
23 #include "ad_internal.h" | |
24 #include "libavformat/avformat.h" | |
25 #include "libavcodec/avcodec.h" | |
26 #include "libavutil/opt.h" | |
27 | |
28 static const ad_info_t info = { | |
29 "libavformat/spdifenc audio pass-through decoder.", | |
30 "spdif", | |
31 "Naoya OYAMA", | |
32 "Naoya OYAMA", | |
33 "For ALL hardware decoders" | |
34 }; | |
35 | |
36 LIBAD_EXTERN(spdif) | |
37 | |
38 #define FILENAME_SPDIFENC "spdif" | |
39 #define OUTBUF_SIZE 65536 | |
40 struct spdifContext { | |
41 AVFormatContext *lavf_ctx; | |
42 int iec61937_packet_size; | |
43 int out_buffer_len; | |
44 int out_buffer_size; | |
45 uint8_t *out_buffer; | |
46 uint8_t pb_buffer[OUTBUF_SIZE]; | |
47 }; | |
48 | |
49 static int read_packet(void *p, uint8_t *buf, int buf_size) | |
50 { | |
51 // spdifenc does not use read callback. | |
52 return 0; | |
53 } | |
54 | |
55 static int write_packet(void *p, uint8_t *buf, int buf_size) | |
56 { | |
57 int len; | |
58 struct spdifContext *ctx = p; | |
59 | |
60 len = FFMIN(buf_size, ctx->out_buffer_size -ctx->out_buffer_len); | |
61 memcpy(&ctx->out_buffer[ctx->out_buffer_len], buf, len); | |
62 ctx->out_buffer_len += len; | |
63 return len; | |
64 } | |
65 | |
66 static int64_t seek(void *p, int64_t offset, int whence) | |
67 { | |
68 // spdifenc does not use seek callback. | |
69 return 0; | |
70 } | |
71 | |
72 static int preinit(sh_audio_t *sh) | |
73 { | |
74 sh->samplesize = 2; | |
75 return 1; | |
76 } | |
77 | |
78 static int init(sh_audio_t *sh) | |
79 { | |
80 int i, x, in_size, srate, bps, *dtshd_rate; | |
81 unsigned char *start; | |
82 double pts; | |
83 static const struct { | |
84 const char *name; enum CodecID id; | |
85 } fmt_id_type[] = { | |
86 { "aac" , CODEC_ID_AAC }, | |
87 { "ac3" , CODEC_ID_AC3 }, | |
88 { "dca" , CODEC_ID_DTS }, | |
89 { "eac3", CODEC_ID_EAC3 }, | |
90 { "mpa" , CODEC_ID_MP3 }, | |
91 { "thd" , CODEC_ID_TRUEHD }, | |
92 { NULL , 0 } | |
93 }; | |
94 AVFormatContext *lavf_ctx = NULL; | |
95 AVStream *stream = NULL; | |
96 const AVOption *opt = NULL; | |
97 struct spdifContext *spdif_ctx = NULL; | |
98 | |
99 spdif_ctx = av_mallocz(sizeof(*spdif_ctx)); | |
100 if (!spdif_ctx) | |
101 goto fail; | |
102 spdif_ctx->lavf_ctx = avformat_alloc_context(); | |
103 if (!spdif_ctx->lavf_ctx) | |
104 goto fail; | |
105 | |
106 sh->context = spdif_ctx; | |
107 lavf_ctx = spdif_ctx->lavf_ctx; | |
108 | |
34203
362c9229e16e
Call av_register_all() before initialising the SPDIF muxer.
cehoyos
parents:
34103
diff
changeset
|
109 av_register_all(); |
34103 | 110 lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL); |
111 if (!lavf_ctx->oformat) | |
112 goto fail; | |
113 lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size); | |
114 if (!lavf_ctx->priv_data) | |
115 goto fail; | |
116 lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx, | |
117 read_packet, write_packet, seek); | |
118 if (!lavf_ctx->pb) | |
119 goto fail; | |
34204
c1b5018b5edb
Use new API avformat_new_stream() instead of the deprecated
cehoyos
parents:
34203
diff
changeset
|
120 stream = avformat_new_stream(lavf_ctx, 0); |
34103 | 121 if (!stream) |
122 goto fail; | |
123 lavf_ctx->duration = AV_NOPTS_VALUE; | |
124 lavf_ctx->start_time = AV_NOPTS_VALUE; | |
125 for (i = 0; fmt_id_type[i].name; i++) { | |
126 if (!strcmp(sh->codec->dll, fmt_id_type[i].name)) { | |
127 lavf_ctx->streams[0]->codec->codec_id = fmt_id_type[i].id; | |
128 break; | |
129 } | |
130 } | |
131 lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE; | |
132 if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) { | |
133 mp_msg(MSGT_DECAUDIO,MSGL_INFO, | |
134 "This codec is not supported by spdifenc.\n"); | |
135 goto fail; | |
136 } | |
137 | |
138 // get sample_rate & bitrate from parser | |
139 bps = srate = 0; | |
140 x = ds_get_packet_pts(sh->ds, &start, &pts); | |
141 in_size = x; | |
142 if (x <= 0) { | |
143 pts = MP_NOPTS_VALUE; | |
144 x = 0; | |
145 } | |
146 ds_parse(sh->ds, &start, &x, pts, 0); | |
147 if (x == 0) { // not enough buffer | |
148 srate = 48000; //fake value | |
149 bps = 768000/8; //fake value | |
150 } else if (sh->avctx) { | |
151 if (sh->avctx->sample_rate < 44100) { | |
152 mp_msg(MSGT_DECAUDIO,MSGL_INFO, | |
153 "This stream sample_rate[%d Hz] may be broken. " | |
154 "Force reset 48000Hz.\n", | |
155 sh->avctx->sample_rate); | |
156 srate = 48000; //fake value | |
157 } else | |
158 srate = sh->avctx->sample_rate; | |
159 bps = sh->avctx->bit_rate/8; | |
160 } | |
161 sh->ds->buffer_pos -= in_size; | |
162 | |
163 switch (lavf_ctx->streams[0]->codec->codec_id) { | |
164 case CODEC_ID_AAC: | |
165 spdif_ctx->iec61937_packet_size = 16384; | |
166 sh->sample_format = AF_FORMAT_IEC61937_LE; | |
167 sh->samplerate = srate; | |
168 sh->channels = 2; | |
169 sh->i_bps = bps; | |
170 break; | |
171 case CODEC_ID_AC3: | |
172 spdif_ctx->iec61937_packet_size = 6144; | |
173 sh->sample_format = AF_FORMAT_IEC61937_LE; | |
174 sh->samplerate = srate; | |
175 sh->channels = 2; | |
176 sh->i_bps = bps; | |
177 break; | |
178 case CODEC_ID_DTS: // FORCE USE DTS-HD | |
179 opt = av_opt_find(&lavf_ctx->oformat->priv_class, | |
180 "dtshd_rate", NULL, 0, 0); | |
181 if (!opt) | |
182 goto fail; | |
183 dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) + | |
184 opt->offset); | |
185 *dtshd_rate = 192000*4; | |
186 spdif_ctx->iec61937_packet_size = 32768; | |
187 sh->sample_format = AF_FORMAT_IEC61937_LE; | |
188 sh->samplerate = 192000; // DTS core require 48000 | |
189 sh->channels = 2*4; | |
190 sh->i_bps = bps; | |
191 break; | |
192 case CODEC_ID_EAC3: | |
193 spdif_ctx->iec61937_packet_size = 24576; | |
194 sh->sample_format = AF_FORMAT_IEC61937_LE; | |
195 sh->samplerate = 192000; | |
196 sh->channels = 2; | |
197 sh->i_bps = bps; | |
198 break; | |
199 case CODEC_ID_MP3: | |
200 spdif_ctx->iec61937_packet_size = 4608; | |
201 sh->sample_format = AF_FORMAT_MPEG2; | |
202 sh->samplerate = srate; | |
203 sh->channels = 2; | |
204 sh->i_bps = bps; | |
205 break; | |
206 case CODEC_ID_TRUEHD: | |
207 spdif_ctx->iec61937_packet_size = 61440; | |
208 sh->sample_format = AF_FORMAT_IEC61937_LE; | |
209 sh->samplerate = 192000; | |
210 sh->channels = 8; | |
211 sh->i_bps = bps; | |
212 break; | |
213 default: | |
214 break; | |
215 } | |
216 | |
217 return 1; | |
218 | |
219 fail: | |
220 uninit(sh); | |
221 return 0; | |
222 } | |
223 | |
224 static int decode_audio(sh_audio_t *sh, unsigned char *buf, | |
225 int minlen, int maxlen) | |
226 { | |
227 struct spdifContext *spdif_ctx = sh->context; | |
228 AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; | |
229 AVPacket pkt; | |
230 double pts; | |
231 int ret, in_size, consumed, x; | |
232 unsigned char *start = NULL; | |
233 | |
234 consumed = spdif_ctx->out_buffer_len = 0; | |
235 spdif_ctx->out_buffer_size = maxlen; | |
236 spdif_ctx->out_buffer = buf; | |
237 while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen | |
238 && spdif_ctx->out_buffer_len < minlen) { | |
239 if (sh->ds->eof) | |
240 break; | |
241 x = ds_get_packet_pts(sh->ds, &start, &pts); | |
242 if (x <= 0) { | |
243 x = 0; | |
244 ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0); | |
245 if (x == 0) | |
246 continue; // END_NOT_FOUND | |
247 in_size = x; | |
248 } else { | |
249 in_size = x; | |
250 consumed = ds_parse(sh->ds, &start, &x, pts, 0); | |
251 if (x == 0) { | |
252 mp_msg(MSGT_DECAUDIO,MSGL_V, | |
253 "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n", | |
254 start, pkt.size, in_size, consumed, x); | |
255 continue; // END_NOT_FOUND | |
256 } | |
257 sh->ds->buffer_pos -= in_size - consumed; | |
258 } | |
259 av_init_packet(&pkt); | |
260 pkt.data = start; | |
261 pkt.size = x; | |
262 mp_msg(MSGT_DECAUDIO,MSGL_V, | |
263 "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n", | |
264 start, pkt.size, in_size, consumed, x); | |
265 if (pts != MP_NOPTS_VALUE) { | |
266 sh->pts = pts; | |
267 sh->pts_bytes = 0; | |
268 } | |
269 ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt); | |
270 if (ret < 0) | |
271 break; | |
272 } | |
273 sh->pts_bytes += spdif_ctx->out_buffer_len; | |
274 return spdif_ctx->out_buffer_len; | |
275 } | |
276 | |
277 static int control(sh_audio_t *sh, int cmd, void* arg, ...) | |
278 { | |
279 unsigned char *start; | |
280 double pts; | |
281 | |
282 switch (cmd) { | |
283 case ADCTRL_RESYNC_STREAM: | |
284 case ADCTRL_SKIP_FRAME: | |
285 ds_get_packet_pts(sh->ds, &start, &pts); | |
286 return CONTROL_TRUE; | |
287 } | |
288 return CONTROL_UNKNOWN; | |
289 } | |
290 | |
291 static void uninit(sh_audio_t *sh) | |
292 { | |
293 struct spdifContext *spdif_ctx = sh->context; | |
294 AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx; | |
295 | |
296 if (lavf_ctx) { | |
297 if (lavf_ctx->oformat) | |
298 lavf_ctx->oformat->write_trailer(lavf_ctx); | |
299 av_freep(&lavf_ctx->pb); | |
300 if (lavf_ctx->streams) { | |
301 av_freep(&lavf_ctx->streams[0]->codec); | |
302 av_freep(&lavf_ctx->streams[0]->info); | |
303 av_freep(&lavf_ctx->streams[0]); | |
304 } | |
305 av_freep(&lavf_ctx->streams); | |
306 av_freep(&lavf_ctx->priv_data); | |
307 } | |
308 av_freep(&lavf_ctx); | |
309 av_freep(&spdif_ctx); | |
310 } |