小丸子压缩软件出的调整音视频同步软件不同步

小丸子工具箱压制视频cpu跑不满什么情况?如图_小丸工具箱吧_百度贴吧
&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&签到排名:今日本吧第个签到,本吧因你更精彩,明天继续来努力!
本吧签到人数:0成为超级会员,使用一键签到本月漏签0次!成为超级会员,赠送8张补签卡连续签到:天&&累计签到:天超级会员单次开通12个月以上,赠送连续签到卡3张
关注:3,377贴子:
小丸子工具箱压制视频cpu跑不满什么情况?如图收藏
工具箱选上海立瑞,专业生产铝箱,上海8年大型铝箱厂,免费打样,质量可靠价格合理,上海立瑞工具箱一站式采购:上海中凡EVA工具箱内衬,距离500米,欢迎参观定制!
8核16线程 Orz。。压片好像吃主频啊
这不是小丸的问题,而且X264的问题。X264最多只能利用到16个线程……想要跑满,只能多开小丸。
登录百度帐号推荐应用
为兴趣而生,贴吧更懂你。或用FFMPEG SDK进行视频转码压缩时解决音视频不同步问题的方法(转)
我的图书馆
用FFMPEG SDK进行视频转码压缩时解决音视频不同步问题的方法(转)
用FFMPEG SDK进行视频转码压缩的时候,转码成功后去看视频的内容,发现音视频是不同步的。这个的确是一个恼火的事情。我在用FFMPEG SDK做h264格式的FLV文件编码Filter的时候就碰到了这个问题。经过研究发现,FFMPEG SDK写入视频的时候有两个地方用来控制写入的时间戳,一个是AvPacket, 一个是AvFrame。 在调用avcodec_encode_video的时候需要传入AvFrame的对象指针,也就是传入一帧未压缩的视频进行压缩处理,AvFrame包含一个pts的参数,这个参数就是当前帧将来在还原播放的时候的时间戳。而AvPacket里面也有pts,还有dts。说起这个就必须要说明一下I,P,B三种视频压缩帧。I帧就是关键帧,不依赖于其他视频帧,P帧是向前预测的帧,只依赖于前面的视频帧,而B帧是双向预测视频帧,依赖于前后视频帧。由于B帧的存在,因为它是双向的,必须知道前面的视频帧和后面的视频帧的详细内容后,才能知道本B帧最终该呈现什么图像。而pts和dts两个参数就是用来控制视频帧的显示和解码的顺序。pts就是帧显示的顺序。dts就是帧被读取进行解码的顺序。如果没有B帧存在,dts和pts是相同的。反之,则是不相同的。关于这个的详细介绍可以参考一下mpeg的原理。再说说AvPacket中包含的pts和dts两个到底该设置什么值?pts和dts需要设置的就是视频帧解码和显示的顺序。每增加一帧就加一,并不是播放视频的时间戳。但是实践证明经过rmvb解码的视频有时候并不是固定帧率的,而是变帧率的,这样,如果每压缩一帧,pts和dts加一的方案为导致音视频不同步。那怎么来解决音视频同步的问题呢?请看如下代码段。lTimeStamp 是通过directshow 获取的当前的视频帧的时间戳。m_llframe_index为当前已经经过压缩处理的帧的数量。首先av_rescale计算得到当前压缩处理已经需要处理什么时间戳的视频帧,如果该时间戳尚未到达directshow当前提供的视频帧的时间戳,则将该帧丢弃掉。否则进行压缩操作。并设置AVPacket的pts和dts。这里假设B帧不存在。因为在将来播放的时候视频以我们设定的固定播放帧率进行播放,所以需要根据设定的播放帧率计算得到的视频帧时间戳和directshow提供的当前视频帧的时间戳进行比较,设定是否需要进行实施延缓播放的策略。如果需要延缓播放,则将pts增加步长2,否则以普通速度播放,则设置为1.dts与之相同。__int64 x =av_rescale(m_llframe_index,AV_TIME_BASE*(int64_t)c-&time_base.num,c-&time_base.den);if( x & lTimeStamp ){return TRUE;}m_pVideoFrame2-&pts = lTimeSm_pVideoFrame2-&pict_type = 0;int out_size = avcodec_encode_video( c, m_pvideo_outbuf, video_outbuf_size,m_pVideoFrame2 );/* if zero size, it means the image was buffered */if (out_size & 0){AVPav_init_packet(&pkt);if( x & lTimeStamp ){pkt.pts = pkt.dts = m_llframe_pkt.duration = 0;}else{pkt.duration = (lTimeStamp - x)*c-&time_base.den/1000000 + 1;pkt.pts = m_llframe_pkt.dts = pkt.m_llframe_index += pkt.}//pkt.pts = lTimeStamp * (__int64)frame_rate.den / 1000;if( c-&coded_frame && c-&coded_frame-&key_frame ){pkt.flags |= PKT_FLAG_KEY;}pkt.stream_index= m_pVideoStream-&pkt.data= m_pvideo_pkt.size= out_/* write the compressed frame in the media file */ret = av_interleaved_write_frame( m_pAvFormatContext, &pkt );}else{ret = 0;}请问avcodec_decode_video解码的帧为什么后面的比前面的pts小呢?请问如下代码:while( av_read_frame(pFormatCtxSource,&packet)&=0 ){if( packet.stream_index==videoStream ){int out_size =&avcodec_decode_video(pCodecCtxSource,pFrameSource, &bFrameFinished, packet.data, packet.size); // Decode fromsource frameif( bFrameFinished ){pFrameSource-&pts =av_rescale_q(packet.pts, pCodecCtxSource-&time_base,pStCodec-&time_base);int out_size =avcodec_encode_video(pStCodec, video_buffer, 200000, pFrameSource); // Encodeto outputif( out_size&0 ){// ...}}}av_free_packet(&packet);}在我Decode的时候,第一帧得到的 pFrameSource-&pts 是96,再解第二帧的时候,pFrameSource-&pts 计算完后就成了80几,后几帧也是比96小,过一会又会解出来一个100多的,接下来又是比100多小的,这是为什么?在Encode的时候,先Encode一个pts=96的,再去Encode比96小的帧就返回-1了,直到找到一个比96大的。另外,我计算pts的方法正确吗?答复:Because you have B - Framefor example:the Inputsequence for video encoder1&&2&&3& &4& &5& & 6& &7I& &B& &B& &P&&B& &B& &ILet's take1,2,3.. as PTS for simplificationthe out sequencefor video encoder ( this equals the decoder sequence)1&&4&&2& & 3& &7& &5& &6I&&P& & B& &B& &I& & B& &Byou will get aPTS sequence as following:1&&4&&2&&3&&7&&5&&6&7&&5 6sequence will be same as your question问:哦,那是不是我的pts不能这么算呢?而是要每次+1,对吗?那么,packet中的pts和dts要用在什么地方呢?我这样按存储顺序进行解码的话,显示之前是不是要自己进行缓存呢?谢谢!另外,还有个问题,既然解码的时候,不一定是按照pts递增的顺序得到的解码后的画面,那我在编码图像的时候,是应该按照解码出来的帧顺序进行编码吗?还是把帧先缓存起来,最后严格接照图像的显示顺序来编码呢?用代码来表示,就是:方法一:while(av_read_frame ){&解码;&pts+1;&编码;&输出;}方法二:while(av_read_frame ){解码;if( pts{缓存;}else{编码缓存的帧并写入文件;}}这两个方法,哪个是正确的呢?因为我看到网上的代码都用的是方法一,但是我觉得方法二是对的呀?答:the output of decoderis the right order for display because I/P frames will be cacheduntil next I/P理解:Decoder 后output的pts 是按正常的顺序,即显示的顺序输出的,如果有B帧,decoder会缓存。但encoder后,输出的是按dts输出的。Pts,dts并不是时间戳,而更应该理解为frame的顺序序列号。由于每帧frame的帧率并不一定是一致的,可能会变化的。转换为时间戳的话,应该是(pts*帧率)。为加深理解可以将pts比做是第pts帧frame,假设每帧的帧率不变的话,则显示的时间戳为(pts*帧率),如果考虑帧率变化的,则要想办法将(pts*当前的帧率)累加到后面。在tutorial5中在decode 下增加trace后打印情况:len1 = avcodec_decode_video(is-&video_st-&codec,pFrame, &frameFinished,packet-&data,packet-&size);printf("-----------------------------------------------------------------------------\n");printf("avcodec_decode_videopacket-&pts:%x,packet-&dts:%x\n",packet-&pts,packet-&dts);printf("avcodec_decode_videopFrame-&pkt_pts:%x,pFrame-&pkt_dts:%x,pFrame-&pts:%x\n",pFrame-&pkt_pts,pFrame-&pkt_dts,pFrame-&pts);if(pFrame-&opaque)printf("avcodec_decode_video*(uint64_t *)pFrame-&opaque:%x\n",*(uint64_t *)pFrame-&opaque);其中播一个mp4文件的打印情况:-----------------------------------------------------------------------------avcodec_decode_video packet-&pts:1ae,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:1ae-----------------------------------------------------------------------------avcodec_decode_video packet-&pts:1af,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:1af-----------------------------------------------------------------------------avcodec_decode_video packet-&pts:24c,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:1ac-----------------------------------------------------------------------------avcodec_decode_video packet-&pts:24d,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:24d-----------------------------------------------------------------------------avcodec_decode_video packet-&pts:24e,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video*(uint64_t *)pFrame-&opaque:24e以下为播放rm文件的情况:-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:1831b,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:1831b-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:18704,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:18704-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:18aed,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:18aed-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:18ed6,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:18ed6-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:192bf,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:192bf-----------------------------------------------------------------------------avcodec_decode_videopacket-&pts:196a8,packet-&dts:0avcodec_decode_videopFrame-&pkt_pts:0,pFrame-&pkt_dts:,pFrame-&pts:0avcodec_decode_video *(uint64_t *)pFrame-&opaque:196a8可以看出有的pts是+1 累加,有的是加了很多,但都是按顺序累加的。当传人decoder前的packet有pts时,则decoder后获取的frame将会赋值packet的pts;当传人的packet 只是一帧的部分数据或是B帧,由于decoder出来的frame要按正常的pts顺序输出,有可能decoder不会获取到frame ,或decoder内部会缓存也不会输出frame,即frame的pts会为空。Frame pts(即opaque) 为空的话则会看frame-&dts,dts都没有的话才认为frame-&pts为0.对于:pts *= av_q2d(is-&video_st-&time_base);////即pts*帧率// Did we get avideo frame?if(frameFinished) {pts =synchronize_video(is, pFrame, pts);///// synchronize_video考虑了3中情况:1.&&&&pts拿到的话就用该pts2.&&&&pts没有拿到的话就用前一帧的pts时间3.&&&&如果该帧要重复显示,则将显示的数量*帧率,再加到前面的pts中。if(queue_picture(is, pFrame, pts) & 0 decodershowp&static double synchronize_video(VideoState *is, AVFrame*src_frame, double pts) {doubleframe_if(pts != 0) {/* if we havepts, set video clock to it */is-&video_clock =} else {/* if we aren'tgiven a pts, set it to the clock */pts =is-&video_}/* update thevideo clock *//////很关键:前面传进来的pts已经是时间戳了,是当前frame开始播放的时间戳,/////下面frame_delay是该帧显示完将要花费的时间,(pts+frame_delay)也即是/////预测的下一帧将要播放的时间戳。frame_delay =av_q2d(is-&video_st-&codec-&time_base);/* if we arerepeating a frame, adjust clock accordingly *///////重复多帧的话要累加上frame_delay +=src_frame-&repeat_pict * (frame_delay * 0.5);is-&video_clock += frame_/////此时返回的值即为下一帧将要开始显示的时间戳。}///////开定时器去显示帧队列中的已经decode过的数据,按前面的分析我们已经知道帧队列中的数据已经是按pts顺序插入到队列中的。Timer的作用就是有帧率不一致及重复帧的情况造成时间戳不是线性的,有快有慢,从而tutorial5才有timer的方式来播放:追赶以下是一个网友很直观浅显的例子解释:ccq() 17:05:21 if(packet-&dts ==AV_NOPTS_VALUE 是不是就是没有获取到dts的情况?David Cen(:06:44 就是有一把尺子 一只蚂蚁跟着一个标杆走& David Cen(:06:58 标杆是匀速的 蚂蚁或快或慢 DavidCen(:07:18 慢了你就抽它 让他跑起来 快了就拽它& David Cen(:07:38 这样音(标杆)视频(蚂蚁)就能同步了 DavidCen(:08:00 这里最大的问题就是音频是匀速的 视频是非线性的另外:此时vp–&pts获取到的pts已经转化为时间戳了,这个时间戳为就是当前帧显示结束的时间戳,也即是下一帧将显示的预测时间戳。static void video_refresh_timer(void *userdata) {VideoState *is = (VideoState*)VideoPicture *double actual_delay, delay,sync_threshold, ref_clock,if(is-&video_st) {if(is-&pictq_size == 0) {schedule_refresh(is, 1);} else {vp =&is-&pictq[is-&pictq_rindex];delay = vp-&pts -is-&frame_last_ /* the pts from last time */& ////这是当前要显示的frame和下一副&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&//////将要显示的frame的间隔时间if(delay & delay&= 1.0) {/* if incorrect delay, useprevious one */delay =is-&frame_last_}/* save for next time */is-&frame_last_delay =is-&frame_last_pts =vp-&/* update delay to sync toaudio */ref_clock = get_audio_clock(is);/////获取到声音当前播放的时间戳。diff = vp-&pts -ref_////// vp-&pts实际上是预测的下一帧将要播放的开始时间,//////////也就是说在diff这段时间中声音是匀速发生的,但是在delay这段时间frame的显示可能就会有快//////////慢的区别。/* Skip or repeat the frame.Take delay into accountFFPlay still doesn't "know if this is thebest guess." */sync_threshold = (delay &AV_SYNC_THRESHOLD) ? delay : AV_SYNC_THRESHOLD;if(fabs(diff) & AV NOSYNC_THRESHOLD p&if(diff & -sync_threshold p&delay = 0;//////下一帧画面显示的时间和当前的声音很近的话加快显示下一帧(即后面video_display显示完当前帧后开启定时器很快去显示下一帧)} else if(diff &=sync_threshold) {delay = 2 *//////下一帧开始显示的时间和当前声音的时间隔的比较长则延缓,即两帧画面间话的显示的时间长度大于两帧画面间的声音播放的时间,则我们将两帧画显示的时候加倍拖长点,比如帧1和帧2的时间显示间隔为40ms,但帧1和帧2的声音播放时间为55ms,怎么办呢?我们不可能去打乱声音的质量的,则我们采用的方法是:将两帧画面的播放间隔加大,本来是过30ms就要开始播下一帧的,我们改成60ms后才播下一帧。}}/////////当然如果diff大于AV_NOSYNC_THRESHOLD,即快进的模式了,画面跳动太大,不存在音视频同步的问题了。is-&frame_timer +=/* computer the REAL delay*/actual_delay =is-&frame_timer - (av_gettime() / );if(actual_delay & 0 p&/* Really it should skipthe picture instead */actual_delay = 0.010;}schedule_refresh(is,(int)(actual_delay * 1000 + 0.5));////开定时器去显示下一帧/* show the picture! */video_display(is);////立马显示当前帧/* update queue for nextpicture! */if(++is-&pictq_rindex ==VIDEO_PICTURE_QUEUE_SIZE) {is-&pictq_rindex = 0;}SDL_LockMutex(is-&pictq_mutex);is-&pictq_size--;SDL_CondSignal(is-&pictq_cond);SDL_UnlockMutex(is-&pictq_mutex);}} else {schedule_refresh(is, 100);}
发表评论:
TA的最新馆藏视频压缩软件中文版|视频处理软件(小丸工具箱) 绿色免费版-东坡下载
东坡下载:内容最丰富最安全的下载站!
→ 视频处理软件(小丸工具箱)
绿色免费版
小丸工具箱是一款可以压缩和处理视频的图形界面工具,内核是x264、FF、mp4box等软件。小丸工具箱只是一个调用其他程序的程序,自己没有压制功能!只是把平常需要命令行完成的工作图形化了!软件特性:1. mp4/mkv/无损抽取和封装2. 封装mp4或抽取mp4的音频或视频3. 一键压制H264+AAC视频4. 一键内嵌ass/ssa/srt字幕更新说明:- 增加一图流功能- 更新x264- 修复压制AVS时文件名中有非英文字符时的问题。- 移除2Pass模式
安卓官方手机版
IOS官方手机版
视频处理软件(小丸工具箱)截图
视频编辑软件
现在越来越多的家庭都有了自己的相机和,人们习惯的用这些设备记录生活中的点点滴滴。但是很多人都只会拍摄,而不会后期处理。其实,你只需要一部视频摄像机适当的软件和创作的欲望,就可以创作出属于你的个人视频。...
中文 / 260.4M视频后期调色工具是一款非常不错
中文 / 4.6Mgif动画制作软件(Popims Animato
中文 / 404KB简单srt字幕制作器,一款可以帮助
中文 / 213.7M达芬奇调色软件,一款可以用于影
中文 / 520.1M专业非线性编辑软件(EDIUSPro8),
中文 / 5.2M影谱电脑版,一个在线视频制作和
视频处理软件(小丸工具箱)
绿色免费版
本类最新软件
中国CZ88.NET 网友 客人 发表于:
是一个调用其他程序的程序,把命令行图形化了
本类软件推荐
10.9M / 08-04 / 2.0.5官方版
18.7M / 08-02 / 1.0.0.1绿色免费版
23.0M / 07-26 / 3.1.9.1 官网PC版
7.1M / 07-20 / 1.7.2电脑版
19.3M / 07-20 / 1.0.6 官方中文免费版
本类软件排行
装机必备软件
宅男宅女高清flash
请简要描述您遇到的错误,我们将尽快予以修正。
轮坛转帖HTML方式
轮坛转帖UBB方式

我要回帖

更多关于 调整音视频同步软件 的文章

 

随机推荐