Remove recording and photo code

This commit is contained in:
Linnea May 2022-03-07 13:02:38 -08:00
Родитель 9f56e9f4c6
Коммит 8ba45b544d
6 изменённых файлов: 5 добавлений и 578 удалений

Просмотреть файл

@ -68,11 +68,6 @@ STDMETHODIMP CaptureManager::CaptureEngineCB::OnEvent( _In_ IMFMediaEvent* pEven
m_pManager->OnPreviewStopped(hrStatus);
SetEvent(m_pManager->m_hEvent);
}
else if (guidType == MF_CAPTURE_ENGINE_RECORD_STOPPED)
{
m_pManager->OnRecordStopped(hrStatus);
SetEvent(m_pManager->m_hEvent);
}
else
{
// This is an event we don't know about, we don't really care and there's
@ -302,21 +297,6 @@ HRESULT CaptureManager::OnCaptureEvent(WPARAM wParam, LPARAM lParam)
OnPreviewStopped(hrStatus);
SetErrorID(hrStatus, IDS_ERR_PREVIEW);
}
else if (guidType == MF_CAPTURE_ENGINE_RECORD_STARTED)
{
OnRecordStarted(hrStatus);
SetErrorID(hrStatus, IDS_ERR_RECORD);
}
else if (guidType == MF_CAPTURE_ENGINE_RECORD_STOPPED)
{
OnRecordStopped(hrStatus);
SetErrorID(hrStatus, IDS_ERR_RECORD);
}
else if (guidType == MF_CAPTURE_ENGINE_PHOTO_TAKEN)
{
m_bPhotoPending = false;
SetErrorID(hrStatus, IDS_ERR_PHOTO);
}
else if (guidType == MF_CAPTURE_ENGINE_ERROR)
{
DestroyCaptureEngine();
@ -352,15 +332,6 @@ void CaptureManager::OnPreviewStopped(HRESULT& hrStatus)
m_bPreviewing = false;
}
void CaptureManager::OnRecordStarted(HRESULT& hrStatus)
{
m_bRecording = SUCCEEDED(hrStatus);
}
void CaptureManager::OnRecordStopped(HRESULT& hrStatus)
{
m_bRecording = false;
}
HRESULT CaptureManager::StartPreview()
@ -548,318 +519,6 @@ done:
return hr;
}
HRESULT ConfigureVideoEncoding(IMFCaptureSource *pSource, IMFCaptureRecordSink *pRecord, REFGUID guidEncodingType)
{
IMFMediaType *pMediaType = NULL;
IMFMediaType *pMediaType2 = NULL;
GUID guidSubType = GUID_NULL;
// Configure the video format for the recording sink.
HRESULT hr = pSource->GetCurrentDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_RECORD , &pMediaType);
if (FAILED(hr))
{
goto done;
}
hr = CloneVideoMediaType(pMediaType, guidEncodingType, &pMediaType2);
if (FAILED(hr))
{
goto done;
}
hr = pMediaType->GetGUID(MF_MT_SUBTYPE, &guidSubType);
if(FAILED(hr))
{
goto done;
}
if(guidSubType == MFVideoFormat_H264_ES || guidSubType == MFVideoFormat_H264)
{
//When the webcam supports H264_ES or H264, we just bypass the stream. The output from Capture engine shall be the same as the native type supported by the webcam
hr = pMediaType2->SetGUID(MF_MT_SUBTYPE, MFVideoFormat_H264);
}
else
{
UINT32 uiEncodingBitrate;
hr = GetEncodingBitrate(pMediaType2, &uiEncodingBitrate);
if (FAILED(hr))
{
goto done;
}
hr = pMediaType2->SetUINT32(MF_MT_AVG_BITRATE, uiEncodingBitrate);
}
if (FAILED(hr))
{
goto done;
}
// Connect the video stream to the recording sink.
DWORD dwSinkStreamIndex;
hr = pRecord->AddStream((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_VIDEO_RECORD, pMediaType2, NULL, &dwSinkStreamIndex);
done:
SafeRelease(&pMediaType);
SafeRelease(&pMediaType2);
return hr;
}
HRESULT ConfigureAudioEncoding(IMFCaptureSource *pSource, IMFCaptureRecordSink *pRecord, REFGUID guidEncodingType)
{
IMFCollection *pAvailableTypes = NULL;
IMFMediaType *pMediaType = NULL;
IMFAttributes *pAttributes = NULL;
// Configure the audio format for the recording sink.
HRESULT hr = MFCreateAttributes(&pAttributes, 1);
if(FAILED(hr))
{
goto done;
}
// Enumerate low latency media types
hr = pAttributes->SetUINT32(MF_LOW_LATENCY, TRUE);
if(FAILED(hr))
{
goto done;
}
// Get a list of encoded output formats that are supported by the encoder.
hr = MFTranscodeGetAudioOutputAvailableTypes(guidEncodingType, MFT_ENUM_FLAG_ALL | MFT_ENUM_FLAG_SORTANDFILTER,
pAttributes, &pAvailableTypes);
if (FAILED(hr))
{
goto done;
}
// Pick the first format from the list.
hr = GetCollectionObject(pAvailableTypes, 0, &pMediaType);
if (FAILED(hr))
{
goto done;
}
// Connect the audio stream to the recording sink.
DWORD dwSinkStreamIndex;
hr = pRecord->AddStream((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_AUDIO, pMediaType, NULL, &dwSinkStreamIndex);
if(hr == MF_E_INVALIDSTREAMNUMBER)
{
//If an audio device is not present, allow video only recording
hr = S_OK;
}
done:
SafeRelease(&pAvailableTypes);
SafeRelease(&pMediaType);
SafeRelease(&pAttributes);
return hr;
}
HRESULT CaptureManager::StartRecord(PCWSTR pszDestinationFile)
{
if (m_pEngine == NULL)
{
return MF_E_NOT_INITIALIZED;
}
if (m_bRecording == true)
{
return MF_E_INVALIDREQUEST;
}
PWSTR pszExt = PathFindExtension(pszDestinationFile);
GUID guidVideoEncoding;
GUID guidAudioEncoding;
if (wcscmp(pszExt, L".mp4") == 0)
{
guidVideoEncoding = MFVideoFormat_H264;
guidAudioEncoding = MFAudioFormat_AAC;
}
else if (wcscmp(pszExt, L".wmv") == 0)
{
guidVideoEncoding = MFVideoFormat_WMV3;
guidAudioEncoding = MFAudioFormat_WMAudioV9;
}
else if (wcscmp(pszExt, L".wma") == 0)
{
guidVideoEncoding = GUID_NULL;
guidAudioEncoding = MFAudioFormat_WMAudioV9;
}
else
{
return MF_E_INVALIDMEDIATYPE;
}
IMFCaptureSink *pSink = NULL;
IMFCaptureRecordSink *pRecord = NULL;
IMFCaptureSource *pSource = NULL;
HRESULT hr = m_pEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_RECORD, &pSink);
if (FAILED(hr))
{
goto done;
}
hr = pSink->QueryInterface(IID_PPV_ARGS(&pRecord));
if (FAILED(hr))
{
goto done;
}
hr = m_pEngine->GetSource(&pSource);
if (FAILED(hr))
{
goto done;
}
// Clear any existing streams from previous recordings.
hr = pRecord->RemoveAllStreams();
if (FAILED(hr))
{
goto done;
}
hr = pRecord->SetOutputFileName(pszDestinationFile);
if (FAILED(hr))
{
goto done;
}
// Configure the video and audio streams.
if (guidVideoEncoding != GUID_NULL)
{
hr = ConfigureVideoEncoding(pSource, pRecord, guidVideoEncoding);
if (FAILED(hr))
{
goto done;
}
}
if (guidAudioEncoding != GUID_NULL)
{
hr = ConfigureAudioEncoding(pSource, pRecord, guidAudioEncoding);
if (FAILED(hr))
{
goto done;
}
}
hr = m_pEngine->StartRecord();
if (FAILED(hr))
{
goto done;
}
m_bRecording = true;
done:
SafeRelease(&pSink);
SafeRelease(&pSource);
SafeRelease(&pRecord);
return hr;
}
HRESULT CaptureManager::StopRecord()
{
HRESULT hr = S_OK;
if (m_bRecording)
{
hr = m_pEngine->StopRecord(TRUE, FALSE);
WaitForResult();
}
return hr;
}
HRESULT CaptureManager::TakePhoto(PCWSTR pszFileName)
{
IMFCaptureSink *pSink = NULL;
IMFCapturePhotoSink *pPhoto = NULL;
IMFCaptureSource *pSource;
IMFMediaType *pMediaType = 0;
IMFMediaType *pMediaType2 = 0;
bool bHasPhotoStream = true;
// Get a pointer to the photo sink.
HRESULT hr = m_pEngine->GetSink(MF_CAPTURE_ENGINE_SINK_TYPE_PHOTO, &pSink);
if (FAILED(hr))
{
goto done;
}
hr = pSink->QueryInterface(IID_PPV_ARGS(&pPhoto));
if (FAILED(hr))
{
goto done;
}
hr = m_pEngine->GetSource(&pSource);
if (FAILED(hr))
{
goto done;
}
hr = pSource->GetCurrentDeviceMediaType((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO , &pMediaType);
if (FAILED(hr))
{
goto done;
}
//Configure the photo format
hr = CreatePhotoMediaType(pMediaType, &pMediaType2);
if (FAILED(hr))
{
goto done;
}
hr = pPhoto->RemoveAllStreams();
if (FAILED(hr))
{
goto done;
}
DWORD dwSinkStreamIndex;
// Try to connect the first still image stream to the photo sink
if(bHasPhotoStream)
{
hr = pPhoto->AddStream((DWORD)MF_CAPTURE_ENGINE_PREFERRED_SOURCE_STREAM_FOR_PHOTO, pMediaType2, NULL, &dwSinkStreamIndex);
}
if(FAILED(hr))
{
goto done;
}
hr = pPhoto->SetOutputFileName(pszFileName);
if (FAILED(hr))
{
goto done;
}
hr = m_pEngine->TakePhoto();
if (FAILED(hr))
{
goto done;
}
m_bPhotoPending = true;
done:
SafeRelease(&pSink);
SafeRelease(&pPhoto);
SafeRelease(&pSource);
SafeRelease(&pMediaType);
SafeRelease(&pMediaType2);
return hr;
}

Просмотреть файл

@ -41,7 +41,6 @@ void SetMenuItemText(HMENU hMenu, UINT uItem, _In_ PWSTR pszText);
void ShowError(HWND hwnd, PCWSTR szMessage, HRESULT hr);
void ShowError(HWND hwnd, UINT id, HRESULT hr);
HRESULT CloneVideoMediaType(IMFMediaType *pSrcMediaType, REFGUID guidSubType, IMFMediaType **ppNewMediaType);
HRESULT CreatePhotoMediaType(IMFMediaType *pSrcMediaType, IMFMediaType **ppPhotoMediaType);
// DXGI DevManager support
extern IMFDXGIDeviceManager* g_pDXGIMan;
@ -137,8 +136,6 @@ class CaptureManager
CaptureEngineCB *m_pCallback;
bool m_bPreviewing;
bool m_bRecording;
bool m_bPhotoPending;
UINT m_errorID;
HANDLE m_hEvent;
@ -147,7 +144,7 @@ class CaptureManager
CaptureManager(HWND hwnd) :
m_hwndEvent(hwnd), m_hwndPreview(NULL), m_pEngine(NULL), m_pPreview(NULL),
m_pCallback(NULL), m_bRecording(false), m_bPreviewing(false), m_bPhotoPending(false), m_errorID(0),m_hEvent(NULL)
m_pCallback(NULL), m_bPreviewing(false), m_errorID(0),m_hEvent(NULL)
,m_hpwrRequest(INVALID_HANDLE_VALUE)
,m_fPowerRequestSet(false)
{
@ -169,8 +166,6 @@ class CaptureManager
void OnCaptureEngineInitialized(HRESULT& hrStatus);
void OnPreviewStarted(HRESULT& hrStatus);
void OnPreviewStopped(HRESULT& hrStatus);
void OnRecordStarted(HRESULT& hrStatus);
void OnRecordStopped(HRESULT& hrStatus);
void WaitForResult()
{
WaitForSingleObject(m_hEvent, INFINITE);
@ -223,25 +218,18 @@ public:
SafeRelease(&g_pDXGIMan);
m_bPreviewing = false;
m_bRecording = false;
m_bPhotoPending = false;
m_errorID = 0;
}
bool IsPreviewing() const { return m_bPreviewing; }
bool IsRecording() const { return m_bRecording; }
bool IsPhotoPending() const { return m_bPhotoPending; }
UINT ErrorID() const { return m_errorID; }
HRESULT OnCaptureEvent(WPARAM wParam, LPARAM lParam);
HRESULT SetVideoDevice(IUnknown *pUnk);
HRESULT StartPreview();
HRESULT StopPreview();
HRESULT StartRecord(PCWSTR pszDestinationFile);
HRESULT StopRecord();
HRESULT TakePhoto(PCWSTR pszFileName);
void SleepState(bool fSleeping)
{

Просмотреть файл

@ -17,6 +17,7 @@
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
@ -53,10 +54,8 @@ IDR_MENU1 MENU
BEGIN
POPUP "Capture"
BEGIN
MENUITEM "Start Preview" ID_CAPTURE_PREVIEW
MENUITEM "Start Preview", ID_CAPTURE_PREVIEW
MENUITEM "Choose Device", ID_CAPTURE_CHOOSEDEVICE
MENUITEM "Start Recording", ID_CAPTURE_RECORD
MENUITEM "Take Photo", ID_CAPTURE_TAKEPHOTO
END
END
@ -106,9 +105,7 @@ BEGIN
IDS_ERR_SET_DEVICE "Unable to set the capture device."
IDS_ERR_INITIALIZE "Unable to initialize the capture engine."
IDS_ERR_PREVIEW "An error occurred during preview."
IDS_ERR_RECORD "An error occurred during recording."
IDS_ERR_CAPTURE "An error occurred during capture."
IDS_ERR_PHOTO "Unable to capture still photo."
END
#endif // English (United States) resources

Просмотреть файл

@ -1,6 +1,6 @@
//{{NO_DEPENDENCIES}}
// Microsoft Visual C++ generated include file.
// Used by CaptureEngine.rc
// Used by Capture.rc
//
#define IDR_MENU1 101
#define IDD_CHOOSE_DEVICE 102

Просмотреть файл

@ -81,48 +81,6 @@ done:
return hr;
}
// Creates a JPEG image type that is compatible with a specified video media type.
HRESULT CreatePhotoMediaType(IMFMediaType *pSrcMediaType, IMFMediaType **ppPhotoMediaType)
{
*ppPhotoMediaType = NULL;
const UINT32 uiFrameRateNumerator = 30;
const UINT32 uiFrameRateDenominator = 1;
IMFMediaType *pPhotoMediaType = NULL;
HRESULT hr = MFCreateMediaType(&pPhotoMediaType);
if (FAILED(hr))
{
goto done;
}
hr = pPhotoMediaType->SetGUID(MF_MT_MAJOR_TYPE, MFMediaType_Image);
if (FAILED(hr))
{
goto done;
}
hr = pPhotoMediaType->SetGUID(MF_MT_SUBTYPE, GUID_ContainerFormatJpeg);
if (FAILED(hr))
{
goto done;
}
hr = CopyAttribute(pSrcMediaType, pPhotoMediaType, MF_MT_FRAME_SIZE);
if (FAILED(hr))
{
goto done;
}
*ppPhotoMediaType = pPhotoMediaType;
(*ppPhotoMediaType)->AddRef();
done:
SafeRelease(&pPhotoMediaType);
return hr;
}
void ShowError(HWND hwnd, PCWSTR szMessage, HRESULT hr)
{

Просмотреть файл

@ -267,18 +267,6 @@ namespace MainWindow
void UpdateUI(HWND hwnd)
{
if (g_pEngine->IsRecording() != bRecording)
{
bRecording = g_pEngine->IsRecording();
if (bRecording)
{
SetMenuItemText(GetMenu(hwnd), ID_CAPTURE_RECORD, L"Stop Recording");
}
else
{
SetMenuItemText(GetMenu(hwnd), ID_CAPTURE_RECORD, L"Start Recording");
}
}
if (g_pEngine->IsPreviewing() != bPreviewing)
{
@ -309,11 +297,6 @@ namespace MainWindow
bEnableRecording = FALSE;
}
if (!g_pEngine->IsPreviewing() || g_pEngine->IsPhotoPending())
{
bEnablePhoto = FALSE;
}
EnableMenuItem(GetMenu(hwnd), ID_CAPTURE_RECORD, bEnableRecording ? MF_ENABLED : MF_GRAYED);
EnableMenuItem(GetMenu(hwnd), ID_CAPTURE_TAKEPHOTO, bEnablePhoto ? MF_ENABLED : MF_GRAYED);
}
@ -448,101 +431,7 @@ namespace MainWindow
}
UpdateUI(hwnd);
}
// TODO: Remove record options
void OnStartRecord(HWND hwnd)
{
IFileSaveDialog* pFileSave = NULL;
IShellItem* pItem = NULL;
PWSTR pszFileName = NULL;
const COMDLG_FILTERSPEC rgSpec[] =
{
{ L"MP4 (H.264/AAC)", L"*.mp4" },
{ L"Windows Media Video", L"*.wmv" },
{ L"All Files", L"*.*" },
};
HRESULT hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pFileSave));
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->SetTitle(L"Select File Name");
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->SetFileName(L"MyVideo.mp4");
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->SetDefaultExtension(L"mp4");
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->SetFileTypes(ARRAYSIZE(rgSpec), rgSpec);
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->Show(hwnd);
if (hr == HRESULT_FROM_WIN32(ERROR_CANCELLED))
{
hr = S_OK; // The user canceled the dialog.
goto done;
}
if (FAILED(hr))
{
goto done;
}
hr = pFileSave->GetResult(&pItem);
if (FAILED(hr))
{
goto done;
}
hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFileName);
if (FAILED(hr))
{
goto done;
}
hr = g_pEngine->StartRecord(pszFileName);
if (FAILED(hr))
{
goto done;
}
done:
CoTaskMemFree(pszFileName);
SafeRelease(&pItem);
SafeRelease(&pFileSave);
if (FAILED(hr))
{
ShowError(hwnd, IDS_ERR_RECORD, hr);
}
UpdateUI(hwnd);
}
void OnStopRecord(HWND hwnd)
{
HRESULT hr = g_pEngine->StopRecord();
if (FAILED(hr))
{
ShowError(hwnd, IDS_ERR_RECORD, hr);
}
UpdateUI(hwnd);
}
void OnStopPreview(HWND hwnd)
{
HRESULT hr = g_pEngine->StopPreview();
@ -561,54 +450,6 @@ namespace MainWindow
}
UpdateUI(hwnd);
}
void OnTakePhoto(HWND hwnd)
{
wchar_t filename[MAX_PATH];
LPTSTR path;
// Get the path to the Documents folder.
winrt::com_ptr<IShellItem> psi;
PWSTR pszFolderPath = NULL;
HRESULT hr = SHCreateItemInKnownFolder(FOLDERID_Documents, 0, NULL, IID_PPV_ARGS(&psi));
if (FAILED(hr))
{
goto done;
}
CHECK_HR(hr = psi->GetDisplayName(SIGDN_FILESYSPATH, &pszFolderPath));
// Construct a file name based on the current time.
SYSTEMTIME time;
GetLocalTime(&time);
CHECK_HR(hr = StringCchPrintf(filename, MAX_PATH, L"MyPhoto%04u_%02u%02u_%02u%02u%02u.jpg",
time.wYear, time.wMonth, time.wDay, time.wHour, time.wMinute, time.wSecond));
path = PathCombine(PhotoFileName, pszFolderPath, filename);
if (path == NULL)
{
hr = E_FAIL;
goto done;
}
CHECK_HR(hr = g_pEngine->TakePhoto(path));
if (FAILED(hr))
{
goto done;
}
_SetStatusText(path);
done:
CoTaskMemFree(pszFolderPath);
if (FAILED(hr))
{
ShowError(hwnd, IDS_ERR_PHOTO, hr);
}
UpdateUI(hwnd);
}
void OnCommand(HWND hwnd, int id, HWND /*hwndCtl*/, UINT /*codeNotify*/)
{
@ -618,20 +459,6 @@ namespace MainWindow
OnChooseDevice(hwnd);
break;
case ID_CAPTURE_RECORD:
if (g_pEngine->IsRecording())
{
OnStopRecord(hwnd);
}
else
{
OnStartRecord(hwnd);
}
break;
case ID_CAPTURE_TAKEPHOTO:
OnTakePhoto(hwnd);
break;
case ID_CAPTURE_PREVIEW:
if (g_pEngine->IsPreviewing())
{
@ -682,7 +509,6 @@ namespace MainWindow
DbgPrint(L"++WM_POWERBROADCAST++ Stopping both preview & record stream.\n");
g_fSleepState = true;
g_pEngine->SleepState(g_fSleepState);
g_pEngine->StopRecord();
g_pEngine->StopPreview();
g_pEngine->DestroyCaptureEngine();
DbgPrint(L"++WM_POWERBROADCAST++ streams stopped, capture engine destroyed.\n");
@ -711,7 +537,6 @@ namespace MainWindow
DbgPrint(L"++WM_POWERBROADCAST++ Stopping both preview & record stream.\n");
g_fSleepState = true;
g_pEngine->SleepState(g_fSleepState);
g_pEngine->StopRecord();
g_pEngine->StopPreview();
g_pEngine->DestroyCaptureEngine();
DbgPrint(L"++WM_POWERBROADCAST++ streams stopped, capture engine destroyed.\n");