1 /*
2  *  ac3strm_in.c: AC3 Audio strem class members handling scanning and
3  *  buffering raw input stream.
4  *
5  *  Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com>
6  *  Copyright (C) 2000,2001 Brent Byeler for original header-structure
7  *                          parsing code.
8  *
9  *
10  *  This program is free software; you can redistribute it and/or
11  *  modify it under the terms of version 2 of the GNU General Public License
12  *  as published by the Free Software Foundation.
13  *
14  *  This program is distributed in the hope that it will be useful,
15  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  *  GNU General Public License for more details.
18  *
19  *  You should have received a copy of the GNU General Public License
20  *  along with this program; if not, write to the Free Software
21  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
22  */
23 
24 #include <config.h>
25 #include <math.h>
26 #include <stdlib.h>
27 
28 #include "audiostrm.hpp"
29 #include "interact.hpp"
30 #include "multiplexor.hpp"
31 
32 //#define DEBUG_AC3_HEADERS
33 #define AC3_SYNCWORD            0x0b77
34 #define AC3_PACKET_SAMPLES      1536
35 
36 const unsigned int AC3Stream::default_buffer_size = 16*1024;
37 
38 /// table for the available AC3 bitrates
39 static const unsigned int ac3_bitrate_index[32] =
40 { 32,40,48,56,64,80,96,112,128,160,192,
41   224,256,320,384,448,512,576,640,
42   0,0,0,0,0,0,0,0,0,0,0,0,0
43 };
44 
45 static const unsigned int ac3_frame_size[3][32] =
46 {
47     { 64,80,96,112,128,160,192,224,256,320,384,
48       448,512,640,768,896,1024, 1152,1280,
49       0,0,0,0,0,0,0,0,0,0,0,0,0
50     },
51     { 69,87,104,121,139,174,208,243,278,348,417,
52       487,557,696,835,975,1114, 1253,1393,
53           0,0,0,0,0,0,0,0,0,0,0,0,0
54     },
55     { 96,120,144,168,192,240,288,336,384,480,576,
56       672,768,960,1152,1344, 1536,1728,1920,
57       0,0,0,0,0,0,0,0,0,0,0,0,0
58     }
59 };
60 
61 /// table for the available AC3 frequencies
62 static const unsigned int ac3_frequency[4] =
63 { 48000, 44100, 32000, 0};
64 
65 
AC3Stream(IBitStream & ibs,Multiplexor & into)66 AC3Stream::AC3Stream(IBitStream &ibs, Multiplexor &into) :
67 	AudioStream( ibs, into )
68 {
69 num_frames = 0;
70 }
71 
Probe(IBitStream & bs)72 bool AC3Stream::Probe(IBitStream &bs )
73 {
74     return bs.GetBits(16) == AC3_SYNCWORD;
75 }
76 
77 
78 /*************************************************************************
79  *
80  * Reads initial stream parameters and displays feedback banner to users
81  * @param stream_num AC3 substream ID
82  *************************************************************************/
83 
84 
DisplayAc3HeaderInfo()85 void  AC3Stream::DisplayAc3HeaderInfo()
86 {
87         /* Some stuff to generate frame-header information */
88         printf( "bsid         = %d\n", bs.GetBits(5) );
89         printf( "bsmode       = 0x%1x\n", bs.GetBits(3) );
90         int acmode = bs.GetBits(3);
91         int nfchans = 0;
92         switch( acmode )
93         {
94         case 0x0 :
95             nfchans = 2; break;
96         case 0x1 :
97             nfchans = 1; break;
98         case 0x2 :
99             nfchans = 2; break;
100         case 0x3 :
101         case 0x4 :
102             nfchans = 3; break;
103         case 0x5 :
104         case 0x6 :
105             nfchans = 4; break;
106         case 0x7 :
107             nfchans = 5; break;
108         }
109         printf( "acmode       = 0x%1x (%d channels)\n", acmode, nfchans );
110         if( (acmode & 0x1) && (acmode != 1 ) )
111             printf( "cmixlev  = %d\n", bs.GetBits(2) );
112         if( (acmode & 0x4) )
113             printf( "smixlev  = %d\n", bs.GetBits(2) );
114         if( acmode == 2 )
115             printf( "dsurr    = %d\n", bs.GetBits(2) );
116         printf( "lfeon        = %d\n", bs.GetBits(1) );
117         printf( "dialnorm     = %02d\n", bs.GetBits(5) );
118         int compre = bs.GetBits(1);
119         printf( "compre       = %d\n", compre );
120         if( compre )
121             printf( "compr    = %02d\n", bs.GetBits(8) );
122         int langcode = bs.GetBits(1);
123         printf( "langcode     = %d\n", langcode );
124         if( langcode )
125             printf( "langcod  = 0x%02x\n", bs.GetBits(8) );
126         int audprodie =  bs.GetBits(1);
127         printf( "audprodie    = %d\n", audprodie );
128         if( audprodie )
129         {
130             printf( "mixlevel = 0x%02x\n", bs.GetBits(5) );
131             printf( "roomtyp  = 0x%02x\n", bs.GetBits(2) );
132         }
133         if( acmode == 0 )
134         {
135             printf( "Skipping 1+1 mode parameters\n" );
136             bs.GetBits(5+1+8+1+8);
137             if( bs.GetBits(1) )
138                 bs.GetBits(7);
139         }
140         printf( "Copyright  = %d\n", bs.GetBits(1) );
141         printf( "Original   = %d\n", bs.GetBits(1) );
142         int timecod1e = bs.GetBits(1);
143         if( timecod1e )
144         {
145             printf( "timecod1 = 0x%03x\n", bs.GetBits(14) );
146         }
147         int timecod2e = bs.GetBits(1);
148         if( timecod2e )
149         {
150             printf( "timecod2 = 0x%03x\n", bs.GetBits(14) );
151         }
152         int addbsie = bs.GetBits(1);
153         if( addbsie )
154         {
155             printf( "addbsil  = %02x\n", bs.GetBits(6) );
156         }
157 
158 
159         // FROM This point on we're actually right into the actual audio block
160         printf( "Audio block header...\n" );
161         printf( "blksw  [ch] = %02x\n", bs.GetBits(nfchans) );
162         printf( "dithflg[ch] = %02x\n", bs.GetBits(nfchans) );
163         int dynrnge = bs.GetBits(1);
164         printf( "Dynrange    = %d\n", bs.GetBits(1) );
165         if( dynrnge )
166         {
167             printf( "dynrng    = %02x\n", bs.GetBits(8) );
168         }
169         if( acmode == 0 && bs.GetBits(1) )
170         {
171             printf( "dynrng2   = %02x\n", bs.GetBits(8) );
172         }
173         int cplstre = bs.GetBits(1);
174         printf( "cplstre     = %d\n", cplstre );
175         int cplinu = 0;
176         if( cplstre )
177         {
178             cplinu = bs.GetBits(1);
179             printf( "cplinu    = %d\n", cplinu );
180             if( cplinu )
181             {
182                 printf( "Skipping cplinu=1 info...\n");
183                 bs.GetBits(nfchans);
184                 if( acmode == 2 )
185                     bs.GetBits(1);
186                 int cplbegf = bs.GetBits(4);
187                 int cplendf = bs.GetBits(4);
188                 bs.GetBits(3+cplbegf-cplendf);
189             }
190         }
191         if( cplinu )
192         {
193             printf( "Warning: no parser for coupling co-ordinates mess\n");
194             return;
195         }
196 
197         if( acmode == 2 )
198         {
199             int rmatstr = bs.GetBits(1);
200             printf( "rmatstr = %d\n", rmatstr );
201             printf( "Warning: no parser for rematrixing...\n" );
202         }
203 
204 
205 }
206 
Init(const int _stream_num)207 void AC3Stream::Init ( const int _stream_num)
208 
209 {
210     unsigned int framesize_code;
211     stream_num = _stream_num;
212 	MuxStream::Init( PRIVATE_STR_1,
213 					 1,  // Buffer scale
214 					 default_buffer_size,
215 					 false,
216 					 muxinto.buffers_in_audio,
217 					 muxinto.always_buffers_in_audio
218 		);
219     mjpeg_info ("Scanning for header info: AC3 Audio stream %02x (%s)",
220                 stream_num,
221                 bs.StreamName()
222                 );
223 
224 	AU_start = bs.bitcount();
225     if (bs.GetBits(16)==AC3_SYNCWORD)
226     {
227 		num_syncword++;
228         bs.GetBits(16);         // CRC field
229         frequency = bs.GetBits(2);  // Sample rate code
230         framesize_code = bs.GetBits(6); // Frame size code
231         framesize = ac3_frame_size[frequency][framesize_code>>1];
232         framesize =
233             (framesize_code&1) && frequency == 1 ?
234             (framesize + 1) << 1:
235             (framesize <<1);
236 
237         header_skip = 5;        // Initially skipped past  5 bytes of header
238 
239 	num_frames++;
240         access_unit.start = AU_start;
241 	access_unit.length = framesize;
242         mjpeg_info( "AC3 frame size = %d", framesize );
243         bit_rate = ac3_bitrate_index[framesize_code>>1];
244 		samples_per_second = ac3_frequency[frequency];
245 
246 		/* Presentation time-stamping  */
247 		access_unit.PTS = static_cast<clockticks>(decoding_order) *
248 			static_cast<clockticks>(AC3_PACKET_SAMPLES) *
249 			static_cast<clockticks>(CLOCKS)	/ samples_per_second;
250 		access_unit.DTS = access_unit.PTS;
251 		access_unit.dorder = decoding_order;
252 		++decoding_order;
253 		aunits.Append( access_unit );
254 
255     } else
256     {
257 		mjpeg_error ( "Invalid AC3 Audio stream header.");
258 		exit (1);
259     }
260 
261 
262 	OutputHdrInfo();
263 }
264 
265 /// @returns the current bitrate
NominalBitRate()266 unsigned int AC3Stream::NominalBitRate()
267 {
268 	return bit_rate*1024;
269 }
270 
271 /// Prefills the internal buffer for output multiplexing.
272 /// @param frames_to_buffer the number of audio frames to read ahead
FillAUbuffer(unsigned int frames_to_buffer)273 void AC3Stream::FillAUbuffer(unsigned int frames_to_buffer )
274 {
275 	unsigned int framesize_code;
276 
277 	last_buffered_AU += frames_to_buffer;
278 	mjpeg_debug( "Scanning %d AC3 audio frames to frame %d",
279 				 frames_to_buffer, last_buffered_AU );
280 
281     int skip;
282 	while( !bs.eos()
283            && decoding_order < last_buffered_AU
284            && !muxinto.AfterMaxPTS(access_unit.PTS)
285         )
286 	{
287 		skip=access_unit.length-header_skip;
288         bs.SeekFwdBits(skip);
289 		prev_offset = AU_start;
290 		AU_start = bs.bitcount();
291         if( AU_start - prev_offset != access_unit.length*8 )
292         {
293             mjpeg_warn( "Discarding incomplete final frame AC3 stream %d!",
294                        stream_num);
295             aunits.DropLast();
296             --decoding_order;
297             break;
298         }
299 
300 		/* Check we have reached the end of have  another catenated
301 		   stream to process before finishing ... */
302 		if ( (syncword = bs.GetBits(16))!=AC3_SYNCWORD )
303 		{
304 			if( !bs.eos()   )
305 			{
306 				mjpeg_error_exit1( "Can't find next AC3 frame: @ %lld we have %04x - broken bit-stream?", AU_start/8, syncword );
307             }
308             break;
309 		}
310 
311         bs.GetBits(16);         // CRC field
312         bs.GetBits(2);          // Sample rate code TOOD: check for change!
313         framesize_code = bs.GetBits(6);
314         framesize = ac3_frame_size[frequency][framesize_code>>1];
315         framesize =
316             (framesize_code&1) && frequency == 1 ?
317             (framesize + 1) << 1:
318             (framesize <<1);
319 		access_unit.start = AU_start;
320 		access_unit.length = framesize;
321 		access_unit.PTS = static_cast<clockticks>(decoding_order) *
322 			static_cast<clockticks>(AC3_PACKET_SAMPLES) *
323 			static_cast<clockticks>(CLOCKS)	/ samples_per_second;;
324 		access_unit.DTS = access_unit.PTS;
325 		access_unit.dorder = decoding_order;
326 		decoding_order++;
327 		aunits.Append( access_unit );
328 		num_frames++;
329 
330 		num_syncword++;
331 
332 		if (num_syncword >= old_frames+10 )
333 		{
334 			mjpeg_debug ("Got %d frame headers.", num_syncword);
335 			old_frames=num_syncword;
336 		}
337 
338     }
339 	last_buffered_AU = decoding_order;
340 	eoscan = bs.eos() || muxinto.AfterMaxPTS(access_unit.PTS);
341 }
342 
343 
344 /// Closes the AC3 stream and prints some statistics.
Close()345 void AC3Stream::Close()
346 {
347     stream_length = AU_start >> 3;
348 	mjpeg_info ("AUDIO_STATISTICS: %02x", stream_id);
349     mjpeg_info ("Audio stream length %lld bytes.", stream_length);
350     mjpeg_info   ("Frames         : %8u",  num_frames);
351 }
352 
353 /*************************************************************************
354 	OutputAudioInfo
355 	gibt gesammelte Informationen zu den Audio Access Units aus.
356 
357 	Prints information on audio access units
358 *************************************************************************/
359 
OutputHdrInfo()360 void AC3Stream::OutputHdrInfo ()
361 {
362 	mjpeg_info("AC3 AUDIO STREAM:");
363 
364     mjpeg_info ("Bit rate       : %8u bytes/sec (%3u kbit/sec)",
365 				bit_rate*128, bit_rate);
366 
367     if (frequency == 3)
368 		mjpeg_info ("Frequency      : reserved");
369     else
370 		mjpeg_info ("Frequency      :     %d Hz",
371 				ac3_frequency[frequency]);
372 
373 }
374 
375 /**
376 Reads the bytes neccessary to complete the current packet payload.
377 @param to_read number of bytes to read
378 @param dst byte buffer pointer to read to
379 @returns the number of bytes read
380  */
381 unsigned int
ReadPacketPayload(uint8_t * dst,unsigned int to_read)382 AC3Stream::ReadPacketPayload(uint8_t *dst, unsigned int to_read)
383 {
384     bitcount_t read_start = bs.GetBytePos();
385     // Remember to change StreamHeaderLen if you write a different
386     // length re-using this code...
387     unsigned int bytes_read = bs.GetBytes( dst+4, to_read-4 );
388     assert( bytes_read > 0 );   // Should never try to read nothing
389     bs.Flush( read_start );
390 	clockticks   decode_time;
391 
392     unsigned int first_header =
393         (new_au_next_sec || au_unsent > bytes_read )
394         ? 0
395         : au_unsent;
396 
397     // BUG BUG BUG: how do we set the 1st header pointer if we have
398     // the *middle* part of a large frame?
399     assert( first_header+2 <= to_read );
400 
401     unsigned int syncwords = 0;
402     unsigned int bytes_muxed = bytes_read;
403 
404 	if (bytes_muxed == 0 || MuxCompleted() )
405     {
406 		goto completion;
407     }
408 
409 
410 	/* Work through what's left of the current AU and the following AU's
411 	   updating the info until we reach a point where an AU had to be
412 	   split between packets.
413 	   NOTE: It *is* possible for this loop to iterate.
414 
415 	   The DTS/PTS field for the packet in this case would have been
416 	   given the that for the first AU to start in the packet.
417 
418 	*/
419 
420 	decode_time = RequiredDTS();
421 	while (au_unsent < bytes_muxed)
422 	{
423         // BUG BUG BUG: if we ever had odd payload / packet size we might
424         // split an AC3 frame in the middle of the syncword!
425         assert( bytes_muxed > 1 );
426 		bufmodel.Queued(au_unsent, decode_time);
427 		bytes_muxed -= au_unsent;
428         if( new_au_next_sec )
429             ++syncwords;
430 		if( !NextAU() )
431         {
432             goto completion;
433         }
434 		new_au_next_sec = true;
435 		decode_time = RequiredDTS();
436 	};
437 
438 	// We've now reached a point where the current AU overran or
439 	// fitted exactly.  We need to distinguish the latter case
440 	// so we can record whether the next packet starts with an
441 	// existing AU or not - info we need to decide what PTS/DTS
442 	// info to write at the start of the next packet.
443 
444 	if (au_unsent > bytes_muxed)
445 	{
446         if( new_au_next_sec )
447             ++syncwords;
448 		bufmodel.Queued( bytes_muxed, decode_time);
449 		au_unsent -= bytes_muxed;
450 		new_au_next_sec = false;
451 	}
452 	else //  if (au_unsent == bytes_muxed)
453 	{
454 		bufmodel.Queued(bytes_muxed, decode_time);
455         if( new_au_next_sec )
456             ++syncwords;
457         new_au_next_sec = NextAU();
458 	}
459 completion:
460     // Generate the AC3 header...
461     // Note the index counts from the low byte of the offset so
462     // the smallest value is 1!
463     dst[0] = AC3_SUB_STR_0 + stream_num;
464     dst[1] = syncwords;
465     dst[2] = (first_header+1)>>8;
466     dst[3] = (first_header+1)&0xff;
467 	return bytes_read+4;
468 }
469 
470 
471 
472 /*
473  * Local variables:
474  *  c-file-style: "stroustrup"
475  *  tab-width: 4
476  *  indent-tabs-mode: nil
477  * End:
478  */
479