www.pudn.com > XvidQP.rar > header.cpp


/*	header.cpp 
 
	Implementation of MPEG header class 
 
	A few layer III, MPEG-2 LSF, and seeking modifications made by 
   Jeff Tsay. MPEG-2 LSF is now supported. 
 
   Last modified : 06/04/97 */ 
 
   /* 
 *  @(#) header.cc 1.8, last edit: 6/15/94 16:51:44 
 *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de) 
 *  @(#) Berlin University of Technology 
 * 
 *  This program is free software; you can redistribute it and/or modify 
 *  it under the terms of the GNU General Public License as published by 
 *  the Free Software Foundation; either version 2 of the License, or 
 *  (at your option) any later version. 
 * 
 *  This program is distributed in the hope that it will be useful, 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 *  GNU General Public License for more details. 
 * 
 *  You should have received a copy of the GNU General Public License 
 *  along with this program; if not, write to the Free Software 
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
 */ 
 
/* 
 *  Changes from version 1.1 to 1.2: 
 *    - iostreams manipulator calls like "cerr << setw (2) << ..." replaced by 
 *      "cerr.width (2); ..." due to problems with older GNU C++ releases. 
 *    - syncword recognition slightly changed 
 */ 
 
#ifndef GUI 
#include  
#endif  // GUI 
 
#include "header.h" 
 
const uint32 Header::frequencies[2][4] = 
{{22050, 24000, 16000, 1}, 
 {44100, 48000, 32000, 1}}; 
 
Header::Header() 
{ 
  	framesize = 0; 
   nSlots    = 0; 
  	crc       = NULL; 
   offset    = NULL; 
   initial_sync = false; 
} 
 
