/*static */HRESULT MFMovieSource::GetDuration( IMFSourceReader* reader, UINT64& duration ) { // https://msdn.microsoft.com/ja-jp/library/windows/desktop/ms702060(v=vs.85).aspx HRESULT hr; PROPVARIANT var={}; PropVariantInit( &var ); hr=reader->GetPresentationAttribute( (DWORD)MF_SOURCE_READER_MEDIASOURCE, MF_PD_DURATION, &var ); if( SUCCEEDED( hr ) ) { long long tmp = 0; PropVariantToInt64( var, &tmp ); duration = (UINT64)std::max(tmp, 0LL); PropVariantClear( &var ); } return hr; }
/****************************************************************** * PropVariantChangeType (PROPSYS.@) */ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt) { HRESULT hr; FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc, propvarSrc->vt, flags, vt); if(vt == propvarSrc->vt) return PropVariantCopy(ppropvarDest, propvarSrc); switch (vt) { case VT_I2: { SHORT res; hr = PropVariantToInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; ppropvarDest->u.iVal = res; } return hr; } case VT_UI2: { USHORT res; hr = PropVariantToUInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; ppropvarDest->u.uiVal = res; } return hr; } case VT_I4: { LONG res; hr = PropVariantToInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; ppropvarDest->u.lVal = res; } return hr; } case VT_UI4: { ULONG res; hr = PropVariantToUInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; ppropvarDest->u.ulVal = res; } return hr; } case VT_I8: { LONGLONG res; hr = PropVariantToInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; ppropvarDest->u.hVal.QuadPart = res; } return hr; } case VT_UI8: { ULONGLONG res; hr = PropVariantToUInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; ppropvarDest->u.uhVal.QuadPart = res; } return hr; } case VT_LPWSTR: { WCHAR *res; hr = PropVariantToStringAlloc(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; ppropvarDest->u.pwszVal = res; } return hr; } } switch (propvarSrc->vt) { case VT_FILETIME: return PROPVAR_ConvertFILETIME(ppropvarDest, propvarSrc, vt); default: FIXME("Unhandled source type: %d\n", propvarSrc->vt); } return E_FAIL; }
/****************************************************************** * PropVariantChangeType (PROPSYS.@) */ HRESULT WINAPI PropVariantChangeType(PROPVARIANT *ppropvarDest, REFPROPVARIANT propvarSrc, PROPVAR_CHANGE_FLAGS flags, VARTYPE vt) { HRESULT hr; FIXME("(%p, %p, %d, %d, %d): semi-stub!\n", ppropvarDest, propvarSrc, propvarSrc->vt, flags, vt); if (vt == propvarSrc->vt) return PropVariantCopy(ppropvarDest, propvarSrc); if (propvarSrc->vt == VT_FILETIME) return PROPVAR_ConvertFILETIME(&propvarSrc->u.filetime, ppropvarDest, vt); switch (vt) { case VT_I1: { LONGLONG res; hr = PROPVAR_ConvertNumber(propvarSrc, 8, TRUE, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I1; ppropvarDest->u.cVal = (char)res; } return hr; } case VT_UI1: { LONGLONG res; hr = PROPVAR_ConvertNumber(propvarSrc, 8, FALSE, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI1; ppropvarDest->u.bVal = (UCHAR)res; } return hr; } case VT_I2: { SHORT res; hr = PropVariantToInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I2; ppropvarDest->u.iVal = res; } return hr; } case VT_UI2: { USHORT res; hr = PropVariantToUInt16(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI2; ppropvarDest->u.uiVal = res; } return hr; } case VT_I4: { LONG res; hr = PropVariantToInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I4; ppropvarDest->u.lVal = res; } return hr; } case VT_UI4: { ULONG res; hr = PropVariantToUInt32(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI4; ppropvarDest->u.ulVal = res; } return hr; } case VT_I8: { LONGLONG res; hr = PropVariantToInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_I8; ppropvarDest->u.hVal.QuadPart = res; } return hr; } case VT_UI8: { ULONGLONG res; hr = PropVariantToUInt64(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_UI8; ppropvarDest->u.uhVal.QuadPart = res; } return hr; } case VT_LPWSTR: case VT_BSTR: { WCHAR *res; hr = PropVariantToStringAlloc(propvarSrc, &res); if (SUCCEEDED(hr)) { ppropvarDest->vt = VT_LPWSTR; ppropvarDest->u.pwszVal = res; } return hr; } case VT_LPSTR: { WCHAR *resW; hr = PropVariantToStringAlloc(propvarSrc, &resW); if (SUCCEEDED(hr)) { char *res; DWORD len; len = WideCharToMultiByte(CP_ACP, 0, resW, -1, NULL, 0, NULL, NULL); res = CoTaskMemAlloc(len); if (res) { WideCharToMultiByte(CP_ACP, 0, resW, -1, res, len, NULL, NULL); ppropvarDest->vt = VT_LPSTR; ppropvarDest->u.pszVal = res; } else hr = E_OUTOFMEMORY; CoTaskMemFree(resW); } return hr; } default: FIXME("Unhandled dest type: %d\n", vt); return E_FAIL; } }