GstFlowReturn got_data(GstPad *pad, GstObject *parent, GstBuffer *buf) { GstTfImpl *This = gst_pad_get_element_private(pad); IMediaSample *sample = (IMediaSample *) gst_mini_object_get_qdata(GST_MINI_OBJECT(buf), g_quark_from_static_string(media_quark_string)); REFERENCE_TIME tStart, tStop; HRESULT hr; TRACE("%p, %p\n", pad, buf); if(!sample){ GstMapInfo info; BYTE *ptr; gst_buffer_map(buf, &info, GST_MAP_READ); hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &sample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Could not get output buffer: %08x\n", hr); return GST_FLOW_FLUSHING; } IMediaSample_SetActualDataLength(sample, info.size); IMediaSample_GetPointer(sample, &ptr); memcpy(ptr, info.data, info.size); gst_buffer_unmap(buf, &info); } if (GST_BUFFER_PTS_IS_VALID(buf) && GST_BUFFER_DURATION_IS_VALID(buf)) { tStart = buf->pts / 100; tStop = tStart + buf->duration / 100; IMediaSample_SetTime(sample, &tStart, &tStop); } else IMediaSample_SetTime(sample, NULL, NULL); if (GST_BUFFER_OFFSET_IS_VALID(buf) && GST_BUFFER_OFFSET_END_IS_VALID(buf)) { tStart = buf->offset / 100; tStop = buf->offset_end / 100; IMediaSample_SetMediaTime(sample, &tStart, &tStop); } else IMediaSample_SetMediaTime(sample, NULL, NULL); IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_LIVE)); IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)); IMediaSample_SetActualDataLength(sample, gst_buffer_get_size(buf)); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], sample); IMediaSample_Release(sample); gst_buffer_unref(buf); if (FAILED(hr)) return GST_FLOW_FLUSHING; return GST_FLOW_OK; }
static HRESULT WINAPI IMemAllocator_fnGetBuffer(IMemAllocator* iface,IMediaSample** ppSample,REFERENCE_TIME* prtStart,REFERENCE_TIME* prtEnd,DWORD dwFlags) { CMemoryAllocator_THIS(iface,memalloc); HRESULT hr; TRACE( "(%p)->(%p,%p,%p,%u)\n", This, ppSample, prtStart, prtEnd, dwFlags ); if ( ppSample == NULL ) return E_POINTER; while ( 1 ) { ResetEvent( This->hEventSample ); /* to avoid deadlock, don't hold critical section while blocking */ hr = IMemAllocator_LockUnusedBuffer(This,ppSample); if ( ( hr != VFW_E_TIMEOUT ) || ( dwFlags & AM_GBF_NOWAIT ) ) goto end; WaitForSingleObject( This->hEventSample, INFINITE ); } end: if ( hr == S_OK ) { /* HACK: the docs says that this doesn't happen, but Warcraft 3 doesn't set the time otherwise */ IMediaSample_SetTime(*ppSample, prtStart, prtEnd); } return hr; }
static GstFlowReturn got_data(GstPad *pad, GstBuffer *buf) { GstTfImpl *This = gst_pad_get_element_private(pad); IMediaSample *sample = GST_APP_BUFFER(buf)->priv; REFERENCE_TIME tStart, tStop; HRESULT hr; if (GST_BUFFER_TIMESTAMP_IS_VALID(buf) && GST_BUFFER_DURATION_IS_VALID(buf)) { tStart = buf->timestamp / 100; tStop = tStart + buf->duration / 100; IMediaSample_SetTime(sample, &tStart, &tStop); } else IMediaSample_SetTime(sample, NULL, NULL); if (GST_BUFFER_OFFSET_IS_VALID(buf) && GST_BUFFER_OFFSET_END_IS_VALID(buf)) { tStart = buf->offset / 100; tStop = buf->offset_end / 100; IMediaSample_SetMediaTime(sample, &tStart, &tStop); } else IMediaSample_SetMediaTime(sample, NULL, NULL); IMediaSample_SetDiscontinuity(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DISCONT)); IMediaSample_SetPreroll(sample, GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_PREROLL)); IMediaSample_SetSyncPoint(sample, !GST_BUFFER_FLAG_IS_SET(buf, GST_BUFFER_FLAG_DELTA_UNIT)); IMediaSample_SetActualDataLength(sample, GST_BUFFER_SIZE(buf)); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], sample); gst_buffer_unref(buf); if (FAILED(hr)) return GST_FLOW_WRONG_STATE; if (hr != S_OK) return GST_FLOW_RESEND; return GST_FLOW_OK; }
static HRESULT WINAPI AVIDec_Receive(TransformFilter *tf, IMediaSample *pSample) { AVIDecImpl* This = (AVIDecImpl *)tf; AM_MEDIA_TYPE amt; HRESULT hr; DWORD res; IMediaSample* pOutSample = NULL; DWORD cbDstStream; LPBYTE pbDstStream; DWORD cbSrcStream; LPBYTE pbSrcStream; LONGLONG tStart, tStop; DWORD flags = 0; EnterCriticalSection(&This->tf.csReceive); hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); goto error; } cbSrcStream = IMediaSample_GetActualDataLength(pSample); TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) { ERR("Unable to retrieve media type\n"); goto error; } /* Update input size to match sample size */ This->pBihIn->biSizeImage = cbSrcStream; hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); goto error; } hr = IMediaSample_SetActualDataLength(pOutSample, 0); assert(hr == S_OK); hr = IMediaSample_GetPointer(pOutSample, &pbDstStream); if (FAILED(hr)) { ERR("Unable to get pointer to buffer (%x)\n", hr); goto error; } cbDstStream = IMediaSample_GetSize(pOutSample); if (cbDstStream < This->pBihOut->biSizeImage) { ERR("Sample size is too small %d < %d\n", cbDstStream, This->pBihOut->biSizeImage); hr = E_FAIL; goto error; } if (IMediaSample_IsPreroll(pSample) == S_OK) flags |= ICDECOMPRESS_PREROLL; if (IMediaSample_IsSyncPoint(pSample) != S_OK) flags |= ICDECOMPRESS_NOTKEYFRAME; hr = IMediaSample_GetTime(pSample, &tStart, &tStop); if (hr == S_OK && AVIDec_DropSample(This, tStart)) flags |= ICDECOMPRESS_HURRYUP; res = ICDecompress(This->hvid, flags, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream); if (res != ICERR_OK) ERR("Error occurred during the decompression (%x)\n", res); /* Drop sample if its intended to be dropped */ if (flags & ICDECOMPRESS_HURRYUP) { hr = S_OK; goto error; } IMediaSample_SetActualDataLength(pOutSample, This->pBihOut->biSizeImage); IMediaSample_SetPreroll(pOutSample, (IMediaSample_IsPreroll(pSample) == S_OK)); IMediaSample_SetDiscontinuity(pOutSample, (IMediaSample_IsDiscontinuity(pSample) == S_OK)); IMediaSample_SetSyncPoint(pOutSample, (IMediaSample_IsSyncPoint(pSample) == S_OK)); if (hr == S_OK) IMediaSample_SetTime(pOutSample, &tStart, &tStop); else if (hr == VFW_S_NO_STOP_TIME) IMediaSample_SetTime(pOutSample, &tStart, NULL); else IMediaSample_SetTime(pOutSample, NULL, NULL); if (IMediaSample_GetMediaTime(pSample, &tStart, &tStop) == S_OK) IMediaSample_SetMediaTime(pOutSample, &tStart, &tStop); else IMediaSample_SetMediaTime(pOutSample, NULL, NULL); LeaveCriticalSection(&This->tf.csReceive); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample); EnterCriticalSection(&This->tf.csReceive); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) ERR("Error sending sample (%x)\n", hr); error: if (pOutSample) IMediaSample_Release(pOutSample); LeaveCriticalSection(&This->tf.csReceive); return hr; }
static DWORD WINAPI QTSplitter_thread(LPVOID data) { QTSplitter *This = (QTSplitter *)data; HRESULT hr = S_OK; TimeValue next_time; CVPixelBufferRef pixelBuffer = NULL; OSStatus err; TimeRecord tr; WaitForSingleObject(This->runEvent, -1); EnterCriticalSection(&This->csReceive); if (!This->pQTMovie) { LeaveCriticalSection(&This->csReceive); return 0; } This->state = State_Running; /* Prime the pump: Needed for MPEG streams */ GetMovieNextInterestingTime(This->pQTMovie, nextTimeEdgeOK | nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL); GetMovieTime(This->pQTMovie, &tr); if (This->pAudio_Pin) QT_Create_Extract_Session(This); LeaveCriticalSection(&This->csReceive); do { LONGLONG tStart=0, tStop=0; LONGLONG mStart=0, mStop=0; float time; EnterCriticalSection(&This->csReceive); if (!This->pQTMovie) { LeaveCriticalSection(&This->csReceive); return 0; } GetMovieNextInterestingTime(This->pQTMovie, nextTimeStep, 0, NULL, This->movie_time, 1, &next_time, NULL); if (next_time == -1) { TRACE("No next time\n"); LeaveCriticalSection(&This->csReceive); break; } tr.value = SInt64ToWide(next_time); SetMovieTime(This->pQTMovie, &tr); MoviesTask(This->pQTMovie,0); QTVisualContextTask(This->vContext); TRACE("In loop at time %ld\n",This->movie_time); TRACE("In Next time %ld\n",next_time); mStart = This->movie_time; mStop = next_time; time = (float)(This->movie_time - This->movie_start) / This->movie_scale; tStart = time * 10000000; time = (float)(next_time - This->movie_start) / This->movie_scale; tStop = time * 10000000; /* Deliver Audio */ if (This->pAudio_Pin && This->pAudio_Pin->pin.pin.pConnectedTo && This->aSession) { int data_size=0; BYTE* ptr; IMediaSample *sample = NULL; AudioBufferList aData; UInt32 flags; UInt32 frames; WAVEFORMATEX* pvi; float duration; pvi = (WAVEFORMATEX*)This->pAudio_Pin->pmt->pbFormat; hr = BaseOutputPinImpl_GetDeliveryBuffer(&This->pAudio_Pin->pin, &sample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Audio: Unable to get delivery buffer (%x)\n", hr); goto audio_error; } hr = IMediaSample_GetPointer(sample, &ptr); if (FAILED(hr)) { ERR("Audio: Unable to get pointer to buffer (%x)\n", hr); goto audio_error; } duration = (float)next_time / This->movie_scale; time = (float)This->movie_time / This->movie_scale; duration -= time; frames = pvi->nSamplesPerSec * duration; TRACE("Need audio for %f seconds (%li frames)\n",duration,frames); data_size = IMediaSample_GetSize(sample); if (data_size < frames * pvi->nBlockAlign) FIXME("Audio buffer is too small\n"); aData.mNumberBuffers = 1; aData.mBuffers[0].mNumberChannels = pvi->nChannels; aData.mBuffers[0].mDataByteSize = data_size; aData.mBuffers[0].mData = ptr; err = MovieAudioExtractionFillBuffer(This->aSession, &frames, &aData, &flags); if (frames == 0) { TimeRecord etr; /* Ran out of frames, Restart the extraction session */ TRACE("Restarting extraction session\n"); MovieAudioExtractionEnd(This->aSession); This->aSession = NULL; QT_Create_Extract_Session(This); etr = tr; etr.value = SInt64ToWide(This->movie_time); MovieAudioExtractionSetProperty(This->aSession, kQTPropertyClass_MovieAudioExtraction_Movie, kQTMovieAudioExtractionMoviePropertyID_CurrentTime, sizeof(TimeRecord), &etr ); frames = pvi->nSamplesPerSec * duration; aData.mNumberBuffers = 1; aData.mBuffers[0].mNumberChannels = pvi->nChannels; aData.mBuffers[0].mDataByteSize = data_size; aData.mBuffers[0].mData = ptr; MovieAudioExtractionFillBuffer(This->aSession, &frames, &aData, &flags); } TRACE("Got %i frames\n",(int)frames); IMediaSample_SetActualDataLength(sample, frames * pvi->nBlockAlign); IMediaSample_SetMediaTime(sample, &mStart, &mStop); IMediaSample_SetTime(sample, &tStart, &tStop); hr = OutputQueue_Receive(This->pAudio_Pin->queue, sample); TRACE("Audio Delivered (%x)\n",hr); audio_error: if (sample) IMediaSample_Release(sample); } else TRACE("Audio Pin not connected or no Audio\n"); /* Deliver Video */ if (This->pVideo_Pin && QTVisualContextIsNewImageAvailable(This->vContext,0)) { err = QTVisualContextCopyImageForTime(This->vContext, NULL, NULL, &pixelBuffer); if (err == noErr) { int data_size=0; BYTE* ptr; IMediaSample *sample = NULL; hr = BaseOutputPinImpl_GetDeliveryBuffer(&This->pVideo_Pin->pin, &sample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Video: Unable to get delivery buffer (%x)\n", hr); goto video_error; } data_size = IMediaSample_GetSize(sample); if (data_size < This->outputSize) { ERR("Sample size is too small %d < %d\n", data_size, This->outputSize) ; hr = E_FAIL; goto video_error; } hr = IMediaSample_GetPointer(sample, &ptr); if (FAILED(hr)) { ERR("Video: Unable to get pointer to buffer (%x)\n", hr); goto video_error; } hr = AccessPixelBufferPixels( pixelBuffer, ptr); if (FAILED(hr)) { ERR("Failed to access Pixels\n"); goto video_error; } IMediaSample_SetActualDataLength(sample, This->outputSize); IMediaSample_SetMediaTime(sample, &mStart, &mStop); IMediaSample_SetTime(sample, &tStart, &tStop); hr = OutputQueue_Receive(This->pVideo_Pin->queue, sample); TRACE("Video Delivered (%x)\n",hr); video_error: if (sample) IMediaSample_Release(sample); if (pixelBuffer) CVPixelBufferRelease(pixelBuffer); } } else TRACE("No video to deliver\n"); This->movie_time = next_time; LeaveCriticalSection(&This->csReceive); } while (hr == S_OK); This->state = State_Stopped; if (This->pAudio_Pin) OutputQueue_EOS(This->pAudio_Pin->queue); if (This->pVideo_Pin) OutputQueue_EOS(This->pVideo_Pin->queue); return hr; }
static HRESULT WINAPI ACMWrapper_Receive(TransformFilter *tf, IMediaSample *pSample) { ACMWrapperImpl* This = (ACMWrapperImpl*)tf; AM_MEDIA_TYPE amt; IMediaSample* pOutSample = NULL; DWORD cbDstStream, cbSrcStream; LPBYTE pbDstStream; LPBYTE pbSrcStream = NULL; ACMSTREAMHEADER ash; BOOL unprepare_header = FALSE, preroll; MMRESULT res; HRESULT hr; LONGLONG tStart = -1, tStop = -1, tMed; EnterCriticalSection(&This->tf.filter.csFilter); hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); LeaveCriticalSection(&This->tf.filter.csFilter); return hr; } preroll = (IMediaSample_IsPreroll(pSample) == S_OK); IMediaSample_GetTime(pSample, &tStart, &tStop); cbSrcStream = IMediaSample_GetActualDataLength(pSample); /* Prevent discontinuities when codecs 'absorb' data but not give anything back in return */ if (IMediaSample_IsDiscontinuity(pSample) == S_OK) { This->lasttime_real = tStart; This->lasttime_sent = tStart; } else if (This->lasttime_real == tStart) tStart = This->lasttime_sent; else WARN("Discontinuity\n"); tMed = tStart; TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) { ERR("Unable to retrieve media type\n"); LeaveCriticalSection(&This->tf.filter.csFilter); return hr; } ash.pbSrc = pbSrcStream; ash.cbSrcLength = cbSrcStream; while(hr == S_OK && ash.cbSrcLength) { hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); LeaveCriticalSection(&This->tf.filter.csFilter); return hr; } IMediaSample_SetPreroll(pOutSample, preroll); hr = IMediaSample_SetActualDataLength(pOutSample, 0); assert(hr == S_OK); hr = IMediaSample_GetPointer(pOutSample, &pbDstStream); if (FAILED(hr)) { ERR("Unable to get pointer to buffer (%x)\n", hr); goto error; } cbDstStream = IMediaSample_GetSize(pOutSample); ash.cbStruct = sizeof(ash); ash.fdwStatus = 0; ash.dwUser = 0; ash.pbDst = pbDstStream; ash.cbDstLength = cbDstStream; if ((res = acmStreamPrepareHeader(This->has, &ash, 0))) { ERR("Cannot prepare header %d\n", res); goto error; } unprepare_header = TRUE; if (IMediaSample_IsDiscontinuity(pSample) == S_OK) { res = acmStreamConvert(This->has, &ash, ACM_STREAMCONVERTF_START); IMediaSample_SetDiscontinuity(pOutSample, TRUE); /* One sample could be converted to multiple packets */ IMediaSample_SetDiscontinuity(pSample, FALSE); } else { res = acmStreamConvert(This->has, &ash, 0); IMediaSample_SetDiscontinuity(pOutSample, FALSE); } if (res) { if(res != MMSYSERR_MOREDATA) ERR("Cannot convert data header %d\n", res); goto error; } TRACE("used in %u/%u, used out %u/%u\n", ash.cbSrcLengthUsed, ash.cbSrcLength, ash.cbDstLengthUsed, ash.cbDstLength); hr = IMediaSample_SetActualDataLength(pOutSample, ash.cbDstLengthUsed); assert(hr == S_OK); /* Bug in acm codecs? It apparantly uses the input, but doesn't necessarily output immediately kl*/ if (!ash.cbSrcLengthUsed) { WARN("Sample was skipped? Outputted: %u\n", ash.cbDstLengthUsed); ash.cbSrcLength = 0; goto error; } TRACE("Sample start time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000)); if (ash.cbSrcLengthUsed == cbSrcStream) { IMediaSample_SetTime(pOutSample, &tStart, &tStop); tStart = tMed = tStop; } else if (tStop != tStart) { tMed = tStop - tStart; tMed = tStart + tMed * ash.cbSrcLengthUsed / cbSrcStream; IMediaSample_SetTime(pOutSample, &tStart, &tMed); tStart = tMed; } else { ERR("No valid timestamp found\n"); IMediaSample_SetTime(pOutSample, NULL, NULL); } TRACE("Sample stop time: %u.%03u\n", (DWORD)(tStart/10000000), (DWORD)((tStart/10000)%1000)); LeaveCriticalSection(&This->tf.filter.csFilter); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample); EnterCriticalSection(&This->tf.filter.csFilter); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) { if (FAILED(hr)) ERR("Error sending sample (%x)\n", hr); goto error; } error: if (unprepare_header && (res = acmStreamUnprepareHeader(This->has, &ash, 0))) ERR("Cannot unprepare header %d\n", res); unprepare_header = FALSE; ash.pbSrc += ash.cbSrcLengthUsed; ash.cbSrcLength -= ash.cbSrcLengthUsed; if (pOutSample) IMediaSample_Release(pOutSample); pOutSample = NULL; } This->lasttime_real = tStop; This->lasttime_sent = tMed; LeaveCriticalSection(&This->tf.filter.csFilter); return hr; }
static void trackingCallback( void *decompressionTrackingRefCon, OSStatus result, ICMDecompressionTrackingFlags decompressionTrackingFlags, CVPixelBufferRef pixelBuffer, TimeValue64 displayTime, TimeValue64 displayDuration, ICMValidTimeFlags validTimeFlags, void *reserved, void *sourceFrameRefCon ) { QTVDecoderImpl *This = (QTVDecoderImpl*)decompressionTrackingRefCon; IMediaSample *pSample = (IMediaSample*)sourceFrameRefCon; HRESULT hr = S_OK; IMediaSample* pOutSample = NULL; LPBYTE pbDstStream; DWORD cbDstStream; if (result != noErr) { ERR("Error from Codec, no frame decompressed\n"); return; } if (!pixelBuffer) { ERR("No pixel buffer, no frame decompressed\n"); return; } EnterCriticalSection(&This->tf.csReceive); hr = BaseOutputPinImpl_GetDeliveryBuffer((BaseOutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); goto error; } hr = IMediaSample_SetActualDataLength(pOutSample, 0); assert(hr == S_OK); hr = IMediaSample_GetPointer(pOutSample, &pbDstStream); if (FAILED(hr)) { ERR("Unable to get pointer to buffer (%x)\n", hr); goto error; } cbDstStream = IMediaSample_GetSize(pOutSample); if (cbDstStream < This->outputSize) { ERR("Sample size is too small %d < %d\n", cbDstStream, This->outputSize); hr = E_FAIL; goto error; } hr = AccessPixelBufferPixels(pixelBuffer, pbDstStream); if (FAILED(hr)) goto error; IMediaSample_SetActualDataLength(pOutSample, This->outputSize); IMediaSample_SetPreroll(pOutSample, (IMediaSample_IsPreroll(pSample) == S_OK)); IMediaSample_SetDiscontinuity(pOutSample, (IMediaSample_IsDiscontinuity(pSample) == S_OK)); IMediaSample_SetSyncPoint(pOutSample, (IMediaSample_IsSyncPoint(pSample) == S_OK)); if (!validTimeFlags) IMediaSample_SetTime(pOutSample, NULL, NULL); else { LONGLONG tStart, tStop; if (validTimeFlags & kICMValidTime_DisplayTimeStampIsValid) tStart = displayTime; else tStart = 0; if (validTimeFlags & kICMValidTime_DisplayDurationIsValid) tStop = tStart + displayDuration; else tStop = tStart; IMediaSample_SetTime(pOutSample, &tStart, &tStop); } LeaveCriticalSection(&This->tf.csReceive); hr = BaseOutputPinImpl_Deliver((BaseOutputPin*)This->tf.ppPins[1], pOutSample); EnterCriticalSection(&This->tf.csReceive); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) ERR("Error sending sample (%x)\n", hr); error: LeaveCriticalSection(&This->tf.csReceive); if (pOutSample) IMediaSample_Release(pOutSample); This->decodeHR = hr; }
static HRESULT AVIDec_ProcessSampleData(InputPin *pin, IMediaSample *pSample) { AVIDecImpl* This = (AVIDecImpl *)pin->pin.pinInfo.pFilter; AM_MEDIA_TYPE amt; HRESULT hr; DWORD res; IMediaSample* pOutSample = NULL; DWORD cbDstStream; LPBYTE pbDstStream; DWORD cbSrcStream; LPBYTE pbSrcStream; LONGLONG tStart, tStop; EnterCriticalSection(&This->tf.csFilter); if (This->tf.state == State_Stopped) { LeaveCriticalSection(&This->tf.csFilter); return VFW_E_WRONG_STATE; } if (pin->end_of_stream || pin->flushing) { LeaveCriticalSection(&This->tf.csFilter); return S_FALSE; } hr = IMediaSample_GetPointer(pSample, &pbSrcStream); if (FAILED(hr)) { ERR("Cannot get pointer to sample data (%x)\n", hr); goto error; } cbSrcStream = IMediaSample_GetActualDataLength(pSample); TRACE("Sample data ptr = %p, size = %d\n", pbSrcStream, cbSrcStream); hr = IPin_ConnectionMediaType(This->tf.ppPins[0], &amt); if (FAILED(hr)) { ERR("Unable to retrieve media type\n"); goto error; } /* Update input size to match sample size */ This->pBihIn->biSizeImage = cbSrcStream; hr = OutputPin_GetDeliveryBuffer((OutputPin*)This->tf.ppPins[1], &pOutSample, NULL, NULL, 0); if (FAILED(hr)) { ERR("Unable to get delivery buffer (%x)\n", hr); goto error; } hr = IMediaSample_SetActualDataLength(pOutSample, 0); assert(hr == S_OK); hr = IMediaSample_GetPointer(pOutSample, &pbDstStream); if (FAILED(hr)) { ERR("Unable to get pointer to buffer (%x)\n", hr); goto error; } cbDstStream = IMediaSample_GetSize(pOutSample); if (cbDstStream < This->pBihOut->biSizeImage) { ERR("Sample size is too small %d < %d\n", cbDstStream, This->pBihOut->biSizeImage); hr = E_FAIL; goto error; } res = ICDecompress(This->hvid, 0, This->pBihIn, pbSrcStream, This->pBihOut, pbDstStream); if (res != ICERR_OK) ERR("Error occurred during the decompression (%x)\n", res); IMediaSample_SetActualDataLength(pOutSample, This->pBihOut->biSizeImage); IMediaSample_SetPreroll(pOutSample, (IMediaSample_IsPreroll(pSample) == S_OK)); IMediaSample_SetDiscontinuity(pOutSample, (IMediaSample_IsDiscontinuity(pSample) == S_OK)); IMediaSample_SetSyncPoint(pOutSample, (IMediaSample_IsSyncPoint(pSample) == S_OK)); if (IMediaSample_GetTime(pSample, &tStart, &tStop) == S_OK) IMediaSample_SetTime(pOutSample, &tStart, &tStop); else IMediaSample_SetTime(pOutSample, NULL, NULL); LeaveCriticalSection(&This->tf.csFilter); hr = OutputPin_SendSample((OutputPin*)This->tf.ppPins[1], pOutSample); if (hr != S_OK && hr != VFW_E_NOT_CONNECTED) ERR("Error sending sample (%x)\n", hr); IMediaSample_Release(pOutSample); return hr; error: if (pOutSample) IMediaSample_Release(pOutSample); LeaveCriticalSection(&This->tf.csFilter); return hr; }