2
* This file is part of MPlayer.
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.
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.
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.
23
#include "ad_internal.h"
24
#include "av_helpers.h"
25
#include "libavformat/avformat.h"
26
#include "libavcodec/avcodec.h"
27
#include "libavutil/opt.h"
29
static const ad_info_t info = {
30
"libavformat/spdifenc audio pass-through decoder.",
34
"For ALL hardware decoders"
39
#define FILENAME_SPDIFENC "spdif"
40
#define OUTBUF_SIZE 65536
42
AVFormatContext *lavf_ctx;
43
int iec61937_packet_size;
47
uint8_t pb_buffer[OUTBUF_SIZE];
50
static int read_packet(void *p, uint8_t *buf, int buf_size)
52
// spdifenc does not use read callback.
56
static int write_packet(void *p, uint8_t *buf, int buf_size)
59
struct spdifContext *ctx = p;
61
len = FFMIN(buf_size, ctx->out_buffer_size -ctx->out_buffer_len);
62
memcpy(&ctx->out_buffer[ctx->out_buffer_len], buf, len);
63
ctx->out_buffer_len += len;
67
static int64_t seek(void *p, int64_t offset, int whence)
69
// spdifenc does not use seek callback.
73
static int preinit(sh_audio_t *sh)
79
static int init(sh_audio_t *sh)
81
int i, x, in_size, srate, bps, *dtshd_rate;
85
const char *name; enum CodecID id;
87
{ "aac" , CODEC_ID_AAC },
88
{ "ac3" , CODEC_ID_AC3 },
89
{ "dca" , CODEC_ID_DTS },
90
{ "eac3", CODEC_ID_EAC3 },
91
{ "mpa" , CODEC_ID_MP3 },
92
{ "thd" , CODEC_ID_TRUEHD },
95
AVFormatContext *lavf_ctx = NULL;
96
AVStream *stream = NULL;
97
const AVOption *opt = NULL;
98
struct spdifContext *spdif_ctx = NULL;
100
spdif_ctx = av_mallocz(sizeof(*spdif_ctx));
103
spdif_ctx->lavf_ctx = avformat_alloc_context();
104
if (!spdif_ctx->lavf_ctx)
107
sh->context = spdif_ctx;
108
lavf_ctx = spdif_ctx->lavf_ctx;
111
lavf_ctx->oformat = av_guess_format(FILENAME_SPDIFENC, NULL, NULL);
112
if (!lavf_ctx->oformat)
114
lavf_ctx->priv_data = av_mallocz(lavf_ctx->oformat->priv_data_size);
115
if (!lavf_ctx->priv_data)
117
lavf_ctx->pb = avio_alloc_context(spdif_ctx->pb_buffer, OUTBUF_SIZE, 1, spdif_ctx,
118
read_packet, write_packet, seek);
121
stream = avformat_new_stream(lavf_ctx, 0);
124
lavf_ctx->duration = AV_NOPTS_VALUE;
125
lavf_ctx->start_time = AV_NOPTS_VALUE;
126
for (i = 0; fmt_id_type[i].name; i++) {
127
if (!strcmp(sh->codec->dll, fmt_id_type[i].name)) {
128
lavf_ctx->streams[0]->codec->codec_id = fmt_id_type[i].id;
132
lavf_ctx->raw_packet_buffer_remaining_size = RAW_PACKET_BUFFER_SIZE;
133
if (AVERROR_PATCHWELCOME == lavf_ctx->oformat->write_header(lavf_ctx)) {
134
mp_msg(MSGT_DECAUDIO,MSGL_INFO,
135
"This codec is not supported by spdifenc.\n");
139
// get sample_rate & bitrate from parser
141
x = ds_get_packet_pts(sh->ds, &start, &pts);
144
pts = MP_NOPTS_VALUE;
147
ds_parse(sh->ds, &start, &x, pts, 0);
148
if (x == 0) { // not enough buffer
149
srate = 48000; //fake value
150
bps = 768000/8; //fake value
151
} else if (sh->avctx) {
152
if (sh->avctx->sample_rate < 44100) {
153
mp_msg(MSGT_DECAUDIO,MSGL_INFO,
154
"This stream sample_rate[%d Hz] may be broken. "
155
"Force reset 48000Hz.\n",
156
sh->avctx->sample_rate);
157
srate = 48000; //fake value
159
srate = sh->avctx->sample_rate;
160
bps = sh->avctx->bit_rate/8;
162
sh->ds->buffer_pos -= in_size;
164
switch (lavf_ctx->streams[0]->codec->codec_id) {
166
spdif_ctx->iec61937_packet_size = 16384;
167
sh->sample_format = AF_FORMAT_IEC61937_LE;
168
sh->samplerate = srate;
173
spdif_ctx->iec61937_packet_size = 6144;
174
sh->sample_format = AF_FORMAT_IEC61937_LE;
175
sh->samplerate = srate;
179
case CODEC_ID_DTS: // FORCE USE DTS-HD
180
opt = av_opt_find(&lavf_ctx->oformat->priv_class,
181
"dtshd_rate", NULL, 0, 0);
184
dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) +
186
*dtshd_rate = 192000*4;
187
spdif_ctx->iec61937_packet_size = 32768;
188
sh->sample_format = AF_FORMAT_IEC61937_LE;
189
sh->samplerate = 192000; // DTS core require 48000
194
spdif_ctx->iec61937_packet_size = 24576;
195
sh->sample_format = AF_FORMAT_IEC61937_LE;
196
sh->samplerate = 192000;
201
spdif_ctx->iec61937_packet_size = 4608;
202
sh->sample_format = AF_FORMAT_MPEG2;
203
sh->samplerate = srate;
207
case CODEC_ID_TRUEHD:
208
spdif_ctx->iec61937_packet_size = 61440;
209
sh->sample_format = AF_FORMAT_IEC61937_LE;
210
sh->samplerate = 192000;
225
static int decode_audio(sh_audio_t *sh, unsigned char *buf,
226
int minlen, int maxlen)
228
struct spdifContext *spdif_ctx = sh->context;
229
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
232
int ret, in_size, consumed, x;
233
unsigned char *start = NULL;
235
consumed = spdif_ctx->out_buffer_len = 0;
236
spdif_ctx->out_buffer_size = maxlen;
237
spdif_ctx->out_buffer = buf;
238
while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen
239
&& spdif_ctx->out_buffer_len < minlen) {
242
x = ds_get_packet_pts(sh->ds, &start, &pts);
245
ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0);
247
continue; // END_NOT_FOUND
251
consumed = ds_parse(sh->ds, &start, &x, pts, 0);
253
mp_msg(MSGT_DECAUDIO,MSGL_V,
254
"start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
255
start, pkt.size, in_size, consumed, x);
256
continue; // END_NOT_FOUND
258
sh->ds->buffer_pos -= in_size - consumed;
260
av_init_packet(&pkt);
263
mp_msg(MSGT_DECAUDIO,MSGL_V,
264
"start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
265
start, pkt.size, in_size, consumed, x);
266
if (pts != MP_NOPTS_VALUE) {
270
ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt);
274
sh->pts_bytes += spdif_ctx->out_buffer_len;
275
return spdif_ctx->out_buffer_len;
278
static int control(sh_audio_t *sh, int cmd, void* arg, ...)
280
unsigned char *start;
284
case ADCTRL_RESYNC_STREAM:
285
case ADCTRL_SKIP_FRAME:
286
ds_get_packet_pts(sh->ds, &start, &pts);
289
return CONTROL_UNKNOWN;
292
static void uninit(sh_audio_t *sh)
294
struct spdifContext *spdif_ctx = sh->context;
295
AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
298
if (lavf_ctx->oformat)
299
lavf_ctx->oformat->write_trailer(lavf_ctx);
300
av_freep(&lavf_ctx->pb);
301
if (lavf_ctx->streams) {
302
av_freep(&lavf_ctx->streams[0]->codec);
303
av_freep(&lavf_ctx->streams[0]->info);
304
av_freep(&lavf_ctx->streams[0]);
306
av_freep(&lavf_ctx->streams);
307
av_freep(&lavf_ctx->priv_data);
310
av_freep(&spdif_ctx);