STM32F4 HAL ADC DMA Transfer Error - microcontroller

I'm using an STM32F405OG for a project and one of the necessary functions is monitoring 3 analog channels at ~1 Hz. My desired implementation is starting an ADC DMA read of all 3 channels in Scan mode and retrieving the results at a later time after the DMA complete interrupt has occurred.
I'm using ADC1 and have tried both DMA channels 0 and 4, both with the same result: HAL_ADC_ErrorCallback() is invoked after the first call to HAL_ADC_Start_DMA(). At this point, the ADC handle is in an error state (HAL_ADC_STATE_ERROR_DMA) with the error code 0x04 (HAL_ADC_ERROR_DMA). Checking the linked DMA handle yields a DMA error code of HAL_DMA_ERROR_NO_XFER, meaning "Abort requested with no Xfer ongoing."
I'm totally lost as to what's causing this - my code should be consistent with examples and the "how to use this module" comments at the top of stm32f4xx_hal_adc.c. I've attached my code below.
ADC_HandleTypeDef ADC_hADC =
{
.Instance = ADC1,
.Init =
{
.ClockPrescaler = ADC_CLOCK_SYNC_PCLK_DIV8,
.Resolution = ADC_RESOLUTION_12B,
.EOCSelection = ADC_EOC_SEQ_CONV, // EOC at end of sequence of channel conversions
.ScanConvMode = ENABLE,
.ContinuousConvMode = DISABLE,
.DiscontinuousConvMode = DISABLE,
.NbrOfDiscConversion = 0U,
.ExternalTrigConvEdge = ADC_EXTERNALTRIGCONVEDGE_NONE,
.ExternalTrigConv = ADC_SOFTWARE_START,
.DataAlign = ADC_DATAALIGN_RIGHT,
.NbrOfConversion = _NUM_ADC_CONV,
.DMAContinuousRequests = DISABLE
}
};
DMA_HandleTypeDef _hDmaAdc =
{
.Instance = DMA2_Stream0,
.Init =
{
.Channel = DMA_CHANNEL_0,
.Direction = DMA_PERIPH_TO_MEMORY,
.PeriphInc = DMA_PINC_DISABLE,
.MemInc = DMA_MINC_ENABLE,
.PeriphDataAlignment = DMA_PDATAALIGN_WORD,
.MemDataAlignment = DMA_MDATAALIGN_WORD,
.Mode = DMA_NORMAL,
.Priority = DMA_PRIORITY_HIGH,
.FIFOMode = DMA_FIFOMODE_DISABLE,
.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL,
.MemBurst = DMA_MBURST_SINGLE,
.PeriphBurst = DMA_PBURST_SINGLE
}
};
void HAL_ADC_MspInit(ADC_HandleTypeDef *h)
{
if (!h)
{
return;
}
else if (h->Instance == ADC1)
{
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_DMA2_CLK_ENABLE();
HAL_DMA_Init(&_hDmaAdc);
__HAL_LINKDMA(h, DMA_Handle, _hDmaAdc);
HAL_NVIC_SetPriority(ADC_IRQn, IT_PRIO_ADC, 0);
HAL_NVIC_SetPriority(DMA2_Stream0_IRQn, IT_PRIO_ADC, 0);
HAL_NVIC_EnableIRQ(ADC_IRQn);
HAL_NVIC_EnableIRQ(DMA2_Stream0_IRQn);
}
}
uint32_t _meas[3];
ADC_ChannelConfTypeDef _chanCfg[3] =
{
// VIN_MON
{
.Channel = ADC_CHANNEL_1,
},
// VDD_MON
{
.Channel = ADC_CHANNEL_8,
},
// VDD2_MON
{
.Channel = ADC_CHANNEL_2,
}
};
Bool ADC_Init(void)
{
ADC_DeInit();
memset(_meas, 0, sizeof(_meas));
Bool status = (HAL_ADC_Init(&ADC_hADC) == HAL_OK);
if (status)
{
// Configure each ADC channel
for (uint32_t i = 0U; i < NELEM(_chanCfg); i++)
{
_chanCfg[i].Rank = (i + 1U);
_chanCfg[i].SamplingTime = ADC_SAMPLETIME_480CYCLES;
_chanCfg[i].Offset = 0U;
if (HAL_ADC_ConfigChannel(&ADC_hADC, &_chanCfg[i]) != HAL_OK)
{
status = FALSE;
break;
}
}
_state = ADC_STATE_READY;
}
if (!status)
{
ADC_DeInit();
}
return status;
}
Bool ADC_StartRead(void)
{
Bool status = TRUE;
status = (HAL_ADC_Start_DMA(&ADC_hADC, &_meas[0], 3) == HAL_OK);
return status;
}

