Commit 49749086 authored by Ghislain MARY's avatar Ghislain MARY

Get video sample and output them from the mediastreamer2 filter.

parent 3c604c4a
......@@ -42,6 +42,9 @@ MSWinRTCap::MSWinRTCap()
return;
}
mVideoSize.width = MS_VIDEO_SIZE_CIF_W;
mVideoSize.height = MS_VIDEO_SIZE_CIF_H;
ms_mutex_init(&mMutex, NULL);
ms_queue_init(&mSampleToSendQueue);
ms_queue_init(&mSampleToFreeQueue);
......@@ -135,7 +138,6 @@ int MSWinRTCap::activate()
WaitForSingleObjectEx(mActivationCompleted, INFINITE, FALSE);
if (mIsActivated && (mCaptureElement != nullptr)) {
mCaptureElement->Source = mCapture.Get();
mMediaSink = ref new MSWinRTMediaSinkProxy();
}
return 0;
}
......@@ -174,21 +176,17 @@ void MSWinRTCap::start()
WaitForSingleObjectEx(mPreviewStartCompleted, INFINITE, FALSE);
MediaEncodingProfile^ mediaEncodingProfile = mEncodingProfile;
IAsyncOperation<Windows::Media::IMediaExtension^>^ op = mMediaSink->InitializeAsync(mEncodingProfile->Video);
op->Completed = ref new AsyncOperationCompletedHandler<Windows::Media::IMediaExtension^>(
[this](IAsyncOperation<Windows::Media::IMediaExtension^>^ asyncOp, Windows::Foundation::AsyncStatus asyncStatus) {
if (asyncStatus == Windows::Foundation::AsyncStatus::Completed) {
Windows::Media::IMediaExtension^ mediaExtension = asyncOp->GetResults();
IAsyncAction^ action = mCapture->StartRecordToCustomSinkAsync(mEncodingProfile, mediaExtension);
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
if (asyncStatus == Windows::Foundation::AsyncStatus::Completed)
mIsStarted = true;
SetEvent(mStartCompleted);
});
} else {
// TODO
SetEvent(mStartCompleted);
}
MakeAndInitialize<MSWinRTMediaSink>(&mMediaSink, mEncodingProfile->Video);
static_cast<MSWinRTMediaSink *>(mMediaSink.Get())->SetCaptureFilter(this);
ComPtr<IInspectable> spInspectable;
HRESULT hr = mMediaSink.As(&spInspectable);
if (FAILED(hr)) return;
IMediaExtension^ mediaExtension = safe_cast<IMediaExtension^>(reinterpret_cast<Object^>(spInspectable.Get()));
IAsyncAction^ action = mCapture->StartRecordToCustomSinkAsync(mEncodingProfile, mediaExtension);
action->Completed = ref new AsyncActionCompletedHandler([this](IAsyncAction^ asyncAction, Windows::Foundation::AsyncStatus asyncStatus) {
if (asyncStatus == Windows::Foundation::AsyncStatus::Completed)
mIsStarted = true;
SetEvent(mStartCompleted);
});
WaitForSingleObjectEx(mStartCompleted, INFINITE, FALSE);
}
......@@ -236,21 +234,19 @@ static void freeSample(void *sample)
delete[] sample;
}
#if 0
void MSWinRTCap::OnSampleAvailable(ULONGLONG hnsPresentationTime, ULONGLONG hnsSampleDuration, DWORD cbSample, BYTE* pSample)
void MSWinRTCap::OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime)
{
MS_UNUSED(hnsSampleDuration);
mblk_t *m;
uint32_t timestamp = (uint32_t)((hnsPresentationTime / 10000LL) * 90LL);
uint32_t timestamp = (uint32_t)((presentationTime / 10000LL) * 90LL);
int w = mVConf.vsize.width;
int h = mVConf.vsize.height;
int w = mVideoSize.width;
int h = mVideoSize.height;
if ((mDeviceOrientation % 180) == 0) {
w = mVConf.vsize.height;
h = mVConf.vsize.width;
w = mVideoSize.height;
h = mVideoSize.width;
}
uint8_t *y = (uint8_t *)pSample;
uint8_t *cbcr = (uint8_t *)(pSample + w * h);
uint8_t *y = (uint8_t *)buf;
uint8_t *cbcr = (uint8_t *)(buf + w * h);
m = copy_ycbcrbiplanar_to_true_yuv_with_rotation(mAllocator, y, cbcr, 0, w, h, w, w, TRUE);
mblk_set_timestamp_info(m, timestamp);
......@@ -258,7 +254,6 @@ void MSWinRTCap::OnSampleAvailable(ULONGLONG hnsPresentationTime, ULONGLONG hnsS
ms_queue_put(&mSampleToSendQueue, m);
ms_mutex_unlock(&mMutex);
}
#endif
void MSWinRTCap::setFps(float fps)
......
......@@ -53,7 +53,7 @@ namespace libmswinrtvid
void stop();
int feed(MSFilter *f);
//void OnSampleAvailable(ULONGLONG hnsPresentationTime, ULONGLONG hnsSampleDuration, DWORD cbSample, BYTE* pSample);
void OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime);
void setCaptureElement(Windows::UI::Xaml::Controls::CaptureElement^ captureElement) { mCaptureElement = captureElement; };
void setDeviceId(Platform::String^ id) { mDeviceId = id; };
......@@ -96,6 +96,6 @@ namespace libmswinrtvid
Platform::String^ mDeviceId;
Platform::Agile<MediaCapture^> mCapture;
MediaEncodingProfile^ mEncodingProfile;
MSWinRTMediaSinkProxy^ mMediaSink;
ComPtr<IMFMediaSink> mMediaSink;
};
}
#include "mswinrtmediasink.h"
#include "mswinrtcap.h"
#include <mediastreamer2/mscommon.h>
using namespace libmswinrtvid;
......@@ -970,7 +971,7 @@ HRESULT MSWinRTStreamSink::PrepareSample(IMFSample *pSample)
DWORD currentLength = 0;
hr = spMediaBuffer->Lock(&pBuffer, NULL, &currentLength);
if (SUCCEEDED(hr)) {
// TODO
static_cast<MSWinRTMediaSink *>(_spSink.Get())->OnSampleAvailable(pBuffer, currentLength, llSampleTime);
hr = spMediaBuffer->Unlock();
if (FAILED(hr)) break;
}
......@@ -1266,76 +1267,10 @@ void MSWinRTMediaSink::ReportEndOfStream()
_mutex.unlock();
}
MSWinRTMediaSinkProxy::MSWinRTMediaSinkProxy()
{
}
MSWinRTMediaSinkProxy::~MSWinRTMediaSinkProxy()
{
_mutex.lock();
if (_spMediaSink != nullptr) {
_spMediaSink->Shutdown();
_spMediaSink = nullptr;
}
_mutex.unlock();
}
Windows::Media::IMediaExtension ^MSWinRTMediaSinkProxy::GetMFExtensions() {
_mutex.lock();
if (_spMediaSink == nullptr) {
_mutex.unlock();
throw ref new Exception(MF_E_NOT_INITIALIZED);
}
ComPtr<IInspectable> spInspectable;
HRESULT hr = _spMediaSink.As(&spInspectable);
if (FAILED(hr)) {
_mutex.unlock();
throw ref new Exception(hr);
}
_mutex.unlock();
return safe_cast<IMediaExtension^>(reinterpret_cast<Object^>(spInspectable.Get()));
}
Windows::Foundation::IAsyncOperation<IMediaExtension^>^ MSWinRTMediaSinkProxy::InitializeAsync(Windows::Media::MediaProperties::IMediaEncodingProperties ^videoEncodingProperties)
void MSWinRTMediaSink::OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime)
{
return concurrency::create_async([this, videoEncodingProperties]()
{
_mutex.lock();
CheckShutdown();
if (_spMediaSink != nullptr) {
_mutex.unlock();
throw ref new Exception(MF_E_ALREADY_INITIALIZED);
}
// Prepare the MF extension
HRESULT hr = MakeAndInitialize<MSWinRTMediaSink>(&_spMediaSink, /*ref new StspSinkCallback(this), */ videoEncodingProperties);
if (FAILED(hr)) {
_mutex.unlock();
throw ref new Exception(hr);
}
ComPtr<IInspectable> spInspectable;
hr = _spMediaSink.As(&spInspectable);
if (FAILED(hr)) {
_mutex.unlock();
throw ref new Exception(hr);
}
_mutex.unlock();
return safe_cast<IMediaExtension^>(reinterpret_cast<Object^>(spInspectable.Get()));
});
}
void MSWinRTMediaSinkProxy::OnShutdown()
{
_mutex.lock();
if (_fShutdown) {
_mutex.unlock();
return;
ms_message("MSWinRTMediaSink::OnSampleAvailable");
if (_capture != NULL) {
_capture->OnSampleAvailable(buf, bufLen, presentationTime);
}
_fShutdown = true;
_spMediaSink = nullptr;
_mutex.unlock();
}
......@@ -32,6 +32,7 @@ using namespace Windows::Media::MediaProperties;
namespace libmswinrtvid {
//interface class ISinkCallback;
class MSWinRTCap;
class MSWinRTMediaSink;
......@@ -280,6 +281,8 @@ namespace libmswinrtvid {
LONGLONG GetStartTime() const { return _llStartTime; }
void ReportEndOfStream();
void SetCaptureFilter(MSWinRTCap *capture) { _capture = capture; }
void OnSampleAvailable(BYTE *buf, DWORD bufLen, LONGLONG presentationTime);
private:
void HandleError(HRESULT hr);
......@@ -296,6 +299,7 @@ namespace libmswinrtvid {
private:
std::recursive_mutex _mutex;
ComPtr<IMFStreamSink> _stream;
MSWinRTCap *_capture;
long _cRef; // reference count
......@@ -309,33 +313,4 @@ namespace libmswinrtvid {
DWORD _waitingConnectionId;
};
public ref class MSWinRTMediaSinkProxy sealed
{
public:
MSWinRTMediaSinkProxy();
virtual ~MSWinRTMediaSinkProxy();
Windows::Media::IMediaExtension ^GetMFExtensions();
Windows::Foundation::IAsyncOperation<Windows::Media::IMediaExtension^>^ InitializeAsync(Windows::Media::MediaProperties::IMediaEncodingProperties ^videoEncodingProperties);
internal:
void SetVideoStreamProperties(_In_opt_ Windows::Media::MediaProperties::IMediaEncodingProperties ^mediaEncodingProperties);
private:
void OnShutdown();
void CheckShutdown()
{
if (_fShutdown) {
throw ref new Exception(MF_E_SHUTDOWN);
}
}
private:
std::mutex _mutex;
ComPtr<IMFMediaSink> _spMediaSink;
bool _fShutdown;
};
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment