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