www.pudn.com > XvidQP.rar > ceglue.cpp
/* * @(#) ceglue.cpp, last edit: 4/9/1998 * @(#) Copyright (C) 1998 Syntrillium Software (www.syntrillium.com) * * 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. * * Basically we are taking what we need from mp2win.cpp and doing a * non-independent-thread (non Windows GUI) version of maplay. * * */ #define STRICT #include#include #include #include #include "all.h" #include "crc.h" #include "ibitstr.h" #include "header.h" #include "args.h" #include "subband.h" #include "sublay1.h" #include "sublay2.h" #include "synfilt.h" #include "ibitstr.h" #include "obuffer.h" #include "layer3.h" extern "C" { #include "ceglue.h" } #include #define NUM_RFL_ENTRIES 4 #define REMOTE_THRESH 5 BOOL MPEG = FALSE; enum e_channels mode = both; // Dummy CRC pointer //Crc16 *crc; SynthesisFilter *filter1 = NULL, *filter2 = NULL; Obuffer *buffer = NULL; LayerIII_Decoder *l3decoder = NULL; enum e_mode actualmode; uint32 layer; // These arguments should not change while decoding Ibitstream *stream = NULL; Header *header = NULL; enum e_channels which_channels; BOOL bComplete=FALSE; MPEG_Args _maplay_args; MPEG_Args *maplay_args = &_maplay_args; void maplay_Exit(uint32 returncode) { delete buffer; buffer = NULL; delete filter1; filter1 = NULL; delete filter2; filter2 = NULL; delete l3decoder; l3decoder = NULL; } BOOL CPPMPEG_GetInfo(MPEG_INFO * mpi) { if (!MPEG) return FALSE; if (!header) return FALSE; mpi->iLayer =(int)header->layer(); mpi->iVersion =(int)header->version(); mpi->iStereoMode =(int)header->mode(); mpi->iSamplerate =(int)header->frequency(); mpi->iChannels =(header->mode()==single_channel)?1:2; mpi->bIsChecksummed =(BOOL)header->checksums(); mpi->bIsCopyrighted =(BOOL)header->copyright(); mpi->bIsOriginal =(BOOL)header->original(); mpi->iBitrateIndex =(int)header->bitrate_index(); mpi->iFrameSize =(int)header->calculate_framesize(); mpi->fLengthInMilliseconds=header->total_ms(stream); lstrcpy(mpi->szBitrate,header->bitrate_string()); lstrcpy(mpi->szVersion,header->version_string()); return TRUE; } // header_copy.total_ms(&stream_copy) in CPPMPEG_GetInfo BOOL CPPMPEG_Open(LPSTR szName) { MPEG = TRUE; bComplete=FALSE; real own_scalefactor = 32768.0f; //args->mutex = CreateMutex(NULL, FALSE, "m"); stream = new Ibitstream(szName); header = new Header; /* if (!header->read_header(stream, &crc)){ return FALSE; }*/ // AND GET THINGS STARTED! // crc = NULL; which_channels = both; // or left, right, downmix bComplete=FALSE; // get info from header of first frame: layer = header->layer(); if ((actualmode=header->mode())== single_channel) which_channels = left; // create filter(s): { real scalefactor = own_scalefactor; // insert any scal factor here filter1 = new SynthesisFilter(0, scalefactor); if ((actualmode != single_channel) && (which_channels == both)) filter2 = new SynthesisFilter(1, scalefactor); } // set up args for buffer class to use maplay_args->MPEGheader=header; maplay_args->which_c=which_channels; // create buffer, and check to see if created ok: // buffer=create_CEP_Obuffer(maplay_args); if (buffer == NULL) { maplay_Exit(0); return 1; } // Layer III : initialize decoder if (layer == 3) l3decoder = new LayerIII_Decoder(stream, header, filter1, filter2, buffer, which_channels); return TRUE; } // Returns number of bytes, or zero for complete int CPPMPEG_Read(BYTE * pBuffer) { bool read_ready = false, write_ready = false; int iRead; if (bComplete) return 0; // is there a change in important parameters? // (bitrate switching is allowed) if (header->layer() != layer) { // layer switching is allowed if (header->layer() == 3) { l3decoder = new LayerIII_Decoder(stream, header, filter1, filter2, buffer, which_channels); } else if (layer == 3) { delete l3decoder; l3decoder = NULL; } layer = header->layer(); } if (layer != 3) { Subband *subbands[32]; uint32 num_subbands = header->number_of_subbands(); uint32 i; actualmode = header->mode(); // create subband objects: if (layer == 1) { if (actualmode == single_channel) for (i = 0; i < num_subbands; ++i) subbands[i] = new SubbandLayer1(i); else if (actualmode == joint_stereo) { for (i = 0; i < header->intensity_stereo_bound(); ++i) subbands[i] = new SubbandLayer1Stereo(i); for (; i < num_subbands; ++i) subbands[i] = new SubbandLayer1IntensityStereo(i); } else { for (i = 0; i < num_subbands; ++i) subbands[i] = new SubbandLayer1Stereo(i); } } else { // Layer II if (actualmode == single_channel) for (i = 0; i < num_subbands; ++i) subbands[i] = new SubbandLayer2(i); else if (actualmode == joint_stereo) { for (i = 0; i < header->intensity_stereo_bound(); ++i) subbands[i] = new SubbandLayer2Stereo(i); for (; i < num_subbands; ++i) subbands[i] = new SubbandLayer2IntensityStereo(i); } else { for (i = 0; i < num_subbands; ++i) subbands[i] = new SubbandLayer2Stereo(i); } } // start to read audio data: for (i = 0; i < num_subbands; ++i) // subbands[i]->read_allocation(stream, header, crc); if (layer == 2) for (i = 0; i < num_subbands; ++i) //((SubbandLayer2 *)subbands[i])->read_scalefactor_selection(stream, // crc); /* if (!crc || header->checksum_ok()) { // no checksums or checksum ok, continue reading from stream: for (i = 0; i < num_subbands; ++i) subbands[i]->read_scalefactor(stream, header); do { for (i = 0; i < num_subbands; ++i) read_ready = subbands[i]->read_sampledata(stream); do { for (i = 0; i < num_subbands; ++i) write_ready = subbands[i]->put_next_sample(which_channels, filter1, filter2); filter1->calculate_pcm_samples(buffer); if ((which_channels == both) && (actualmode!= single_channel)) filter2->calculate_pcm_samples(buffer); } while (!write_ready); } while (!read_ready); buffer->write_buffer(1); } // checksum ok*/ // Jeff : Don't let user know if crc violated. // else // Sh*t! Wrong crc checksum in frame! // cerr << "WARNING: frame contains wrong crc checksum! (throwing frame away)\n"; for (i = 0; i < num_subbands; ++i) delete subbands[i]; } else { // Layer III l3decoder->decode(); } /* if (!header->read_header(stream, &crc)) bComplete=TRUE;*/ // BYTE * pBuf=buffer->get_buffer(&iRead); // CopyMemory(pBuffer,pBuf,iRead); return iRead; } void CPPMPEG_Close() { maplay_Exit(0); if (MPEG) { delete stream; stream = NULL; delete header; header = NULL; } } // To interface with the Cool Edit File Filters API, we make "C" callable functions extern "C" { void MPEG_Close() { CPPMPEG_Close(); } int MPEG_Read(BYTE * pBuffer) { return CPPMPEG_Read(pBuffer); } BOOL MPEG_Open(LPSTR szName) { return CPPMPEG_Open(szName); } BOOL MPEG_GetInfo(MPEG_INFO * mpi) { return CPPMPEG_GetInfo(mpi); } }