After slowing down the conversions via the ClockPrescaler init structure field, increasing the number of ADC cycles, and calling HAL_ADC_Stop_DMA() (per file header comment in stm32f4xx_hal_adc.c), everything is working.
Note that calling HAL_ADC_Stop_DMA() in the DMA Transfer Complete ISR caused the aforementioned error conditions as well, so calls to that function will have to be made sometime after the DMAXferCplt ISR is invoked.

Related

I have an error with this : Thread 1: EXC_BAD_ACCESS (code=1, address=0x18) I don't know if the nil value is because the recording is faulty

This is my code use AVAudioEngine for change voice in my app.
Can anyone point out what's wrong in this code of mine and help me get rid of the error message?
extension AudioPlayer {
func setupAudio(){
// initialize (recording) audio file
do{
audioFile = try AVAudioFile(forReading: recordedAudioURL as URL)
}catch{
print("Audio File Error ")
}
}
func playSound(rate: Float? = nil, pitch: Float? = nil, echo: Bool = false,reverb:Bool = false){
// initialize audio engine components
audioFile = AVAudioFile()
audioEngine = AVAudioEngine()
// node for playing audio
audioPlayerNode = AVAudioPlayerNode()
audioEngine.attach(audioPlayerNode)//attach the player node to the audio engine
audioMixer = AVAudioMixerNode()
audioEngine.attach(audioMixer)// attach a single output to the audio engine
//node for the adjusting rate/pitch
let changeRatePitchNode = AVAudioUnitTimePitch()
if let pitch = pitch {
changeRatePitchNode.pitch = pitch
}
if let rate = rate {
changeRatePitchNode.rate = rate
}
audioEngine.attach(changeRatePitchNode)
//node for the echo
let echoNode = AVAudioUnitDistortion()
echoNode.loadFactoryPreset(.multiEcho1)
audioEngine.attach(echoNode)
//node for the reverb
let reverbNode = AVAudioUnitReverb()
reverbNode.loadFactoryPreset(.cathedral)
reverbNode.wetDryMix = 50
audioEngine.attach(reverbNode)
//connect the player node to the output node
if echo == true && reverb == true{
connectAudioNode(audioPlayerNode,changeRatePitchNode,echoNode,reverbNode,audioMixer,audioEngine.outputNode)
}else if echo == true{
connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode,audioMixer,audioEngine.outputNode)
}else if reverb == true{
connectAudioNode(audioPlayerNode, changeRatePitchNode, echoNode, audioMixer, audioEngine.outputNode)
}else{
connectAudioNode(audioPlayerNode, changeRatePitchNode,audioMixer,audioEngine.outputNode)
}
//schedule to replay the entire audio file- phat lai toan bo tep am thanh
audioPlayerNode.stop()
audioPlayerNode.scheduleFile(audioFile, at: nil)
do{
try audioEngine.start()
}catch{
print("Not OutPut")
}
//generate media resource modeling assets at the specified URL
let audioAsset = AVURLAsset.init(url: recordedAudioURL)
// returns the representation t/g = (s)
let durationInSeconds = CMTimeGetSeconds(audioAsset.duration)
let length = 4000
let buffer = AVAudioPCMBuffer(pcmFormat: audioPlayerNode.outputFormat(forBus: 0), frameCapacity: AVAudioFrameCount(length))
buffer!.frameLength = AVAudioFrameCount(durationInSeconds)//bộ đêmj âm thanh cho định dạng PCM
// MARK: Create a new path after adding effects to the file
let dirPath: AnyObject = NSSearchPathForDirectoriesInDomains(FileManager.SearchPathDirectory.documentDirectory,FileManager.SearchPathDomainMask.userDomainMask, true)[0] as AnyObject
let tmpFileURL : NSURL = NSURL.fileURL(withPath: dirPath.appendingPathComponent("NewVoice.m4a")) as NSURL
filteredOutputURL = tmpFileURL
//setting for new file
do{
print(dirPath)
let settings = [AVFormatIDKey: kAudioFormatLinearPCM,
AVSampleRateKey: 44100,
AVNumberOfChannelsKey: 1]
self.newAudio = try AVAudioFile(forWriting: tmpFileURL as URL, settings: settings)
//setting for output
self.audioMixer.installTap(onBus: 0, bufferSize: (AVAudioFrameCount(durationInSeconds)), format: self.audioPlayerNode.outputFormat(forBus: 0)) { [self](buffer: AVAudioPCMBuffer!, time: AVAudioTime!) in
print(self.newAudio!.length)
print(self.audioFile.length)
if (self.newAudio!.length) < (self.audioFile.length){
do{
try self.newAudio!.write(from: buffer)
}catch {
print("error writing")
}
}else{
audioPlayerNode.removeTap(onBus: 0)
}
}
}catch _{
print("problem")
}
// MARK: Play Sound Effect
audioPlayerNode.play()
}
func connectAudioNode(_ nodes:AVAudioNode...){
for i in 0..<nodes.count-1{
audioEngine.connect(nodes[i], to: nodes[i + 1], format: audioFile.processingFormat)
}//*error here "processingFormat"*
}
}
error: "processingFormat"
I don't know if it's because the link to read the file is wrong or what's wrong with my settings

