Showing posts with label DirectShow. Show all posts
Showing posts with label DirectShow. Show all posts

September 12, 2009

Mp4 Explorer

Brief Introdution
This software is a very helpful tool to inspect and see in details a mp4 file and it is open source. In my case, I was trying to write a program to convert certain video to be compatible with iPhone, but I had no idea about it. Then, I found this useful utility and used it to inspect the video structure of some compatible mp4 files.

Mp4 Explorer

You can download the program and its source code in the following web site:

Official Website - Mp4 Explorer
http://mp4explorer.codeplex.com/

May 20, 2009

Windows Media ASF Viewer

Windows Media® ASF Viewer 9 Series is a tool for inspecting the contents of files (such as .asf. .wma, and .wmv file) to make sure they meet the requirements of the Advanced Systems Format (ASF) specification. -- Microsoft


Brief Introduction
This tool is very helpful for analyzing the contents of ASF files, it helps us to know the media structure and content easily. I was trying to encode WMV using Windows Media Format SDK, and this tool really helped me to verify the output content.

Download from Microsoft

April 28, 2009

How To: Handle dynamic format change in ReceiveConnection function on a renderer filter.

I was trying to correctly handle dynamic format change on my video null renderer and had fought against it for several days.

The following code snippet is my final work for handling dynamic format change, it seems to work fine, I hope so :p


STDMETHODIMP CNullRendererInputPin::ReceiveConnection(IPin * pConnector, const AM_MEDIA_TYPE *pmt)
{
  CAutoLock lock(m_pLock);

  CMediaType newMediaType(*pmt);

  HRESULT hr = E_FAIL;

  if(m_Connected && m_Connected == pConnector && newMediaType != m_mt)
  {
    do {

      hr = CheckMediaType(&newMediaType);
      if(FAILED(hr)) break;

      BITMAPINFO bmpinfo = {0};
      if(FORMAT_VideoInfo == pmt->formattype && 1 == pmt->bFixedSizeSamples)
      {
        VIDEOINFOHEADER* t = (VIDEOINFOHEADER*)(pmt->pbFormat);
        bmpinfo.bmiHeader = t->bmiHeader;
      }
      else if(FORMAT_VideoInfo2 == pmt->formattype && 1 == pmt->bFixedSizeSamples)
      {
        VIDEOINFOHEADER2* t = (VIDEOINFOHEADER2*)(pmt->pbFormat);
        bmpinfo.bmiHeader = t->bmiHeader;
      }
      else
      {
        hr = E_UNEXPECTED;
        break;
      }

      ALLOCATOR_PROPERTIES allocProperties = {0};
      {
        hr = m_pAllocator->GetProperties(&allocProperties);
        if(FAILED(hr)) break;

        allocProperties.cbBuffer = bmpinfo.bmiHeader.biSizeImage;
      }

      hr = SetMediaType(&newMediaType);
      if(FAILED(hr)) break;

      hr = m_pAllocator->Decommit();
      if(FAILED(hr)) break;

      {
        ALLOCATOR_PROPERTIES newAllocProperties = {0};
        hr = m_pAllocator->SetProperties(&allocProperties, &newAllocProperties);
        if(FAILED(hr)) break;
      }

      hr = m_pAllocator->Commit();
      if(FAILED(hr)) break;

      hr = S_OK;

    } while(false);
  }
  else
  {
    hr = CBasePin::ReceiveConnection(pConnector, pmt);
  }

  return hr;
}

March 10, 2009

Where can I find the list of installed ACM codecs on Vista?

It has moved to a strange place on Vista. Do the following steps to see the list:

1. Click on Windows Media Player 11 -> Help -> About -> Technical Support Information

2. It will generate "Support Information for Windows Media Player" and look under "Audio Codecs".

You can also see the information about windows media player binaries and the list of video codecs.

Reference:

March 04, 2009

error C3861: 'CoInitializeEx': identifier not found, even with argument-dependent lookup

You may get the following errors when trying to call CoInitializeEx(NULL, COINIT_MULTITHREADED).
 
error C2065: 'COINIT_MULTITHREADED' : undeclared identifier
error C3861: 'CoInitializeEx': identifier not found, even with argument-dependent lookup

The article in MSDN says "You must include the #define _WIN32_DCOM preprocessor directive at the beginning of your code to be able to use CoInitializeEx."

Look at the code snap in ObjBase.h:

#if (_WIN32_WINNT >= 0x0400 ) || defined(_WIN32_DCOM) // DCOM

WINOLEAPI  CoInitializeEx(IN LPVOID pvReserved, IN DWORD dwCoInit);
WINOLEAPI  CoGetCallerTID( LPDWORD lpdwTID );

#endif // DCOM

So, you need to follow the above rule if you want to call CoInitializeEx, of course you also need to include <objbase.h>.

Reference in MSDN:

March 01, 2009

Why is the media sample upside down after convert its buffer data from YUV to RGB?

Question
I converted the buffer of a media sample from YUY2 to RGB24 pixel by pixel, and then I got a upside-down image. What's wrong with it?

Answer
The definition of the biHeight field of BITMAPINFOHEADER depends the the biCompression field of BITMAPINFOHEADER.

If the bitmap is uncompressed RGB format, the positive biHeight value means the image is bottom-up image; if the bitmap is one of YUV formats such as YUY2, UYVY, and YV12, the image is top-down oriented and the sign of biHeight value must be ignored.

So, I need to do a vertical flip to get a correct image after convert buffer data from YUY2 to RGB24.

You can get more detail information in FOURCC.org: Bitmap Orientation and biHeight

