annotate libmpcodecs/ad_spdif.c @ 36931:884277c93772

Set guiInfo.Position in SetMoviePosition event. Additionally, use this variable to call uiAbsSeek(). (This also allows setting the movie position before playback now.)
author ib
date Fri, 21 Mar 2014 14:29:40 +0000
parents 9b88b87f5921
children 39b662840ac7
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 {
35864
9b88b87f5921 Fix mplayer compilation.
iive
parents: 35715
diff changeset
85 const char *name; enum AVCodecID id;
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
86 } fmt_id_type[] = {
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
87 { "aac" , AV_CODEC_ID_AAC },
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
88 { "ac3" , AV_CODEC_ID_AC3 },
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
89 { "dca" , AV_CODEC_ID_DTS },
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
90 { "eac3", AV_CODEC_ID_EAC3 },
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
91 { "mpa" , AV_CODEC_ID_MP3 },
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
92 { "thd" , AV_CODEC_ID_TRUEHD },
34103
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 x = ds_get_packet_pts(sh->ds, &start, &pts);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
141 in_size = x;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
142 if (x <= 0) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
143 pts = MP_NOPTS_VALUE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
144 x = 0;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
145 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
146 ds_parse(sh->ds, &start, &x, pts, 0);
35423
eef7c4527712 Do not fall back to 0 for samplerate when parser is not initialized.
reimar
parents: 35306
diff changeset
147 srate = 48000; //fake value
eef7c4527712 Do not fall back to 0 for samplerate when parser is not initialized.
reimar
parents: 35306
diff changeset
148 bps = 768000/8; //fake value
eef7c4527712 Do not fall back to 0 for samplerate when parser is not initialized.
reimar
parents: 35306
diff changeset
149 if (x && sh->avctx) { // we have parser and large enough buffer
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
150 if (sh->avctx->sample_rate < 44100) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
151 mp_msg(MSGT_DECAUDIO,MSGL_INFO,
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
152 "This stream sample_rate[%d Hz] may be broken. "
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
153 "Force reset 48000Hz.\n",
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
154 sh->avctx->sample_rate);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
155 srate = 48000; //fake value
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
156 } else
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
157 srate = sh->avctx->sample_rate;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
158 bps = sh->avctx->bit_rate/8;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
159 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
160 sh->ds->buffer_pos -= in_size;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
161
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
162 switch (lavf_ctx->streams[0]->codec->codec_id) {
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
163 case AV_CODEC_ID_AAC:
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
164 spdif_ctx->iec61937_packet_size = 16384;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
165 sh->sample_format = AF_FORMAT_IEC61937_LE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
166 sh->samplerate = srate;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
167 sh->channels = 2;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
168 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
169 break;
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
170 case AV_CODEC_ID_AC3:
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
171 spdif_ctx->iec61937_packet_size = 6144;
35442
2b45dfcde03c ad_spdif: use the more specific AF_FORMAT_AC3_LE when
reimar
parents: 35423
diff changeset
172 sh->sample_format = AF_FORMAT_AC3_LE;
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
173 sh->samplerate = srate;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
174 sh->channels = 2;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
175 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
176 break;
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
177 case AV_CODEC_ID_DTS: // FORCE USE DTS-HD
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
178 opt = av_opt_find(&lavf_ctx->oformat->priv_class,
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
179 "dtshd_rate", NULL, 0, 0);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
180 if (!opt)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
181 goto fail;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
182 dtshd_rate = (int*)(((uint8_t*)lavf_ctx->priv_data) +
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
183 opt->offset);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
184 *dtshd_rate = 192000*4;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
185 spdif_ctx->iec61937_packet_size = 32768;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
186 sh->sample_format = AF_FORMAT_IEC61937_LE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
187 sh->samplerate = 192000; // DTS core require 48000
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
188 sh->channels = 2*4;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
189 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
190 break;
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
191 case AV_CODEC_ID_EAC3:
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
192 spdif_ctx->iec61937_packet_size = 24576;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
193 sh->sample_format = AF_FORMAT_IEC61937_LE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
194 sh->samplerate = 192000;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
195 sh->channels = 2;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
196 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
197 break;
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
198 case AV_CODEC_ID_MP3:
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
199 spdif_ctx->iec61937_packet_size = 4608;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
200 sh->sample_format = AF_FORMAT_MPEG2;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
201 sh->samplerate = srate;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
202 sh->channels = 2;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
203 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
204 break;
35715
8517826b0dbd Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents: 35442
diff changeset
205 case AV_CODEC_ID_TRUEHD:
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
206 spdif_ctx->iec61937_packet_size = 61440;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
207 sh->sample_format = AF_FORMAT_IEC61937_LE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
208 sh->samplerate = 192000;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
209 sh->channels = 8;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
210 sh->i_bps = bps;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
211 break;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
212 default:
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
213 break;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
214 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
215
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
216 return 1;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
217
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
218 fail:
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
219 uninit(sh);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
220 return 0;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
221 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
222
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
223 static int decode_audio(sh_audio_t *sh, unsigned char *buf,
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
224 int minlen, int maxlen)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
225 {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
226 struct spdifContext *spdif_ctx = sh->context;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
227 AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
228 AVPacket pkt;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
229 double pts;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
230 int ret, in_size, consumed, x;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
231 unsigned char *start = NULL;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
232
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
233 consumed = spdif_ctx->out_buffer_len = 0;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
234 spdif_ctx->out_buffer_size = maxlen;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
235 spdif_ctx->out_buffer = buf;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
236 while (spdif_ctx->out_buffer_len + spdif_ctx->iec61937_packet_size < maxlen
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
237 && spdif_ctx->out_buffer_len < minlen) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
238 if (sh->ds->eof)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
239 break;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
240 x = ds_get_packet_pts(sh->ds, &start, &pts);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
241 if (x <= 0) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
242 x = 0;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
243 ds_parse(sh->ds, &start, &x, MP_NOPTS_VALUE, 0);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
244 if (x == 0)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
245 continue; // END_NOT_FOUND
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
246 in_size = x;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
247 } else {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
248 in_size = x;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
249 consumed = ds_parse(sh->ds, &start, &x, pts, 0);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
250 if (x == 0) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
251 mp_msg(MSGT_DECAUDIO,MSGL_V,
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
252 "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
35306
f30c2707e168 Do not use pkt which is uninitialized at that point.
reimar
parents: 34206
diff changeset
253 start, 0, in_size, consumed, x);
34103
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
254 continue; // END_NOT_FOUND
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
255 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
256 sh->ds->buffer_pos -= in_size - consumed;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
257 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
258 av_init_packet(&pkt);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
259 pkt.data = start;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
260 pkt.size = x;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
261 mp_msg(MSGT_DECAUDIO,MSGL_V,
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
262 "start[%p] pkt.size[%d] in_size[%d] consumed[%d] x[%d].\n",
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
263 start, pkt.size, in_size, consumed, x);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
264 if (pts != MP_NOPTS_VALUE) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
265 sh->pts = pts;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
266 sh->pts_bytes = 0;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
267 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
268 ret = lavf_ctx->oformat->write_packet(lavf_ctx, &pkt);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
269 if (ret < 0)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
270 break;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
271 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
272 sh->pts_bytes += spdif_ctx->out_buffer_len;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
273 return spdif_ctx->out_buffer_len;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
274 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
275
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
276 static int control(sh_audio_t *sh, int cmd, void* arg, ...)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
277 {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
278 unsigned char *start;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
279 double pts;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
280
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
281 switch (cmd) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
282 case ADCTRL_RESYNC_STREAM:
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
283 case ADCTRL_SKIP_FRAME:
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
284 ds_get_packet_pts(sh->ds, &start, &pts);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
285 return CONTROL_TRUE;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
286 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
287 return CONTROL_UNKNOWN;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
288 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
289
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
290 static void uninit(sh_audio_t *sh)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
291 {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
292 struct spdifContext *spdif_ctx = sh->context;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
293 AVFormatContext *lavf_ctx = spdif_ctx->lavf_ctx;
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
294
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
295 if (lavf_ctx) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
296 if (lavf_ctx->oformat)
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
297 lavf_ctx->oformat->write_trailer(lavf_ctx);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
298 av_freep(&lavf_ctx->pb);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
299 if (lavf_ctx->streams) {
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
300 av_freep(&lavf_ctx->streams[0]->codec);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
301 av_freep(&lavf_ctx->streams[0]->info);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
302 av_freep(&lavf_ctx->streams[0]);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
303 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
304 av_freep(&lavf_ctx->streams);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
305 av_freep(&lavf_ctx->priv_data);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
306 }
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
307 av_freep(&lavf_ctx);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
308 av_freep(&spdif_ctx);
febe300dbfc0 S/PDIF passthrough decoder
diego
parents:
diff changeset
309 }