Infognition forum
May 18, 2012, 10:29:18 PM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length
News: Last GraphEditPlus version: 1.4.0   Last Video Enhancer version: 1.9.7
 
   Home   Help Search Login Register  
Pages: [1]
  Print  
Author Topic: Sound out of Sync.  (Read 273 times)
floydus
Newbie
*

Karma: +0/-0
Posts: 19


View Profile
« on: January 19, 2012, 06:52:17 PM »

I have, after maybe one or two hours playback audio out of sync.

Here's the graph, maybe I should have audio filtering, I don't know what to do.



Thanks.
Logged
Dee Mon
Administrator
Hero Member
*****

Karma: +8/-0
Posts: 530



View Profile WWW
« Reply #1 on: January 20, 2012, 07:59:13 AM »

Check what filter acts as a reference clock.
Timers in audio card and TV tuner may have slightly different speeds, so usually one has to choose a reference clock used by all the filters in a graph. By default DirectShow could select the audio renderer, it's a good choice when playing a file. In your case you might want to make your input device the reference clock. Check if its filter supports IReferenceClock interface. If it does, you need to tell the graph to use it.
Logged
floydus
Newbie
*

Karma: +0/-0
Posts: 19


View Profile
« Reply #2 on: January 20, 2012, 07:14:39 PM »

Is it possible that none of the filters supports IReferenceClock interface ?
I ran this code and got no result...
I though maybe at least the audio renderer or smart tee would support it.
Is there other ways of requesting existance of that Interface ?
Am I getting no results because I'm calling this after they all got connected ?
Code:
IEnumFilters enumFilters;
            graphBuilder.EnumFilters(out enumFilters);
            IBaseFilter[] filters = new IBaseFilter[1];

            while (enumFilters.Next(1, filters, IntPtr.Zero) == 0)
            {
                IReferenceClock refClock = null;
                filters[0].GetSyncSource(out refClock);
                FilterInfo thisFilterInfo;
                filters[0].QueryFilterInfo(out thisFilterInfo);
                if (refClock != null)
                {
                    filters[0].QueryFilterInfo(out thisFilterInfo);
                    MessageBox.Show("This Filter has IReferenceClock " + thisFilterInfo.achName + " " + refClock.ToString());
                }
                Marshal.ReleaseComObject(filters[0]);
            }
            Marshal.ReleaseComObject(enumFilters);
Logged
floydus
Newbie
*

Karma: +0/-0
Posts: 19


View Profile
« Reply #3 on: January 20, 2012, 08:57:39 PM »

 Grin I realized I just cannot rely on GetSyncSource to verify that a filter supports IReferenceClock interface.

The following function tells me if a filter supports it or not :

Code:
private IReferenceClock IsImplementingIReferenceClock(ICaptureGraphBuilder2 capGraph, IBaseFilter capFilter)
        {
            int hr;
            object o;
            Guid GuidInterfaceToFind = typeof(IReferenceClock).GUID;
            hr = capGraph.FindInterface(null, null, capFilter, GuidInterfaceToFind, out o);
            if (hr != 0)
            {
                return null;
            }
            else
            {
                IReferenceClock returnedIReference = (IReferenceClock)o;
                return returnedIReference;
            }
        }

After the interface is found from the TV Capture Card, I set the source to it using the following code.

Code:
IReferenceClock returnedClockReference = IsImplementingIReferenceClock(pBuilder, pAVerMedia7231AnalogCapture);
pVideoRenderer.SetSyncSource(returnedClockReference);
pDefaultDirectSoundDevice.SetSyncSource(returnedClockReference);
Is that ok ? Should I set the sync to more filters or that would be ok ?

I will let you know the result overtime later.

Thanks.
Logged
Dee Mon
Administrator
Hero Member
*****

Karma: +8/-0
Posts: 530



View Profile WWW
« Reply #4 on: January 21, 2012, 03:34:19 PM »

When scanning for interfaces we're using another method of querying for an interface:
Code:
               
IntPtr objectPointer = Marshal.GetIUnknownForObject(scannedObject);
IntPtr pInterface;
Guid queryInterface = InterfaceGUID;
Marshal.QueryInterface(objectPointer, ref queryInterface, out pInterface);
if (pInterface != IntPtr.Zero) ...

But in many cases it's simpler just to use "as":
Code:
if ((someFilter as IReferenceClock) != null) ...

Then, documentaion says:
"An application can select a clock by calling the IMediaFilter::SetSyncSource method on the Filter Graph Manager."
So once you've found a reference clock you don't just provide it to some particular filters, you should set it to the whole graph by quering your graph object for IMediaFilter and calling SetSyncSource.
« Last Edit: January 21, 2012, 03:36:37 PM by Dee Mon » Logged
Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.13 | SMF © 2006-2011, Simple Machines LLC Valid XHTML 1.0! Valid CSS!