Wednesday, March 12, 2008

RTP Audio Source Filter Problem without Glitches

Solution for Removing Audio Glitches in a RTP Audio Source Filter
-------------------------------------------------------------------
1.Test the Timestamp of the large files.
- it is also having some strange values like Start Time : 40000 and End Time :0
2.Set only start Time and be the stop time always 0.3.Dump the RTP Packet within the file.( No Problem with audio data)4.Implement the IAMPushSource interface.
I tested the large MP2 file in GraphEdit :
------------------------------------------------
If I inserted the dummy filter before the MPEG1 Audio Decoder filter, I got the following :
Start Time : 28114700 Stop Time : 23998200 Diff : 4116500Another time I got it as follows:
Start Time :31588108 Stop Time :28454648
Differnece :3133460

If I inserted the Dummy Filter after the MPEg1 Audio Decoder, I got the timestamp values as follows:
Grabber Sample size is : 18432 Start Time :0 Stop Time :0
Grabber Sample size is : 18432 Start Time :960000 Stop Time :0
Grabber Sample size is : 18432 Start Time : 1920000 Stop Time : 0
For the RTP Source Filter I got the following:
----------------------------------------------- 1.If I inserted the dummy filter before the MPEG1 Audio Decoder filter, I got the following :
Start Time Stop Time 2520000 2520000 2520000 2835000 2835000 3150000 2.If I inserted the Dummy Filter after the MPEG1 Audio Decoder, I got the timestamp values as follows:
Grabber Sample Size is : 18432 Start Time : 2520000 Stop Time : 0
Start Time : 2835000 Stop Time : 0 Start Time : 3150000 Stop Time : 0
Start Time : 3465000 Stop Time : 0 Start Time : 3780000 Stop Time : 0
Nothing above is works.
Solution:
-------------------

I am sending mp2 audio data with 48Hz frequency. At the RTP Audio Source Filter, I modified the frequency as 22.05 ( 22050 samples per second)..

Samples per second is the speed controller of a filter graph. it determines the speed of the filter.

48000(48 KHz) filter will run fast.
44100 (44.1KHz) filter will be some extent slow compare to the 48000.
22050( 22.05 KHz ) is very slow.
we are rendering the audio half of the transmitted audio's speed.

Labels: , ,

Thursday, February 28, 2008

Source Filter without Timestamp will works?

Source Filter without Timestamp will works ?
within FillBuffer() fn of a source Filter, I have not set the timestamp .
But it is working well.Timestamp is necessary for storing the media( audio and video ) content to a file.
without Setting timestamp for the media sample, the Source Filter is working well.

Labels: ,

Friday, January 11, 2008

How to call callback functions repeatedly ?

ll the callbacks will be in the form of as follows :

WSARecv( AsyncCallback);

if the data is received in a socket, AsyncCallback () fn is being called .
How can we repeatly Read data from socket ? By calling WSARecv() fn in a thread ( which is being called repeatedly)
?

No.. we can achive this by the following


WSARecv(AsyncCallback);


within AsyncCallback()
{

//call the WSARecv() fn based on some condition ...
}

For Example,

AsyncCallback()
{
if( bStop == false)
{
WsaRecv(AsyncCallback);
}
}



Another one way is :


bool bContinueLoop = true;
RecvSocket()
{
WSARecv(AsyncCallback);
}

AsyncCallback()
{
if(bContinueLoop)
{
RecvSocket();
}

}

StopRecvSocket()
{
bContinueLoop = false;
}

Labels: , ,

Thursday, August 23, 2007

Connect mechanism to Build the graph

using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;
using DirectShowLib;

