首页| 论坛| 消息

标题:Qt编写万能硬解播放器/支持传入QByteArray流数据解码/websocket视频流/tcp和udp网络流/gb28181监控rtp流
作者:liudianwu
日期:2025-05-12 17:22
内容:

## 一、前言说明
用纯Qt+ffmpeg打造的这个播放组件,在各种复杂的环境中测试,满足各种音视频格式和场景需求,后期又多了一种需求,那就是没有音视频地址的,直接是内存流数据,比如有个下位机,直接通过tcp或者udp收到的264/265裸流数据,很多时候可能还是私有协议上传的,需要解包后才是裸流数据,然后希望直接用ffmpeg来解码。按照常规的做法,就是先打开一个地址,再去解码,网上也基本上都是这种示例,而如果是内存流数据,根本没有地址,如何处理?查阅了大量资料发现ffmpeg肯定提供了对应的接口,那就是AVIOContext和AVFifo,这种专用于处理内存流数据,和之前的解码框架流程几乎一致,唯一区别就两个,一个是需要增加AVFormatContext的回调formatCtx->pb = avio->getCtx(),然后就是打开的时候对应地址参数填空值,avformat_open_input(&formatCtx, NULL, NULL, &options),在创建内存流上下文对象的时候指定读取回调函数read_packet,avioCtx = avio_alloc_context(avioBuf, fifoSize, 0, fifo, &read_packet, NULL, NULL),收到数据后往这个环形缓冲数据添加数据即可。
如何在之前的框架上增加这个功能,以便用户使用起来非常方便,那就需要增加一种地址格式比如stream://就表示内存流,一旦用户调用open函数填入地址stream://就表示接下来打开的是内存流。然后只要对外提供一个appenddata函数即可,不断的往里面追加数据,追加的数据会自动解码。
- 内核ffmpeg和内核mdk支持内存流数据解码。
- 内存流数据一般指264/265裸流数据。
- 比如tcp或者udp收到下位机传过来的数据。
- 或者自己根据私有协议解包后的数据。
- 还有ws://协议开头的websocket收到的数据。
- 以及监控国标gb28181协议中rtp解包后的ps流数据。
- 只要是ffmpeg支持的内存流数据就可以。
```cpp
//表示接下来打开的是内存流
w.open("stream://");
//然后收到数据后添加到对应解码线程即可
QByteArray data = "xxxxx";
w.getVideoThread()->appendData(data);
//特别提示/记得判断解码线程对象是否为空/不为空才可以调用
//什么时候肯定不为空/在收到receivePlayStart信号后
VideoThread *videoThread = w.getVideoThread();
if (videoThread) {
videoThread->appendData(data);
}
```
## 二、效果图

## 三、相关代码
```cpp
#include "ffmpegavio.h"
# ..

回复 发表
主题 版块