解决REAL VIDEO的视频平滑问题

简介:

存在问题:当前的播放器产品上,播放REAL VIDEO时,虽然文件是25fps的,并且在DEOCDER和RENDER都没有丢帧,但是视频看起来就是一顿一顿的,不流畅,但是并没有延迟。

1、检查后,发现问题出在时间戳上。当前在DECODE之后,frame的timestamp根据demux出来的pFrame->ulTimestamp拿的,DECODER输出时,时间戳如下(单位微秒)

Rv output buffer pts = 323000, dur = 1000, Current = 48534, Skew = 274466
Rv output buffer pts = 480000, dur = 157000, Current = 59978, Skew = 420022
Rv output buffer pts = 481000, dur = 1000, Current = 67589, Skew = 413411
Rv output buffer pts = 482000, dur = 1000, Current = 74178, Skew = 407822
Rv output buffer pts = 483000, dur = 1000, Current = 80045, Skew = 402955
Rv output buffer pts = 640000, dur = 157000, Current = 86134, Skew = 553866
Rv output buffer pts = 641000, dur = 1000, Current = 91322, Skew = 549678
Rv output buffer pts = 642000, dur = 1000, Current = 108634, Skew = 533366
Rv output buffer pts = 643000, dur = 1000, Current = 113267, Skew = 529733
Rv output buffer pts = 800000, dur = 157000, Current = 118922, Skew = 681078
Rv output buffer pts = 801000, dur = 1000, Current = 124000, Skew = 677000
Rv output buffer pts = 802000, dur = 1000, Current = 128767, Skew = 673233
Rv output buffer pts = 803000, dur = 1000, Current = 133456, Skew = 669544
Rv output buffer pts = 960000, dur = 157000, Current = 138845, Skew = 821155
Rv output buffer pts = 961000, dur = 1000, Current = 144111, Skew = 816889
Rv output buffer pts = 962000, dur = 1000, Current = 148734, Skew = 813266
Rv output buffer pts = 963000, dur = 1000, Current = 153478, Skew = 809522
Rv output buffer pts = 1200000, dur = 237000, Current = 159911, Skew = 1040089
Rv output buffer pts = 1201000, dur = 1000, Current = 165689, Skew = 1035311
Rv output buffer pts = 1202000, dur = 1000, Current = 170911, Skew = 1031089
Rv output buffer pts = 1203000, dur = 1000, Current = 176211, Skew = 1026789
Rv output buffer pts = 1360000, dur = 157000, Current = 183034, Skew = 1176966
Rv output buffer pts = 1361000, dur = 1000, Current = 188367, Skew = 1172633
Rv output buffer pts = 1362000, dur = 1000, Current = 193211, Skew = 1168789
Rv output buffer pts = 1363000, dur = 1000, Current = 198289, Skew = 1164711
Rv output buffer pts = 1520000, dur = 157000, Current = 204034, Skew = 1315966
Rv output buffer pts = 1521000, dur = 1000, Current = 216122, Skew = 1304878
Rv output buffer pts = 1522000, dur = 1000, Current = 221100, Skew = 1300900
Rv output buffer pts = 1523000, dur = 1000, Current = 226122, Skew = 1296878

两个FRAME之间间隔可能是150MS以上,也可能是1MS,在经过Video Compositor和OSD合成后,间隔时间一毫秒的FRAME全部被compositor丢弃,到了compositor输出时,帧间隔都是150MS左右的了,每秒帧率的确不到10帧。所以需要修改时间戳的计算方法

2、一段时间以来,我一直认为REAL文件的帧率不是固定的,因为无法在DEMUX中按照协议取得REAL文件的帧率;并且帧率不固定、存在漂移这点也被Doctor.Li赞同。今天静下心来查了一下,发现根本原因并不是帧率漂移造成的,而是部分RV ENCODER并不是按照REAL协议来封装RM文件的。在rv_depacki_unpack_format_info函数中,ufFramesPerSecond应该是32bit的数据,但实际上相当大的一部分REAL文件在这里只用了16bit,所以读出来的帧率是几万几万的。这个地方需要稍微修改一下来容错
if( FramesPerSecond > 0xFFFF)
{
        FramesPerSecond = FramesPerSecond >> 16;
}
这样就能得到固定的帧率了。不过很奇怪为什么桌面的REALONE PLAYER它就能读到帧率,而SDK里却存在容错性的问题。

3、得到帧率后,修正时间戳算法
在rv_frame_struct结构体中,我们可以看到
typedef struct rv_frame_struct
{
    UINT32             ulDataLen;
    BYTE*              pData;
    UINT32             ulTimestamp;
    UINT16             usSequenceNum;
    UINT16             usFlags;
    HXBOOL          bLastPacket;
    UINT32             ulNumSegments;
    rv_segment* pSegment;
} rv_frame;

我本来打算用  usSequenceNum * FrameDuration 来做时间戳,结果发现即使时间戳和AUDIO同步了,播放时演员的嘴型还是对不上。这说明RV FRAME在时间并就不是均匀的,这也再次证实了前面提到的REAL格式帧率不固定、存在轻微漂移的观点。我只好将计就计,对时间戳进行造假了。下面伪代码中的时间单位都是毫秒(mili seconds), 与时间间隔不是一毫秒的帧我们称为"有效帧", 否则称为"无效帧". 暂时这么叫把, 最后不论有效帧无效帧都应该发送出去的.

