ffmpeg 使用av_read_frame连续读取摄像头,帧时间戳间隔大于帧持续时间导致丢帧

使用的摄像头支持15帧和30帧。

循环调用av_read_frame读取摄像头,pkt的时间戳间隔间隔固定在120000左右,但帧的持续时间为33333(30帧)。

导致实际帧率远低于预期。

我试着用同样的方法读取屏幕,结果很正常,以下分别是30hz 60hz。

难道是我摄像头有问题? 

有没有遇到这种情况的,一起交流

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,那么我来给你提供一个使用C++实现将FFmpegav_read_frame读取的数据放到队列中,另外一个线程从队列中获取数据并解码的示例代码。 首先,需要定义一个结构体来存储读取到的视频数据,包括数据指针、数据大小、时间戳等信息: ``` typedef struct VideoPacket { uint8_t* data; int size; int64_t pts; } VideoPacket; ``` 然后,需要定义一个队列来存储VideoPacket结构体,这里可以使用STL中的std::queue: ``` std::queue<VideoPacket> videoQueue; ``` 接着,在读取视频数据的线程中,使用av_read_frame函数读取视频数据,并将数据放入队列中: ``` AVPacket packet; while (av_read_frame(formatContext, &packet) >= 0) { if (packet.stream_index == videoStreamIndex) { VideoPacket videoPacket; videoPacket.data = new uint8_t[packet.size]; memcpy(videoPacket.data, packet.data, packet.size); videoPacket.size = packet.size; videoPacket.pts = packet.pts; videoQueue.push(videoPacket); } av_packet_unref(&packet); } ``` 在解码视频的线程中,从队列中取出数据进行解码: ``` VideoPacket videoPacket; while (!videoQueue.empty()) { videoPacket = videoQueue.front(); videoQueue.pop(); // 解码视频数据 AVPacket avPacket; av_init_packet(&avPacket); avPacket.data = videoPacket.data; avPacket.size = videoPacket.size; avPacket.pts = videoPacket.pts; int ret = avcodec_send_packet(codecContext, &avPacket); if (ret < 0) { // 错误处理 } AVFrame* frame = av_frame_alloc(); while (ret >= 0) { ret = avcodec_receive_frame(codecContext, frame); if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) { break; } else if (ret < 0) { // 错误处理 } // 处理解码后的视频 } av_frame_free(&frame); av_packet_unref(&avPacket); delete[] videoPacket.data; } ``` 需要注意的是,这里没有进行线程安全处理,实际应用中需要进行加锁操作来保证队列的线程安全性。 另外,需要在使用完视频数据后,释放VideoPacket结构体中的data指针,避免内存泄漏。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值