annotate libmpcodecs/ad_spdif.c @ 35170:6f214e8ae780

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