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