123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300 |
- #include "stdafx.h"
- #include <InitGuid.h>
- #include "filter.h"
- #include "videohorflip.h"
- #include <algorithm>
- #include <immintrin.h>
- using namespace std;
- //
- // VideoHozFlipFilter
- //
- VideoHozFlipFilter::VideoHozFlipFilter( LPUNKNOWN punk, HRESULT *phr ) : CTransInPlaceFilter(NAME("VideoHozFlip"), punk, CLSID_VideoHozFlip, phr)
- {
- //_mm_shuffle_epi8()
- }
- HRESULT VideoHozFlipFilter::Transform( IMediaSample *pSample )
- {
- LPBYTE lpData;
- pSample->GetPointer(&lpData);
- AM_MEDIA_TYPE *pType = &InputPin()->CurrentMediaType();
- VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER *) pType->pbFormat;
- int cxImage = pvi->bmiHeader.biWidth;
- int cyImage = pvi->bmiHeader.biHeight;
- unsigned char *data[4] = {lpData, 0, 0, 0};
- int linesize[4] = {cxImage*3, 0, 0, 0};
- videohorflip_transform(data, linesize, cxImage, cyImage, 2);
- return S_OK;
- }
- HRESULT VideoHozFlipFilter::CheckInputType( const CMediaType *mtIn )
- {
- VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)mtIn->pbFormat;
- if (mtIn->majortype != MEDIATYPE_Video) // check media type
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- // check subtype and formattype
- if (mtIn->subtype != MEDIASUBTYPE_RGB24 ||
- mtIn->formattype != FORMAT_VideoInfo ||
- mtIn->cbFormat < sizeof(VIDEOINFOHEADER))
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- return S_OK;
- }
- CUnknown * WINAPI VideoHozFlipFilter::CreateInstance( LPUNKNOWN punk, HRESULT *phr )
- {
- ASSERT(phr);
- VideoHozFlipFilter *pFilter = new VideoHozFlipFilter(punk, phr);
- if (pFilter == NULL) {
- if (phr)
- *phr = E_OUTOFMEMORY;
- }
- return pFilter;
- }
- //
- // VideoGrabberRenderFilter
- //
- VideoGrabberRenderFilter::VideoGrabberRenderFilter( LPUNKNOWN punk, HRESULT *phr ) : CBaseRenderer(CLSID_VideoGrabberRender, NAME("VideoGrabberRender"), punk, phr),
- m_user_data(NULL), m_on_sample(NULL)
- {
- }
- CUnknown * WINAPI VideoGrabberRenderFilter::CreateInstance( LPUNKNOWN punk, HRESULT *phr )
- {
- ASSERT(phr);
- VideoGrabberRenderFilter *pFilter = new VideoGrabberRenderFilter(punk, phr);
- if (pFilter == NULL) {
- if (phr)
- *phr = E_OUTOFMEMORY;
- }
- return pFilter;
- }
- HRESULT VideoGrabberRenderFilter::DoRenderSample( IMediaSample *pMediaSample )
- {
- if (m_on_sample) {
- LPBYTE lpData;
- if (SUCCEEDED(pMediaSample->GetPointer(&lpData))) {
- (*m_on_sample)(m_user_data, lpData);
- }
- }
- return S_OK;
- }
- HRESULT VideoGrabberRenderFilter::CheckMediaType( const CMediaType * mtIn)
- {
- VIDEOINFOHEADER *pvi = (VIDEOINFOHEADER*)mtIn->pbFormat;
- if (mtIn->majortype != MEDIATYPE_Video) // check media type
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- // check subtype and formattype
- if (mtIn->subtype != MEDIASUBTYPE_RGB24 ||
- mtIn->formattype != FORMAT_VideoInfo ||
- mtIn->cbFormat < sizeof(VIDEOINFOHEADER))
- {
- return VFW_E_TYPE_NOT_ACCEPTED;
- }
- return S_OK;
- }
- VIDEOHORFLIP_API(void*) videohorflip_create_filter()
- {
- HRESULT hr = S_OK;
- CUnknown *pUnknown = VideoHozFlipFilter::CreateInstance(NULL, &hr);
- IBaseFilter *pBaseFilter = NULL;
- if (SUCCEEDED(hr)) {
- pUnknown->NonDelegatingAddRef();
- hr = pUnknown->NonDelegatingQueryInterface(IID_IBaseFilter, (void**)&pBaseFilter);
- pUnknown->NonDelegatingRelease();
- }
- return pBaseFilter;
- }
- VIDEOHORFLIP_API(void*) videohorflip_create_grabber_render(void (*on_sample)(void *user_data, void *data), void *user_data)
- {
- HRESULT hr = S_OK;
- CUnknown *pUnknown = VideoGrabberRenderFilter::CreateInstance(NULL, &hr);
- IBaseFilter *pBaseFilter = NULL;
- if (SUCCEEDED(hr)) {
- pUnknown->NonDelegatingAddRef();
- hr = pUnknown->NonDelegatingQueryInterface(IID_IBaseFilter, (void**)&pBaseFilter);
- pUnknown->NonDelegatingRelease();
- if (SUCCEEDED(hr)) {
- VideoGrabberRenderFilter *pGrabberRender = dynamic_cast<VideoGrabberRenderFilter *>(pUnknown);
- pGrabberRender->SetCallback(on_sample, user_data);
- }
- }
- return pBaseFilter;
- }
- VIDEOHORFLIP_API(int) videohorflip_transform(unsigned char *data[], int linesize[], int cxImage, int cyImage, int format)
- {
- if (format == 2) { // rgb24
- int i, j;
- LPBYTE lpData = data[0];
- for (i = 0; i < cyImage; ++i) {
- LPBYTE x = lpData;
- LPBYTE y = x + (cxImage-1) * 3;
- for (j = 0; j < cxImage >> 1; ++j) {
- swap(*x, *y);
- x++;
- y++;
- swap(*x, *y);
- x++;
- y++;
- swap(*x, *y);
- x++;
- y-=5;
- }
- lpData += linesize[0];
- }
- return 0;
- } else {
- return -1; // not support other types currently
- }
- }
- VIDEOHORFLIP_API(void) videohorflip_fast_copy(void *dst, const void *src, int size)
- {
- #if 1
- if (((int)dst&0xf) == 0 && ((int)src&0xf)==0) { // 16 byte alignment
- int i;
- int n = size / 128;
- __m128i xmm0;
- __m128i xmm1;
- __m128i xmm2;
- __m128i xmm3;
- __m128i xmm4;
- __m128i xmm5;
- __m128i xmm6;
- __m128i xmm7;
- const __m128i *source = reinterpret_cast<const __m128i *>(src);
- __m128i *destination = reinterpret_cast<__m128i*>(dst);
- for (i = 0; i < n; ++i) {
- _mm_prefetch((const char*)source, _MM_HINT_NTA);
- _mm_prefetch((const char*)source+64, _MM_HINT_NTA);
- _mm_prefetch((const char*)source+128, _MM_HINT_NTA);
- xmm0 = _mm_load_si128(source++);
- xmm1 = _mm_load_si128(source++);
- xmm2 = _mm_load_si128(source++);
- xmm3 = _mm_load_si128(source++);
- xmm4 = _mm_load_si128(source++);
- xmm5 = _mm_load_si128(source++);
- xmm6 = _mm_load_si128(source++);
- xmm7 = _mm_load_si128(source++);
- _mm_stream_si128(destination++, xmm0);
- _mm_stream_si128(destination++, xmm1);
- _mm_stream_si128(destination++, xmm2);
- _mm_stream_si128(destination++, xmm3);
- _mm_stream_si128(destination++, xmm4);
- _mm_stream_si128(destination++, xmm5);
- _mm_stream_si128(destination++, xmm6);
- _mm_stream_si128(destination++, xmm7);
- }
- n = (size % 128) / 16;
- for (i = 0; i < n; ++i) {
- _mm_prefetch((const char*)source, _MM_HINT_NTA);
- xmm0 = _mm_load_si128(source++);
- _mm_stream_si128(destination++, xmm0);
- }
- } else {
- memcpy(dst, src, size);
- }
- #else
- memcpy(dst, src, size);
- #endif
- }
- // counter clockwise
- static void rotate1(const unsigned char *src_data, int width, int height, unsigned char *dst_data)
- {
- int i, j;
- int src_linesize = width * 3;
- int dst_linesize = height * 3;
- const unsigned char *pp = src_data + (height-1) * src_linesize;
- const unsigned char *p;
- unsigned char *ss = dst_data;
- unsigned char *s;
- for (i = 0; i < height; ++i) {
- p = pp;
- s = ss;
- for (j = 0; j < width; ++j) {
- s[0] = p[0];
- s[1] = p[1];
- s[2] = p[2];
- s += dst_linesize;
- p += 3;
- }
- ss += 3;
- pp -= src_linesize;
- }
- }
- // clockwise
- static void rotate2(const unsigned char *src_data, int width, int height, unsigned char *dst_data)
- {
- int i, j;
- int src_linesize = width * 3;
- int dst_linesize = height * 3;
- const unsigned char *pp = src_data + (width-1)*3;
- const unsigned char *p;
- unsigned char *ss = dst_data;
- unsigned char *s;
- for (i = 0; i < height; ++i) {
- p = pp;
- s = ss;
- for (j = 0; j < width; ++j) {
- s[0] = p[0];
- s[1] = p[1];
- s[2] = p[2];
- s += dst_linesize;
- p -= 3;
- }
- pp += src_linesize;
- ss += 3;
- }
- }
- VIDEOHORFLIP_API(int) videohorflip_rotate(const unsigned char *src_data, int width, int height, unsigned char *dst_data, int rotation)
- {
- if (rotation == 1) {
- rotate1(src_data, width, height, dst_data);
- } else if (rotation == -1) {
- rotate2(src_data, width, height, dst_data);
- } else { // unknown rotation param
- return -1;
- }
- return 0;
- }
|