最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

winapi - Unable to write audio to WMV file with IMFSinkWriter - Stack Overflow

programmeradmin1浏览0评论

I'm trying to create a WMV file with video and audio using IMFSikWriter. The video works perfectly, and the audio gets written without any errors. However, upon playing the resulting WMV file, there's no sound.

Further, the source video and audio content, when stored as a WMV file with ffmpeg, occupies about 2 megabytes. The one created with my code occupies about 77 megabytes.

These are the relevant portions of the code I've written - simplified here, with no error checking, as it's not actually running into any errors.

The audio is stored as a PCMWAVFORMAT followed by 16-bit short integer samples.

I suspect that I've omitted setting a parameter that the IMFSinkWriter interface and its various components wants to see.

Madness is setting in - if anyone has any suggestions as to what I should try, I'd be grateful.

Thanks.


HRESULT CreateAudioSinkWriter(IMFSinkWriter *pSinkWriter,DWORD *pStreamIndexAudio,HANDLE hAudio)
{
        PCMWAVEFORMAT *pwave = NULL;
        IMFMediaType *pAudioType = NULL;
        DWORD streamIndexAudio = 0;
        HRESULT hr;
        long nChannels = 2;
        long nSamplesPerSec = 44100;
        long wBitsPerSample = 16;
        long nBlockAlign = 4;
        long nAvgBytesPerSec = 176400;

        if(hAudio != NULL) {
                if((pwave = (PCMWAVEFORMAT *)GlobalLock(hAudio)) != NULL) {
                        nChannels = pwave->wf.nChannels;
                        nSamplesPerSec = pwave->wf.nSamplesPerSec;
                        wBitsPerSample = pwave->wBitsPerSample;

                        nBlockAlign = nChannels * (wBitsPerSample / 8);
                        nAvgBytesPerSec = nBlockAlign * nSamplesPerSec;

                        GlobalUnlock(hAudio);
                }
        }

        hr = MFCreateMediaType(&pAudioType);
        hr = pAudioType->SetGUID(MF_MT_MAJOR_TYPE,MFMediaType_Audio);
        hr = pAudioType->SetGUID(MF_MT_SUBTYPE,MFAudioFormat_WMAudioV8);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_BITS_PER_SAMPLE,wBitsPerSample);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_SAMPLES_PER_SECOND,nSamplesPerSec);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_NUM_CHANNELS,nChannels);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_BLOCK_ALIGNMENT,nBlockAlign);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_AVG_BYTES_PER_SECOND,nAvgBytesPerSec);
        hr = pAudioType->SetUINT32(MF_MT_AUDIO_PREFER_WAVEFORMATEX,TRUE);
        hr = pSinkWriter->AddStream(pAudioType,&streamIndexAudio);

        *pStreamIndexAudio = streamIndexAudio;

        SafeRelease(pAudioType);

        return(hr);
}

HRESULT CreateSinkWriter(const WCHAR *outputFile,IMFSinkWriter **ppWriter,DWORD *pStreamIndex,DWORD *pStreamIndexAudio,long width,long height,long rate,HANDLE hAudio) 
{
        *ppWriter = NULL;
        *pStreamIndex = NULL;
        *pStreamIndexAudio = NULL;

        IMFSinkWriter *pSinkWriter=NULL;
        IMFAttributes *pAttributes=NULL;
        HRESULT hr;
 
        hr = MFCreateAttributes(&pAttributes,2);
    hr = pAttributes->SetUINT32(MF_READWRITE_ENABLE_HARDWARE_TRANSFORMS,TRUE);
    hr = pAttributes->SetUINT32(MF_SINK_WRITER_DISABLE_THROTTLING,TRUE);
        hr = MFCreateSinkWriterFromURL(outputFile,NULL,pAttributes,&pSinkWriter);
        hr = CreateVideoSinkWriter(pSinkWriter,pStreamIndex,width,height,rate);
        hr = CreateAudioSinkWriter(pSinkWriter,pStreamIndexAudio,hAudio);
        hr = pSinkWriter->BeginWriting();       

        *ppWriter = pSinkWriter;
        (*ppWriter)->AddRef();

        SafeRelease(pAttributes);
        SafeRelease(pSinkWriter);
      
        return(hr);
}


HRESULT WriteAudioData(IMFSinkWriter *pWriter,DWORD streamIndex,HANDLE hAudio)
{
        HRESULT hr = S_OK;
        IMFSample *pSample=NULL;
        IMFMediaBuffer *pBuffer=NULL;
        DWORD sampleSize = GlobalSize(hAudio) - sizeof(PCMWAVEFORMAT);
        PCMWAVEFORMAT *pwave;
        LONGLONG duration;
        BYTE *pData;
        char *ps;
        DWORD chunkSize = 8192;
        LONGLONG sampleTime = 0;

        if((ps = (char *)GlobalLock(hAudio)) == NULL) return(E_OUTOFMEMORY);

        pwave = (PCMWAVEFORMAT *)ps;
        ps += sizeof(PCMWAVEFORMAT);

        while(sampleSize > 0) {
                DWORD currentChunkSize = min(chunkSize,sampleSize);

                duration = (LONGLONG)((double)currentChunkSize / (pwave->wf.nSamplesPerSec * pwave->wf.nBlockAlign) * 10000000);
                
                hr = MFCreateMemoryBuffer(currentChunkSize,&pBuffer);
                hr = pBuffer->Lock(&pData,NULL,NULL);
                
                memcpy(pData,ps,currentChunkSize);

                hr = pBuffer->Unlock();
                hr = pBuffer->SetCurrentLength(currentChunkSize);
                hr = MFCreateSample(&pSample);
                hr = pSample->AddBuffer(pBuffer);
        hr = pSample->SetSampleTime(sampleTime);
        hr = pSample->SetSampleDuration(duration);
        hr = pWriter->WriteSample(streamIndex,pSample);
                
                ps += currentChunkSize;
                sampleSize -= currentChunkSize;
                sampleTime += duration;

                SafeRelease(pBuffer);
                SafeRelease(pSample);
        }

        SafeRelease(pBuffer);
        SafeRelease(pSample);
        GlobalUnlock(hAudio);
        return(hr);
}
发布评论

评论列表(0)

  1. 暂无评论