1 /*
2 * Copyright (C) 2001-2018 the xine project
3 *
4 * This file is part of xine, a free video player.
5 *
6 * xine is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * xine 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 General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110, USA
19 */
20
21 /*
22 * AC3 File Demuxer by Mike Melanson (melanson@pcisys.net)
23 * This demuxer detects raw AC3 data in a file and shovels AC3 data
24 * directly to the AC3 decoder.
25 */
26
27 #ifdef HAVE_CONFIG_H
28 #include "config.h"
29 #endif
30
31 #include <stdio.h>
32 #include <fcntl.h>
33 #include <unistd.h>
34 #include <string.h>
35 #include <stdlib.h>
36 #include <ctype.h>
37 #ifdef HAVE_ALLOCA_H
38 #include <alloca.h>
39 #endif
40 #ifdef HAVE_MALLOC_H
41 #include <malloc.h>
42 #endif
43
44 #define LOG_MODULE "demux_ac3"
45 #define LOG_VERBOSE
46 /*
47 #define LOG
48 */
49
50 #include <xine/xine_internal.h>
51 #include <xine/xineutils.h>
52 #include <xine/demux.h>
53 #include <xine/buffer.h>
54 #include "bswap.h"
55 #include "group_audio.h"
56
57 #define DATA_TAG 0x61746164
58
59 typedef struct {
60 demux_plugin_t demux_plugin;
61
62 xine_stream_t *stream;
63 fifo_buffer_t *video_fifo;
64 fifo_buffer_t *audio_fifo;
65 input_plugin_t *input;
66 int status;
67
68 int seek_flag;
69 int sample_rate;
70 int frame_size;
71 int running_time;
72
73 uint32_t buf_type;
74
75 } demux_ac3_t;
76
77 /* returns 1 if the AC3 file was opened successfully, 0 otherwise */
open_ac3_file(demux_ac3_t * this)78 static int open_ac3_file(demux_ac3_t *this) {
79 buf_element_t *buf = NULL;
80 uint32_t offset = 0;
81 int ret = 0;
82
83 do {
84 uint32_t bsize = 0;
85 int spdif_mode = 0;
86 uint8_t hb[MAX_PREVIEW_SIZE];
87 const uint8_t *b;
88
89 do {
90 if (!INPUT_IS_SEEKABLE (this->input))
91 break;
92 bsize = this->input->get_blocksize (this->input);
93 if (!bsize)
94 break;
95 if (this->input->seek (this->input, 0, SEEK_SET) != 0)
96 break;
97 buf = this->input->read_block (this->input, this->stream->audio_fifo, bsize);
98 if (!buf)
99 break;
100 if (this->input->seek (this->input, 0, SEEK_SET) != 0) { /* should not happen */
101 buf->free_buffer (buf);
102 buf = NULL;
103 break;
104 }
105 b = buf->content;
106 bsize = buf->size;
107 } while (0);
108 if (!buf) {
109 int s;
110 s = _x_demux_read_header (this->input, hb, MAX_PREVIEW_SIZE);
111 if (s <= 0)
112 break;
113 bsize = s;
114 b = hb;
115 }
116 lprintf ("peek size: %u\n", (unsigned int)bsize);
117 if (bsize < 16)
118 break;
119
120 do {
121 /* Check for wav header, as we'll handle AC3 with a wav header shoved
122 * on the front for CD burning.
123 * FIXME: This is risky. Real LPCM may contain anything, even sync words. */
124 unsigned int audio_type;
125 xine_waveformatex *wave;
126 uint32_t o;
127
128 /* Check this looks like a cd audio wav */
129 if (bsize < 20 + sizeof (xine_waveformatex))
130 break;
131 if (memcmp (b, "RIFF", 4) && memcmp (b + 8, "WAVEfmt ", 8))
132 break;
133 wave = (xine_waveformatex *)(b + 20);
134 _x_waveformatex_le2me (wave);
135 audio_type = _x_formattag_to_buf_audio (wave->wFormatTag);
136 if ((audio_type != BUF_AUDIO_LPCM_LE) || (wave->nChannels != 2) ||
137 (wave->nSamplesPerSec != 44100) || (wave->wBitsPerSample != 16))
138 break;
139 lprintf ("looks like a cd audio wav file\n");
140
141 /* Find the data chunk */
142 o = _X_LE_32 (b + 16);
143 if (o > bsize - 20 - 8)
144 break;
145 o += 20;
146 do {
147 uint32_t chunk_tag = _X_LE_32 (b + o);
148 uint32_t chunk_size = _X_LE_32 (b + o + 4);
149 o += 8;
150 if (chunk_tag == DATA_TAG) {
151 offset = o;
152 lprintf ("found the start of the data at offset %d\n", offset);
153 break;
154 }
155 if (o >= bsize)
156 break;
157 if (chunk_size > bsize - o)
158 break;
159 o += chunk_size;
160 } while (o <= bsize - 8);
161 } while (0);
162
163 /* Look for a valid AC3 sync word */
164 {
165 uint32_t syncword = 0;
166 while (offset < bsize) {
167 if ((syncword & 0xffff) == 0x0b77) {
168 offset -= 2;
169 lprintf ("found AC3 syncword at offset %u\n", (unsigned int)offset);
170 break;
171 }
172 if ((syncword == 0x72f81f4e) && (b[offset] == 0x01)) {
173 spdif_mode = 1;
174 lprintf ("found AC3 SPDIF header at offset %u\n", (unsigned int)offset - 4);
175 offset += 4;
176 break;
177 }
178 syncword = (syncword << 8) | b[offset];
179 offset++;
180 }
181 }
182 if (offset >= bsize - 2)
183 break;
184
185 if (spdif_mode) {
186 this->sample_rate = 44100;
187 this->frame_size = 256 * 6 * 4;
188 this->buf_type = BUF_AUDIO_DNET;
189 ret = 1;
190 break;
191 }
192
193 {
194 static const uint8_t byterates[19] = {
195 4, 5, 6, 7, 8, 10, 12, 14,
196 16, 20, 24, 28, 32, 40, 48, 56,
197 64, 72, 80
198 };
199 uint32_t idx, rate;
200 if (offset >= bsize - 4)
201 break;
202 idx = b[offset + 4];
203 if ((idx & 0x3f) > 37)
204 break;
205 rate = (uint32_t)byterates[(idx >> 1) & 0x1f];
206 if (idx & 0x80) {
207 if (idx & 0x40) {
208 break;
209 } else {
210 this->frame_size = rate * 24 * 2;
211 this->sample_rate = 32000;
212 }
213 } else {
214 if (idx & 0x40) {
215 this->frame_size = ((rate * 16 * 48000 / 44100) + (idx & 0x01)) * 2;
216 this->sample_rate = 44100;
217 } else {
218 this->frame_size = rate * 16 * 2;
219 this->sample_rate = 48000;
220 }
221 }
222 }
223
224 /* Look for a second sync word */
225 if ((offset + this->frame_size + 1 >= bsize) ||
226 (b[offset + this->frame_size] != 0x0b) ||
227 (b[offset + this->frame_size + 1] != 0x77)) {
228 break;
229 }
230 lprintf ("found second AC3 sync word\n");
231 this->buf_type = BUF_AUDIO_A52;
232 ret = 1;
233 } while (0);
234
235 if (buf)
236 buf->free_buffer (buf);
237
238 if (ret) {
239 this->running_time = this->input->get_length (this->input) - offset;
240 this->running_time /= this->frame_size;
241 this->running_time *= (90000 / 1000) * (256 * 6);
242 this->running_time /= this->sample_rate;
243
244 lprintf ("sample rate: %d\n", this->sample_rate);
245 lprintf ("frame size: %d\n", this->frame_size);
246 lprintf("running time: %d\n", this->running_time);
247 }
248 return ret;
249 }
250
demux_ac3_send_chunk(demux_plugin_t * this_gen)251 static int demux_ac3_send_chunk (demux_plugin_t *this_gen) {
252 demux_ac3_t *this = (demux_ac3_t *) this_gen;
253
254 buf_element_t *buf = NULL;
255 off_t current_stream_pos;
256 int64_t audio_pts;
257 int frame_number;
258 uint32_t blocksize;
259
260 current_stream_pos = this->input->get_current_pos(this->input);
261 frame_number = current_stream_pos / this->frame_size;
262
263 /*
264 * Each frame represents 256*6 new audio samples according to the a52 spec.
265 * Thus, the pts computation should work something like:
266 *
267 * pts = frame # * 256*6 samples 1 sec 90000 pts
268 * ------------- * ----------- * ---------
269 * 1 frame sample rate 1 sec
270 */
271 audio_pts = frame_number;
272 audio_pts *= 90000;
273 audio_pts *= 256 * 6;
274 audio_pts /= this->sample_rate;
275
276 if (this->seek_flag) {
277 _x_demux_control_newpts(this->stream, audio_pts, BUF_FLAG_SEEK);
278 this->seek_flag = 0;
279 }
280
281 blocksize = this->input->get_blocksize(this->input);
282 if (blocksize) {
283 buf = this->input->read_block(this->input, this->audio_fifo,
284 blocksize);
285 if (!buf) {
286 this->status = DEMUX_FINISHED;
287 return this->status;
288 }
289 } else {
290 buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
291 buf->size = this->input->read(this->input, buf->content,
292 this->frame_size);
293 }
294
295 if (buf->size <= 0) {
296 buf->free_buffer(buf);
297 this->status = DEMUX_FINISHED;
298 return this->status;
299 }
300
301 buf->type = this->buf_type;
302 if( this->input->get_length (this->input) )
303 buf->extra_info->input_normpos = (int)( (double) current_stream_pos *
304 65535 / this->input->get_length (this->input) );
305 buf->extra_info->input_time = audio_pts / 90;
306 buf->pts = audio_pts;
307 buf->decoder_flags |= BUF_FLAG_FRAME_END;
308
309 this->audio_fifo->put (this->audio_fifo, buf);
310
311 return this->status;
312 }
313
demux_ac3_send_headers(demux_plugin_t * this_gen)314 static void demux_ac3_send_headers(demux_plugin_t *this_gen) {
315 demux_ac3_t *this = (demux_ac3_t *) this_gen;
316 buf_element_t *buf;
317
318 this->video_fifo = this->stream->video_fifo;
319 this->audio_fifo = this->stream->audio_fifo;
320
321 this->status = DEMUX_OK;
322
323 /* load stream information */
324 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
325 _x_stream_info_set(this->stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
326
327 /* send start buffers */
328 _x_demux_control_start(this->stream);
329
330 /* send init info to decoders */
331 if (this->audio_fifo) {
332 buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
333 buf->type = this->buf_type;
334 buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
335 buf->size = 0;
336 this->audio_fifo->put (this->audio_fifo, buf);
337 }
338 }
339
demux_ac3_seek(demux_plugin_t * this_gen,off_t start_pos,int start_time,int playing)340 static int demux_ac3_seek (demux_plugin_t *this_gen,
341 off_t start_pos, int start_time, int playing) {
342
343 demux_ac3_t *this = (demux_ac3_t *) this_gen;
344 start_pos = (off_t) ( (double) start_pos / 65535 *
345 this->input->get_length (this->input) );
346
347 (void)start_time;
348 (void)playing;
349
350 this->seek_flag = 1;
351 this->status = DEMUX_OK;
352 _x_demux_flush_engine (this->stream);
353
354 /* if input is non-seekable, do not proceed with the rest of this
355 * seek function */
356 if (!INPUT_IS_SEEKABLE(this->input))
357 return this->status;
358
359 /* divide the requested offset integer-wise by the frame alignment and
360 * multiply by the frame alignment to determine the new starting block */
361 start_pos /= this->frame_size;
362 start_pos *= this->frame_size;
363 this->input->seek(this->input, start_pos, SEEK_SET);
364
365 return this->status;
366 }
367
demux_ac3_get_status(demux_plugin_t * this_gen)368 static int demux_ac3_get_status (demux_plugin_t *this_gen) {
369 demux_ac3_t *this = (demux_ac3_t *) this_gen;
370
371 return this->status;
372 }
373
374 /* return the approximate length in milliseconds */
demux_ac3_get_stream_length(demux_plugin_t * this_gen)375 static int demux_ac3_get_stream_length (demux_plugin_t *this_gen) {
376 demux_ac3_t *this = (demux_ac3_t *) this_gen;
377
378 return this->running_time;
379 }
380
demux_ac3_get_capabilities(demux_plugin_t * this_gen)381 static uint32_t demux_ac3_get_capabilities(demux_plugin_t *this_gen) {
382 (void)this_gen;
383 return DEMUX_CAP_NOCAP;
384 }
385
demux_ac3_get_optional_data(demux_plugin_t * this_gen,void * data,int data_type)386 static int demux_ac3_get_optional_data(demux_plugin_t *this_gen,
387 void *data, int data_type) {
388 (void)this_gen;
389 (void)data;
390 (void)data_type;
391 return DEMUX_OPTIONAL_UNSUPPORTED;
392 }
393
open_plugin(demux_class_t * class_gen,xine_stream_t * stream,input_plugin_t * input)394 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
395 input_plugin_t *input) {
396
397 demux_ac3_t *this;
398
399 this = calloc(1, sizeof(demux_ac3_t));
400 if (!this)
401 return NULL;
402
403 this->stream = stream;
404 this->input = input;
405
406 this->demux_plugin.send_headers = demux_ac3_send_headers;
407 this->demux_plugin.send_chunk = demux_ac3_send_chunk;
408 this->demux_plugin.seek = demux_ac3_seek;
409 this->demux_plugin.dispose = default_demux_plugin_dispose;
410 this->demux_plugin.get_status = demux_ac3_get_status;
411 this->demux_plugin.get_stream_length = demux_ac3_get_stream_length;
412 this->demux_plugin.get_capabilities = demux_ac3_get_capabilities;
413 this->demux_plugin.get_optional_data = demux_ac3_get_optional_data;
414 this->demux_plugin.demux_class = class_gen;
415
416 this->status = DEMUX_FINISHED;
417
418 switch (stream->content_detection_method) {
419
420 case METHOD_BY_MRL:
421 case METHOD_BY_CONTENT:
422 case METHOD_EXPLICIT:
423
424 if (!open_ac3_file(this)) {
425 free (this);
426 return NULL;
427 }
428
429 break;
430
431 default:
432 free (this);
433 return NULL;
434 }
435
436 return &this->demux_plugin;
437 }
438
demux_ac3_init_plugin(xine_t * xine,const void * data)439 void *demux_ac3_init_plugin (xine_t *xine, const void *data) {
440
441 (void)xine;
442 (void)data;
443
444 static const demux_class_t demux_ac3_class = {
445 .open_plugin = open_plugin,
446 .description = N_("Raw AC3 demux plugin"),
447 .identifier = "AC3",
448 .mimetypes = "audio/ac3: ac3: Dolby Digital audio;",
449 .extensions = "ac3",
450 .dispose = NULL,
451 };
452
453 return (void *)&demux_ac3_class;
454 }
455