mpastrm_in.cpp
来自「Motion JPEG编解码器源代码」· C++ 代码 · 共 336 行
CPP
336 行
/* * audiostrm_in.c: MPEG Audio strem class members handling scanning * and buffering raw input stream. * * Copyright (C) 2001 Andrew Stevens <andrew.stevens@philips.com> * * * This program is free software; you can redistribute it and/or * modify it under the terms of version 2 of the GNU General Public License * as published by the Free Software Foundation. * * 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */#include <config.h>#include <math.h>#include <stdlib.h>#include "audiostrm.hpp"#include "interact.hpp"#include "multiplexor.hpp"static const char *mpa_audio_version[4] ={ "2.5", "2.0", "reserved", "1.0"};static const unsigned int mpa_bitrates_kbps [4][3][16] ={ { /* MPEG audio V2.5 */ {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0} }, { /*RESERVED*/ {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0}, {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} }, { /* MPEG audio V2 */ {0,32,48,56,64,80,96,112,128,144,160,176,192,224,256,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0}, {0,8,16,24,32,40,48,56,64,80,96,112,128,144,160,0} }, { /* MPEG audio V1 */ {0,32,64,96,128,160,192,224,256,288,320,352,384,416,448,0}, {0,32,48,56,64,80,96,112,128,160,192,224,256,320,384,0}, {0,32,40,48,56,64,80,96,112,128,160,192,224,256,320,0} }};static const int mpa_freq_table [4][4] = { /* MPEG audio V2.5 */ {11025,12000,8000,0}, /* RESERVED */ { 0, 0, 0, 0 }, /* MPEG audio V2 */ {22050,24000, 16000,0}, /* MPEG audio V1 */ {44100, 48000, 32000, 0}};static const char mpa_stereo_mode [4][15] ={ "stereo", "joint stereo", "dual channel", "single channel" };static const char mpa_copyright_status [2][20] ={ "no copyright","copyright protected" };static const char mpa_original_bit [2][10] ={ "copy","original" };static const char mpa_emphasis_mode [4][20] ={ "none", "50/15 microseconds", "reserved", "CCITT J.17" };static const unsigned int mpa_slots [4] = {12, 144, 144, 0};static const unsigned int mpa_samples [4] = {384, 1152, 1152, 0};MPAStream::MPAStream(IBitStream &ibs, Multiplexor &into) : AudioStream( ibs, into ){ for( int i = 0; i <2 ; ++i ) num_frames[i] = size_frames[i] = 0;}bool MPAStream::Probe(IBitStream &bs ){ return bs.GetBits(11) == AUDIO_SYNCWORD;}/************************************************************************* * * Reads initial stream parameters and displays feedback banner to users * *************************************************************************/void MPAStream::Init ( const int stream_num ){ int padding_bit; MuxStream::Init( AUDIO_STR_0 + stream_num, 0, // Buffer scale muxinto.audio_buffer_size, muxinto.vcd_zero_stuffing, muxinto.buffers_in_audio, muxinto.always_buffers_in_audio ); mjpeg_info ("Scanning for header info: Audio stream %02x (%s)", AUDIO_STR_0 + stream_num, bs.StreamName() ); /* A.Stevens 2000 - update to be compatible up to MPEG2.5 */ AU_start = bs.bitcount(); if (bs.GetBits(11)==AUDIO_SYNCWORD) { num_syncword++; version_id = bs.GetBits( 2); layer = 3-bs.GetBits( 2); /* 0..2 not 1..3!! */ protection = bs.Get1Bit(); bit_rate_code = bs.GetBits( 4); frequency = bs.GetBits( 2); padding_bit = bs.Get1Bit(); bs.Get1Bit(); mode = bs.GetBits( 2); mode_extension = bs.GetBits( 2); copyright = bs.Get1Bit(); original_copy = bs.Get1Bit (); emphasis = bs.GetBits( 2); framesize = mpa_bitrates_kbps[version_id][layer][bit_rate_code] * mpa_slots[layer] *1000 / mpa_freq_table[version_id][frequency]; size_frames[0] = framesize * ( layer == 0 ? 4 : 1); size_frames[1] = (framesize+1) * ( layer == 0 ? 4 : 1); num_frames[padding_bit]++; access_unit.start = AU_start; access_unit.length = size_frames[padding_bit]; samples_per_second = mpa_freq_table[version_id][frequency]; /* Presentation time-stamping */ access_unit.PTS = static_cast<clockticks>(decoding_order) * static_cast<clockticks>(mpa_samples [layer]) * static_cast<clockticks>(CLOCKS) / samples_per_second; access_unit.DTS = access_unit.PTS; access_unit.dorder = decoding_order; ++decoding_order; aunits.Append( access_unit ); } else { mjpeg_error ( "Invalid MPEG Audio stream header."); exit (1); } OutputHdrInfo();}unsigned int MPAStream::NominalBitRate(){ return mpa_bitrates_kbps[version_id][layer][bit_rate_code]*1024;}unsigned int MPAStream::SizeFrame( int rate_code, int padding ){ return ( mpa_bitrates_kbps[version_id][layer][rate_code] * mpa_slots [layer] *1000 / mpa_freq_table[version_id][frequency] + padding ) * ( layer == 0 ? 4 : 1);}void MPAStream::FillAUbuffer(unsigned int frames_to_buffer ){ unsigned int padding_bit; last_buffered_AU += frames_to_buffer; if( eoscan ) return; mjpeg_debug( "Scanning %d MPA frames to frame %d", frames_to_buffer, last_buffered_AU ); while( !bs.eos() && decoding_order < last_buffered_AU && !muxinto.AfterMaxPTS(access_unit.PTS) ) { int skip=access_unit.length-4; bs.SeekFwdBits( skip ); prev_offset = AU_start; AU_start = bs.bitcount(); if( AU_start - prev_offset != access_unit.length*8 ) { mjpeg_warn("Discarding incomplete final frame MPEG audio stream %02x!", stream_id ); aunits.DropLast(); --decoding_order; break; } /* Check we have reached the end of have another catenated stream to process before finishing ... */ if ( (syncword = bs.GetBits( 11))!=AUDIO_SYNCWORD ) { // // Handle a broken last frame... if( !bs.eos() ) { mjpeg_warn( "Data follows end of last recogniseable MPEG audio frame - bad stream?"); eoscan = true; return; } break; } // Skip version_id:2, layer:2, protection:1 (void) bs.GetBits( 5); int rate_code = bs.GetBits( 4); // Skip frequency (void) bs.GetBits( 2); padding_bit=bs.Get1Bit(); access_unit.start = AU_start; access_unit.length = SizeFrame( rate_code, padding_bit ); access_unit.PTS = static_cast<clockticks>(decoding_order) * static_cast<clockticks>(mpa_samples[layer]) * static_cast<clockticks>(CLOCKS) / samples_per_second; access_unit.DTS = access_unit.PTS; access_unit.dorder = decoding_order; decoding_order++; aunits.Append( access_unit ); num_frames[padding_bit]++; bs.GetBits( 9); num_syncword++; if (num_syncword >= old_frames+10 ) { mjpeg_debug ("Got %d frame headers.", num_syncword); old_frames=num_syncword; } } last_buffered_AU = decoding_order; eoscan = bs.eos() || muxinto.AfterMaxPTS(access_unit.PTS);}void MPAStream::Close(){ stream_length = AU_start >> 3; mjpeg_info ("AUDIO_STATISTICS: %02x", stream_id); mjpeg_info ("Audio stream length %lld bytes.", stream_length); mjpeg_info ("Syncwords : %8u",num_syncword); mjpeg_info ("Frames : %8u padded", num_frames[0]); mjpeg_info ("Frames : %8u unpadded", num_frames[1]); }/************************************************************************* OutputAudioInfo gibt gesammelte Informationen zu den Audio Access Units aus. Prints information on audio access units*************************************************************************/void MPAStream::OutputHdrInfo (){ unsigned int bitrate; bitrate = mpa_bitrates_kbps[version_id][layer][bit_rate_code]; mjpeg_info("MPEG AUDIO STREAM: %02x", stream_id); mjpeg_info("Audio version : %s", mpa_audio_version[version_id]); mjpeg_info("Layer : %8u",layer+1); if (protection == 0) mjpeg_info ("CRC checksums : yes"); else mjpeg_info ("CRC checksums : no"); if (bit_rate_code == 0) mjpeg_info ("Bit rate : free"); else if (bit_rate_code == 0xf) mjpeg_info ("Bit rate : reserved"); else mjpeg_info ("Bit rate : %8u bytes/sec (%3u kbit/sec)", bitrate*128, bitrate); if (frequency == 3) mjpeg_info ("Frequency : reserved"); else mjpeg_info ("Frequency : %d Hz", mpa_freq_table[version_id][frequency]); mjpeg_info ("Mode : %8u %s", mode,mpa_stereo_mode[mode]); mjpeg_info ("Mode extension : %8u",mode_extension); mjpeg_info ("Copyright bit : %8u %s", copyright,mpa_copyright_status[copyright]); mjpeg_info ("Original/Copy : %8u %s", original_copy,mpa_original_bit[original_copy]); mjpeg_info ("Emphasis : %8u %s", emphasis,mpa_emphasis_mode[emphasis]);}/* * Local variables: * c-file-style: "stroustrup" * tab-width: 4 * indent-tabs-mode: nil * End: */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?