Header::Header(const Header &h0) 
{ 
  int32 entries; 
  int32 i; 
 
  h_layer          = h0.h_layer; 
  h_protection_bit = h0.h_protection_bit; 
  h_bitrate_index  = h0.h_bitrate_index; 
  h_padding_bit    = h0.h_padding_bit; 
  h_mode_extension = h0.h_mode_extension; 
  h_version        = h0.h_version; 
  h_mode           = h0.h_mode; 
 
  h_sample_frequency   = h0.h_sample_frequency; 
  h_number_of_subbands = h0.h_number_of_subbands; 
  h_intensity_stereo_bound = h0.h_intensity_stereo_bound; 
 
  h_copyright  = h0.h_copyright; 
  h_original   = h0.h_original; 
  initial_sync = h0.initial_sync; 
 
  crc       = h0.crc; 
 
  if (h0.offset) { 
 
     entries   = sizeof(h0.offset) / sizeof(uint32); 
     offset    = new uint32 [entries]; 
 
     for (i=0; iget_header(&headerstring, INITIAL_SYNC)) 
	 	return false; 
 
  	h_version = (e_version) ((headerstring >> 19) & 1); 
 
   if ((h_sample_frequency = (e_sample_frequency) 
                             ((headerstring >> 10) & 3)) == 3) 
   { 
#ifdef WIN32GUI 
		 MessageBox(NULL, "Unknown sample frequency in header", 
	    				"Stream not supported", MB_ICONSTOP | MB_OK); 
#else 
		 cerr << "Unknown sample frequency!" << endl; 
#endif 
	    return false; 
   } 
 
   stream->set_syncword(headerstring & 0xFFF80CC0); 
 
   initial_sync = true; 
 
  } else { 
 
	  	if (!stream->get_header(&headerstring, STRICT_SYNC)) 
		 	return false; 
  } // initial_sync 
 
/*  if ((h_layer = (headerstring >> 17) & 3) == 0) 
  { 
	 cerr << "unknown layer identifier found!\n"; 
	 exit (1); 
  } 
  h_layer = 4 - h_layer;		// now 1 means Layer I and 3 means Layer III   */ 
 
  h_layer   = 4 - (headerstring >> 17) & 3; 
 
  h_protection_bit = (headerstring >> 16) & 1; 
 
 
/*  if ((h_bitrate_index = (headerstring >> 12) & 0xF) == 15) 
  { 
	 cerr << "unknown bitrate index found!\n"; 
	 exit (1); 
  }           */ 
/*  if (!h_bitrate_index) 
  { 
	 cerr << "free format not yet implemented!\n"; 
	 exit (1); 
  } */ 
 
  h_bitrate_index  = (headerstring >> 12) & 0xF; 
 
  h_padding_bit = (headerstring >> 9) & 1; 
  h_mode        = (e_mode)((headerstring >> 6) & 3); 
 
/*  if (h_layer == 2) 
	 // testing validity of mode and bitrate: 
	 if ((((h_bitrate_index >= 1 && h_bitrate_index <= 3) || h_bitrate_index == 5) && 
	 h_mode != single_channel) || 
	(h_bitrate_index >= 11 && h_mode == single_channel)) 
	 { 
		cerr << "illegal combination of mode and bitrate in a layer II stream:\n" 
			"  mode: " << mode_string () 
		<< "\n  bitrate: " << bitrate_string () << '\n'; 
		exit (1); 
	 } */ 
 
  h_mode_extension = (headerstring >> 4) & 3; 
 
  if (h_mode == joint_stereo) 
	 h_intensity_stereo_bound = (h_mode_extension << 2) + 4; 
  else 
	 h_intensity_stereo_bound = 0;		// should never be used 
 
  h_copyright = (bool) ((headerstring >> 3) & 1); 
  h_original  = (bool) ((headerstring >> 2) & 1); 
 
  // calculate number of subbands: 
  if (h_layer == 1) 
	 h_number_of_subbands = 32; 
  else 
  { 
	 channel_bitrate = h_bitrate_index; 
 
	 // calculate bitrate per channel: 
	 if (h_mode != single_channel) 
		if (channel_bitrate == 4) 
			channel_bitrate = 1; 
		else 
			channel_bitrate -= 4; 
 
	 if ((channel_bitrate == 1) || (channel_bitrate == 2)) 
		if (h_sample_frequency == thirtytwo) 
			h_number_of_subbands = 12; 
		else 
			h_number_of_subbands = 8; 
	 else 
		if ((h_sample_frequency == fourtyeight) || ((channel_bitrate >= 3) && 
      													  	  (channel_bitrate <= 5))) 
			h_number_of_subbands = 27; 
		else 
			h_number_of_subbands = 30; 
  } 
 
  if (h_intensity_stereo_bound > h_number_of_subbands) 
     h_intensity_stereo_bound = h_number_of_subbands; 
 
 
  // calculate framesize and nSlots 
	calculate_framesize(); 
 
  // read framedata: 
  if (stream->read_frame(framesize) == false) 
     return false; 
 
  if (!h_protection_bit) 
  { 
	 // frame contains a crc checksum 
	 checksum = (uint16) stream->get_bits(16); 
	 if (!crc) 
       crc = new Crc16; 
	 crc->add_bits(headerstring, 16); 
	 *crcp = crc; 
  } 
  else 
	 *crcp = NULL; 
 
#ifdef SEEK_STOP 
  if (h_sample_frequency == fourtyfour_point_one) { 
 
	 if (!offset) { 
 
    	uint32 max = max_number_of_frames(stream); 
 
		offset = new uint32[max]; 
 
      for(uint32 i=0; icurrent_frame(); 
     int32 lf = stream->last_frame(); 
	  if ((cf > 0) && (cf == lf)) { 
		   offset[cf] = offset[cf-1] + h_padding_bit; 
     } else { 
  	      offset[0] = h_padding_bit; 
     } 
    } 
  } 
#endif // SEEK_STOP 
 
  return true; 
} 
 
uint32 Header::calculate_framesize() 
// calculates framesize in bytes excluding header size 
{ 
  static const int32 bitrates[2][3][16] = { 
  {{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, 
    112000, 128000, 144000, 160000, 176000, 192000 ,224000, 256000, 0}, 
   {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, 
    56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}, 
   {0 /*free format*/, 8000, 16000, 24000, 32000, 40000, 48000, 
    56000, 64000, 80000, 96000, 112000, 128000, 144000, 160000, 0}}, 
  {{0 /*free format*/, 32000, 64000, 96000, 128000, 160000, 192000, 
	 224000, 256000, 288000, 320000, 352000, 384000, 416000, 448000, 0}, 
	{0 /*free format*/, 32000, 48000, 56000, 64000, 80000, 96000, 
	 112000, 128000, 160000, 192000, 224000, 256000, 320000, 384000, 0}, 
	{0 /*free format*/, 32000, 40000, 48000, 56000, 64000, 80000, 
	 96000, 112000, 128000, 160000, 192000, 224000, 256000, 320000, 0}} 
  }; 
 
  if (h_layer == 1) { 
	 framesize = (12 * bitrates[h_version][0][h_bitrate_index]) / 
                 frequencies[h_version][h_sample_frequency]; 
 
	 if (h_padding_bit) framesize++; 
 
	 framesize <<= 2;		// one slot is 4 bytes long 
 
    nSlots = 0; 
 
  } else { 
 
	 framesize = (144 * bitrates[h_version][h_layer - 1][h_bitrate_index]) / 
                 frequencies[h_version][h_sample_frequency]; 
 
	 if (h_version == MPEG2_LSF) 
    	framesize >>= 1; 
 
	 if (h_padding_bit) framesize++; 
 
	 // Layer III slots 
	 if (h_layer == 3) { 
 
       if (h_version == MPEG1) { 
 
			 nSlots = framesize - ((h_mode == single_channel) ? 17 : 32) // side info size 
									  -  (h_protection_bit ? 0 : 2) 		       // CRC size 
									  - 4; 								             // header size 
       } else {  // MPEG-2 LSF 
        	 nSlots = framesize - ((h_mode == single_channel) ?  9 : 17) // side info size 
						   		  -  (h_protection_bit ? 0 : 2) 		       // CRC size 
									  - 4; 								             // header size 
       } 
	 } else { 
    	 nSlots = 0; 
    } 
  } 
 
  framesize -= 4;             // subtract header size 
 
  return framesize; 
} 
 
const char *Header::layer_string() const 
{ 
  switch (h_layer) 
  { 
	 case 1: 
		return "I"; 
	 case 2: 
		return "II"; 
	 case 3: 
		return "III"; 
  } 
  return NULL;			// dummy 
} 
 
 
const char *Header::bitrate_string() const 
{ 
 
  static const char *bitrate_str[2][3][16] = { 
  {{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", 
    "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", 
    "160 kbit/s", "176 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", 
    "forbidden"}, 
   {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", 
    "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", 
    "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", 
    "forbidden"}, 
   {"free format", "8 kbit/s", "16 kbit/s", "24 kbit/s", "32 kbit/s", 
    "40 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", "80 kbit/s", 
    "96 kbit/s", "112 kbit/s", "128 kbit/s", "144 kbit/s", "160 kbit/s", 
    "forbidden"}}, 
  {{"free format", "32 kbit/s", "64 kbit/s", "96 kbit/s", "128 kbit/s", 
    "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "288 kbit/s", 
    "320 kbit/s", "352 kbit/s", "384 kbit/s", "416 kbit/s", "448 kbit/s", 
    "forbidden"}, 
	{"free format", "32 kbit/s", "48 kbit/s", "56 kbit/s", "64 kbit/s", 
    "80 kbit/s", "96 kbit/s", "112 kbit/s", "128 kbit/s", "160 kbit/s", 
    "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", "384 kbit/s", 
    "forbidden"}, 
	{"free format", "32 kbit/s", "40 kbit/s", "48 kbit/s", "56 kbit/s", 
    "64 kbit/s", "80 kbit/s" , "96 kbit/s", "112 kbit/s", "128 kbit/s", 
    "160 kbit/s", "192 kbit/s", "224 kbit/s", "256 kbit/s", "320 kbit/s", 
    "forbidden"}} 
  }; 
 
  return bitrate_str[h_version][h_layer - 1][h_bitrate_index]; 
} 
 
const char *Header::sample_frequency_string() const 
{ 
  switch (h_sample_frequency) 
  { 
	 case thirtytwo: 
    	if (h_version == MPEG1) 
			return "32 kHz"; 
      else 
      	return "16 kHz"; 
	 case fourtyfour_point_one: 
    	if (h_version == MPEG1) 
			return "44.1 kHz"; 
      else 
      	return "22.05 kHz"; 
	 case fourtyeight: 
    	if (h_version == MPEG1) 
			return "48 kHz"; 
      else 
      	return "24 kHz"; 
  } 
  return(NULL);			// dummy 
} 
 
const char *Header::mode_string() const 
{ 
  switch (h_mode) 
  { 
	 case stereo: 
		return "Stereo"; 
	 case joint_stereo: 
		return "Joint stereo"; 
	 case dual_channel: 
		return "Dual channel"; 
	 case single_channel: 
		return "Single channel"; 
  } 
  return NULL;			// dummy 
} 
 
const char *Header::version_string() const 
{ 
 	switch (h_version) 
   { 
   	case MPEG1: 
        return "MPEG-1"; 
      case MPEG2_LSF: 
        return "MPEG-2 LSF"; 
   } 
   return(NULL); 
} 
 
#ifdef SEEK_STOP 
// Stream searching routines 
bool Header::stream_seek(Ibitstream *stream, uint32 seek_pos) 
{ 
   return((h_sample_frequency == fourtyfour_point_one) ? 
          stream->seek_pad(seek_pos, framesize - h_padding_bit, 
                           this, offset) : 
     		 stream->seek(seek_pos, framesize)); 
} 
#endif 
 
uint32 Header::max_number_of_frames(Ibitstream *stream) const 
// Returns the maximum number of frames in the stream 
{ 
	return(stream->file_size() / (framesize + 4 - h_padding_bit)); 
} 
 
uint32 Header::min_number_of_frames(Ibitstream *stream) const 
// Returns the minimum number of frames in the stream 
{ 
   return(stream->file_size() / (framesize + 5 - h_padding_bit)); 
} 
 
real Header::ms_per_frame() const 
{ 
	static real ms_per_frame_array[3][3] = {{8.707483f,  8.0f, 12.0f}, 
												       {26.12245f, 24.0f, 36.0f}, 
   	                                     {26.12245f, 24.0f, 36.0f}}; 
 
	return ms_per_frame_array[h_layer-1][h_sample_frequency]; 
} 
 
real Header::total_ms(Ibitstream *stream) const 
{ 
	return(max_number_of_frames(stream) * ms_per_frame()); 
}