C++/CX concurrency::create_task with DataReader LoadAsync function cause: 'The operation identifier is not valid.'

I am developing a TCP client module for Hololens 1st gen with native C++/CX.
I create a packet class which contains 1 x (uint32_t) + 7 x (float)
The server is implemented in the synchronized manner, which streams the packets to the client (Hololens) every frame.
Receiver.h
namespace HoloNet {
public ref class holoATCFrameReceiver sealed
{
public:
holoATCFrameReceiver(
_In_ Windows::Networking::Sockets::StreamSocket^ streamSocket);
Windows::Foundation::IAsyncOperation<TrackerFrame^>^ ReceiveAsync();
private:
Concurrency::task<TrackerFrame^> ReceiveTrackerFrameAsync();
private:
Windows::Networking::Sockets::StreamSocket^ _streamSocket;
Windows::Storage::Streams::DataReader^ _reader;
bool _readInProgress;
};
}
and Receiver.cpp
namespace HoloNet {
holoATCFrameReceiver::holoATCFrameReceiver(
Windows::Networking::Sockets::StreamSocket ^ streamSocket)
: _streamSocket(streamSocket)
{
_readInProgress = false;
// reader
_reader = ref new Windows::Storage::Streams::DataReader(
_streamSocket->InputStream);
_reader->UnicodeEncoding =
Windows::Storage::Streams::UnicodeEncoding::Utf8;
_reader->ByteOrder =
Windows::Storage::Streams::ByteOrder::LittleEndian;
}
Windows::Foundation::IAsyncOperation<TrackerFrame^>^ holoATCFrameReceiver::ReceiveAsync()
{
return concurrency::create_async(
[this]()
{
return ReceiveTrackerFrameAsync();
});
}
Concurrency::task<TrackerFrame^>
holoATCFrameReceiver::ReceiveTrackerFrameAsync()
{
return concurrency::create_task(
_reader->LoadAsync(TrackerFrame::TrackerFrameLength)
).then([this](Concurrency::task<unsigned int> headerBytesLoadedTaskResult)
{
headerBytesLoadedTaskResult.wait();
const size_t frameBytesLoaded = headerBytesLoadedTaskResult.get();
if (TrackerFrame::TrackerFrameLength != frameBytesLoaded)
{
throw ref new Platform::FailureException();
}
_readInProgress = true;
TrackerFrame^ header;
TrackerFrame::Read(
_reader,
&header);
dbg::trace(
L"SensorFrameReceiver::ReceiveAsync: sensor %i: t( %f, %f %f ), q( %f, %f, %f, %f)",
header->sensorID,
header->x,
header->y,
header->z,
header->qw,
header->qx,
header->qy,
header->qz);
_readInProgress = false;
return header;
});
}
}
The error throws at * _reader->LoadAsync(TrackerFrame::TrackerFrameLength) *
The receiver is called in the client class like below:
void holoTcpATCClient::OnReceiveATCframe(TrackerFrame^& header) {
std::lock_guard<std::mutex> guard(_socketMutex);
// check read in process
if (_readInProcess)
{
return;
}
_readInProcess = true;
concurrency::create_task(
_receiver->ReceiveAsync()).then(
[&](concurrency::task<TrackerFrame^> sensorFrameTask)
{
sensorFrameTask.wait();
TrackerFrame^ sensorFrame = sensorFrameTask.get()
header = sensorFrame;
});
_readInProcess = false;
}
_receiver->ReceiveAsync() is the begining of the error.
I wonder whether there is a way to pretend this happens by doing some modification on LoadAsync() of DataReader for StreamSocket under concurrency:: create_task?
Thank you very much for your help in advance!

