1/*
2Copyright (c) 2012, Broadcom Europe Ltd
3All rights reserved.
4
5Redistribution and use in source and binary forms, with or without
6modification, are permitted provided that the following conditions are met:
7 * Redistributions of source code must retain the above copyright
8 notice, this list of conditions and the following disclaimer.
9 * Redistributions in binary form must reproduce the above copyright
10 notice, this list of conditions and the following disclaimer in the
11 documentation and/or other materials provided with the distribution.
12 * Neither the name of the copyright holder nor the
13 names of its contributors may be used to endorse or promote products
14 derived from this software without specific prior written permission.
15
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
17ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
20DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26*/
27
28/** \file
29 * Implementation of an MPEG1/2/2.5 audio Layer I/II/III and AAC ADTS packetizer.
30 */
31
32#include <stdlib.h>
33#include <string.h>
34
35#include "containers/packetizers.h"
36#include "containers/core/packetizers_private.h"
37#include "containers/core/containers_common.h"
38#include "containers/core/containers_logging.h"
39#include "containers/core/containers_time.h"
40#include "containers/core/containers_utils.h"
41#include "containers/core/containers_bytestream.h"
42#include "mpga_common.h"
43
44#define MAX_FRAME_SIZE 2881 /* MPEG 2.5 Layer II, 8000 Hz, 160 kbps */
45
46VC_CONTAINER_STATUS_T mpga_packetizer_open( VC_PACKETIZER_T * );
47
48/*****************************************************************************/
49typedef struct VC_PACKETIZER_MODULE_T {
50 enum {
51 STATE_SYNC = 0,
52 STATE_SYNC_LOST,
53 STATE_SYNC_NEXT,
54 STATE_SYNC_DONE,
55 STATE_HEADER,
56 STATE_DATA,
57 } state;
58
59 VC_CONTAINER_STATUS_T (*pf_read_header)( uint8_t frame_header[MPGA_HEADER_SIZE],
60 uint32_t *p_frame_size, unsigned int *p_frame_bitrate, unsigned int *p_version,
61 unsigned int *p_layer, unsigned int *p_sample_rate, unsigned int *p_channels,
62 unsigned int *p_frame_size_samples, unsigned int *p_offset);
63
64 uint32_t frame_size;
65 unsigned int frame_bitrate;
66 unsigned int version;
67 unsigned int layer;
68 unsigned int sample_rate;
69 unsigned int channels;
70 unsigned int frame_size_samples;
71 unsigned int offset;
72
73 unsigned int lost_sync;
74
75 unsigned int stream_version;
76 unsigned int stream_layer;
77
78 uint32_t bytes_read;
79
80} VC_PACKETIZER_MODULE_T;
81
82/*****************************************************************************/
83static VC_CONTAINER_STATUS_T mpga_packetizer_close( VC_PACKETIZER_T *p_ctx )
84{
85 free(p_ctx->priv->module);
86 return VC_CONTAINER_SUCCESS;
87}
88
89/*****************************************************************************/
90static VC_CONTAINER_STATUS_T mpga_packetizer_reset( VC_PACKETIZER_T *p_ctx )
91{
92 VC_PACKETIZER_MODULE_T *module = p_ctx->priv->module;
93 module->lost_sync = 0;
94 module->state = STATE_SYNC;
95 return VC_CONTAINER_SUCCESS;
96}
97
98/*****************************************************************************/
99static VC_CONTAINER_STATUS_T mpga_packetizer_packetize( VC_PACKETIZER_T *p_ctx,
100 VC_CONTAINER_PACKET_T *out, VC_PACKETIZER_FLAGS_T flags )
101{
102 VC_PACKETIZER_MODULE_T *module = p_ctx->priv->module;
103 VC_CONTAINER_BYTESTREAM_T *stream = &p_ctx->priv->stream;
104 VC_CONTAINER_TIME_T *time = &p_ctx->priv->time;
105 uint8_t header[MPGA_HEADER_SIZE];
106 VC_CONTAINER_STATUS_T status;
107 unsigned int version, layer;
108 int64_t pts, dts;
109
110 while(1) switch (module->state)
111 {
112 case STATE_SYNC_LOST:
113 bytestream_skip_byte( stream );
114 if( !module->lost_sync++ )
115 LOG_DEBUG(0, "lost sync");
116 module->state = STATE_SYNC;
117
118 case STATE_SYNC:
119 while( bytestream_peek( stream, header, 2 ) == VC_CONTAINER_SUCCESS )
120 {
121 /* 11 bits sync work (0xffe) */
122 if( header[0] == 0xff && (header[1] & 0xe0) == 0xe0 )
123 {
124 module->state = STATE_HEADER;
125 break;
126 }
127 bytestream_skip_byte( stream );
128 module->lost_sync++;
129 }
130 if( module->state != STATE_HEADER )
131 return VC_CONTAINER_ERROR_INCOMPLETE_DATA; /* We need more data */
132
133 case STATE_HEADER:
134 if( bytestream_peek( stream, header, MPGA_HEADER_SIZE ) != VC_CONTAINER_SUCCESS )
135 return VC_CONTAINER_ERROR_INCOMPLETE_DATA;
136
137 status = mpga_read_header( header,
138 &module->frame_size, &module->frame_bitrate, &module->version,
139 &module->layer, &module->sample_rate, &module->channels,
140 &module->frame_size_samples, &module->offset );
141 if (status != VC_CONTAINER_SUCCESS)
142 {
143 LOG_ERROR(0, "invalid header");
144 module->state = STATE_SYNC_LOST;
145 break;
146 }
147
148 /* Version and layer are not allowed to change mid-stream */
149 if ((module->stream_version && module->stream_version != module->version) ||
150 (module->stream_layer && module->stream_layer != module->layer))
151 {
152 LOG_ERROR(0, "invalid header");
153 module->state = STATE_SYNC_LOST;
154 break;
155 }
156 /* We currently do not support free format streams */
157 if (!module->frame_size)
158 {
159 LOG_ERROR(0, "free format not supported");
160 module->state = STATE_SYNC_LOST;
161 break;
162 }
163 module->state = STATE_SYNC_NEXT;
164 /* fall through to the next state */
165
166 case STATE_SYNC_NEXT:
167 /* To avoid being caught by emulated start codes, we also look at where the next frame is supposed to be */
168 if( bytestream_peek_at( stream, module->frame_size, header, MPGA_HEADER_SIZE ) != VC_CONTAINER_SUCCESS )
169 {
170 /* If we know there won't be anymore data then we can just assume
171 * we've got the frame we're looking for */
172 if (flags & VC_PACKETIZER_FLAG_FLUSH)
173 {
174 module->state = STATE_SYNC_DONE;
175 break;
176 }
177 return VC_CONTAINER_ERROR_INCOMPLETE_DATA;
178 }
179
180 status = mpga_read_header( header, 0, 0, &version, &layer, 0, 0, 0, 0 );
181 if (status != VC_CONTAINER_SUCCESS)
182 {
183 LOG_ERROR(0, "invalid next header");
184 module->state = STATE_SYNC_LOST;
185 break;
186 }
187
188 /* Version and layer are not allowed to change mid-stream */
189 if (module->version != version || module->layer != layer)
190 {
191 LOG_ERROR(0, "invalid header");
192 module->state = STATE_SYNC_LOST;
193 break;
194 }
195
196 module->state = STATE_SYNC_DONE;
197 /* fall through to the next state */
198
199 case STATE_SYNC_DONE:
200 if( module->lost_sync )
201 LOG_DEBUG(0, "recovered sync after %i bytes", module->lost_sync);
202 module->lost_sync = 0;
203
204 bytestream_skip( stream, module->offset );
205 module->stream_version = module->version;
206 module->stream_layer = module->layer;
207
208 vc_container_time_set_samplerate(time, module->sample_rate, 1);
209 bytestream_get_timestamps(stream, &pts, &dts, true);
210
211 vc_container_time_set(time, pts);
212
213 module->bytes_read = 0;
214 module->state = STATE_DATA;
215 /* fall through to the next state */
216
217 case STATE_DATA:
218 if( bytestream_size( stream ) < module->frame_size)
219 return VC_CONTAINER_ERROR_INCOMPLETE_DATA;
220
221 out->size = module->frame_size - module->bytes_read;
222 out->pts = out->dts = VC_CONTAINER_TIME_UNKNOWN;
223 out->flags = VC_CONTAINER_PACKET_FLAG_FRAME_END;
224
225 if(!module->bytes_read)
226 {
227 out->pts = out->dts = vc_container_time_get(time);
228 out->flags |= VC_CONTAINER_PACKET_FLAG_FRAME_START;
229 }
230
231 if(flags & VC_PACKETIZER_FLAG_INFO)
232 return VC_CONTAINER_SUCCESS;
233
234 if(flags & VC_PACKETIZER_FLAG_SKIP)
235 {
236 bytestream_skip( stream, out->size );
237 }
238 else
239 {
240 out->size = MIN(out->size, out->buffer_size);
241 bytestream_get( stream, out->data, out->size );
242 }
243 module->bytes_read += out->size;
244
245 if(module->bytes_read == module->frame_size)
246 {
247 vc_container_time_add(time, module->frame_size_samples);
248 module->state = STATE_HEADER;
249 }
250 return VC_CONTAINER_SUCCESS;
251
252 default:
253 break;
254 };
255
256 return VC_CONTAINER_SUCCESS;
257}
258
259/*****************************************************************************/
260VC_CONTAINER_STATUS_T mpga_packetizer_open( VC_PACKETIZER_T *p_ctx )
261{
262 VC_PACKETIZER_MODULE_T *module;
263
264 if(p_ctx->in->codec != VC_CONTAINER_CODEC_MPGA &&
265 p_ctx->in->codec != VC_CONTAINER_CODEC_MP4A)
266 return VC_CONTAINER_ERROR_FORMAT_NOT_SUPPORTED;
267
268 p_ctx->priv->module = module = malloc(sizeof(*module));
269 if(!module)
270 return VC_CONTAINER_ERROR_OUT_OF_MEMORY;
271 memset(module, 0, sizeof(*module));
272
273 if(p_ctx->in->codec == VC_CONTAINER_CODEC_MPGA)
274 module->pf_read_header = mpga_read_header;
275 else
276 module->pf_read_header = adts_read_header;
277
278 vc_container_format_copy( p_ctx->out, p_ctx->in, 0);
279 p_ctx->max_frame_size = MAX_FRAME_SIZE;
280 p_ctx->priv->pf_close = mpga_packetizer_close;
281 p_ctx->priv->pf_packetize = mpga_packetizer_packetize;
282 p_ctx->priv->pf_reset = mpga_packetizer_reset;
283 LOG_DEBUG(0, "using mpeg audio packetizer");
284 return VC_CONTAINER_SUCCESS;
285}
286
287/*****************************************************************************/
288VC_PACKETIZER_REGISTER(mpga_packetizer_open, "mpga");
289