计算视频播放的时间(pts)
http://yejun8500.blog.163.com/blog/static/463360020095298410979/
在解碼視頻流的時候對每一個視頻幀都會有一個時間戳pts(顯示時間戳),得到這個pts的值,并記下最開始的一個pts值(pts_00),以后畫面顯示的時間就可以用當前播放的幀的時間戳(pts_now -pts_00)/90000獲得了,單位是秒,
至于為什么是除以90000,這個問題還不清楚,我會繼續跟蹤下去,哈哈
A: RFC3984 規定采用 90000 Hz 的時鐘,因此如果編碼幀頻是 30,那么時間戳間隔就該是 90000 / 30 = 3000,根據抓包來看,似乎時間戳間隔的確是 3000。
時間戳的 間隔不固定,比如有的時間戳間隔是 2990 有的是 3002,會導致解析出來的視頻快播的效果么
參考網頁:
http://topic.csdn.net/u/20080429/18/E4DF1098-0326-41B5-B744-D30475F221B0.html
http://www.cnblogs.com/loveclover/archive/2011/03/23/1993065.html
http://hi.baidu.com/y_x_b_s/item/a9d2e907146f1fed3499026b
問題是這樣的用一個VLC(流媒體客戶端)去 請求流媒體服務器上的數據,但是獲得的數據播放速度明顯快于1倍速,大概是timestamp不對,不知道是服務器的錯誤,還是客戶端解碼時出 錯,總感覺服務器那邊有問題,由于服務器端是客戶端提供的,客戶說是我們的問題,我還不知道如何證明是誰的錯。
A:RFC3984規定采用90000Hz的時鐘,因此如果編碼幀頻是30,那么時間戳間隔就該是90000/30=3000,根據抓包來看,似乎時間戳間隔的確是3000。
時間戳的間隔不固定,比如有的時間戳間隔是2990有的是3002,會導致解析出來的視頻快播的效果么
Q:各位大俠好:
我現在正在開發視頻實時流播放,簡單的過程如下:
采集視頻流->視頻流轉換為SorensonH.263編碼格式->把編碼的實時流通過RTMP協議發送->flash客戶端進行播放。
現在我的時間戳顆粒是這樣生成的:
第一幀的時間戳為0;
第二幀的時間戳的算法為:第一個字符編碼的當前時間-上一幀第一個字符編碼的當前時間
根據這個時間顆粒的算法,我在flash客戶端播放就會產生延時。
請問各位大俠有什么好的建議或是文檔之類的,以前firstime管管建議我看RFC4629文檔,但是效果不太明顯?
謝謝!
A;時間戳順序累加就行了,每次加1
Q:最近做了一個捕捉攝像頭并保存FLV的小東西,發現轉換完畢后的FLV文件,用播放器播放的時候,速度特別快,大概是正常速度的4倍。請問這是怎么回事?網上搜了一下,說是時間戳的問題,可是PTS我跟了,AVPacket的PTS是每幀增長40,time_base為:25/s.。DTS是個無效值。PTS的計算是根據ffmpeg的例子寫的。
pkt.pts=av_rescale_q(oAcc->coded_frame->pts,oAcc->time_base,audio_st->time_base);
1.dts到底需不需要自己計算?
2.還有播放速度過快的可能原因?
3.還有PTS和DTS的具體含義?
int64_tpts;///<presentationtimestampintime_baseunits
int64_tdts;///<decompressiontimestampintime_baseunits
上面的意思是不是說,播放器根據PTS進行播放。然后DTS是在編碼的時候自己設置?
剛用ffmpeg,好些東西不懂,還請大俠多多指教------剛才又試了一下,把time_base降為10幀每秒。播放速度和正常速度接近。但是不知道FLV文件的幀率該設置多少合適。有沒有一個權威的說法。
A:我也做攝像頭捕捉,跟你出現一樣的問題,我自己分析的話,應該是捕捉攝像頭的圖像的速度只有10幀每秒,但是保存成視頻25幀每秒的話播放看起來就非常快,但是我攝像頭捕捉設定的是25幀每秒,難道是速度達不到?
反正我還沒解決,LZ解決了的話告訴下,
謝謝。暫時認為是攝像頭捕捉速率問題。換了一個高清無驅攝像頭就好了
Q:在每個音視頻數據
包中都含有PTS和DTS,一個數據包中應該含有多個數據幀以及音頻數據,那么這里的PTS和DTS它是如何來標識數據幀的?PTS和DTS的單位是
什么?視頻的最小單位是幀,可通過PTS來指定它何時播放,那音頻的最小單位是什么?這里的PTS對音頻而言它標識的是什么?是這個時間點采樣點嗎?
在網上找了很久關于音視頻編解碼的資料,都沒有合適的
A:
audio_timebase=av_q2d(fmtctx->streams[audio_index]->time_base);
video_timebase=av_q2d(fmtctx->streams[video_index]->time_base);
last_video_pts=pts*video_timebase;
last_audio_pts=pts*audio_timebase;
timebase就是單位
以audio為基準同步video。只要設置好了ao的參數,如samplerate,channels,samplesize等,audio驅動就能以正確的速度播放,所以只要程序里write不出大問題的話,這種同步是非常有效的。
在videoout里如下做:
pre_time=av_gettime();
gl_vo->vo_display(pic);
after_time=av_gettime();
rest_time=1000*1000/fps-(after_time-pre_time);
av_diff=last_audio_pts-last_video_pts;
if(av_diff>0.2)
{
if(av_diff<0.5)rest_time-=rest_time/4;
elserest_time-=rest_time/2;
}
elseif(av_diff<-0.2)
{
if(av_diff>-0.5)rest_time+=rest_time/4;
elserest_time+=rest_time/2;
}
if(rest_time>0)
usleep(rest_time);
Q:謝謝kf701的回復,看后明白了不少
這種同步是音頻抽樣一次就與一幀圖像去同步的嗎?
A:上面的代碼是每display一個picture,就與audio的PTS比較一下,
如果沒有audio,只有video,那么video就會以fps顯示,靠的就是那個usleep(rest_time)
Q:如何利用AVPacket包里的pts,dts實現音視頻同步?聲頻播放是只管自己播放,視頻有一個初始化播放幀率,如何根據AVPacket里的pts,dts還實現兩者的同步?
現在我的視頻播放一直按原始播放幀率播放,聲音有點卡!哪位知道,盡快告知小弟!
A:DTS:decodingtimestamp
PTS:presentationtimestamp
GenerallythePTSandDTSwillonlydifferwhenthestreamweareplayinghasBframesinit.
Q:關于b幀和時間戳的問題
我從mpeg2視頻中用av_read_frame()讀取視頻幀并解碼,順序是IPBBPBB...
它們的pts順序是1423756...現在我要把這個視頻再用mpeg2編碼,最大b幀數還是2.那么我在編碼時是否要將視頻數據調整為按顯示時間先后的順序,再交給avcodec_encode_video()編碼?即把第2幀放在3、4幀之后,第7幀放在5、6幀之后?
A:你不能這么做,編碼器會給你這么做的。如果你有B幀,那么所有的B幀都會被放在緩沖區里直到下一個I/P幀到來
例如:你的輸入序列是IBBPBBPBBI
那么輸出的序列是
輸入I,編碼I,輸出I
輸入B
輸入B
輸入P,編碼P,輸出P
編碼B,輸出B
編碼B,輸出B
輸入P,編碼P,輸出P
。。。。。。
在解碼端所有的P幀都會被放在緩沖力直到下一個I/P真的到來
如:解碼I,輸出I
解碼P,放入緩沖P
解碼B,輸出B
解碼B,輸出B
解碼P,輸出上一次P幀
Q:解碼出來的圖片的時間戳問題MPEG一個包中包含有時間戳,而可能幾個包才能解碼出一張圖象,也可能一個包能解碼出幾張圖,請問包中的時間戳與解碼出來的圖象如何對應上?
A:
在ffmpeg中通過parser部件把從avformat部件取下來的原始包重新“合成”為有僅包含一個完整幀的包。從MPEG2部份的代碼中看出,
如果“幾個包才能解碼出一張圖象”的話,會取第一個包的PTS和DTS,如果“也可能一個包能解碼出幾張圖”,則會跟據這個包的PTS和DTS通過幀頻
推算出其它幀的DTS。
Q:ffmpeg的avcodec_decode_video函數解碼時間戳問題?在VLC中調用avcodec_decode_video()函數進行解碼時,AVFrame->pts時間戳不對,導致我的圖像不能夠顯示?請問有誰知道它的解碼原理,這個PTS怎么得出的嗎?還是外部傳入的?
A:
is->video_st->codec->reordered_opaque=pkt->pts;
len1=avcodec_decode_video(is->video_st->codec,
frame,&got_picture,
pkt->data,pkt->size);
if((decoder_reorder_pts||pkt->dts==AV_NOPTS_VALUE)
&&frame->reordered_opaque!=AV_NOPTS_VALUE)
pts=frame->reordered_opaque;
elseif(pkt->dts!=AV_NOPTS_VALUE)
pts=pkt->dts;
else
pts=0;
pts*=av_q2d(is->video_st->time_base);
Q:我貼下VLC的代碼,(vlc-0.9.8a/modules/codec/avcodec/video.c文件中)
i_used=avcodec_decode_video(p_sys->p_context,p_sys->p_ff_pic,
&b_gotpicture,
p_sys->i_buffer<=0&&p_sys->b_flush?NULL:(uint8_t*)p_sys->p_buffer,p_sys->i_buffer);
中間省略
取得PTS,
if(p_sys->p_ff_pic->pts)
{
printf("p_sys->p_ff_pic->pts=%Lx
",p_sys->p_ff_pic->pts);
p_sys->i_pts=p_sys->p_ff_pic->pts;
}
從AVFrame結構中取得這個PTS,但是這個AVFrame結構中取得這個PTS從哪里取得的呢?
A:時間戳一般是在編碼的時候加入到媒體文件中的,所以在解碼時可以從中分析出PTS。
總結
以上是生活随笔為你收集整理的计算视频播放的时间(pts)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [ JAVA编程 ] double类型计
- 下一篇: 袁姗姗宫1(景甜演的电视剧大全)