Is there any control property to fix video playback speed problem when using ffmpeg to decode in Qt platform?

I want to play local video file in Qt platform using ffmpeg to decode.Everything is OK except that play speed is as twice as normal.
The first thing I think about is that there must be a sampling frequency involved.But to be a new to ffmpeg,I don't know how to fix this problem.
Above is my code to read frame,is anyone can tell me what's wrong with the code ?
void VideoThread::run()
{
m_pInFmtCtx = avformat_alloc_context(); //ini struct
char path[] = "d:/test.mp4";
// open specific file
if(avformat_open_input(&m_pInFmtCtx, *path, NULL, NULL)){
{
qDebug()<<"get rtsp failed";
return;
}
else
{
qDebug()<<"get rtsp success";
}
if(avformat_find_stream_info(m_pInFmtCtx, NULL) < 0)
{
qDebug()<<"could not find stream information";
return;
}
int nVideoIndex = -1;
for(int i = 0; i < m_pInFmtCtx->nb_streams; i++)
{
if(m_pInFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
nVideoIndex = i;
break;
}
}
if(nVideoIndex == -1)
{
qDebug()<<"could not find video stream";
return;
}
qDebug("---------------- File Information ---------------");
m_pCodecCtx = m_pInFmtCtx->streams[nVideoIndex]->codec;
m_pCodec = avcodec_find_decoder(m_pCodecCtx->codec_id);
if(!m_pCodec)
{
qDebug()<<"could not find codec";
return;
}
//start Decoder
if (avcodec_open2(m_pCodecCtx, m_pCodec, NULL) < 0) {
qDebug("Could not open codec.\n");
return;
}
//malloc space for stroring frame
m_pFrame = av_frame_alloc();
m_pFrameRGB = av_frame_alloc();
m_pOutBuf = (uint8_t*)av_malloc(avpicture_get_size(AV_PIX_FMT_RGB32, m_pCodecCtx->width, m_pCodecCtx->height));
avpicture_fill((AVPicture*)m_pFrameRGB, m_pOutBuf, AV_PIX_FMT_RGB32, m_pCodecCtx->width, m_pCodecCtx->height);
//for color switch,from YUV to RGB
struct SwsContext *pImgCtx = sws_getContext(m_pCodecCtx->width, m_pCodecCtx->height, m_pCodecCtx->pix_fmt,
m_pCodecCtx->width, m_pCodecCtx->height, AV_PIX_FMT_RGB32, SWS_BICUBIC, NULL, NULL, NULL);
int nSize = m_pCodecCtx->width * m_pCodecCtx->height;
m_pPacket = (AVPacket *)av_malloc(sizeof(AVPacket));
if(av_new_packet(m_pPacket, nSize) != 0)
{
qDebug()<<"new packet failed";
}
//isInterruptionRequested is a flag,determine whether the thread is over
// read each frame from specific video file
while (!isInterruptionRequested())
{
int nGotPic = 0;
if(av_read_frame(m_pInFmtCtx, m_pPacket) >= 0)
{
if(m_pPacket->stream_index == nVideoIndex)
{
//avcodec_decode_video2()transform from packet to frame
if(avcodec_decode_video2(m_pCodecCtx, m_pFrame, &nGotPic, m_pPacket) < 0)
{
qDebug()<<"decode failed";
return;
}
if(nGotPic)
{ // transform to RGB color
sws_scale(pImgCtx, (const uint8_t* const*)m_pFrame->data,
m_pFrame->linesize, 0, m_pCodecCtx->height, m_pFrameRGB->data,
m_pFrameRGB->linesize);
// save to QImage,for later use
QImage *pImage = new QImage((uchar*)m_pOutBuf, m_pCodecCtx->width, m_pCodecCtx->height, QImage::Format_RGB32);
}
}
}
av_free_packet(m_pPacket);
msleep(5);
}
exec();
}

GetMonitorCapabilities returns false

I want to adjust the brightness of my monitor on Windows.
I follow this page:
How to use GetMonitorCapabilities and GetMonitorBrightness functions
but, the GetMonitorCapabilities function returns false.
I printed using qDebug, hPhysicalMonitor is NULL. Is this point wrong?
(The GetPhysicalMonitorsFromHMONITOR function returns true)
How can I fix this code?
HMONITOR hMonitor = NULL;
DWORD cPhysicalMonitors = 1;
LPPHYSICAL_MONITOR pPhysicalMonitors;
HWND hWnd = GetDesktopWindow();
// Get the monitor handle.
hMonitor = MonitorFromWindow(hWnd, MONITOR_DEFAULTTOPRIMARY);
// Get the number of physical monitors.
BOOL bSuccess = GetNumberOfPhysicalMonitorsFromHMONITOR(hMonitor, &cPhysicalMonitors);
if (bSuccess)
{
// Allocate the array of PHYSICAL_MONITOR structures.
pPhysicalMonitors = (LPPHYSICAL_MONITOR)malloc(cPhysicalMonitors* sizeof(PHYSICAL_MONITOR));
if (pPhysicalMonitors != NULL)
{
// Get the array.
bSuccess = GetPhysicalMonitorsFromHMONITOR( hMonitor, cPhysicalMonitors, pPhysicalMonitors);
if (bSuccess == FALSE)
{
qDebug("GetPhysicalMonitorsFromHMONITOR");
}
// Get physical monitor handle.
HANDLE hPhysicalMonitor = pPhysicalMonitors[0].hPhysicalMonitor;
DWORD pdwMonitorCapabilities = 0;
DWORD pdwSupportedColorTemperatures = 0;
bSuccess = GetMonitorCapabilities(hPhysicalMonitor, &pdwMonitorCapabilities, &pdwSupportedColorTemperatures);
if (bSuccess == FALSE)
{
qDebug("GetMonitorCapabilities");
}
DWORD pdwMinimumBrightness = 0;
DWORD pdwCurrentBrightness = 0;
DWORD pdwMaximumBrightness = 0;
bSuccess = GetMonitorBrightness(hPhysicalMonitor, &pdwMinimumBrightness, &pdwCurrentBrightness, &pdwMaximumBrightness);
if (bSuccess == FALSE)
{
qDebug("GetMonitorBrightness");
}
qDebug(QByteArray::number(bSuccess));
qDebug(QByteArray::number((WORD)pdwMinimumBrightness));
qDebug(QByteArray::number((WORD)pdwCurrentBrightness));
qDebug(QByteArray::number((WORD)pdwMaximumBrightness));
// Close the monitor handles.
bSuccess = DestroyPhysicalMonitors(cPhysicalMonitors, pPhysicalMonitors);
// Free the array.
free(pPhysicalMonitors);
}
}
If you want to adjust the brightness using WmiMonitorBrightnessMethods use the code below.
public static void SetWmiMonitorBrightness(byte targetBrightness)
{
ManagementScope scope = new ManagementScope("root\\WMI");
SelectQuery query = new SelectQuery("WmiMonitorBrightnessMethods");
using (ManagementObjectSearcher searcher = new ManagementObjectSearcher(scope, query))
{
using (ManagementObjectCollection objectCollection = searcher.Get())
{
foreach (ManagementObject mObj in objectCollection)
{
mObj.InvokeMethod("WmiSetBrightness",
new Object[] { UInt32.MaxValue, targetBrightness });
break;
}
}
}
}
Doing GetMonitorBrightness on the specific monitor I have causes ERROR_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA.
So I used WmiSetBrightness instead. It works fine.
If you got a tip related to ERROR_GRAPHICS_I2C_ERROR_TRANSMITTING_DATA, please share it with me.

Negotiating an allocator between Directshow filters fails

I'm developing a custom Directshow source filter to provide decompressed video data to a rendering filter. I've used the PushSource sample provided by the Directshow SDK as a basis for my filter. I'm attempting to connect this to a VideoMixingRenderer9 filter.
When creating the graph I'm calling ConnectDirect():
HRESULT hr = mp_graph_builder->ConnectDirect(OutPin, InPin, &mediaType);
but during this call, calling SetProperties on the downstream filters allocator (in DecideBufferSize()), fails with D3DERR_INVALIDCALL (0x8876086c):
ALLOCATOR_PROPERTIES actual;
memset(&actual,0,sizeof(actual));
hr = pAlloc->SetProperties(pRequest, &actual);
If I let it try to use my allocator (the one provided by CBaseOutputPin) when setting the allocator on the downstream filter, this fails with E_FAIL (in CBaseOutputPin::DecideAllocator)
hr = pPin->NotifyAllocator(*ppAlloc, FALSE);
Any help would be much appreciated!
Thanks.
EDIT:
This is the media type provided by GetMediaType
VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)pMediaType->AllocFormatBuffer(sizeof(VIDEOINFOHEADER));
if (pvi == 0)
return(E_OUTOFMEMORY);
ZeroMemory(pvi, pMediaType->cbFormat);
pvi->AvgTimePerFrame = m_rtFrameLength;
pMediaType->formattype = FORMAT_VideoInfo;
pMediaType->majortype = MEDIATYPE_Video;
pMediaType->subtype = MEDIASUBTYPE_RGB24;
pMediaType->bTemporalCompression = FALSE;
pMediaType->bFixedSizeSamples = TRUE;
pMediaType->formattype = FORMAT_VideoInfo;
pvi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
pvi->bmiHeader.biWidth = (640 / 128 + 1) * 128;
pvi->bmiHeader.biHeight = -480; // negative so top down..
pvi->bmiHeader.biPlanes = 1;
pvi->bmiHeader.biBitCount = 24;
pvi->bmiHeader.biCompression = NULL; // ok if rgb else use MAKEFOURCC(...)
pvi->bmiHeader.biSizeImage = GetBitmapSize(&pvi->bmiHeader);
pvi->bmiHeader.biClrImportant = 0;
pvi->bmiHeader.biClrUsed = 0; //Use max colour depth
pvi->bmiHeader.biXPelsPerMeter = 0;
pvi->bmiHeader.biYPelsPerMeter = 0;
SetRectEmpty(&(pvi->rcSource));
SetRectEmpty(&(pvi->rcTarget));
pvi->rcSource.bottom = 480;
pvi->rcSource.right = 640;
pvi->rcTarget.bottom = 480;
pvi->rcTarget.right = 640;
pMediaType->SetType(&MEDIATYPE_Video);
pMediaType->SetFormatType(&FORMAT_VideoInfo);
pMediaType->SetTemporalCompression(FALSE);
const GUID SubTypeGUID = GetBitmapSubtype(&pvi->bmiHeader);
pMediaType->SetSubtype(&SubTypeGUID);
pMediaType->SetSampleSize(pvi->bmiHeader.biSizeImage);
and DecideBufferSize where pAlloc->SetProperties is called
HRESULT CPushPinBitmap::DecideBufferSize(IMemAllocator *pAlloc, ALLOCATOR_PROPERTIES *pRequest) {
HRESULT hr;
CAutoLock cAutoLock(CBasePin::m_pLock);
CheckPointer(pAlloc, E_POINTER);
CheckPointer(pRequest, E_POINTER);
if (pRequest->cBuffers == 0) {
pRequest->cBuffers = 2;
}
pRequest->cbBuffer = 480 * ( (640 / 128 + 1) * 128 ) * 3;
ALLOCATOR_PROPERTIES actual;
memset(&actual,0,sizeof(actual));
hr = pAlloc->SetProperties(pRequest, &actual);
if (FAILED(hr)) {
return hr;
}
if (actual.cbBuffer < pRequest->cbBuffer) {
return E_FAIL;
}
return S_OK;
}
The constants are only temporary!
There is no way you can use your own allocator with VMR/EVR filters. They just insist on their own, which in turn is backed on DirectDraw/Direct3D surfaces.
To connect directly to VMR/EVR filters you need a different strategy. The allocator is always theirs. You need to support extended strides. See Handling Format Changes from the Video Renderer.

Resources