namespace AddRendererFilter
{
class AddRendererFilter
{
private IGraphBuilder m_pGraphBuilder = null;
private IMediaControl m_pMediaControl = null;
private IMediaEventEx m_pMediaEventEx = null;

private IBaseFilter m_pSourceFilter = null;
private IBaseFilter m_pRendererFilter = null;



public AddRendererFilter()
{
m_pGraphBuilder = new FilterGraph() as IGraphBuilder;
}
~AddRendererFilter()
{
ReleaseGraph();
}

private void ReleaseGraph()
{
if (m_pGraphBuilder != null)
{
Marshal.ReleaseComObject(m_pGraphBuilder);
m_pGraphBuilder = null;
}
GC.Collect();
}

public void Render()
{
int hr = 0;

IPin pOutputPin = null;
IPin pInputPin = null;


hr = m_pGraphBuilder.AddSourceFilter("D:\\hands.avi", "Source Filter", out m_pSourceFilter);
DsError.ThrowExceptionForHR(hr);

hr = AddFilterByCLSID(ref m_pGraphBuilder, typeof(VideoRenderer), "Renderer Filter", out m_pRendererFilter);
DsError.ThrowExceptionForHR(hr);

pOutputPin = DsFindPin.ByDirection(m_pSourceFilter, PinDirection.Output, 0);
pInputPin = DsFindPin.ByDirection(m_pRendererFilter, PinDirection.Input, 0);

hr = m_pGraphBuilder.Connect(pOutputPin, pInputPin);
DsError.ThrowExceptionForHR(hr);

m_pMediaControl = m_pGraphBuilder as IMediaControl;
m_pMediaControl.Run();

}

private int AddFilterByCLSID(ref IGraphBuilder pGraph,
Type comType,
string FilterName,
out IBaseFilter pFilter
)
{
Object comObject = null;
int hr = 0;
try
{
comObject = Activator.CreateInstance(comType);
if (comObject == null)
{
throw new NotSupportedException("\n Invalid Class Id Type");
}
pFilter = comObject as IBaseFilter;
hr = m_pGraphBuilder.AddFilter(pFilter, FilterName);
DsError.ThrowExceptionForHR(hr);
return hr;
}
catch (Exception ex)
{
pFilter = null;
return -1;
}
}
}
}

client Usage :
---------------------
AddRendererFilter m_pAddRendererFilter = null;
m_pAddRendererFilter = new AddRendererFilter();
m_pAddRendererFilter.Render();

Labels:

RenderFile method Directshow_C#

Render File with C# with Directshow Sample application :



using System;
using System.Collections.Generic;
using System.Text;

using System.Runtime.InteropServices;
using DirectShowLib;

