//----------------------------------------------------------------------------- // Name: CreateBuffer() // Desc: create a CMediaBuffer //----------------------------------------------------------------------------- HRESULT CreateBuffer( DWORD cbMaxLength, CMediaBuffer **ppBuffer) { CMediaBuffer *pBuffer = new CMediaBuffer( cbMaxLength ); if ( pBuffer == NULL || FAILED( pBuffer->Init() ) ) { delete pBuffer; *ppBuffer = NULL; return E_OUTOFMEMORY; } *ppBuffer = pBuffer; (*ppBuffer)->AddRef(); return S_OK; }
BOOL DMOProcessInputFile(DWORD dwSize, ASF_FILE_INFO* pInfo) { HRESULT hr; LPBYTE pbInBuf; DWORD dwInBuf, dwRead; CMediaBuffer* pmbIn = new CMediaBuffer(dwSize); if (!pmbIn) return FALSE; pmbIn->GetBufferAndLength(&pbInBuf, &dwInBuf); if (!ReadFile(pInfo->hFile, pbInBuf, dwSize, &dwRead, NULL) || dwRead != dwSize) return FALSE; pmbIn->SetLength(dwSize); hr = pInfo->pMediaObject->ProcessInput(0, pmbIn, pInfo->PayloadInfo.Key ? DMO_INPUT_DATA_BUFFERF_SYNCPOINT : 0, 0, 0); pmbIn->Release(); return hr == S_OK ? TRUE : FALSE; }
HRESULT CAppStream::Stream( BYTE **ppbOutData, ULONG *pbDataSize, LPWAVEFORMATEX *ppwfx ) { HRESULT hr = S_OK; BYTE *pOut; *pbDataSize = m_uDataSize; *ppwfx = m_pwfx; if ( m_pObjectInPlace ){ pOut = new BYTE [m_uDataSize]; if( pOut == 0 ){ return E_OUTOFMEMORY; } CopyMemory(pOut, m_pbInData, m_uDataSize); // pass the number of samples to Process() hr = m_pObjectInPlace->Process( m_uDataSize, pOut, 0, DMO_INPLACE_NORMAL); if( FAILED( hr ) ){ return hr; } *ppbOutData = pOut; SAFE_RELEASE( m_pObjectInPlace ); } else { CMediaBuffer *pInputBuffer; const REFERENCE_TIME rtStart = 0; const REFERENCE_TIME rtStop = 0; BYTE* pBuffer; DWORD dwLength; // create and fill CMediaBuffer hr = CreateBuffer(m_uDataSize, &pInputBuffer); if( FAILED( hr ) ){ return hr; } hr = pInputBuffer->GetBufferAndLength( &pBuffer, &dwLength ); if( FAILED( hr ) ){ return hr; } CopyMemory(pBuffer, m_pbInData, m_uDataSize); hr = pInputBuffer->SetLength( m_uDataSize ); if( FAILED( hr ) ){ return hr; } // call processInput hr = m_pObject->ProcessInput( 0, pInputBuffer, DMO_INPUT_DATA_BUFFERF_SYNCPOINT, rtStart, rtStop - rtStart); if( FAILED( hr ) ){ return hr; } //release input buffer SAFE_RELEASE( pInputBuffer ); // retrieve the output data from DMO and put into pOut if(S_FALSE == hr){ return E_FAIL; } else { pOut = NULL; hr = ProcessOutputs( &pOut ); if( FAILED( hr ) ){ delete [] pOut; return hr; } } *ppbOutData = pOut; SAFE_RELEASE( m_pObject ); } return S_OK; }
STDMETHODIMP CDecWMV9::ProcessOutput() { HRESULT hr = S_OK; DWORD dwStatus = 0; BYTE *pBuffer = GetBuffer(m_pRawBufferSize); CMediaBuffer *pOutBuffer = new CMediaBuffer(pBuffer, m_pRawBufferSize, true); pOutBuffer->SetLength(0); DMO_OUTPUT_DATA_BUFFER OutputBufferStructs[1]; memset(&OutputBufferStructs[0], 0, sizeof(DMO_OUTPUT_DATA_BUFFER)); OutputBufferStructs[0].pBuffer = pOutBuffer; hr = m_pDMO->ProcessOutput(0, 1, OutputBufferStructs, &dwStatus); if (FAILED(hr)) { ReleaseBuffer(pBuffer); DbgLog((LOG_TRACE, 10, L"-> ProcessOutput failed with hr: %x", hr)); return S_FALSE; } if (hr == S_FALSE) { ReleaseBuffer(pBuffer); return S_FALSE; } LAVFrame *pFrame = NULL; AllocateFrame(&pFrame); BITMAPINFOHEADER *pBMI = NULL; videoFormatTypeHandler(mtOut, &pBMI); pFrame->width = pBMI->biWidth; pFrame->height = pBMI->biHeight; pFrame->format = m_OutPixFmt; pFrame->key_frame = (OutputBufferStructs[0].dwStatus & DMO_OUTPUT_DATA_BUFFERF_SYNCPOINT); AVRational display_aspect_ratio; int64_t num = (int64_t)m_StreamAR.num * pBMI->biWidth; int64_t den = (int64_t)m_StreamAR.den * pBMI->biHeight; av_reduce(&display_aspect_ratio.num, &display_aspect_ratio.den, num, den, 1 << 30); BYTE contentType = 0; DWORD dwPropSize = 1; pOutBuffer->GetProperty(WM_SampleExtensionGUID_ContentType, &contentType, &dwPropSize); pFrame->interlaced = !!(contentType & WM_CT_INTERLACED); pFrame->repeat = !!(contentType & WM_CT_REPEAT_FIRST_FIELD); LAVDeintFieldOrder fo = m_pSettings->GetDeintFieldOrder(); pFrame->tff = (fo == DeintFieldOrder_Auto) ? !!(contentType & WM_CT_TOP_FIELD_FIRST) : (fo == DeintFieldOrder_TopFieldFirst); if (pFrame->interlaced && !m_bInterlaced) m_bInterlaced = TRUE; pFrame->interlaced = (pFrame->interlaced || (m_bInterlaced && m_pSettings->GetDeinterlacingMode() == DeintMode_Aggressive) || m_pSettings->GetDeinterlacingMode() == DeintMode_Force) && !(m_pSettings->GetDeinterlacingMode() == DeintMode_Disable); if (m_bManualReorder) { if (!m_timestampQueue.empty()) { pFrame->rtStart = m_timestampQueue.front(); m_timestampQueue.pop(); if (OutputBufferStructs[0].dwStatus & DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH) { pFrame->rtStop = pFrame->rtStart + OutputBufferStructs[0].rtTimelength; } } } else { if (OutputBufferStructs[0].dwStatus & DMO_OUTPUT_DATA_BUFFERF_TIME) { pFrame->rtStart = OutputBufferStructs[0].rtTimestamp; if (OutputBufferStructs[0].dwStatus & DMO_OUTPUT_DATA_BUFFERF_TIMELENGTH) { pFrame->rtStop = pFrame->rtStart + OutputBufferStructs[0].rtTimelength; } } } // Check alignment // If not properly aligned, we need to make the data aligned. int alignment = (m_OutPixFmt == LAVPixFmt_NV12) ? 16 : 32; if ((pFrame->width % alignment) != 0) { AllocLAVFrameBuffers(pFrame); size_t ySize = pFrame->width * pFrame->height; memcpy_plane(pFrame->data[0], pBuffer, pFrame->width, pFrame->stride[0], pFrame->height); if (m_OutPixFmt == LAVPixFmt_NV12) { memcpy_plane(pFrame->data[1], pBuffer+ySize, pFrame->width, pFrame->stride[1], pFrame->height / 2); } else if (m_OutPixFmt == LAVPixFmt_YUV420) { size_t uvSize = ySize / 4; memcpy_plane(pFrame->data[2], pBuffer+ySize, pFrame->width / 2, pFrame->stride[2], pFrame->height / 2); memcpy_plane(pFrame->data[1], pBuffer+ySize+uvSize, pFrame->width / 2, pFrame->stride[1], pFrame->height / 2); } ReleaseBuffer(pBuffer); } else { if (m_OutPixFmt == LAVPixFmt_NV12) { pFrame->data[0] = pBuffer; pFrame->data[1] = pBuffer + pFrame->width * pFrame->height; pFrame->stride[0] = pFrame->stride[1] = pFrame->width; } else if (m_OutPixFmt == LAVPixFmt_YUV420) { pFrame->data[0] = pBuffer; pFrame->data[2] = pBuffer + pFrame->width * pFrame->height; pFrame->data[1] = pFrame->data[2] + (pFrame->width / 2) * (pFrame->height / 2); pFrame->stride[0] = pFrame->width; pFrame->stride[1] = pFrame->stride[2] = pFrame->width / 2; } pFrame->destruct = wmv9_buffer_destruct; pFrame->priv_data = this; } pFrame->flags |= LAV_FRAME_FLAG_BUFFER_MODIFY; Deliver(pFrame); SafeRelease(&pOutBuffer); if (OutputBufferStructs[0].dwStatus & DMO_OUTPUT_DATA_BUFFERF_INCOMPLETE) return ProcessOutput(); return hr; }