/* set timestamp of real video frame */
{
        声明 静态变量 前一帧的原始时间戳;
        声明 静态变量  最后一个有效帧的时间戳;
        声明 静态变量 最后一个有效帧的序号;  //上面rv_frame_struct结构体中的usSequenceNum
        声明 临时变量 当前帧与前一帧的原始时间间隔;  //未伪造过的时间戳之差

        当前帧与上一帧的原始时间间隔 = 当前帧德原始时间戳 - 前一帧的原始时间戳;
        如果(  当前帧与上一帧的原始时间间隔 >  (根据帧率算出的两帧之间平均时长 / 2 ) )  //把当前帧算作有效帧
        {
                最后一个有效帧的时间戳 = 当前帧的原始时间戳;
                最后一格有效帧的序号 = 当前帧的序号;
                设置当前帧的伪造时间戳 = 当前帧的原始时间戳;
        }
        否则  //无效帧
        {
                伪造当前帧的时间戳 = (当前帧 的序号 - 最后一个有效帧的序号) * 根据帧率算出的两帧之间平均时长 + 最后一个有效帧的时间戳;
        }
        
        前一帧原始时间戳 = 当前帧的原始时间戳;   
}

伪造完成,效果让人满意,视频输出平滑。但是对于码率太低的RV文件,比如视频只有200KBPS却有VGA的分辨率,由于帧率实在太低,所以看起来是一卡一卡的,没有办法咯,实际上并没有丢帧,把码率提高就OK了。

另一方面,在输出时丢帧判断条件是: 当前帧的时间戳 < 系统当前时间 + 两帧的平均间隔时间。 由于我们伪造了时间戳,比如在25fps下两帧间隔应该是40ms, 但REAL VIDEO在某些时候两帧间隔会达到80ms,而我们伪造出来仍然只有间隔40ms,所以在RENDER位置上的丢帧处理应该更"宽容"些,改为:当前帧的时间戳 < 系统当前时间 + 两帧的平均间隔时间*2  毕竟汇聚劳动人民血汗好不容易解出来的一个帧,终于跑到播放器的终点,却因为伪造的时间戳慢了那么一点点儿丢弃,实在是浪费。


本文转自Walzer博客园博客,原文链接:http://www.cnblogs.com/walzer/archive/2007/05/01/733871.html,如需转载请自行联系原作者


相关文章
|
7月前
|
计算机视觉
halcon系列基础之Scale_image_range
halcon系列基础之Scale_image_range
327 0
|
7月前
|
编解码 缓存 开发工具
Zynq7020 使用 Video Processing Subsystem 实现图像缩放
1、前言 没玩过图像缩放都不好意思说自己玩儿过FPGA,这是CSDN某大佬说过的一句话,鄙人深信不疑。。。 目前市面上主流的FPGA图像缩放方案如下:1:Xilinx的HLS方案,该方案简单,易于实现,但只能用于Xilinx自家的FPGA;2:非纯Verilog方案,大部分代码使用Verilog实现,但中间的fifo或ram等使用了IP,导致移植性变差,难以在Xilinx、Altera和国产FPGA之间自由移植;3:纯Verilog方案; 本文使用Xilinx Zynq7000系列FPGA Zynq7020实现Video Processing Subsystem图像缩放,输入视频源采用O
125 1
paraformer支持设置 speech_noise_threshold 这个参数吗 ?
请问:speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch 这个模型支持设置 speech_noise_threshold 这个参数吗 ? vad 本身是支持的,但对这个集成的模型好像不起作用? 如果支持,应该如何正确地设置呢 ? 如果不支持,那该模型有没有什么方法可以过滤掉背景噪声? 经常会有背景噪声被识别出文字
64 0
paraforme支持speech_noise_threshold吗?
请问:speech_paraformer-large-vad-punc_asr_nat-zh-cn-16k-common-vocab8404-pytorch 这个模型支持设置 speech_noise_threshold 这个参数吗 ? vad 本身是支持的,但对这个集成的模型好像不起作用? 如果支持,应该如何正确地设置呢 ? 如果不支持,那该模型有没有什么方法可以过滤掉背景噪声? 经常会有背景噪声被识别出文字
66 0
|
存储 缓存
ZYNQ-Video out IP和Video Timing Controller IP简介
ZYNQ-Video out IP和Video Timing Controller IP简介
945 0
ZYNQ-Video out IP和Video Timing Controller IP简介
《Audio Tagging with Compact Feedforward Sequential Memory Network and Audio-to-Audio Ratio Based Data Augmentation》电子版地址
Audio Tagging with Compact Feedforward Sequential Memory Network and Audio-to-Audio Ratio Based Data Augmentation
83 0
《Audio Tagging with Compact Feedforward Sequential Memory Network and Audio-to-Audio Ratio Based Data Augmentation》电子版地址
|
计算机视觉
【事件图像】RGB Image conversion to event Image
【事件图像】RGB Image conversion to event Image
【事件图像】RGB Image conversion to event Image
|
编解码
猪笼草表面连续定向输水Continuous directional water transport on the peristome surface of Nepenthes alata-2016-阅读笔记
打破了传统水往下流的思路,仿生猪笼草表面结构,提出定向水传输结构。
|
编解码 语音技术
采样率(sample rate)
采样率(sample rate)
1049 0
Halcon裁剪图片reduce_domain与crop_domain
Halcon裁剪图片reduce_domain与crop_domain
1419 0