一个DSPACK中枚举FilterGraph所有使有的Filter及Pin的例子!我如何切换流! ( 积分: 100 )

  • 主题发起人 主题发起人 david_sale
  • 开始时间 开始时间
D

david_sale

Unregistered / Unconfirmed
GUEST, unregistred user!
这个例子是我用来测试播放MKV文件的代码,MKV文件是一种容器文件格式,可组合多种视频文件及多条音轨同时播放,比如组合一个realVideo的视频流和2条AC3的音轨(一条原唱及一条伴唱)
通用GraphEdit分析发现Matroska Splitter输出两个audio Pin和一个video Pin,两个audio Pin最后都连接到defalut directSound device,我最终的目的FilterGraph运行过程中只单独播放一条音频流(原唱或伴唱),但是切换另一条音频流时要与Video的时间同步,我如何操作呢?

我设想这么一种解决方法不知道可不可行:
两条音频同时输出时,我把其中一条的filter设为pasue状态,这时可以正常输出另一条音频流,但当我切换回来时继续用filter.run方法时发现这条音频流是继续播放,并不能与video的时间同步。
如此在两条音频流间切换达到只输出一条音轨的目的。
我想这应该是时间同步的问题,但我不是太理解,请DS们指教。

下面是我的部分代码:(有谁能告诉我如何能上传DFW上)
枚举所有的Filter及Pin:

procedure TForm1.Button1Click(Sender: TObject);
var
hr:HResult;
wIpin:IPin;
temp: IFilterGraph;
ti,tj:integer;
wFilterInfo:TFilterInfo;
wPinInfo:TPinInfo;
wEnumPins:IEnumPins;
wPin:IPin;
wID:PwideChar;
wFilterList:TFilterList;
begin

wFilterList:=TFilterList.Create;
hr:=FilterGraph1.QueryInterface(IFilterGraph,temp);
if Succeeded(hr) then

begin

wFilterList.Assign(temp);
form2.Memo1.Lines.Clear;
form2.Memo1.Lines.Add(format('Filter Count: %d',[wFilterList.Count]));
for ti:=0 to wFilterList.Count-1do

begin

//找出filter Graph中的所有的filter
wFilterList.Items[ti].QueryFilterInfo(wFilterInfo);
form2.Memo1.Lines.Add(' Filter Name: '+ wFilterInfo.achName);
//找中filter中的所有Pins
wFilterList.Items[ti].EnumPins(wEnumPins);
while wEnumPins.Next(1,wPin,nil)=S_OKdo

begin

wPin.QueryPinInfo(wPinInfo);
case wPininfo.dir of
PINDIR_INPUT : form2.Memo1.Lines.Add(' Pin dir : PINDIR_INPUT ');
PINDIR_OUTPUT : form2.Memo1.Lines.Add(' Pin dir : PINDIR_OUT ');
end;

form2.Memo1.Lines.Add(' Pin Name: '+ wPinInfo.achName);
hr:=wPin.QueryId(wID);
if succeeded(hr) then
form2.Memo1.Lines.Add(' Pin ID : '+wID);
end;


end;

wFilterList.Free;
form2.ShowModal;
end;


可以通过这个来暂停播放一个流:
wFilterList.Items[0].Pause;
这个是第1条音频流的Filter
wFilterList.Items[1].Pause;
这个是第2条音频流的Filter

继续播放一条音频流:
aa:int64
wFilterList.Items[1].Run(aa);
//这个aa的值我不知道是指的哪个时钟
 
这个例子是我用来测试播放MKV文件的代码,MKV文件是一种容器文件格式,可组合多种视频文件及多条音轨同时播放,比如组合一个realVideo的视频流和2条AC3的音轨(一条原唱及一条伴唱)
通用GraphEdit分析发现Matroska Splitter输出两个audio Pin和一个video Pin,两个audio Pin最后都连接到defalut directSound device,我最终的目的FilterGraph运行过程中只单独播放一条音频流(原唱或伴唱),但是切换另一条音频流时要与Video的时间同步,我如何操作呢?

我设想这么一种解决方法不知道可不可行:
两条音频同时输出时,我把其中一条的filter设为pasue状态,这时可以正常输出另一条音频流,但当我切换回来时继续用filter.run方法时发现这条音频流是继续播放,并不能与video的时间同步。
如此在两条音频流间切换达到只输出一条音轨的目的。
我想这应该是时间同步的问题,但我不是太理解,请DS们指教。

下面是我的部分代码:(有谁能告诉我如何能上传DFW上)
枚举所有的Filter及Pin:

procedure TForm1.Button1Click(Sender: TObject);
var
hr:HResult;
wIpin:IPin;
temp: IFilterGraph;
ti,tj:integer;
wFilterInfo:TFilterInfo;
wPinInfo:TPinInfo;
wEnumPins:IEnumPins;
wPin:IPin;
wID:PwideChar;
wFilterList:TFilterList;
begin

wFilterList:=TFilterList.Create;
hr:=FilterGraph1.QueryInterface(IFilterGraph,temp);
if Succeeded(hr) then

begin

wFilterList.Assign(temp);
form2.Memo1.Lines.Clear;
form2.Memo1.Lines.Add(format('Filter Count: %d',[wFilterList.Count]));
for ti:=0 to wFilterList.Count-1do

begin

//找出filter Graph中的所有的filter
wFilterList.Items[ti].QueryFilterInfo(wFilterInfo);
form2.Memo1.Lines.Add(' Filter Name: '+ wFilterInfo.achName);
//找中filter中的所有Pins
wFilterList.Items[ti].EnumPins(wEnumPins);
while wEnumPins.Next(1,wPin,nil)=S_OKdo

begin

wPin.QueryPinInfo(wPinInfo);
case wPininfo.dir of
PINDIR_INPUT : form2.Memo1.Lines.Add(' Pin dir : PINDIR_INPUT ');
PINDIR_OUTPUT : form2.Memo1.Lines.Add(' Pin dir : PINDIR_OUT ');
end;

form2.Memo1.Lines.Add(' Pin Name: '+ wPinInfo.achName);
hr:=wPin.QueryId(wID);
if succeeded(hr) then
form2.Memo1.Lines.Add(' Pin ID : '+wID);
end;


end;

wFilterList.Free;
form2.ShowModal;
end;


可以通过这个来暂停播放一个流:
wFilterList.Items[0].Pause;
这个是第1条音频流的Filter
wFilterList.Items[1].Pause;
这个是第2条音频流的Filter

继续播放一条音频流:
aa:int64
wFilterList.Items[1].Run(aa);
//这个aa的值我不知道是指的哪个时钟
 
后退
顶部