1 /*
2 * Copyright (C) 2012 Naoya OYAMA
3 *
4 * This file is part of mpv.
5 *
6 * mpv is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * mpv is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with mpv. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #include <string.h>
21 #include <assert.h>
22
23 #include <libavformat/avformat.h>
24 #include <libavcodec/avcodec.h>
25 #include <libavutil/opt.h>
26
27 #include "audio/aframe.h"
28 #include "audio/format.h"
29 #include "common/av_common.h"
30 #include "common/codecs.h"
31 #include "common/msg.h"
32 #include "demux/packet.h"
33 #include "demux/stheader.h"
34 #include "filters/f_decoder_wrapper.h"
35 #include "filters/filter_internal.h"
36 #include "options/options.h"
37
38 #define OUTBUF_SIZE 65536
39
40 struct spdifContext {
41 struct mp_log *log;
42 enum AVCodecID codec_id;
43 AVFormatContext *lavf_ctx;
44 int out_buffer_len;
45 uint8_t out_buffer[OUTBUF_SIZE];
46 bool need_close;
47 bool use_dts_hd;
48 struct mp_aframe *fmt;
49 int sstride;
50 struct mp_aframe_pool *pool;
51
52 struct mp_decoder public;
53 };
54
write_packet(void * p,uint8_t * buf,int buf_size)55 static int write_packet(void *p, uint8_t *buf, int buf_size)
56 {
57 struct spdifContext *ctx = p;
58
59 int buffer_left = OUTBUF_SIZE - ctx->out_buffer_len;
60 if (buf_size > buffer_left) {
61 MP_ERR(ctx, "spdif packet too large.\n");
62 buf_size = buffer_left;
63 }
64
65 memcpy(&ctx->out_buffer[ctx->out_buffer_len], buf, buf_size);
66 ctx->out_buffer_len += buf_size;
67 return buf_size;
68 }
69
70 // (called on both filter destruction _and_ if lavf fails to init)
destroy(struct mp_filter * da)71 static void destroy(struct mp_filter *da)
72 {
73 struct spdifContext *spdif_ctx = da->priv;
74 AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
75
76 if (lavf_ctx) {
77 if (spdif_ctx->need_close)
78 av_write_trailer(lavf_ctx);
79 if (lavf_ctx->pb)
80 av_freep(&lavf_ctx->pb->buffer);
81 av_freep(&lavf_ctx->pb);
82 avformat_free_context(lavf_ctx);
83 spdif_ctx->lavf_ctx = NULL;
84 }
85 }
86
determine_codec_params(struct mp_filter * da,AVPacket * pkt,int * out_profile,int * out_rate)87 static void determine_codec_params(struct mp_filter *da, AVPacket *pkt,
88 int *out_profile, int *out_rate)
89 {
90 struct spdifContext *spdif_ctx = da->priv;
91 int profile = FF_PROFILE_UNKNOWN;
92 AVCodecContext *ctx = NULL;
93 AVFrame *frame = NULL;
94
95 AVCodecParserContext *parser = av_parser_init(spdif_ctx->codec_id);
96 if (parser) {
97 // Don't make it wait for the next frame.
98 parser->flags |= PARSER_FLAG_COMPLETE_FRAMES;
99
100 ctx = avcodec_alloc_context3(NULL);
101 if (!ctx) {
102 av_parser_close(parser);
103 goto done;
104 }
105
106 uint8_t *d = NULL;
107 int s = 0;
108 av_parser_parse2(parser, ctx, &d, &s, pkt->data, pkt->size, 0, 0, 0);
109 *out_profile = profile = ctx->profile;
110 *out_rate = ctx->sample_rate;
111
112 avcodec_free_context(&ctx);
113 av_parser_close(parser);
114 }
115
116 if (profile != FF_PROFILE_UNKNOWN || spdif_ctx->codec_id != AV_CODEC_ID_DTS)
117 return;
118
119 const AVCodec *codec = avcodec_find_decoder(spdif_ctx->codec_id);
120 if (!codec)
121 goto done;
122
123 frame = av_frame_alloc();
124 if (!frame)
125 goto done;
126
127 ctx = avcodec_alloc_context3(codec);
128 if (!ctx)
129 goto done;
130
131 if (avcodec_open2(ctx, codec, NULL) < 0)
132 goto done;
133
134 if (avcodec_send_packet(ctx, pkt) < 0)
135 goto done;
136 if (avcodec_receive_frame(ctx, frame) < 0)
137 goto done;
138
139 *out_profile = profile = ctx->profile;
140 *out_rate = ctx->sample_rate;
141
142 done:
143 av_frame_free(&frame);
144 avcodec_free_context(&ctx);
145
146 if (profile == FF_PROFILE_UNKNOWN)
147 MP_WARN(da, "Failed to parse codec profile.\n");
148 }
149
init_filter(struct mp_filter * da,AVPacket * pkt)150 static int init_filter(struct mp_filter *da, AVPacket *pkt)
151 {
152 struct spdifContext *spdif_ctx = da->priv;
153
154 int profile = FF_PROFILE_UNKNOWN;
155 int c_rate = 0;
156 determine_codec_params(da, pkt, &profile, &c_rate);
157 MP_VERBOSE(da, "In: profile=%d samplerate=%d\n", profile, c_rate);
158
159 AVFormatContext *lavf_ctx = avformat_alloc_context();
160 if (!lavf_ctx)
161 goto fail;
162
163 spdif_ctx->lavf_ctx = lavf_ctx;
164
165 lavf_ctx->oformat = av_guess_format("spdif", NULL, NULL);
166 if (!lavf_ctx->oformat)
167 goto fail;
168
169 void *buffer = av_mallocz(OUTBUF_SIZE);
170 if (!buffer)
171 abort();
172 lavf_ctx->pb = avio_alloc_context(buffer, OUTBUF_SIZE, 1, spdif_ctx, NULL,
173 write_packet, NULL);
174 if (!lavf_ctx->pb) {
175 av_free(buffer);
176 goto fail;
177 }
178
179 // Request minimal buffering
180 lavf_ctx->pb->direct = 1;
181
182 AVStream *stream = avformat_new_stream(lavf_ctx, 0);
183 if (!stream)
184 goto fail;
185
186 stream->codecpar->codec_id = spdif_ctx->codec_id;
187
188 AVDictionary *format_opts = NULL;
189
190 spdif_ctx->fmt = mp_aframe_create();
191 talloc_steal(spdif_ctx, spdif_ctx->fmt);
192
193 int num_channels = 0;
194 int sample_format = 0;
195 int samplerate = 0;
196 switch (spdif_ctx->codec_id) {
197 case AV_CODEC_ID_AAC:
198 sample_format = AF_FORMAT_S_AAC;
199 samplerate = 48000;
200 num_channels = 2;
201 break;
202 case AV_CODEC_ID_AC3:
203 sample_format = AF_FORMAT_S_AC3;
204 samplerate = c_rate > 0 ? c_rate : 48000;
205 num_channels = 2;
206 break;
207 case AV_CODEC_ID_DTS: {
208 bool is_hd = profile == FF_PROFILE_DTS_HD_HRA ||
209 profile == FF_PROFILE_DTS_HD_MA ||
210 profile == FF_PROFILE_UNKNOWN;
211
212 // Apparently, DTS-HD over SPDIF is specified to be 7.1 (8 channels)
213 // for DTS-HD MA, and stereo (2 channels) for DTS-HD HRA. The bit
214 // streaming rate as well as the signaled channel count are defined
215 // based on this value.
216 int dts_hd_spdif_channel_count = profile == FF_PROFILE_DTS_HD_HRA ?
217 2 : 8;
218 if (spdif_ctx->use_dts_hd && is_hd) {
219 av_dict_set_int(&format_opts, "dtshd_rate",
220 dts_hd_spdif_channel_count * 96000, 0);
221 sample_format = AF_FORMAT_S_DTSHD;
222 samplerate = 192000;
223 num_channels = dts_hd_spdif_channel_count;
224 } else {
225 sample_format = AF_FORMAT_S_DTS;
226 samplerate = 48000;
227 num_channels = 2;
228 }
229 break;
230 }
231 case AV_CODEC_ID_EAC3:
232 sample_format = AF_FORMAT_S_EAC3;
233 samplerate = 192000;
234 num_channels = 2;
235 break;
236 case AV_CODEC_ID_MP3:
237 sample_format = AF_FORMAT_S_MP3;
238 samplerate = 48000;
239 num_channels = 2;
240 break;
241 case AV_CODEC_ID_TRUEHD:
242 sample_format = AF_FORMAT_S_TRUEHD;
243 samplerate = 192000;
244 num_channels = 8;
245 break;
246 default:
247 abort();
248 }
249
250 struct mp_chmap chmap;
251 mp_chmap_from_channels(&chmap, num_channels);
252 mp_aframe_set_chmap(spdif_ctx->fmt, &chmap);
253 mp_aframe_set_format(spdif_ctx->fmt, sample_format);
254 mp_aframe_set_rate(spdif_ctx->fmt, samplerate);
255
256 spdif_ctx->sstride = mp_aframe_get_sstride(spdif_ctx->fmt);
257
258 if (avformat_write_header(lavf_ctx, &format_opts) < 0) {
259 MP_FATAL(da, "libavformat spdif initialization failed.\n");
260 av_dict_free(&format_opts);
261 goto fail;
262 }
263 av_dict_free(&format_opts);
264
265 spdif_ctx->need_close = true;
266
267 return 0;
268
269 fail:
270 destroy(da);
271 mp_filter_internal_mark_failed(da);
272 return -1;
273 }
274
process(struct mp_filter * da)275 static void process(struct mp_filter *da)
276 {
277 struct spdifContext *spdif_ctx = da->priv;
278
279 if (!mp_pin_can_transfer_data(da->ppins[1], da->ppins[0]))
280 return;
281
282 struct mp_frame inframe = mp_pin_out_read(da->ppins[0]);
283 if (inframe.type == MP_FRAME_EOF) {
284 mp_pin_in_write(da->ppins[1], inframe);
285 return;
286 } else if (inframe.type != MP_FRAME_PACKET) {
287 if (inframe.type) {
288 MP_ERR(da, "unknown frame type\n");
289 mp_filter_internal_mark_failed(da);
290 }
291 return;
292 }
293
294 struct demux_packet *mpkt = inframe.data;
295 struct mp_aframe *out = NULL;
296 double pts = mpkt->pts;
297
298 AVPacket pkt;
299 mp_set_av_packet(&pkt, mpkt, NULL);
300 pkt.pts = pkt.dts = 0;
301 if (!spdif_ctx->lavf_ctx) {
302 if (init_filter(da, &pkt) < 0)
303 goto done;
304 }
305 spdif_ctx->out_buffer_len = 0;
306 int ret = av_write_frame(spdif_ctx->lavf_ctx, &pkt);
307 avio_flush(spdif_ctx->lavf_ctx->pb);
308 if (ret < 0) {
309 MP_ERR(da, "spdif mux error: '%s'\n", mp_strerror(AVUNERROR(ret)));
310 goto done;
311 }
312
313 out = mp_aframe_new_ref(spdif_ctx->fmt);
314 int samples = spdif_ctx->out_buffer_len / spdif_ctx->sstride;
315 if (mp_aframe_pool_allocate(spdif_ctx->pool, out, samples) < 0) {
316 TA_FREEP(&out);
317 goto done;
318 }
319
320 uint8_t **data = mp_aframe_get_data_rw(out);
321 if (!data) {
322 TA_FREEP(&out);
323 goto done;
324 }
325
326 memcpy(data[0], spdif_ctx->out_buffer, spdif_ctx->out_buffer_len);
327 mp_aframe_set_pts(out, pts);
328
329 done:
330 talloc_free(mpkt);
331 if (out) {
332 mp_pin_in_write(da->ppins[1], MAKE_FRAME(MP_FRAME_AUDIO, out));
333 } else {
334 mp_filter_internal_mark_failed(da);
335 }
336 }
337
338 static const int codecs[] = {
339 AV_CODEC_ID_AAC,
340 AV_CODEC_ID_AC3,
341 AV_CODEC_ID_DTS,
342 AV_CODEC_ID_EAC3,
343 AV_CODEC_ID_MP3,
344 AV_CODEC_ID_TRUEHD,
345 AV_CODEC_ID_NONE
346 };
347
find_codec(const char * name)348 static bool find_codec(const char *name)
349 {
350 for (int n = 0; codecs[n] != AV_CODEC_ID_NONE; n++) {
351 const char *format = mp_codec_from_av_codec_id(codecs[n]);
352 if (format && name && strcmp(format, name) == 0)
353 return true;
354 }
355 return false;
356 }
357
358 // codec is the libavcodec name of the source audio codec.
359 // pref is a ","-separated list of names, some of them which do not match with
360 // libavcodec names (like dts-hd).
select_spdif_codec(const char * codec,const char * pref)361 struct mp_decoder_list *select_spdif_codec(const char *codec, const char *pref)
362 {
363 struct mp_decoder_list *list = talloc_zero(NULL, struct mp_decoder_list);
364
365 if (!find_codec(codec))
366 return list;
367
368 bool spdif_allowed = false, dts_hd_allowed = false;
369 bstr sel = bstr0(pref);
370 while (sel.len) {
371 bstr decoder;
372 bstr_split_tok(sel, ",", &decoder, &sel);
373 if (decoder.len) {
374 if (bstr_equals0(decoder, codec))
375 spdif_allowed = true;
376 if (bstr_equals0(decoder, "dts-hd") && strcmp(codec, "dts") == 0)
377 spdif_allowed = dts_hd_allowed = true;
378 }
379 }
380
381 if (!spdif_allowed)
382 return list;
383
384 const char *suffix_name = dts_hd_allowed ? "dts_hd" : codec;
385 char name[80];
386 snprintf(name, sizeof(name), "spdif_%s", suffix_name);
387 mp_add_decoder(list, codec, name,
388 "libavformat/spdifenc audio pass-through decoder");
389 return list;
390 }
391
392 static const struct mp_filter_info ad_spdif_filter = {
393 .name = "ad_spdif",
394 .priv_size = sizeof(struct spdifContext),
395 .process = process,
396 .destroy = destroy,
397 };
398
create(struct mp_filter * parent,struct mp_codec_params * codec,const char * decoder)399 static struct mp_decoder *create(struct mp_filter *parent,
400 struct mp_codec_params *codec,
401 const char *decoder)
402 {
403 struct mp_filter *da = mp_filter_create(parent, &ad_spdif_filter);
404 if (!da)
405 return NULL;
406
407 mp_filter_add_pin(da, MP_PIN_IN, "in");
408 mp_filter_add_pin(da, MP_PIN_OUT, "out");
409
410 da->log = mp_log_new(da, parent->log, NULL);
411
412 struct spdifContext *spdif_ctx = da->priv;
413 spdif_ctx->log = da->log;
414 spdif_ctx->pool = mp_aframe_pool_create(spdif_ctx);
415 spdif_ctx->public.f = da;
416
417 if (strcmp(decoder, "spdif_dts_hd") == 0)
418 spdif_ctx->use_dts_hd = true;
419
420 spdif_ctx->codec_id = mp_codec_to_av_codec_id(codec->codec);
421
422
423 if (spdif_ctx->codec_id == AV_CODEC_ID_NONE) {
424 talloc_free(da);
425 return NULL;
426 }
427 return &spdif_ctx->public;
428 }
429
430 const struct mp_decoder_fns ad_spdif = {
431 .create = create,
432 };
433