流播放器音视频同步的一点思考

音视频同步是一个坑,一个绕不过去的坑,一个无可奈何的坑,一个主动跳进去的坑。


时间戳是前提。没有时间戳或者时间戳错误,一切播放端音视频同步的方法基础都是不牢靠的。


生成的音视频流要音视频同步。可以转成文件要本地播放器来验证一下

rtmp播放器特点:
1,不能堆积数据。如果播放数据堆积,那么给人的感觉就是延迟太大了。预留的数据不能太少了,不然视频帧还好说,音频播放的时候就会出现卡顿的现象。
2,通道数不确定,可能只有视频,而没有音频。


0,当前音频帧的时间戳m1,视频帧的时间戳m2
1,音频未播放数据需要的时间t1,视频未播放的帧数(或者播放完这些帧需要的时间t2)。
2,没有音频只有视频
3,当音频存余的数据量太多时就删除掉
   当视频存取的帧数太多时就删除掉
   特别是当两者都堆积数据时,要一起删除掉。这里是rtmp播放器与一般的视频文件播放不一样的地方。
4,当音视频两者的时间戳差太多时,删除掉时间差的多的。


(这里阈值我们设置为1.0s,这个最好可以定义,这里就是定义缓冲区的大小,如果这里定义的小了,就会出现时断时续,一直跳帧的情况)
音视频冗余的将要播放的数据在1.0s内是正常的。
如果 音视频帧的冗余时间都超过了1.0秒,就要对数据进行抛弃处理。
如果 音视频的不同步超过0.5s(这个值看实际情况,一般视觉上差个0.1s就能感觉出来),就要进行同步操作。


从理论上来说,如果传输数据正常,数据是持续产生的,我们持续播放,不会出现需要我们丢弃数据的情况。
实际情况是,网络情况有点抖动,有的时候没有数据(这种情况我们不管),有的时候,大量数据涌了过来(这个时候我们就要进行数据抛弃了)。


发送(编码发送)部分:
这里我们要保证输出的文件是音视频同步的。
需要加一个事件校正,因为音频和视频编码之后,时间戳可能有点偏差。





int _tmain(int argc, _TCHAR* argv[]) { currentAudioClock = 0; currentVideoClock = 0; currentBufferClock = 0; //currentPlayClock=0; CurrentVolume = SDL_MIX_MAXVOLUME; if (SDL_Init(SDL_INIT_EVERYTHING) != 0) { fprintf(stderr, "Unable to initialize SDL: %s\n", SDL_GetError()); return 1; } SDL_EventState(SDL_SYSWMEVENT, SDL_IGNORE); SDL_EventState(SDL_USEREVENT, SDL_IGNORE); atexit(SDL_Quit);// 注册SDL_Quit,当退出时调用,使得退出时程序自动清理 //flag=2; //给音视频队列分配空间 videoQueue = (VideoQueue *)av_mallocz(sizeof(VideoQueue)); audioQueue = (AudioQueue *)av_mallocz(sizeof(AudioQueue)); //初始化音视频队列 VideoQueueInit(videoQueue); AudioQueueInit(audioQueue); char* url = "G:/上海滩.mp4"; //char* url = "G:/2014年5月26日17 12 00至2014年5月26日17 14 59.avi"; //char* url = "H:/视频/不当交易.The.Unjust.BD.MiniSD-TLF.mkv"; //char* url = "E:/BaiduMusic/Songs/Love Story - Taylor Swift.mp3"; decodeTid = SDL_CreateThread(DecodePacket, "DecodePacket", (void*)url); PlayVideoTid = SDL_CreateThread(PlayVideo, "PlayVideo", NULL); PlayAudioTid = SDL_CreateThread(PlayAudio, "PlayAudioTid", NULL); int tid; SDL_WaitThread(decodeTid, &tid); printf("decodeTid %d\n", tid); SDL_WaitThread(PlayVideoTid, &tid); printf("PlayVideoTid %d\n", tid); SDL_WaitThread(PlayAudioTid, &tid); printf("PlayAudioTid %d\n", tid); SDL_DestroyMutex(audioQueue->audioMutex); SDL_DestroyCond(audioQueue->audioCond); SDL_DestroyMutex(videoQueue->videoMutex); SDL_DestroyCond(videoQueue->videoCond); av_free(videoQueue); av_free(audioQueue); return 0; }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值