2 Star 0 Fork 0

mirrors_chromium_googlesource/webmdshow

加入 Gitee
与超过 1400万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
克隆/下载
vp8encoderoutpinpreview.cc 7.06 KB
一键复制 编辑 原始数据 按行查看 历史
Tom Finegan 提交于 2014-11-20 05:40 +08:00 . webmdshow clean up: Mass file extension update.
// Copyright (c) 2010 The WebM project authors. All Rights Reserved.
//
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file in the root of the source
// tree. An additional intellectual property rights grant can be found
// in the file PATENTS. All contributing project authors may
// be found in the AUTHORS file in the root of the source tree.
#include <strmif.h>
#include <comdef.h>
#include <uuids.h>
#include "vp8encoderfilter.h"
#include "vp8encoderoutpinpreview.h"
#include "cmediasample.h"
#include "mediatypeutil.h"
#include <vfwmsgs.h>
#include <amvideo.h>
#include <dvdmedia.h>
#include <cassert>
#ifdef _DEBUG
#include "odbgstream.h"
#include "iidstr.h"
using std::endl;
using std::dec;
using std::hex;
#endif
using std::wstring;
namespace VP8EncoderLib
{
OutpinPreview::OutpinPreview(Filter* pFilter) :
Outpin(pFilter, L"preview")
{
}
OutpinPreview::~OutpinPreview()
{
}
HRESULT OutpinPreview::QueryInterface(const IID& iid, void** ppv)
{
if (ppv == 0)
return E_POINTER;
IUnknown*& pUnk = reinterpret_cast<IUnknown*&>(*ppv);
if (iid == __uuidof(IUnknown))
pUnk = static_cast<IPin*>(this);
else if (iid == __uuidof(IPin))
pUnk = static_cast<IPin*>(this);
else
{
pUnk = 0;
return E_NOINTERFACE;
}
pUnk->AddRef();
return S_OK;
}
ULONG OutpinPreview::AddRef()
{
return m_pFilter->AddRef();
}
ULONG OutpinPreview::Release()
{
return m_pFilter->Release();
}
HRESULT OutpinPreview::QueryAccept(const AM_MEDIA_TYPE* pmt)
{
if (pmt == 0)
return E_INVALIDARG;
const AM_MEDIA_TYPE& mt = *pmt;
if (mt.majortype != MEDIATYPE_Video)
return S_FALSE;
if (mt.subtype != MEDIASUBTYPE_YV12)
return S_FALSE;
if (mt.pbFormat == 0)
return S_FALSE;
const BITMAPINFOHEADER* pbmih;
if (mt.formattype == FORMAT_VideoInfo)
{
if (mt.cbFormat < sizeof(VIDEOINFOHEADER))
return S_FALSE;
const VIDEOINFOHEADER& vih = (VIDEOINFOHEADER&)(*mt.pbFormat);
const BITMAPINFOHEADER& bmih = vih.bmiHeader;
pbmih = &bmih;
}
else if (mt.formattype == FORMAT_VideoInfo2)
{
if (mt.cbFormat < sizeof(VIDEOINFOHEADER2))
return S_FALSE;
const VIDEOINFOHEADER2& vih = (VIDEOINFOHEADER2&)(*mt.pbFormat);
const BITMAPINFOHEADER& bmih = vih.bmiHeader;
pbmih = &bmih;
}
else
return S_FALSE;
assert(pbmih);
const BITMAPINFOHEADER& bmih = *pbmih;
if (bmih.biSize != sizeof(BITMAPINFOHEADER)) //TODO: liberalize
return S_FALSE;
//TODO: compare these to preferred media type
//(or to width and height of inpin)
if (bmih.biWidth <= 0)
return S_FALSE;
//if (bmih.biHeight <= 0)
// return S_FALSE;
if (bmih.biCompression != mt.subtype.Data1)
return S_FALSE;
return S_OK;
}
std::wstring OutpinPreview::GetName() const
{
return L"Preview";
}
void OutpinPreview::SetDefaultMediaTypes()
{
m_preferred_mtv.Clear();
AM_MEDIA_TYPE mt;
mt.majortype = MEDIATYPE_Video;
mt.subtype = MEDIASUBTYPE_YV12;
mt.bFixedSizeSamples = FALSE;
mt.bTemporalCompression = FALSE;
mt.lSampleSize = 0;
mt.formattype = GUID_NULL;
mt.pUnk = 0;
mt.cbFormat = 0;
mt.pbFormat = 0;
m_preferred_mtv.Add(mt);
}
HRESULT OutpinPreview::PostConnect(IPin* p)
{
GraphUtil::IMemInputPinPtr pInputPin;
HRESULT hr = p->QueryInterface(&pInputPin);
if (FAILED(hr))
return hr;
GraphUtil::IMemAllocatorPtr pAllocator;
hr = pInputPin->GetAllocator(&pAllocator);
if (FAILED(hr))
hr = CMediaSample::CreateAllocator(&pAllocator);
if (FAILED(hr))
return VFW_E_NO_ALLOCATOR;
return InitAllocator(pInputPin, pAllocator);
}
void OutpinPreview::Render(
CLockable::Lock& lock,
const vpx_image_t* img)
{
assert(img);
if (!bool(m_pPinConnection))
return;
if (!bool(m_pInputPin))
return;
if (!bool(m_pAllocator))
return;
HRESULT hr = lock.Release();
assert(SUCCEEDED(hr));
GraphUtil::IMediaSamplePtr pOutSample;
const HRESULT hrGetBuffer = m_pAllocator->GetBuffer(
&pOutSample,
0,
0,
AM_GBF_NOWAIT);
hr = lock.Seize(m_pFilter);
assert(SUCCEEDED(hr)); //TODO
if (FAILED(hrGetBuffer))
return;
assert(bool(pOutSample));
AM_MEDIA_TYPE* pmt;
hr = pOutSample->GetMediaType(&pmt);
if (SUCCEEDED(hr) && (pmt != 0))
{
assert(QueryAccept(pmt) == S_OK);
m_connection_mtv.Clear();
m_connection_mtv.Add(*pmt);
MediaTypeUtil::Free(pmt);
pmt = 0;
}
unsigned int wIn = img->d_w;
unsigned int hIn = img->d_h;
const BITMAPINFOHEADER& bmih = GetBMIH();
LONG strideOut = bmih.biWidth;
assert(strideOut);
assert((strideOut % 2) == 0);
//Y
const BYTE* pInY = img->planes[VPX_PLANE_Y];
assert(pInY);
BYTE* pOutBuf;
hr = pOutSample->GetPointer(&pOutBuf);
assert(SUCCEEDED(hr));
assert(pOutBuf);
BYTE* pOut = pOutBuf;
const int strideInY = img->stride[VPX_PLANE_Y];
for (unsigned int y = 0; y < hIn; ++y)
{
memcpy(pOut, pInY, wIn);
pInY += strideInY;
pOut += strideOut;
}
strideOut /= 2;
wIn = (wIn + 1) / 2;
hIn = (hIn + 1) / 2;
const BYTE* pInV = img->planes[VPX_PLANE_V];
assert(pInV);
const int strideInV = img->stride[VPX_PLANE_V];
const BYTE* pInU = img->planes[VPX_PLANE_U];
assert(pInU);
const int strideInU = img->stride[VPX_PLANE_U];
//V
for (unsigned int y = 0; y < hIn; ++y)
{
memcpy(pOut, pInV, wIn);
pInV += strideInV;
pOut += strideOut;
}
//U
for (unsigned int y = 0; y < hIn; ++y)
{
memcpy(pOut, pInU, wIn);
pInU += strideInU;
pOut += strideOut;
}
hr = pOutSample->SetTime(0, 0);
assert(SUCCEEDED(hr));
hr = pOutSample->SetSyncPoint(TRUE);
assert(SUCCEEDED(hr));
hr = pOutSample->SetPreroll(FALSE);
assert(SUCCEEDED(hr));
const ptrdiff_t lenOut_ = pOut - pOutBuf;
const long lenOut = static_cast<long>(lenOut_);
hr = pOutSample->SetActualDataLength(lenOut);
assert(SUCCEEDED(hr));
hr = pOutSample->SetDiscontinuity(FALSE); //?
hr = pOutSample->SetMediaTime(0, 0);
hr = lock.Release();
assert(SUCCEEDED(hr));
hr = m_pInputPin->Receive(pOutSample);
hr = lock.Seize(m_pFilter);
assert(SUCCEEDED(hr)); //TODO
}
void OutpinPreview::GetSubtype(GUID& subtype) const
{
subtype = MEDIASUBTYPE_YV12;
}
} //end namespace VP8EncoderLib
Loading...
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mirrors_chromium_googlesource/webmdshow.git
git@gitee.com:mirrors_chromium_googlesource/webmdshow.git
mirrors_chromium_googlesource
webmdshow
webmdshow
main

搜索帮助