音视同步时,如何对音频进行快进等控制操作

rightorwrong 2009-06-14 05:26:05
在播放时,我使用音频进行视频同步。解析媒体文件后,我直接把音频数据通过waveOutWrite进行播放(这样音频数据可能比较早的写入了声卡缓冲),通过音频的播放时间来播放视频。但是我需要进行快进等操作,这个时候我就不能对音频文件进行定位了,因为音频文件可能已经在声卡缓冲了,或者是声卡将要播放的是已经在声卡缓冲中的数据了。我定位到得数据刚通过waveOutWrite到了声卡缓冲,这样我的快进功能就有问题。
请问怎么处理这个问题呢,在播放音频文件时用什么函数。
在同步控制这块,我对音频的处理是错误的。
...全文
440 9 打赏 收藏 转发到动态 举报
写回复
用AI写文章
9 条回复
切换为时间正序
请发表友善的回复…
发表回复
rightorwrong 2009-06-16
  • 打赏
  • 举报
回复
进行快进,倒退时,参考时钟怎么处理?
这个时候需要把起始的时间设置为快进的时间么?
jinlking 2009-06-16
  • 打赏
  • 举报
回复
[Quote=引用 7 楼 rightorwrong 的回复:]
你说的对,使用waveOutGetPosition是不行,需要记录之前的位置,很麻烦,是我没考虑的周到。
对于我的avi文件,存储的一帧音频数据有2048字节,我是每秒16000的数据,这样对2048字节打PTS,将会有0.128S的误差。加上其它因素,可能导致误差比较大。音频时间戳怎么打,快进的时候,怎么找音频?

要让声卡知道?你是说通过调用waveOutPrepare么,在音频采集的时候有这样用

谢谢jinlking指导
[/Quote]
跳转的时候找音频应该是你文件分析时候做的事情,音频的pts在读音频文件的时候就已经打好了。
缓冲区就是这样的基本原理。
瓶盒 2009-06-15
  • 打赏
  • 举报
回复
mark
用waveOutClose(),停止了再开始不行吗?
rightorwrong 2009-06-15
  • 打赏
  • 举报
回复
你说的对,使用waveOutGetPosition是不行,需要记录之前的位置,很麻烦,是我没考虑的周到。
对于我的avi文件,存储的一帧音频数据有2048字节,我是每秒16000的数据,这样对2048字节打PTS,将会有0.128S的误差。加上其它因素,可能导致误差比较大。音频时间戳怎么打,快进的时候,怎么找音频?

要让声卡知道?你是说通过调用waveOutPrepare么,在音频采集的时候有这样用

谢谢jinlking指导
jinlking 2009-06-15
  • 打赏
  • 举报
回复
waveOutGetPosition 获取输出设备当前的播放位置 The position is set to zero when the device is opened or reset.
不好意思,这个函数没有怎么用过,当时粗略的看一下msdn,但是这个函数是和缓冲相关的,就是说它是记录了上次open或者reset开始到现在的的播放时间。一旦打开或者复位就会回到此初始化状态。你的同步是不能快进和快退的,因为这个函数是记录的是播放的时间,如果快进和快退就会跳过一些时间。这样这个函数返回的值就会有问题。不知道我的理解对不对。

我们一般的音视频同步都不是这样做的,我们读取音视频数据,一般每一个Sample上面都会有一个pts,来表示这帧数据是什么时候播放的,跳转的时候就会直接根据这个值来跳转。

双缓冲可以用队列,但是数据存在队列里面还不是双缓存,要让声卡知道,这一块数据播完了,下面的一块数据在哪,这样就不会有中断。
rightorwrong 2009-06-15
  • 打赏
  • 举报
回复
to jinlking,我在使用中,它返回的是整个音频的位置呀。我的当前缓冲就2000字节,在播放过程中,调用该函数,它可以获取比2000大的值,获取的是我认为整个播放的音频位置。
对于双缓冲,我是从音频播放队列中取数据直接播放,基本能保证有多个缓冲。
对于waveOutGetPosition 函数,你能在说清楚些么
jinlking 2009-06-15
  • 打赏
  • 举报
回复
waveOutGetPosition 只会返回当前缓冲区的播放位置,而不是整个音频的位置,音频数据不可能一下子就放到缓存里面,你用这个数据来同步显然是不行的。
一般要用到双缓存,一个缓冲区播放完后,会跳到下一个缓冲区,这个时候就要把先前的缓冲区填满,否则就会出现明显的音频中断
rightorwrong 2009-06-15
  • 打赏
  • 举报
回复
在程序中我用waveOutGetPosition来获取播放长度从而来计算音频播放的时间,然后与视频时间戳进行比较,决定视频是否播放。
我测了下waveOutReset这个函数,他能把当前播放的长度计数清0,应该是可以在快进时起到把缓冲清掉的作用。waveOutClose肯定可以,这样调用觉得时间花销会大些,需要再调用waveOutOpen。

对于对音频进行控制操作,一般是用什么函数进行播放控制呢,是wave类的函数么?mix函数会不会简单点,没有用过mix。

to jinlking,播放时我直接从解码缓冲中读取音频,直接调用的waveOutWrite,卡一下。waveout缓冲我知道点,这里卡一下,是因为我的解码缓冲队列没有设计好。有什么好的方法可以对缓冲队列进行控制。当缓冲队列满了以后是通过等待指定时间还是通过事件做好?

谁有这方面的经验请指导下
jinlking 2009-06-15
  • 打赏
  • 举报
回复
[Quote=引用楼主 rightorwrong 的帖子:]
在播放时,我使用音频进行视频同步。解析媒体文件后,我直接把音频数据通过waveOutWrite进行播放(这样音频数据可能比较早的写入了声卡缓冲),通过音频的播放时间来播放视频。但是我需要进行快进等操作,这个时候我就不能对音频文件进行定位了,因为音频文件可能已经在声卡缓冲了,或者是声卡将要播放的是已经在声卡缓冲中的数据了。我定位到得数据刚通过waveOutWrite到了声卡缓冲,这样我的快进功能就有问题。
请问怎么处理这…
[/Quote]
flush掉缓存的数据 再往里面填充新的数据,一般用waveout都是多缓存的,你可以查查以前的帖子。

2,543

社区成员

发帖
与我相关
我的任务
社区描述
专题开发/技术/项目 多媒体/流媒体开发
社区管理员
  • 多媒体/流媒体开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