February 21, 2009

FORMAT_VideoInfo v.s. FORMAT_VideoInfo2

If the media type is FORMAT_VideoInfo, it means the format buffer is a VIDEOINFOHEADER struct; if the media type is FORMAT_VideoInfo2, it means the format buffer is a VIDEOINFOHEADER2 struct. So, what's different between VIDEOINFOHEADER and VIDEOINFOHEADER2?

VIDEOINFOHEADER and VIDEOINFOHEADER2 are very different, VIDEOINFOHEADER2 is not just an entended struct of VIDEOINFOHEADER. This means you cannot cast a pointer of VIDEOINFOHEADER2 to a pointer of VIDEOINFOHEADER.

INCORRECT:

if(pmt->formattype == FORMAT_VideoInfo || pmt->formattype == FORMAT_VideoInfo2)
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // *** Wrong! ***
}

CORRECT:

if(pmt->formattype == FORMAT_VideoInfo)
{
    VIDEOINFOHEADER *pVIH = (VIDEOINFOHEADER*)pmt->pbFormat;
    // Now you can use pVIH.
}
else if(pmt->formattype == FORMAT_VideoInfo2)
{
    VIDEOINFOHEADER2 *pVIH = (VIDEOINFOHEADER2*)pmt->pbFormat;
    // Now you can use pVIH.
}

Reference in MSDN:

January 19, 2009

More explanation of CoInitialize() and CoUninitialize()

In this article, I'll not talk about how it works about the COM's apartment model, but the coding practice.

CoInitializeEx() provides the same functionality as CoInitialize() except it provides a parameter to specify the thread's apartment model. So, MSDN recommands us to call CoInitializeEx() instead of CoInitialize().

For using CoInitializeEx(), we also need to follow the same rules as CoInitialize(), I mentioned in the previous article.

The following examples explain how to use CoInitializeEx() and CoUninitialize():

Example #1: CoInitializeEx() will return S_FALSE if the COM library was loaded.

void main()
{
  HRESULT hr = E_FAIL;

  // The first call
  hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK

  // The second call
  hr = CoInitialize(NULL); // hr = S_FALSE, CoInitialize(NULL) = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED)

  // ... skip ...

  // For the second call
  CoUninitialize();

  // For the first call
  CoUninitialize(); // COM library will be unloaded
}

Example #2: CoInitializeEx() will return RPC_E_CHANGED_MODE if a previous call to CoInitializeEx() specified a different apartment model

void main()
{
  HRESULT hr = E_FAIL;

  // The first call
  hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED); // hr = S_OK

  // The second call
  hr = CoInitializeEx(NULL, COINIT_MULTITHREADED); // hr = RPC_E_CHANGED_MODE, the thread's apartment model is still the single thread apartment.

  // ... skip ...

  // NOTE: We do not need to call CoUninitialize() if the corresponding call made by CoInitializeEx() returns error.

  // For the first call
  CoUninitialize(); // COM library will be unloaded
}

January 18, 2009

A clear explanation of CoInitialize() and CoUninitialize()

As you know, when you are using DirectShow or the other COM-based components, the first thing you have to do is calling CoInitialize() to initialize the COM library.

Furthermore, there are several rules you should follow. Now, I will give you a clear explanation here.

Rule #1: For each thread, you have to call CoInitialize() before you call any of the COM library funtions except CoGetMalloc() and the memory allocation functions.

Rule #2: For each successful call made by CoInitialize(), you have to call CoUninitialize() to free the COM library.

Rule #3: Do not call CoInitialize() or CoUninitialize() from the DllMain() function.

Rule #4: The first thread in the application that calls CoInitialize() must be the last thread to call CoUninitialize().


Reference in MSDN:
CoInitialize

January 15, 2009

fatal error RC1015: cannot open include file 'activex.ver'.

Error Message:

fatal error RC1015: cannot open include file 'activex.ver'.

When compile the DirectShow filter sample in DXSDK, you may get the above error message.

Root Cause:

The resource file(.rc) includes <activex.ver> and <activex.rcv>, but compiler cannot find them.

Solution:

activex.ver and activex.rcv are in %DXSDK%\Samples\C++\DirectShow\BaseClasses
(%DXSDK% is your dx sdk installed directory.)

Add the above path to "VC++ Directories" of your VC++ setting,
or add it to "Additional Include Directories" of your project setting.

September 28, 2008

How to mute an Audio Capture Filter of webcam in DirectShow?

If you want to mute an audio capture of webcam, you have to query IAMAudioInputMixer interface on its INPUT PIN, and then use put_Enable method to disable it.

Both the audio capture filter itself and its input pin have IAMAudioInputMixer interface, but the put_Enable / get_Enable methods are implemented on input pin only.

Reference in MSDN:
http://msdn.microsoft.com/en-us/library/ms783820.aspx

September 07, 2008

How to get the string from GUID in DirectShow?

There is a very useful global array that contains strings representing the GUIDs defined in Uuids.h

char* GuidNames[guid]

Example:
const char* GetMajorTypeString(CMediaType* pMediaType)
{
  return GuidNames[*(pMediaType->Type())];
}

Reference:
http://msdn.microsoft.com/en-us/library/ms783758.aspx

January 24, 2008

Notes for QueryFilterInfo()

FILTER_INFO Info = {0};
pFilter->QueryFilterInfo(&Info);
if(Info.pGraph != NULL)
    Info.pGraph->Release(); // You MUST release here

January 01, 2008

Notes for to remove certain filter from a graph

You should check that the graph is stopped or it will fail to remove any filter.