Help with MJPEG sample from RiseOfTheAnts.com

31 views
Skip to first unread message

Jon E

unread,
Mar 12, 2008, 10:31:02 AM3/12/08
to
I'm trying to use a (M)JPEG streaming sample from
http://www.riseoftheants.com/mmx/faq.htm as a reference for our own design.

Whilst it is good as it strips out all the usual fluff you get with
examples, it unfortunately uses a template that works fine under VS2005 but
doesn't seem to work under VC6 - and I have to use VC6 in this instance.

The template is :-

template <class C, class I> HRESULT STDMETHODCALLTYPE CreateInstance(I** ppv)
{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;
C* p = new C(&hr);
if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr = p->QueryInterface(__uuidof(I),(void**)ppv))) goto exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}

Used in a class def

class __declspec(uuid("{F8DDAE70-63C7-4b38-B7A9-61223765ABA6}"))
CJpegPushSource : public CSource
{
friend HRESULT STDMETHODCALLTYPE
CreateInstance<CJpegPushSource,IBaseFilter>(IBaseFilter** ppv);
....

which gives the errors
error C2143: syntax error : missing ';' before '<'
warning C4229: anachronism used : modifiers on data are ignored
error C2433: 'CreateInstance' : 'friend' not permitted on data declarations

for the line beggining 'friend'.

Problem is I don't quite understand the code so don't know how to replace
the template. Why does it need the 'friend' declaration if it is a function
that is actually inside the class itself ? And if it is being used to create
an instance of the object shouldn't it be static ? Or, is the line just a
function prototype in which case where exactly does the code itself live ?

TTFN,
Jon


Alessandro Angeli

unread,
Mar 12, 2008, 1:51:55 PM3/12/08
to
From: "Jon E"

> Problem is I don't quite understand the code so don't
> know how to replace the template. Why does it need the
> 'friend' declaration if it is a function that is actually
> inside the class itself ?

It is not a member of the class. The template is istantiated
as a global function, hence the need to declare the template
instance as a friend of the class to give it access to the
private constructor.

> And if it is being used to
> create an instance of the object shouldn't it be static ?

It is global, so it is static.

> Or, is the line just a function prototype in which case
> where exactly does the code itself live ?

The template is defined in utils.h.

Anyway, you do not need the template and you can just expand
it as global function or a static method:

1.

class CJpegPushSource ...
{
...
public: static HRESULT STDMETHODCALLTYPE
CreateInstance(IBaseFilter** ppv)


{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;

CJpegPushSource* p = new CJpegPushSource(&hr);


if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr =

p->QueryInterface(__uuidof(IBaseFilter),(void**)ppv))) goto

exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}

...
};

...CJpegPushSource::CreateInstance(&pSrcFilter)...

2.

HRESULT STDMETHODCALLTYPE CreateJpegPushSource(IBaseFilter**

ppv)
{
if(ppv == NULL) return E_POINTER; else *ppv = NULL;
HRESULT hr = S_OK;

CJpegPushSource* p = new CJpegPushSource(&hr);


if(NULL == p) { hr = E_OUTOFMEMORY; goto exit; }
if(S_OK != hr) goto exit;
if(S_OK != (hr =

p->QueryInterface(__uuidof(IBaseFilter),(void**)ppv))) goto

exit;
p = NULL;
exit:
if(p) delete p;
return hr;
}

class CJpegPushSource ...
{
friend HRESULT STDMETHODCALLTYPE
CreateJpegPushSource(IBaseFilter** ppv);
...
};

...CreateJpegPushSource(&pSrcFilter)...


--
// Alessandro Angeli
// MVP :: DirectShow / MediaFoundation
// mvpnews at riseoftheants dot com
// http://www.riseoftheants.com/mmx/faq.htm


Jon E

unread,
Mar 14, 2008, 6:53:00 AM3/14/08
to
Hi Alessandro,

Just a minor update for your sample code.

In 'jpeg2mjpeg.cpp', there is a minor bugette. In 'FillBuffer', the code :-

if(INVALID_HANDLE_VALUE == (hf = CreateFile(fn,.....
{
DWORD rc = GetLastError();
hr = ERROR_NOT_FOUND == rc ? S_FALSE : HRESULT_FROM_WIN32(rc);

'ERROR_NOT_FOUND' should read ERROR_FILE_NOT_FOUND, otherwise on stream
completion you not only get the graph notification EC_COMPLETE but also an
EC_ERROR_ABORT since FillBuffer never returns S_FALSE.

Like I said, only minor, thanks for posting the sample projects, they've
_really_ helped.

TTFN,
Jon


Alessandro Angeli

unread,
Mar 14, 2008, 1:46:20 PM3/14/08
to
From: "Jon E"

> 'ERROR_NOT_FOUND' should read ERROR_FILE_NOT_FOUND,

Thanks, I'll fix the code. That should teach me not to copy
from old code of mine when I don't really remember what the
macros mean.

Reply all
Reply to author
Forward
0 new messages