金富贵

金富贵

9个粉丝

11

问答

0

专栏

0

资料

金富贵  发布于  2022-07-19 09:52:28
采纳率 0%
11个问答
4726

海思解码API 中的PTS 问题

悬赏金¥ 5
已结题

我这边用海思的解码模块,业务就是解包 送包 解码 同步,这样好控制播放的进度,以及seek等操作,代码如下
1、ffmpeg 解包

  1. ret = av_read_frame(fmt_ctx, &pkt);

2、filter h264 转换 送包,解码

  1. int64_t PTS =pkt.pts;
  2. int64_t DTS =pkt.dts;
  3. int num =fmt_ctx->streams[videoindex]->time_base.num;
  4. int den =fmt_ctx->streams[videoindex]->time_base.den;
  5. double avq =num*1000000 /(double)den;
  6. int time_in_seconds =PTS*avq;
  7. ret =av_bitstream_filter_filter(h264bsfc, fmt_ctx->streams[videoindex]->codec, NULL, &video_buf, &video_len, pkt.data, pkt.size, 0);
  8. stStream.u64PTS = time_in_seconds;
  9. stStream.pu8Addr = video_buf ;
  10. stStream.u32Len = video_len;
  11. stStream.bEndOfFrame = HI_FALSE;
  12. stStream.bEndOfStream = HI_FALSE;
  13. stStream.bDisplay = 1;
  14. HI_MPI_VDEC_SendStream(0, &stStream, -1);

3、读取当前通道的时间戳

  1. s32Ret = HI_MPI_VO_GetChnPTS(0, 1, &u64ChnPts);

按照api 里面的说法,我现在是送帧模式 ,HI_S32 HI_MPI_VDEC_SendStream(VDEC_CHN VdChn, const VDEC_STREAM_S
*pstStream, HI_S32 s32MilliSec);解码api里面的VDEC_STREAM_S的结构体连有个U64pts的参数,他原文是这么描述的
————————————————————————
时间戳(PTS)处理
在模式 VIDEO_MODE_FRAME 下发送码流时,解码输出的图像时间戳 PTS 为发
送码流接口(HI_MPI_VDEC_SendStream)中用户送入的 PTS,解码器不会更改此HiMPP V4.0 媒体处理软件
开发参考 7 视频解码
文档版本 07 (2019-04-30) 版权所有©上海海思技术有限公司 7-4
值;如果用户配置的 PTS 值为 0,则表示用户不进行帧率控制,而是由视频输出
模块(VO)进行帧率控制;如果用户送入的 PTS 值为-1,则表示此图像不会被视
频输出模块(VO)显示;如果是其他值,则表示视频输出模块(VO)根据用户
设置的 PTS 值进行帧率控制。
注意:不能出现 PTS 值为 0 和非 0 混合的情况
——————————————————————————

我现在的模式就是VIDEO_MODE_FRAME,然后我在结构体里面的PTS赋值,ffmpeg解包出来的算出来的当前一帧的时间戳,最终的结果就是解码不成功,蓝屏,但是我的u64PTS如果是0,就是板子VO端去控制,但是这样实时读出来的时间戳HI_MPI_VO_GetChnPTS,是由板子自己去实现时间戳的,跟我ffmpeg 解包时候的时间戳不一致,我现在就想要解码时候的时间戳跟ffmpeg 解包时候的时间戳是一致,这样好实现同步性,或者大佬们还有什么其他方案实现同步性

我来回答
回答9个
时间排序
认可量排序

刘兵

6个粉丝

3

问答

3

专栏

6

资料

刘兵 2022-07-19 11:52:36
认可0

建议用全0的方式送时间戳。然后定时器每隔2秒钟计算一次,放到h264的vui信息里。绝对时间戳会坑死人,时间长了就不准了

金富贵
金富贵   回复   刘兵  2022-07-19 13:39:04
1

现在也只能够用全0的方式去送时间戳,不然他不解码啊,然而现在我用的最笨 办法就是usleep,计算每帧的时间间隔去执行一次解包到解码的任务,这样就是不好同步控制,海思的解码并没有反馈机制呀,关于seek 之间的操作也不好去控制

魔都小二
魔都小二   回复   金富贵  2022-08-06 09:47:17
0

同意 不要用时间戳

刘兵
刘兵   回复   金富贵  2022-08-25 13:24:14
0

可以用clock_gettime函数实现。
struct timespec ts;
clock_gettime(CLOCK_MONOTONIC,&ts);
例如帧率预计的是25fps,你就每隔50帧(大约2秒)—用上述方法获取ts,然后两次相减,就得到准确的微秒级别的时间长度。然后再除一下,就算出了真实的fps了。如果还是有误差,那就每隔10秒或更长时间,总之时间越长,算的越准,但是刷新速度就越慢。

金富贵
金富贵   回复   刘兵  2022-08-26 09:07:29
0

1、现在板子是venc 2160p 30的模式去录制视频
2、板子解码,参数配置成2160p 30 的模式去解码,但是我用cat /proc/umap/venc 查看实时解码帧率是25fps 左右,那这个也会对解码产生偏差。所以我现在的步骤
usleep(1/30)—->ffmpeg av_read_frame—->板子sdk 送帧 HI_MPI_VDEC_SendStream ——>通过获取当前解码帧率来获取进度条时间戳 HI_MPI_VO_GetChnPTS(0, 1, &u64ChnPts)->再去送到ui 刷新进度条
大佬能加个联系方式么

刘兵
刘兵   回复   金富贵  2022-08-26 09:52:19
0

13751892699VX

Tiger

0个粉丝

2

问答

0

专栏

0

资料

Tiger 2022-08-25 09:37:03
认可0

各位老板,我也遇到一个pts的麻烦。vpss里出来的视频pts=0,vo怎么进行播放控制能达到丝滑状态?

刘兵
刘兵   回复   Tiger  2022-08-26 08:09:58
1

不加控制

金富贵
金富贵   回复   Tiger  2022-08-26 09:11:58
1

vo 控制不了,他海思的解码机制你送帧。他就解码。但是没有反馈。你进行seek 操作,你也不能完全很准确的算出他当前的播放状态,要么弄一个seek-offset的偏差,不然他里面的播放顺序(pts)是连续的。

或将文件直接拖到这里
悬赏:
E币
网盘
* 网盘链接:
* 提取码:
悬赏:
E币

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
+ 添加网盘链接/附件

Markdown 语法

  • 加粗**内容**
  • 斜体*内容*
  • 删除线~~内容~~
  • 引用> 引用内容
  • 代码`代码`
  • 代码块```编程语言↵代码```
  • 链接[链接标题](url)
  • 无序列表- 内容
  • 有序列表1. 内容
  • 缩进内容
  • 图片![alt](url)
举报反馈

举报类型

  • 内容涉黄/赌/毒
  • 内容侵权/抄袭
  • 政治相关
  • 涉嫌广告
  • 侮辱谩骂
  • 其他

详细说明

易百纳技术社区