⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpegac.cpp

📁 音频编码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/* *  LAME MP3 encoder for DirectShow *  DirectShow filter implementation * *  Copyright (c) 2000-2005 Marie Orlova, Peter Gubanov, Vitaly Ivanov, Elecard Ltd. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library 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 * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the * Free Software Foundation, Inc., 59 Temple Place - Suite 330, * Boston, MA 02111-1307, USA. */#include <streams.h>#include <olectl.h>#include <initguid.h>//#include <olectlid.h>#include "uids.h"#include "iaudioprops.h"#include "mpegac.h"#include "resource.h"#include "PropPage.h"#include "PropPage_adv.h"#include "aboutprp.h"#include "Encoder.h"#include "Reg.h"#ifndef _INC_MMREG#include <mmreg.h>#endif// default parameters#define         DEFAULT_LAYER               3#define         DEFAULT_STEREO_MODE         JOINT_STEREO#define         DEFAULT_FORCE_MS            0#define         DEFAULT_MODE_FIXED          0#define         DEFAULT_ENFORCE_MIN         0#define         DEFAULT_VOICE               0#define         DEFAULT_KEEP_ALL_FREQ       0#define         DEFAULT_STRICT_ISO          0#define         DEFAULT_DISABLE_SHORT_BLOCK 0#define         DEFAULT_XING_TAG            0#define         DEFAULT_SAMPLE_RATE         44100#define         DEFAULT_BITRATE             128#define         DEFAULT_VARIABLE            0#define         DEFAULT_CRC                 0#define         DEFAULT_FORCE_MONO          0#define         DEFAULT_SET_DURATION        1#define         DEFAULT_COPYRIGHT           0#define         DEFAULT_ORIGINAL            0#define         DEFAULT_VARIABLEMIN         80#define         DEFAULT_VARIABLEMAX         160#define         DEFAULT_ENCODING_QUALITY    5#define         DEFAULT_VBR_QUALITY         4#define         DEFAULT_PES                 0/*  Registration setup stuff *///  Setup dataAMOVIESETUP_MEDIATYPE sudMpgInputType[] ={    { &MEDIATYPE_Audio, &MEDIASUBTYPE_PCM }};AMOVIESETUP_MEDIATYPE sudMpgOutputType[] ={    { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG1AudioPayload },    { &MEDIATYPE_Audio, &MEDIASUBTYPE_MPEG2_AUDIO },};AMOVIESETUP_PIN sudMpgPins[3] ={    { L"PCM Input",      FALSE,                               // bRendered      FALSE,                               // bOutput      FALSE,                               // bZero      FALSE,                               // bMany      &CLSID_NULL,                         // clsConnectsToFilter      NULL,                                // ConnectsToPin      NUMELMS(sudMpgInputType),            // Number of media types      sudMpgInputType    },    { L"MPEG Output",      FALSE,                               // bRendered      TRUE,                                // bOutput      FALSE,                               // bZero      FALSE,                               // bMany      &CLSID_NULL,                         // clsConnectsToFilter      NULL,                                // ConnectsToPin      NUMELMS(sudMpgOutputType),           // Number of media types      sudMpgOutputType    }};AMOVIESETUP_FILTER sudMpgAEnc ={    &CLSID_LAMEDShowFilter,    L"LAME Audio Encoder",    MERIT_SW_COMPRESSOR,                   // Don't use us for real!    NUMELMS(sudMpgPins),                   // 3 pins    sudMpgPins};/*****************************************************************************/// COM Global table of objects in this dllCFactoryTemplate g_Templates[] = {  { L"LAME Audio Encoder", &CLSID_LAMEDShowFilter, CMpegAudEnc::CreateInstance, NULL, &sudMpgAEnc },  { L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPage, CMpegAudEncPropertyPage::CreateInstance},  { L"LAME Audio Encoder Property Page", &CLSID_LAMEDShow_PropertyPageAdv, CMpegAudEncPropertyPageAdv::CreateInstance},  { L"LAME Audio Encoder About", &CLSID_LAMEDShow_About, CMAEAbout::CreateInstance}};// Count of objects listed in g_cTemplatesint g_cTemplates = sizeof(g_Templates) / sizeof(g_Templates[0]);CUnknown *CMpegAudEnc::CreateInstance(LPUNKNOWN lpunk, HRESULT *phr) {    CUnknown *punk = new CMpegAudEnc(lpunk, phr);    if (punk == NULL)         *phr = E_OUTOFMEMORY;    return punk;}CMpegAudEnc::CMpegAudEnc(LPUNKNOWN lpunk, HRESULT *phr) :  CTransformFilter(NAME("LAME Audio Encoder"), lpunk,     CLSID_LAMEDShowFilter),    CPersistStream(lpunk, phr){    MPEG_ENCODER_CONFIG mec;    ReadPresetSettings(&mec);    m_Encoder.SetOutputType(mec);    m_hasFinished = TRUE;}CMpegAudEnc::~CMpegAudEnc(void){}LPAMOVIESETUP_FILTER CMpegAudEnc::GetSetupData(){    return &sudMpgAEnc;}HRESULT CMpegAudEnc::Receive(IMediaSample * pSample){    CAutoLock lock(&m_cs);    if (!pSample)        return S_OK;    BYTE * pSourceBuffer = NULL;    if (pSample->GetPointer(&pSourceBuffer) != S_OK || !pSourceBuffer)        return S_OK;    long sample_size = pSample->GetActualDataLength();    REFERENCE_TIME rtStart, rtStop;    BOOL gotValidTime = (pSample->GetTime(&rtStart, &rtStop) != VFW_E_SAMPLE_TIME_NOT_SET);    if (sample_size <= 0 || pSourceBuffer == NULL || m_hasFinished || (gotValidTime && rtStart < 0))        return S_OK;    if (gotValidTime)    {        if (m_rtStreamTime < 0)        {            m_rtStreamTime = rtStart;            m_rtEstimated = rtStart;        }        else        {            resync_point_t * sync = m_sync + m_sync_in_idx;            // if old sync data is applied and gap is greater than 1 ms            // then make a new synchronization point            if (sync->applied && (rtStart - m_rtEstimated > 10000))            {                sync->sample    = m_samplesIn;                sync->delta     = rtStart - m_rtEstimated;                sync->applied   = FALSE;                m_rtEstimated  += sync->delta;                if (m_sync_in_idx < (RESYNC_COUNT - 1))                    m_sync_in_idx++;                else                    m_sync_in_idx = 0;            }        }    }    m_rtEstimated   += (LONGLONG)(m_bytesToDuration * sample_size);    m_samplesIn     += sample_size / m_bytesPerSample;    while (sample_size > 0)    {        int bytes_processed = m_Encoder.Encode((short *)pSourceBuffer, sample_size);        if (bytes_processed <= 0)            return S_OK;        FlushEncodedSamples();        sample_size     -= bytes_processed;        pSourceBuffer   += bytes_processed;    }    return S_OK;}HRESULT CMpegAudEnc::FlushEncodedSamples(){    IMediaSample * pOutSample = NULL;    BYTE * pDst = NULL;    if (m_rtStreamTime < 0)        m_rtStreamTime = 0;    while (1)    {        const unsigned char *   pframe      = NULL;        int                     frame_size  = m_Encoder.GetFrame(&pframe);        if (frame_size <= 0 || !pframe)            break;        if (!m_sync[m_sync_out_idx].applied && m_sync[m_sync_out_idx].sample <= m_samplesOut)        {            m_rtStreamTime += m_sync[m_sync_out_idx].delta;            m_sync[m_sync_out_idx].applied = TRUE;            if (m_sync_out_idx < (RESYNC_COUNT - 1))                m_sync_out_idx++;            else                m_sync_out_idx = 0;        }        REFERENCE_TIME rtStart = m_rtStreamTime;        REFERENCE_TIME rtStop = rtStart + m_rtFrameTime;        HRESULT hr = m_pOutput->GetDeliveryBuffer(&pOutSample, NULL, NULL, 0);        if (hr == S_OK && pOutSample)        {            hr = pOutSample->GetPointer(&pDst);            if (hr == S_OK && pDst)            {                CopyMemory(pDst, pframe, frame_size);                pOutSample->SetSyncPoint(TRUE);                pOutSample->SetActualDataLength(frame_size);                pOutSample->SetTime(&rtStart, m_setDuration ? &rtStop : NULL);                m_pOutput->Deliver(pOutSample);            }            pOutSample->Release();        }        m_samplesOut += m_samplesPerFrame;        m_rtStreamTime = rtStop;    }    return S_OK;}//////////////////////////////////////////////////////////////////////////////  StartStreaming - prepare to receive new data////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::StartStreaming(){    WAVEFORMATEX * pwfxOut = (WAVEFORMATEX *) m_pOutput->CurrentMediaType().Format();    WAVEFORMATEX * pwfxIn  = (WAVEFORMATEX *) m_pInput->CurrentMediaType().Format();    m_bytesPerSample    = pwfxIn->nChannels * sizeof(short);    m_samplesPerFrame   = (pwfxOut->nSamplesPerSec >= 32000) ? 1152 : 576;    m_rtFrameTime = MulDiv(10000000, m_samplesPerFrame, pwfxOut->nSamplesPerSec);    m_samplesIn = m_samplesOut = 0;    m_rtStreamTime = -1;    // initialize encoder    m_Encoder.Init();    m_hasFinished   = FALSE;    for (int i = 0; i < RESYNC_COUNT; i++)    {        m_sync[i].sample   = 0;        m_sync[i].delta    = 0;        m_sync[i].applied  = TRUE;    }    m_sync_in_idx = 0;    m_sync_out_idx = 0;    get_SetDuration(&m_setDuration);    return S_OK;}HRESULT CMpegAudEnc::StopStreaming(){    m_Encoder.Close();    return S_OK;}//////////////////////////////////////////////////////////////////////////////  EndOfStream - stop data processing ////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::EndOfStream(){    CAutoLock lock(&m_cs);    // Flush data    m_Encoder.Finish();    FlushEncodedSamples();    // Close encoder    m_Encoder.Close();    m_hasFinished = TRUE;    return CTransformFilter::EndOfStream();}//////////////////////////////////////////////////////////////////////////////  BeginFlush  - stop data processing ////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::BeginFlush(){    HRESULT hr = CTransformFilter::BeginFlush();    if (SUCCEEDED(hr))    {        CAutoLock lock(&m_cs);        DWORD dwDstSize = 0;        // Flush data        m_Encoder.Finish();        FlushEncodedSamples();        m_rtStreamTime = -1;    }    return hr;}//////////////////////////////////////////////////////////////////////////////	SetMediaType - called when filters are connecting////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::SetMediaType(PIN_DIRECTION direction, const CMediaType * pmt){    HRESULT hr = S_OK;    if (*pmt->FormatType() != FORMAT_WaveFormatEx)        return VFW_E_INVALIDMEDIATYPE;    if (pmt->FormatLength() < sizeof(WAVEFORMATEX))        return VFW_E_INVALIDMEDIATYPE;    if (direction == PINDIR_INPUT)    {        DbgLog((LOG_TRACE,1,TEXT("CMpegAudEnc::SetMediaType(), direction = PINDIR_INPUT")));        // Pass input media type to encoder        m_Encoder.SetInputType((LPWAVEFORMATEX)pmt->Format());        WAVEFORMATEX * pwfx = (WAVEFORMATEX *)pmt->Format();        if (pwfx)            m_bytesToDuration = (float)1.e7 / (float)(pwfx->nChannels * sizeof(short) * pwfx->nSamplesPerSec);        else            m_bytesToDuration = 0.0;        Reconnect();    }    else if (direction == PINDIR_OUTPUT)    {        WAVEFORMATEX wfIn;        m_Encoder.GetInputType(&wfIn);        if (wfIn.nSamplesPerSec %            ((LPWAVEFORMATEX)pmt->Format())->nSamplesPerSec != 0)            return VFW_E_TYPE_NOT_ACCEPTED;    }    return hr;}////////////////////////////////////////////////////////////////////////////// CheckInputType - check if you can support mtIn////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::CheckInputType(const CMediaType* mtIn){    if (*mtIn->Type() == MEDIATYPE_Audio && *mtIn->FormatType() == FORMAT_WaveFormatEx)        if (mtIn->FormatLength() >= sizeof(WAVEFORMATEX))            if (mtIn->IsTemporalCompressed() == FALSE)                return m_Encoder.SetInputType((LPWAVEFORMATEX)mtIn->Format(), true);    return E_INVALIDARG;}////////////////////////////////////////////////////////////////////////////// CheckTransform - checks if we can support the transform from this input to this output////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::CheckTransform(const CMediaType* mtIn, const CMediaType* mtOut){	if (*mtOut->FormatType() != FORMAT_WaveFormatEx)		return VFW_E_INVALIDMEDIATYPE;	if (mtOut->FormatLength() < sizeof(WAVEFORMATEX))		return VFW_E_INVALIDMEDIATYPE;	MPEG_ENCODER_CONFIG	mec;	if(FAILED(m_Encoder.GetOutputType(&mec)))		return S_OK;	if (((LPWAVEFORMATEX)mtIn->Format())->nSamplesPerSec % mec.dwSampleRate != 0)		return S_OK;	if (mec.dwSampleRate != ((LPWAVEFORMATEX)mtOut->Format())->nSamplesPerSec)		return VFW_E_TYPE_NOT_ACCEPTED;	return S_OK;}////////////////////////////////////////////////////////////////////////////// DecideBufferSize - sets output buffers number and size////////////////////////////////////////////////////////////////////////////HRESULT CMpegAudEnc::DecideBufferSize(                        IMemAllocator*		  pAllocator,                        ALLOCATOR_PROPERTIES* pProperties){    HRESULT hr = S_OK;    ///    pProperties->cBuffers = 1;    pProperties->cbBuffer = OUT_BUFFER_SIZE;    //    ASSERT(pProperties->cbBuffer);        ALLOCATOR_PROPERTIES Actual;    hr = pAllocator->SetProperties(pProperties,&Actual);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -