mhead.cpp
上传用户:zhongxx05
上传日期:2007-06-06
资源大小:33641k
文件大小:11k
- /* ***** BEGIN LICENSE BLOCK *****
- * Version: RCSL 1.0/RPSL 1.0
- *
- * Portions Copyright (c) 1995-2002 RealNetworks, Inc. All Rights Reserved.
- *
- * The contents of this file, and the files included with this file, are
- * subject to the current version of the RealNetworks Public Source License
- * Version 1.0 (the "RPSL") available at
- * http://www.helixcommunity.org/content/rpsl unless you have licensed
- * the file under the RealNetworks Community Source License Version 1.0
- * (the "RCSL") available at http://www.helixcommunity.org/content/rcsl,
- * in which case the RCSL will apply. You may also obtain the license terms
- * directly from RealNetworks. You may not use this file except in
- * compliance with the RPSL or, if you have a valid RCSL with RealNetworks
- * applicable to this file, the RCSL. Please see the applicable RPSL or
- * RCSL for the rights, obligations and limitations governing use of the
- * contents of the file.
- *
- * This file is part of the Helix DNA Technology. RealNetworks is the
- * developer of the Original Code and owns the copyrights in the portions
- * it created.
- *
- * This file, and the files included with this file, is distributed and made
- * available on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND REALNETWORKS HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS
- * FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- *
- * Technology Compatibility Kit Test Suite(s) Location:
- * http://www.helixcommunity.org/content/tck
- *
- * Contributor(s):
- *
- * ***** END LICENSE BLOCK ***** */
- #include "hlxclib/stdlib.h"
- #include "hlxclib/stdio.h"
- #include "hlxclib/float.h"
- #include "hlxclib/math.h"
- #include "hlxclib/string.h"
- #include "mhead.h" /* mpeg header structure */
- static const int mp_br_table[2][16]=
- {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0,
- 0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0};
- static const int mp_sr20_table[2][4]={441,480,320,-999, 882,960,640,-999};
- static const int mp_br_tableL1[2][16]=
- {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0, /* mpeg2 */
- 0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0};
- static const int mp_br_tableL3[2][16]=
- {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0, /* mpeg 2 */
- 0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0};
- static int find_sync(unsigned char *buf, int n);
- static int sync_scan(unsigned char *buf, int n, int i0);
- static int sync_test(unsigned char *buf, int n, int isync, int padbytes);
- /*--------------------------------------------------------------*/
- int head_info(unsigned char *buf, unsigned int n, MPEG_HEAD *h, int trustFrame)
- {
- int framebytes;
- int mpeg25_flag;
- if( n > 10000 ) n = 10000; /* limit scan for free format */
- h->sync = 0;
- if( (buf[0] == 0xFF) && ((buf[1] & 0xF0) == 0xF0) ) {
- mpeg25_flag = 0; // mpeg 1 & 2
- }
- else if( (buf[0] == 0xFF) && ((buf[1] & 0xF0) == 0xE0) ) {
- mpeg25_flag = 1; // mpeg 2.5
- }
- else return 0; // sync fail
- h->sync = 1;
- if( mpeg25_flag ) h->sync = 2; //low bit clear signals mpeg25 (as in 0xFFE)
- h->id = (buf[1] & 0x08) >> 3;
- h->option = (buf[1] & 0x06) >> 1;
- h->prot = (buf[1] & 0x01);
- h->br_index = (buf[2] & 0xf0) >> 4;
- h->sr_index = (buf[2] & 0x0c) >> 2;
- h->pad = (buf[2] & 0x02) >> 1;
- h->private_bit = (buf[2] & 0x01);
- h->mode = (buf[3] & 0xc0) >> 6;
- h->mode_ext = (buf[3] & 0x30) >> 4;
- h->cr = (buf[3] & 0x08) >> 3;
- h->original = (buf[3] & 0x04) >> 2;
- h->emphasis = (buf[3] & 0x03);
- //if( mpeg25_flag ) {
- // if( h->sr_index == 2 ) return 0; // fail 8khz
- //}
- /* Found a clip with a bad emphasis value. Let this slide for now */
- /*if (h->emphasis == 2)
- return 0;
- */
- /* do some error checking */
- if (h->br_index == 0xFF ||
- h->sr_index == 3 ||
- h->option < 1 ||
- h->option > 3)
- {
- memset(h, 0, sizeof(*h));
- return 0;
- }
- framebytes = 0;
- if( h->br_index > 0 )
- {
- if( h->option == 3 ) { /* layer I */
- framebytes =
- 240 * mp_br_tableL1[h->id][h->br_index]
- /mp_sr20_table[h->id][h->sr_index];
- framebytes = 4*framebytes;
- }
- else if( h->option == 2 ) { /* layer II */
- framebytes =
- 2880 * mp_br_table[h->id][h->br_index]
- /mp_sr20_table[h->id][h->sr_index];
- }
- else if( h->option == 1 ) { /* layer III */
- if( h->id ) { // mpeg1
- framebytes =
- 2880 * mp_br_tableL3[h->id][h->br_index]
- / mp_sr20_table[h->id][h->sr_index];
- }
- else { // mpeg2
- if( mpeg25_flag ) { // mpeg2.2
- framebytes =
- 2880 * mp_br_tableL3[h->id][h->br_index]
- / mp_sr20_table[h->id][h->sr_index];
- }
- else {
- framebytes =
- 1440 * mp_br_tableL3[h->id][h->br_index]
- / mp_sr20_table[h->id][h->sr_index];
- }
- }
- }
- }
- else
- {
- framebytes = find_sync(buf, n); /* free format */
- // If trustFrame != 0, that means we know that we only
- // have valid frames in this buffer (i.e. - we know
- // we are being called from the renderer where our
- // fileformat has already parsed out the frames).
- // Therefore, if find_sync() did not find any frames
- // and trustFrame != 0, then accept the rest of the buffer
- // as valid.
- if (framebytes == 0 && trustFrame != 0)
- {
- // Accept the rest of the buffer as a frame
- framebytes = n - h->pad;
- }
- // The spec states "The decoder is also not required to support bitrates
- // higher than 448 kbits/s, 384 kbits/sec, 320 kbits/sec in respect to Layer I,
- // II, and III when in free format mode."
- if (framebytes)
- {
- // Compute the bitrate
- int lBitrate = 0;
- if(h->option == 1)
- {
- /* layer III */
- if (h->br_index > 0)
- lBitrate = 1000 * mp_br_tableL3[h->id][h->br_index];
- else
- {
- if(h->id) // mpeg1
- lBitrate = 1000 * framebytes * mp_sr20_table[h->id][h->sr_index]/(144*20);
- else
- {
- // mpeg2
- if((h->sync & 1) == 0) // flags mpeg25
- lBitrate = 500*framebytes*mp_sr20_table[h->id][h->sr_index]/(72*20);
- else
- lBitrate = 1000*framebytes*mp_sr20_table[h->id][h->sr_index]/(72*20);
- }
- }
- // Cap the bitrate
- if (lBitrate > 320000 || lBitrate < 0) framebytes = 0;
- }
- if (h->option == 2)
- {
- /* layer II */
- if (h->br_index > 0)
- lBitrate = 1000*mp_br_table[h->id][h->br_index];
- else
- lBitrate = 1000*framebytes*mp_sr20_table[h->id][h->sr_index] / (144*20);
- // Cap the bitrate
- if (lBitrate > 384000 || lBitrate < 0) framebytes = 0;
- }
- if (h->option == 3)
- {
- /* layer I */
- if(h->br_index > 0)
- lBitrate = 1000 * mp_br_tableL1[h->id][h->br_index];
- else
- lBitrate = 1000*framebytes*mp_sr20_table[h->id][h->sr_index] / (48*20);
- // Cap the bitrate
- if (lBitrate > 448000 || lBitrate < 0) framebytes = 0;
- }
- }
- }
- return framebytes;
- }
- /*--------------------------------------------------------------*/
- int head_info2(unsigned char *buf, unsigned int n, MPEG_HEAD *h, int *br, int trustFrame)
- {
- int framebytes;
- /*--- return br (in bits/sec) in addition to frame bytes ---*/
- *br = 0; /*-- assume fail --*/
- framebytes = head_info(buf, n, h, trustFrame);
- if( framebytes == 0 ) return 0;
- if( h->option == 1 ) { /* layer III */
- if( h->br_index > 0 )
- *br = 1000*mp_br_tableL3[h->id][h->br_index];
- else {
- if( h->id ) // mpeg1
- *br = 1000*framebytes*mp_sr20_table[h->id][h->sr_index]/(144*20);
- else { // mpeg2
- if( (h->sync & 1) == 0 ) // flags mpeg25
- *br = 500*framebytes*mp_sr20_table[h->id][h->sr_index]/(72*20);
- else
- *br = 1000*framebytes*mp_sr20_table[h->id][h->sr_index]/(72*20);
- }
- }
- }
- if( h->option == 2 ) { /* layer II */
- if( h->br_index > 0 )
- *br = 1000*mp_br_table[h->id][h->br_index];
- else *br = 1000*framebytes*mp_sr20_table[h->id][h->sr_index]
- / (144*20);
- }
- if( h->option == 3 ) { /* layer I */
- if( h->br_index > 0 )
- *br = 1000*mp_br_tableL1[h->id][h->br_index];
- else *br = 1000*framebytes*mp_sr20_table[h->id][h->sr_index]
- / (48*20);
- }
- return framebytes;
- }
- /*--------------------------------------------------------------*/
- static int compare( unsigned char *buf, unsigned char *buf2)
- {
- if( buf[0] != buf2[0] ) return 0;
- if( buf[1] != buf2[1] ) return 0;
- return 1;
- }
- /*----------------------------------------------------------*/
- /*-- does not scan for initial sync, initial sync assumed --*/
- static int find_sync(unsigned char *buf, int n)
- {
- int i0, isync, nmatch, pad;
- int padbytes, option;
- /* mod 4/12/95 i0 change from 72, allows as low as 8kbits for mpeg1 */
- i0 = 24;
- padbytes = 1;
- option = (buf[1] & 0x06) >> 1;
- if( option == 3 ) {
- padbytes = 4;
- i0 = 24; /* for shorter layer I frames */
- }
- pad = (buf[2] & 0x02) >> 1;
- n -= 3; /* need 3 bytes of header */
- while( i0 < 2000 ) {
- isync = sync_scan(buf, n, i0);
- i0 = isync +1;
- isync -= pad;
- if( isync <= 0 ) return 0;
- nmatch = sync_test(buf, n, isync, padbytes);
- if( nmatch > 0 ) return isync;
- }
- return 0;
- }
- /*------------------------------------------------------*/
- /*---- scan for next sync, assume start is valid -------*/
- /*---- return number bytes to next sync ----------------*/
- static int sync_scan(unsigned char *buf, int n, int i0)
- {
- int i;
- for(i=i0; i<n; i++)
- if( compare(buf, buf+i) ) return i;
- return 0;
- }
- /*------------------------------------------------------*/
- /*- test consecutative syncs, input isync without pad --*/
- static int sync_test(unsigned char *buf, int n, int isync, int padbytes)
- {
- int i, nmatch, pad;
- nmatch = 0;
- for(i=0; ; ) {
- pad = padbytes*( (buf[i+2] & 0x02) >> 1);
- i += (pad + isync);
- if( i > n ) break;
- if( !compare(buf,buf+i) ) return -nmatch;
- nmatch++;
- }
- return nmatch;
- }