zoukankan      html  css  js  c++  java
  • 计算视频播放的时间(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 规定采用 90000 Hz 的时钟,因此如果编码帧频是 30,那么时间戳间隔就该是 90000 / 30 = 3000,根据抓包来看,似乎时间戳间隔的确是 3000。

    时间戳的 间隔不固定,比如有的时间戳间隔是 2990 有的是 3002,会导致解析出来的视频快播的效果么

    Q:各位大侠好:
    我现在正在开发视频实时流播放,简单的过程如下:
    采集视频流 -> 视频流转换为Sorenson H.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_t pts;                         ///< presentation time stamp in time_base units
    int64_t dts;                         ///< decompression time stamp in time_base units

    上面的意思是不是说,播放器根据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 的参数,如sample rate, channels, sample size等, audio驱动就能以正确的速度播放,所以只要程序里write不出大问题的话,这种同步是非常有效的。

    在video out里如下做:

    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;
                else rest_time -= rest_time / 2;
    }
    else if ( av_diff < -0.2)
    {
                if( av_diff > -0.5 ) rest_time += rest_time / 4;
                else rest_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:decoding time stamp 
    PTS:presentation time stamp

    Generally the PTS and DTS will only differ when the stream we are playing has B frames in it.

    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;
            else if(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。

  • 相关阅读:
    POJ 2723 Get Luffy Out(2-SAT)
    ZOJ 3613 Wormhole Transport
    HDU 4085 Peach Blossom Spring
    NBUT 1221 Intermediary
    NBUT 1223 Friends number
    NBUT 1220 SPY
    NBUT 1218 You are my brother
    PAT 1131. Subway Map (30)
    ZSTU OJ 4273 玩具
    ZSTU OJ 4272 最佳淘汰算法
  • 原文地址:https://www.cnblogs.com/jingzhishen/p/3767347.html
Copyright © 2011-2022 走看看