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 * Raw AAC File Demuxer by Mike Melanson (melanson@pcisys.net)
21 * This demuxer detects ADIF and ADTS headers in AAC files.
22 * Then it shovels buffer-sized chunks over to the AAC decoder.
23 */
24
25 #ifdef HAVE_CONFIG_H
26 #include "config.h"
27 #endif
28
29 #include <stdio.h>
30 #include <fcntl.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <stdlib.h>
34 #include <ctype.h>
35
36 #define LOG_MODULE "demux_aac"
37 #define LOG_VERBOSE
38 /*
39 #define LOG
40 */
41
42 #include <xine/xine_internal.h>
43 #include <xine/xineutils.h>
44 #include <xine/demux.h>
45 #include <xine/buffer.h>
46 #include "bswap.h"
47 #include "group_audio.h"
48
49 #include "id3.h"
50
51 typedef struct {
52 demux_plugin_t demux_plugin;
53
54 xine_stream_t *stream;
55 fifo_buffer_t *audio_fifo;
56 input_plugin_t *input;
57 int status;
58
59 int seek_flag; /* this is set when a seek just occurred */
60 } demux_aac_t;
61
62
probe_aac_file(xine_stream_t * stream,input_plugin_t * input)63 static int probe_aac_file(xine_stream_t *stream, input_plugin_t *input) {
64 int i;
65 uint8_t peak[MAX_PREVIEW_SIZE];
66 uint32_t signature;
67 uint16_t syncword = 0;
68 uint32_t id3size = 0;
69 off_t data_start = 0;
70
71 _x_assert(MAX_PREVIEW_SIZE > 10);
72
73 if (_x_demux_read_header(input, &signature, 4) != 4)
74 return 0;
75
76 /* Check if there's an ID3v2 tag at the start */
77 if ( id3v2_istag(signature) ) {
78 if (input->seek(input, 4, SEEK_SET) != 4)
79 return 0;
80
81 id3v2_parse_tag(input, stream, signature);
82 }
83
84 if (input->read(input, &signature, 4) != 4)
85 return 0;
86
87 /* Check for an ADIF header - should be at the start of the file */
88 if (_x_is_fourcc(&signature, "ADIF")) {
89 lprintf("found ADIF header\n");
90 return 1;
91 }
92
93 /* Look for an ADTS header - might not be at the start of the file */
94 if (input->get_capabilities(input) & INPUT_CAP_SEEKABLE) {
95 lprintf("Getting a buffer of size %u\n", MAX_PREVIEW_SIZE);
96
97 if (input->read(input, peak, MAX_PREVIEW_SIZE) != MAX_PREVIEW_SIZE )
98 return 0;
99 if (input->seek(input, 0, SEEK_SET) != 0)
100 return 0;
101
102 } else if (_x_demux_read_header(input, peak, MAX_PREVIEW_SIZE) !=
103 MAX_PREVIEW_SIZE)
104 return 0;
105
106 for (i=0; i<MAX_PREVIEW_SIZE; i++) {
107 if ((syncword & 0xfff6) == 0xfff0) {
108 data_start = i - 2;
109 lprintf("found ADTS header at offset %d\n", i-2);
110 break;
111 }
112
113 syncword = (syncword << 8) | peak[i];
114 }
115
116 /* did we really find the ADTS header? */
117 if (i == MAX_PREVIEW_SIZE)
118 return 0; /* No, we didn't */
119
120 /* Look for second ADTS header to confirm it's really aac */
121 if (data_start + 5 < MAX_PREVIEW_SIZE) {
122 int frame_size = ((peak[data_start+3] & 0x03) << 11) |
123 (peak[data_start+4] << 3) |
124 ((peak[data_start+5] & 0xe0) >> 5);
125
126 lprintf("first frame size %d\n", frame_size);
127
128 if ((frame_size > 0) &&
129 (data_start+frame_size < MAX_PREVIEW_SIZE-1) &&
130 /* first 28 bits must be identical */
131 memcmp(&peak[data_start], &peak[data_start+frame_size], 4) == 0 &&
132 (peak[data_start+3]>>4==peak[data_start+frame_size+3]>>4))
133 {
134 lprintf("found second ADTS header\n");
135
136 if (input->seek(input, data_start+id3size, SEEK_SET) < 0)
137 return 0;
138 return 1;
139 }
140 }
141
142 return 0;
143 }
144
demux_aac_send_chunk(demux_plugin_t * this_gen)145 static int demux_aac_send_chunk(demux_plugin_t *this_gen) {
146 demux_aac_t *this = (demux_aac_t *) this_gen;
147 int bytes_read;
148 off_t current_pos, length;
149 uint32_t bitrate;
150
151 buf_element_t *buf = NULL;
152
153 /* just load an entire buffer from wherever the audio happens to be */
154 buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
155 buf->type = BUF_AUDIO_AAC;
156 buf->pts = 0;
157
158 length = this->input->get_length(this->input);
159 current_pos = this->input->get_current_pos(this->input);
160 bitrate = _x_stream_info_get(this->stream, XINE_STREAM_INFO_AUDIO_BITRATE);
161
162 if (length)
163 buf->extra_info->input_normpos = (int)((double) current_pos * 65535/length);
164
165 if (bitrate)
166 buf->extra_info->input_time = (8*current_pos) / (bitrate/1000);
167
168 bytes_read = this->input->read(this->input, buf->content, buf->max_size);
169 if (bytes_read <= 0) {
170 buf->free_buffer(buf);
171 this->status = DEMUX_FINISHED;
172 return this->status;
173 } else
174 buf->size = bytes_read;
175
176 /* each buffer stands on its own */
177 buf->decoder_flags |= BUF_FLAG_FRAME_END;
178
179 this->audio_fifo->put (this->audio_fifo, buf);
180
181 return this->status;
182 }
183
demux_aac_send_headers(demux_plugin_t * this_gen)184 static void demux_aac_send_headers(demux_plugin_t *this_gen) {
185 demux_aac_t *this = (demux_aac_t *) this_gen;
186 buf_element_t *buf;
187
188 this->audio_fifo = this->stream->audio_fifo;
189
190 this->status = DEMUX_OK;
191
192 /* send start buffers */
193 _x_demux_control_start(this->stream);
194
195 /* send init info to decoders */
196 if (this->audio_fifo) {
197 buf = this->audio_fifo->buffer_pool_alloc (this->audio_fifo);
198 buf->type = BUF_AUDIO_AAC;
199 buf->decoder_flags = BUF_FLAG_HEADER|BUF_FLAG_FRAME_END;
200 buf->content = NULL;
201 buf->size = 0;
202 this->audio_fifo->put (this->audio_fifo, buf);
203 }
204 }
205
demux_aac_seek(demux_plugin_t * this_gen,off_t start_pos,int start_time,int playing)206 static int demux_aac_seek (demux_plugin_t *this_gen,
207 off_t start_pos, int start_time, int playing) {
208 demux_aac_t *this = (demux_aac_t *) this_gen;
209
210 (void)start_pos;
211 (void)start_time;
212 /* if thread is not running, initialize demuxer */
213 if( !playing ) {
214
215 /* send new pts */
216 _x_demux_control_newpts(this->stream, 0, 0);
217
218 this->status = DEMUX_OK;
219 }
220
221 return this->status;
222 }
223
demux_aac_get_status(demux_plugin_t * this_gen)224 static int demux_aac_get_status (demux_plugin_t *this_gen) {
225 demux_aac_t *this = (demux_aac_t *) this_gen;
226
227 return this->status;
228 }
229
demux_aac_get_stream_length(demux_plugin_t * this_gen)230 static int demux_aac_get_stream_length (demux_plugin_t *this_gen) {
231 // demux_aac_t *this = (demux_aac_t *) this_gen;
232
233 (void)this_gen;
234 return 0;
235 }
236
demux_aac_get_capabilities(demux_plugin_t * this_gen)237 static uint32_t demux_aac_get_capabilities(demux_plugin_t *this_gen) {
238 (void)this_gen;
239 return DEMUX_CAP_NOCAP;
240 }
241
demux_aac_get_optional_data(demux_plugin_t * this_gen,void * data,int data_type)242 static int demux_aac_get_optional_data(demux_plugin_t *this_gen,
243 void *data, int data_type) {
244 (void)this_gen;
245 (void)data;
246 (void)data_type;
247 return DEMUX_OPTIONAL_UNSUPPORTED;
248 }
249
open_plugin(demux_class_t * class_gen,xine_stream_t * stream,input_plugin_t * input)250 static demux_plugin_t *open_plugin (demux_class_t *class_gen, xine_stream_t *stream,
251 input_plugin_t *input) {
252
253 demux_aac_t *this;
254
255 switch (stream->content_detection_method) {
256 case METHOD_BY_MRL:
257 case METHOD_BY_CONTENT:
258 case METHOD_EXPLICIT:
259 if (!probe_aac_file(stream, input))
260 return NULL;
261 break;
262 default:
263 return NULL;
264 }
265
266 this = calloc(1, sizeof(demux_aac_t));
267 if (!this)
268 return NULL;
269
270 this->stream = stream;
271 this->input = input;
272
273 this->demux_plugin.send_headers = demux_aac_send_headers;
274 this->demux_plugin.send_chunk = demux_aac_send_chunk;
275 this->demux_plugin.seek = demux_aac_seek;
276 this->demux_plugin.dispose = default_demux_plugin_dispose;
277 this->demux_plugin.get_status = demux_aac_get_status;
278 this->demux_plugin.get_stream_length = demux_aac_get_stream_length;
279 this->demux_plugin.get_capabilities = demux_aac_get_capabilities;
280 this->demux_plugin.get_optional_data = demux_aac_get_optional_data;
281 this->demux_plugin.demux_class = class_gen;
282
283 this->status = DEMUX_FINISHED;
284
285 _x_stream_info_set(stream, XINE_STREAM_INFO_HAS_VIDEO, 0);
286 _x_stream_info_set(stream, XINE_STREAM_INFO_HAS_AUDIO, 1);
287
288 return &this->demux_plugin;
289 }
290
demux_aac_init_plugin(xine_t * xine,const void * data)291 void *demux_aac_init_plugin (xine_t *xine, const void *data) {
292
293 (void)xine;
294 (void)data;
295
296 static const demux_class_t demux_aac_class = {
297 .open_plugin = open_plugin,
298 .description = N_("ADIF/ADTS AAC demux plugin"),
299 .identifier = "AAC",
300 .mimetypes = NULL,
301 .extensions = "aac",
302 .dispose = NULL,
303 };
304
305 return (void*)&demux_aac_class;
306 }
307
308