static void CommitDecommitTest(void) { IMemAllocator* pMemAllocator; HRESULT hr; hr = CoCreateInstance(&CLSID_MemoryAllocator, NULL, CLSCTX_INPROC_SERVER, &IID_IMemAllocator, (LPVOID*)&pMemAllocator); ok(hr==S_OK, "Unable to create memory allocator %x\n", hr); if (hr == S_OK) { ALLOCATOR_PROPERTIES RequestedProps; ALLOCATOR_PROPERTIES ActualProps; IMediaSample *sample = NULL, *sample2 = NULL; RequestedProps.cBuffers = 2; RequestedProps.cbBuffer = 65536; RequestedProps.cbAlign = 1; RequestedProps.cbPrefix = 0; hr = IMemAllocator_SetProperties(pMemAllocator, &RequestedProps, &ActualProps); ok(hr==S_OK, "SetProperties returned: %x\n", hr); hr = IMemAllocator_Commit(pMemAllocator); ok(hr==S_OK, "Commit returned: %x\n", hr); hr = IMemAllocator_Commit(pMemAllocator); ok(hr==S_OK, "Commit returned: %x\n", hr); hr = IMemAllocator_GetBuffer(pMemAllocator, &sample, NULL, NULL, 0); ok(hr==S_OK, "Could not get a buffer: %x\n", hr); hr = IMemAllocator_Decommit(pMemAllocator); ok(hr==S_OK, "Decommit returned: %x\n", hr); hr = IMemAllocator_Decommit(pMemAllocator); ok(hr==S_OK, "Cecommit returned: %x\n", hr); /* Decommit and recommit while holding a sample */ if (sample) { hr = IMemAllocator_Commit(pMemAllocator); ok(hr==S_OK, "Commit returned: %x\n", hr); hr = IMemAllocator_GetBuffer(pMemAllocator, &sample2, NULL, NULL, 0); ok(hr==S_OK, "Could not get a buffer: %x\n", hr); IUnknown_Release(sample); if (sample2) IUnknown_Release(sample2); hr = IMemAllocator_Decommit(pMemAllocator); ok(hr==S_OK, "Cecommit returned: %x\n", hr); } IMemAllocator_Release(pMemAllocator); } }
static HRESULT FFMVWrapper_ProcessReceive( CTransformBaseImpl* pImpl, IMediaSample* pSampIn ) { CFFMVWrapperImpl* This = pImpl->m_pUserData; BYTE* pDataIn = NULL; LONG lDataInLen; IMediaSample* pSampOut = NULL; BYTE* pOutBuf; HRESULT hr; AVFrame tmp_pic; AVPicture dst_pic; int nOut, got_pic; LONG width, height; REFERENCE_TIME rtStart, rtStop, rtNow; BOOL skip; TRACE("(%p)\n",This); if ( This == NULL || !This->ctx.codec || This->m_pbiIn == NULL || This->m_pbiOut == NULL ) return E_UNEXPECTED; hr = IMediaSample_GetPointer( pSampIn, &pDataIn ); if ( FAILED(hr) ) return hr; lDataInLen = IMediaSample_GetActualDataLength( pSampIn ); if ( lDataInLen < 0 ) return E_FAIL; EnterCriticalSection( &This->m_cs ); if ( !This->ctx.codec ) { hr = E_UNEXPECTED; goto failed; } if ( IMediaSample_IsDiscontinuity( pSampIn ) == S_OK ) avcodec_flush_buffers( &This->ctx ); width = This->m_pbiIn->bmiHeader.biWidth; height = (This->m_pbiIn->bmiHeader.biHeight < 0) ? -This->m_pbiIn->bmiHeader.biHeight : This->m_pbiIn->bmiHeader.biHeight; while ( TRUE ) { nOut = avcodec_decode_video( &This->ctx, &tmp_pic, &got_pic, (void*)pDataIn, lDataInLen ); if ( nOut < 0 ) { TRACE("decoding error\n"); goto fail; } TRACE("used %d of %d bytes\n", nOut, lDataInLen); if ( nOut > lDataInLen ) { WARN("arrgh - FFmpeg read too much\n"); nOut = lDataInLen; } pDataIn += nOut; lDataInLen -= nOut; if (!got_pic) { TRACE("no frame decoded\n"); if (lDataInLen) continue; LeaveCriticalSection( &This->m_cs ); return S_OK; } TRACE("frame decoded\n"); This->rtInternal ++; hr = IMediaSample_GetTime( pSampIn, &rtStart, &rtStop ); if ( hr == S_OK ) { /* if the parser gives us a timestamp, the data * we got from it should be a single frame */ if ( lDataInLen ) { ERR("excessive data in compressed frame\n"); lDataInLen = 0; } } else { /* compute our own timestamp */ rtStart = This->rtCur; This->rtCur = This->rtInternal * (REFERENCE_TIME)QUARTZ_TIMEUNITS * This->ctx.frame_rate_base / This->ctx.frame_rate; rtStop = This->rtCur; } TRACE("frame start=%lld, stop=%lld\n", rtStart, rtStop); skip = FALSE; hr = IReferenceClock_GetTime(pImpl->basefilter.pClock, &rtNow); if (SUCCEEDED(hr)) { rtNow -= pImpl->basefilter.rtStart; TRACE("time=%lld\n", rtNow); if (rtStart < rtNow + SKIP_TIME) { skip = TRUE; if ( ++This->skipFrames >= MAX_SKIP ) { This->skipFrames = 0; TRACE("frame late, but max skip exceeded\n"); skip = FALSE; } } } if (skip) { TRACE("skipping late frame\n"); if ( lDataInLen == 0 ) { LeaveCriticalSection( &This->m_cs ); return S_OK; } } else { /* process frame */ hr = IMemAllocator_GetBuffer( pImpl->m_pOutPinAllocator, &pSampOut, &rtStart, &rtStop, 0 ); if ( FAILED(hr) ) goto failed; hr = IMediaSample_GetPointer( pSampOut, &pOutBuf ); if ( FAILED(hr) ) goto failed; dst_pic.data[0] = ( This->m_pOutBuf != NULL ) ? This->m_pOutBuf : pOutBuf; dst_pic.linesize[0] = DIBWIDTHBYTES(This->m_pbiOut->bmiHeader); /* convert to RGB (or BGR) */ switch (This->m_pbiOut->bmiHeader.biBitCount) { case 24: img_convert( &dst_pic, PIX_FMT_BGR24, (AVPicture*)&tmp_pic, This->ctx.pix_fmt, width, height ); break; case 32: /* RGBA32 is misnamed (is actually cpu-endian ARGB, which means BGRA on x86), * might get renamed in future ffmpeg snapshots */ img_convert( &dst_pic, PIX_FMT_RGBA32, (AVPicture*)&tmp_pic, This->ctx.pix_fmt, width, height ); break; default: TRACE("bad bpp\n"); goto fail; } if ( This->m_pOutBuf != NULL ) memcpy( pOutBuf, This->m_pOutBuf, This->m_pbiOut->bmiHeader.biSizeImage ); IMediaSample_SetActualDataLength( pSampOut, This->m_pbiOut->bmiHeader.biSizeImage ); /* FIXME: discontinuity and sync point */ LeaveCriticalSection( &This->m_cs ); hr = CPinBaseImpl_SendSample( &pImpl->pOutPin->pin, pSampOut ); if ( FAILED(hr) ) return hr; IMediaSample_Release( pSampOut ); pSampOut = NULL; if ( lDataInLen == 0 ) return S_OK; EnterCriticalSection( &This->m_cs ); if ( !This->ctx.codec ) { hr = E_UNEXPECTED; goto failed; } } } fail: hr = E_FAIL; failed: LeaveCriticalSection( &This->m_cs ); return hr; }