Docjar: A Java Source and Docuemnt Enginecom.*    java.*    javax.*    org.*    all    new    plug-in

Quick Search    Search Deep

Source code: org/esau/ptarmigan/impl/MPEGFrameHeader.java


1   /* $Header: /cvsroot/ptarmigan/ptarmigan/src/java/org/esau/ptarmigan/impl/MPEGFrameHeader.java,v 1.2 2002/10/02 05:27:03 reedesau Exp $ */
2   
3   package org.esau.ptarmigan.impl;
4   
5   import org.apache.commons.logging.Log;
6   import org.apache.commons.logging.LogFactory;
7   
8   /**
9    * MPEG Frame Header
10   * <p>
11   * Parse and validate a 4-byte MPEG Header
12   * <p>
13   * @author Reed Esau
14   * @version $Revision: 1.2 $ $Date: 2002/10/02 05:27:03 $
15   */
16  public final class MPEGFrameHeader {
17  
18      /** ctor */
19      public MPEGFrameHeader() {
20          resetData();
21      }
22  
23      /** copy ctor */
24      public MPEGFrameHeader(MPEGFrameHeader other) {
25          m_audio_ver      = other.m_audio_ver    ;
26          m_layer_code     = other.m_layer_code   ;
27          m_protection     = other.m_protection   ;
28          m_bitrate_index  = other.m_bitrate_index;
29          m_sample_index   = other.m_sample_index ;
30          m_padding        = other.m_padding      ;
31          m_private_bit    = other.m_private_bit  ;
32          m_channel_mode   = other.m_channel_mode ;
33          m_mode_ext       = other.m_mode_ext     ;
34          m_copyright      = other.m_copyright    ;
35          m_original       = other.m_original     ;
36          m_emphasis       = other.m_emphasis     ;
37  
38          m_bit_rate       = other.m_bit_rate     ;
39          m_sample_rate    = other.m_sample_rate  ;
40          m_frame_length   = other.m_frame_length ;
41      }
42  
43      /**
44       * Try to identify a frame header in the specified buffer at the
45       * specified offset.
46       *
47       * Note that it's not definitive.  You have to look for repeating MPEG
48       * frames and check CRCs to make sure.
49       *
50       * AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
51       *
52       * @return false if not a valid frame header; true if it may be (but not definitive)
53       */
54      public boolean initHeader(byte[] buf, int offset) {
55  
56          resetData();
57  
58          int dw = ((buf[offset+0] & 0xFF) << 24) +
59                   ((buf[offset+1] & 0xFF) << 16) +
60                   ((buf[offset+2] & 0xFF) << 8) +
61                   (buf[offset+3] & 0xFF);
62  
63          if ((dw & FRAME_SYNC_MASK) != FRAME_SYNC_MASK)
64              return false;
65  
66          m_audio_ver = (dw & AUDIO_VER_MASK) >> AUDIO_VER_SHIFT;
67          // 00 - MPEG Version 2.5  (may not be official)
68          // 01 - reserved
69          // 10 - MPEG Version 2 (ISO/IEC 13818-3)
70          // 11 - MPEG Version 1 (ISO/IEC 11172-3)
71  
72          m_layer_code = (dw & LAYER_MASK) >> LAYER_SHIFT;
73          // 00 - reserved
74          // 01 - Layer III
75          // 10 - Layer II
76          // 11 - Layer I
77  
78          m_protection = ((dw & PROTECTION_MASK) == PROTECTION_MASK);
79          // 0 - Protected by CRC (16bit crc follows header)
80          // 1 - Not protected
81  
82          m_bitrate_index = (dw & BITRATE_MASK) >> BITRATE_SHIFT;
83          // used in a table lookup
84  
85          m_sample_index = (dw & SAMPLE_MASK) >> SAMPLE_SHIFT;
86          // used in a table lookup
87  
88          m_padding = ((dw & PADDING_MASK) == PADDING_MASK);
89          // 0 - frame is not padded
90          // 1 - frame is padded with one extra slot
91          // Padding is used to fit the bit rates exactly.  For an example: 128k
92          // 44.1kHz layer II uses a lot of 418 bytes and some of 417 bytes long frames
93          // to get the exact 128k bitrate.  For Layer I slot is 32 bits long, for
94          // Layer II and Layer III slot is 8 bits long.
95  
96          m_private_bit = ((dw & PRIVATE_MASK) == PRIVATE_MASK);
97          // used by application
98  
99          m_channel_mode = (dw & CHANNEL_MASK) >> CHANNEL_SHIFT;
100         // 00 - Stereo
101         // 01 - Joint stereo (Stereo)
102         // 10 - Dual channel (Stereo)
103         // 11 - Single channel (Mono)
104 
105         m_mode_ext = (dw & MODE_EXT_MASK) >> MODE_EXT_SHIFT;
106         //       LAYER I AND II    LAYER III
107         //                         INTENSITY  MS
108         // VALUE                   STEREO     STEREO
109         // 00    bands 4 to 31     off        off
110         // 01    bands 8 to 31     on         off
111         // 10    bands 12 to 31    off        on
112         // 11    bands 16 to 31    on         on
113 
114         m_copyright = ((dw & COPYRIGHT_MASK) == COPYRIGHT_MASK);
115         // 0 - Audio is not copyrighted
116         // 1 - Audio is copyrighted
117 
118         m_original  = ((dw & ORIGINAL_MASK) == ORIGINAL_MASK);
119         // 0 - Copy of original media
120         // 1 - Original media
121 
122         m_emphasis = (dw & EMPHASIS_MASK);     // no shift necessary
123         // 00 - none
124         // 01 - 50/15 ms
125         // 10 - reserved
126         // 11 - CCIT J.17
127 
128         return validate();
129     }
130 
131 
132 //
133 // gettors and settors
134 //
135 
136     public String getAudioVersion() {
137         if (0 <= m_audio_ver && m_audio_ver < S_AUDIO_VER.length)
138             return S_AUDIO_VER[m_audio_ver];
139         else
140             return null;
141     }
142     public int getLayer() {
143         if (0 <= m_layer_code && m_layer_code < S_LAYER.length)
144             return S_LAYER[m_layer_code];
145         else
146             return -1;
147     }
148     public boolean getProtection() {
149         return m_protection;
150     }
151     public boolean getPadding() {
152         return m_padding;
153     }
154     public boolean getPrivateBit() {
155         return m_private_bit;
156     }
157     public int getChannelMode() {
158         return m_channel_mode;
159     }
160     public int getModeExt() {
161         return m_mode_ext;
162     }
163 
164     public int getChannels() {
165         return m_channel_mode==CHANNEL_SINGLE ? 1 : 2;
166     }
167 
168     public String getChannelDesc() {
169         StringBuffer buf = new StringBuffer();
170 
171         buf.append(S_CHANNEL_MODE[m_channel_mode]);
172 
173         if (m_channel_mode == CHANNEL_JOINT_STEREO) {
174             switch (m_layer_code) {
175             case LAYER_I:
176             case LAYER_II:
177                 buf.append("-intensity-").append(S_MODE_EXT_LAYER_I_II[m_mode_ext]);
178                 break;
179             case LAYER_III:
180                 buf.append(S_MODE_EXT_LAYER_III[m_mode_ext]);
181                 break;
182             default:
183             }
184         }
185         return buf.toString();
186     }
187 
188     public boolean getCopyright() {
189         return m_copyright;
190     }
191     public boolean getOriginal() {
192         return m_original;
193     }
194     public int getEmphasis() {
195         return m_emphasis;
196     }
197 
198 //
199 // calculated fields
200 //
201 
202     public int getBitRate() {
203         return m_bit_rate;
204     }
205     public int getSampleRate() {
206         return m_sample_rate;
207     }
208     public int getFrameLength() {
209         return m_frame_length;
210     }
211 
212 //
213 // internal
214 //
215 
216     /**
217      * A number of tests to validate a single frame.  The results are
218      * not definitive.
219      *
220      * For best results, check consecutive frames and the CRC, if present.
221      */
222     boolean validate() {
223 
224         if (m_audio_ver == AUDIO_VER_RESERVED) {
225             log.debug("validate: audio version reserved found");
226             return false;
227         }
228 
229         if (m_layer_code == LAYER_RESERVED) {
230             log.debug("validate: layer reserved found");
231             return false;
232         }
233 
234         if (lookupBitRate() == false) {
235             log.debug("validate: invalid bit rate");
236             return false;
237         }
238 
239         //bitrate allowed modes
240         if (m_layer_code == LAYER_II) {
241             switch (m_bit_rate) {
242             case 32 :
243             case 48 :
244             case 56 :
245             case 80 :
246                 if (m_channel_mode != CHANNEL_SINGLE) {
247                     log.debug("validate: failure (bad channel mode for bitrate)");
248                     return false;
249                 }
250                 break;
251             case 224:
252             case 256:
253             case 320:
254             case 384:
255                 if (m_channel_mode != CHANNEL_STEREO
256                     && m_channel_mode != CHANNEL_JOINT_STEREO
257                     && m_channel_mode != CHANNEL_DUAL) {
258                     log.debug("validate: failure (bad channel mode for bitrate)");
259                     return false;
260                 }
261                 break;
262             default:
263             }
264         }
265 
266         if (lookupSampleRate() == false) {
267             log.debug("validate: invalid sample rate");
268             return false;
269         }
270 
271         if (calculateFrameLength() == false) {
272             log.debug("validate: failure (bad frame length)");
273             return false;
274         }
275 
276         return true;
277     }
278 
279 
280 //
281 // lookups and calculations
282 //
283 
284     /** bit rate in bits per second */
285     boolean lookupBitRate() {
286         if (m_bit_rate > 0)
287             return true;                 // already done
288 
289         //if (log.isDebugEnabled())
290         //    log.debug("lookupBitRate: m_audio_ver=" + m_audio_ver + " m_layer_code=" + m_layer_code);
291 
292         int index = -1;
293 
294         switch (m_audio_ver) {
295         case AUDIO_VER_VERSION_1:
296             switch (m_layer_code) {
297             case LAYER_I:
298                 index = 0;
299                 break;
300             case LAYER_II:
301                 index = 1;
302                 break;
303             case LAYER_III:
304                 index = 2;
305                 break;
306             default:
307             }
308             break;
309         case AUDIO_VER_VERSION_2:
310         case AUDIO_VER_VERSION_2_5:
311             switch (m_layer_code) {
312             case LAYER_I:
313                 index = 3;
314                 break;
315             case LAYER_II:
316             case LAYER_III:
317                 index = 4;
318                 break;
319             default:
320             }
321             break;
322         }
323 
324         //if (log.isDebugEnabled())
325         //    log.debug("lookupBitRate: m_bitrate_index=" + m_bitrate_index + " index=" + index);
326 
327         int lookup = (index != -1
328                       ? BIT_RATES[m_bitrate_index][index]
329                       : LOOKUP_FAILURE);
330 
331         // store the bitrate in bps, not kbps
332         m_bit_rate = lookup > 0 ? lookup*1000 : BAD;   // RESOLVE: should be 1024?
333 
334         if (log.isDebugEnabled())
335             log.debug("lookupBitRate: m_bit_rate=" + m_bit_rate);
336 
337         return m_bit_rate == FREE || m_bit_rate > 0;
338     }
339 
340     /** sample rate */
341     boolean lookupSampleRate() {
342         if (m_sample_rate >= 0)
343             return true;                 // already done
344 
345         //if (log.isDebugEnabled())
346         //    log.debug("lookupSampleRate: m_audio_ver=" + m_audio_ver
347         //              + " m_sample_index=" + m_sample_index);
348 
349         int index = -1;
350 
351         switch (m_audio_ver) {
352         case AUDIO_VER_VERSION_1:
353             index = 0;
354             break;
355         case AUDIO_VER_VERSION_2:
356             index = 1;
357             break;
358         case AUDIO_VER_VERSION_2_5:
359             index = 2;
360             break;
361         default:
362         }
363 
364         m_sample_rate = (index != -1
365                          ? SAMPLE_RATES[m_sample_index][index]
366                          : LOOKUP_FAILURE);
367 
368         if (log.isDebugEnabled())
369             log.debug("lookupSampleRate: m_sample_rate=" + m_sample_rate);
370 
371         return m_sample_rate >= 0;
372     }
373 
374     /** frame length in bytes */
375     boolean calculateFrameLength() {
376         if (m_frame_length >= 0)
377             return true;
378 
379         if (lookupBitRate() == false)
380             return false;
381         if (lookupSampleRate() == false)
382             return false;
383 
384         if (log.isDebugEnabled())
385             log.debug("calculateFrameLength: m_layer_code=" + m_layer_code
386                       + " m_bit_rate=" + m_bit_rate
387                       + " m_sample_rate=" + m_sample_rate
388                       + " m_padding=" + m_padding);
389 
390         switch (m_layer_code) {
391         case LAYER_I:
392             m_frame_length = (4 * ( (12 * m_bit_rate / m_sample_rate)
393                                     + (m_padding ? SLOT_LAYER_I : 0)
394                                   )
395                              );
396             break;
397         case LAYER_II:
398         case LAYER_III:
399             m_frame_length = (144 * m_bit_rate) / m_sample_rate
400                              + (m_padding ? SLOT_LAYER_II_III : 0);
401             break;
402         default:
403             return false;
404         }
405 
406         if (log.isDebugEnabled())
407             log.debug("calculateFrameLength: m_frame_length=" + m_frame_length);
408 
409         return true;
410     }
411 
412 //
413 // resetter
414 //
415 
416     public void resetData() {
417         m_audio_ver      = -1;
418         m_layer_code     = -1;
419         m_protection     = false;
420         m_bitrate_index  = -1;
421         m_sample_index   = -1;
422         m_padding        = false;
423         m_private_bit    = false;
424         m_channel_mode   = -1;
425         m_mode_ext       = -1;
426         m_copyright      = false;
427         m_original       = false;
428         m_emphasis       = -1;
429 
430         m_bit_rate       = -1;
431         m_sample_rate    = -1;
432         m_frame_length   = -1;
433     }
434 
435 //
436 // data members
437 //
438 
439     int         m_audio_ver;
440     int         m_layer_code;
441     boolean     m_protection;
442     int         m_bitrate_index;
443     int         m_sample_index;
444     boolean     m_padding;
445     boolean     m_private_bit;
446     int         m_channel_mode;
447     int         m_mode_ext;
448     boolean     m_copyright;
449     boolean     m_original;
450     int         m_emphasis;
451 
452     int         m_bit_rate;
453     int         m_sample_rate;
454     int         m_frame_length;
455 
456 //
457 // header mask constants
458 //
459 // AAAAAAAA AAABBCCD EEEEFFGH IIJJKLMM
460 //
461 
462     // header masks
463     static final int FRAME_SYNC_MASK = 0xFFE00000;   // A 11-bits (31-21) - Frame sync (all bits set)
464     static final int AUDIO_VER_MASK  = 0x00180000;   // B 2-bits  (20,19) - MPEG Audio version ID
465     static final int AUDIO_VER_SHIFT = 19;
466     static final int LAYER_MASK      = 0x00060000;   // C 2-bits  (18,17) - Layer description
467     static final int LAYER_SHIFT     = 17;
468     static final int PROTECTION_MASK = 0x00010000;   // D 1-bit   (16)    - Protection bit
469     static final int BITRATE_MASK    = 0x0000F000;   // E 4-bits  (15,12) - Bitrate index
470     static final int BITRATE_SHIFT   = 12;
471     static final int SAMPLE_MASK     = 0x00000C00;   // F 2-bits  (11,10) - Sampling rate frequency index (values are in Hz)
472     static final int SAMPLE_SHIFT    = 10;
473     static final int PADDING_MASK    = 0x00000200;   // G 1-bit   (9)     - Padding bit
474     static final int PRIVATE_MASK    = 0x00000100;   // H 1-bit   (8)     - private bit
475     static final int CHANNEL_MASK    = 0x000000C0;   // I 2-bits  (7,6)   - Channel Mode
476     static final int CHANNEL_SHIFT   = 6;
477     static final int MODE_EXT_MASK   = 0x00000030;   // J 2-bits  (5,4)   - Mode extension (Only if Joint stereo)
478     static final int MODE_EXT_SHIFT  = 4;
479     static final int COPYRIGHT_MASK  = 0x00000008;   // K 1-bit   (3)     - copyright bit
480     static final int ORIGINAL_MASK   = 0x00000004;   // L 1-bit   (2)     - Original
481     static final int EMPHASIS_MASK   = 0x00000003;   // M 2-bits  (1,0)   - Emphasis
482     static final int EMPHASIS_SHIFT  = 0;
483 
484 
485 //
486 // lookup tables
487 //
488 
489     static final int LOOKUP_FAILURE = -777;
490     static final int FREE = -1;
491     static final int BAD = -666;
492     static final int[][] BIT_RATES = {
493         //V1L1 V1L2 V1L3 V2L1 V2L2&3
494         {  FREE,FREE,FREE,FREE,FREE}  // 0000  (all 'free')
495         ,{ 32  ,32  ,32  ,32  ,8}     // 0001
496         ,{ 64  ,48  ,40  ,48  ,16}    // 0010
497         ,{ 96  ,56  ,48  ,56  ,24}    // 0011
498         ,{ 128 ,64  ,56  ,64  ,32}    // 0100
499         ,{ 160 ,80  ,64  ,80  ,40}    // 0101
500         ,{ 192 ,96  ,80  ,96  ,48}    // 0110
501         ,{ 224 ,112 ,96  ,112 ,56}    // 0111
502         ,{ 256 ,128 ,112 ,128 ,64}    // 1000
503         ,{ 288 ,160 ,128 ,144 ,80}    // 1001
504         ,{ 320 ,192 ,160 ,160 ,96}    // 1010
505         ,{ 352 ,224 ,192 ,176 ,112}   // 1011
506         ,{ 384 ,256 ,224 ,192 ,128}   // 1100
507         ,{ 416 ,320 ,256 ,224 ,144}   // 1101
508         ,{ 448 ,384 ,320 ,256 ,160}   // 1110
509         ,{ BAD ,BAD ,BAD ,BAD ,BAD}   // 1111  (all 'bad')
510     };
511 
512     static final int[][] SAMPLE_RATES = {
513         {  44100 ,22050 ,11025}
514         ,{ 48000 ,24000 ,12000}
515         ,{ 32000 ,16000 ,8000}
516         ,{ -1    ,-1    ,-1}
517     };
518 
519 //
520 // string constants (for writing into SAX events)
521 //
522 
523     static final String[] S_AUDIO_VER = {
524         "2.5", "reserved", "2.0", "1.0"
525     };
526 
527     static final int[] S_LAYER = {
528         0, 3, 2, 1
529     };
530 
531     static final String[] S_CHANNEL_MODE = {
532         "stereo", "joint-stereo", "dual-mono", "single-mono"
533     };
534 
535     static final String[] S_MODE_EXT_LAYER_I_II = {
536         "4-31", "8-31", "12-31", "16-31"
537     };
538 
539     static final String[] S_MODE_EXT_LAYER_III = {
540         "", "-intensity", "-m/s", "-intensity-m/s"
541     };
542 
543 //
544 // header constants
545 //
546 
547     static final int HEADER_SIZE = 4; // bytes
548 
549     static final int AUDIO_VER_VERSION_2_5 = 0; //00 - MPEG Version 2.5
550     static final int AUDIO_VER_RESERVED    = 1; //01 - reserved
551     static final int AUDIO_VER_VERSION_2   = 2; //10 - MPEG Version 2 (ISO/IEC 13818-3)
552     static final int AUDIO_VER_VERSION_1   = 3; //11 - MPEG Version 1 (ISO/IEC 11172-3)
553 
554     static final int LAYER_RESERVED = 0; // 00 - reserved
555     static final int LAYER_III      = 1; // 01 - Layer III
556     static final int LAYER_II       = 2; // 10 - Layer II
557     static final int LAYER_I        = 3; // 11 - Layer I
558 
559     static final int CHANNEL_STEREO       = 0; // 00 - Stereo
560     static final int CHANNEL_JOINT_STEREO = 1; // 01 - Joint stereo (Stereo)
561     static final int CHANNEL_DUAL         = 2; // 10 - Dual channel (Stereo)
562     static final int CHANNEL_SINGLE       = 3; // 11 - Single channel (Mono)
563 
564     static final int SLOT_LAYER_I      = 4; // bytes
565     static final int SLOT_LAYER_II_III = 1; // byte
566 
567     /**
568      * logging object
569      */
570     static Log log = LogFactory.getLog(MPEGFrameHeader.class);
571 }
572 
573 /*
574 PTARMIGAN MODIFIED BSD LICENSE
575 
576 Copyright (c) 2002, Reed Esau (reed.esau@pobox.com) All rights reserved.
577 
578 Redistribution and use in source and binary forms, with or without
579 modification, are permitted provided that the following conditions are
580 met:
581 
582 Redistributions of source code must retain the above copyright notice,
583 this list of conditions and the following disclaimer.
584 
585 Redistributions in binary form must reproduce the above copyright notice,
586 this list of conditions and the following disclaimer in the documentation
587 and/or other materials provided with the distribution.
588 
589 Neither the name of the Ptarmigan Project
590 (http://ptarmigan.sourceforge.net) nor the names of its contributors may
591 be used to endorse or promote products derived from this software without
592 specific prior written permission.
593 
594 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
595 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
596 THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
597 PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
598 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
599 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
600 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
601 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
602 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
603 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
604 POSSIBILITY OF SUCH DAMAGE.
605 */