namespace PlayWnd
{
internal enum PlayState
{
Stopped,
Paused,
Running,
Init
};

internal enum MediaType
{
Audio,
Video
}


class PlayWnd
{
private const int WMGraphNotify = 0x0400 + 13;

private IGraphBuilder m_pGraphBuilder = null;
private IMediaControl m_pMediaControl = null;
private IMediaEventEx m_pMediaEventEx = null;
private IMediaSeeking m_pMediaSeeking = null;
private IVideoWindow m_pVideoWindow = null;


public PlayWnd()
{
m_pGraphBuilder = (IGraphBuilder) new FilterGraph();
m_pMediaControl = (IMediaControl) m_pGraphBuilder;
m_pMediaEventEx = (IMediaEventEx) m_pGraphBuilder;
m_pMediaSeeking = (IMediaSeeking) m_pGraphBuilder;

}
~PlayWnd()
{
CloseInterfaces();
}

public int RenderFile(IntPtr handle,string filename)
{
int hr = 0;
hr = m_pGraphBuilder.RenderFile(filename,null);
DsError.ThrowExceptionForHR(hr);
m_pVideoWindow = m_pGraphBuilder as IVideoWindow;
hr = m_pMediaEventEx.SetNotifyWindow(handle, WMGraphNotify, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);

return 0;
}

public void Start()
{
int hr = 0;
hr = m_pMediaControl.Run();
DsError.ThrowExceptionForHR(hr);
}
public void Pause()
{
int hr = 0;
hr = m_pMediaControl.Pause();
DsError.ThrowExceptionForHR(hr);
}
public void Stop()
{
int hr = 0;
hr = m_pMediaControl.Stop();
DsError.ThrowExceptionForHR(hr);
}

public void SetWindowPosition(IntPtr hwnd,int x, int y, int width, int height)
{
int hr = 0;
if (m_pVideoWindow != null)
{
hr = m_pVideoWindow.SetWindowPosition(
x,
y,
width,
height
);
DsError.ThrowExceptionForHR(hr);
}
hr = m_pVideoWindow.put_Owner(hwnd);
DsError.ThrowExceptionForHR(hr);

hr = m_pVideoWindow.put_WindowStyle(WindowStyle.Child |

WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
DsError.ThrowExceptionForHR(hr);

hr = m_pVideoWindow.put_Visible(OABool.True);
DsError.ThrowExceptionForHR(hr);


}

public void CloseInterfaces()
{
int hr = 0;
try
{
lock (this)
{
hr = this.m_pVideoWindow.put_Visible(OABool.False);
DsError.ThrowExceptionForHR(hr);
hr = this.m_pVideoWindow.put_Owner(IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);

if (m_pMediaEventEx != null)
{
hr = m_pMediaEventEx.SetNotifyWindow(IntPtr.Zero, 0, IntPtr.Zero);
DsError.ThrowExceptionForHR(hr);
}

if (m_pMediaControl != null)
{
m_pMediaControl = null;
}
if (m_pMediaSeeking != null)
{
m_pMediaSeeking = null;
}
if (m_pVideoWindow != null)
{
m_pVideoWindow = null;
}

if (m_pGraphBuilder != null)
{
Marshal.ReleaseComObject(m_pGraphBuilder);
m_pGraphBuilder = null;
}
GC.Collect();
}


}
catch
{
}
}

}
}


Client Usage :
-----------------------
PlayWnd m_pPlayWnd = null;

void btnRender_Click()
{
m_pPlayWnd.RenderFile(pnlVideo.Handle, "D:\\hands.avi");
m_pPlayWnd.SetWindowPosition(pnlVideo.Handle, 0, 0,

pnlVideo.Width, pnlVideo.Height);
}


private void btnStart_Click(object sender, EventArgs e)
{
m_pPlayWnd.Start();
}

private void btnPause_Click(object sender, EventArgs e)
{
m_pPlayWnd.Pause();
}

private void btnStop_Click(object sender, EventArgs e)
{
m_pPlayWnd.Stop();
}

Labels:

Render method

we have to add Directshow.net as a reference.
( download it from sourceforge.net)

Render Method Sample application in C# with directshow :
--------------------------------------------------------------------------------------

using System.Runtime.InteropServices;
using DirectShowLib;

namespace RenderMethod
{
class RenderMethod
{
private IGraphBuilder m_pGraphBuilder = null;
private IMediaControl m_pMediaControl = null;
private IMediaEventEx m_pMediaEventEx = null;
private IMediaSeeking m_pMediaSeeking = null;

private IBaseFilter m_pSourceFilter = null;
private IPin m_pOutputPin = null;


public RenderMethod()
{
m_pGraphBuilder = (IGraphBuilder)new FilterGraph();
}

~RenderMethod()
{
CloseInterfaces();
}

public int AddSourceFilter(string sourceFilename)
{
int hr = 0;

if (m_pGraphBuilder == null)
{
return DsResults.E_CannotRender;
}

hr = m_pGraphBuilder.AddSourceFilter(sourceFilename, sourceFilename, out m_pSourceFilter);
DsError.ThrowExceptionForHR(hr);
return hr;

}
public int Render()
{
int hr = 0;
m_pOutputPin = DsFindPin.ByDirection(m_pSourceFilter, PinDirection.Output, 0);
hr = m_pGraphBuilder.Render(m_pOutputPin);
DsError.ThrowExceptionForHR(hr);

m_pMediaControl = m_pGraphBuilder as IMediaControl;
m_pMediaEventEx = m_pGraphBuilder as IMediaEventEx;
m_pMediaSeeking = m_pGraphBuilder as IMediaSeeking;


hr = m_pMediaControl.Run();
DsError.ThrowExceptionForHR(hr);
return hr;
}

private void CloseInterfaces()
{
if (m_pGraphBuilder != null)
{
Marshal.ReleaseComObject(m_pGraphBuilder);
}
GC.Collect();
}

}
}


Client Usage of a class :

RenderMethod renderMethod = null;
renderMethod.AddSourceFilter("D:\\hands.avi");
renderMethod.Render();

Labels: