FFmpeg入门教程10.09:软解并使用QML播放视频(YUV420P转OpenGL)
系列索引:FFmpeg入门系列索引
上一篇:FFmpeg入门教程10.09:软解并使用QOpenGL播放视频(YUV420P->OpenGL)
QML显示视频无法用之前的方法实现,我结果多次尝试过后终于找到了可以使用的方法。
解码流程图为:
flowchart TB
F --Yes--> I
K --下一帧--> F
I --No--> F
subgraph init
direction TB
A(开始) --> B[打开文件]
B --> C[查找流信息]
C --> D[查找对应解码器]
D --> E[打开解码器]
E --> F{读取帧}
F --No--> G(结束)
end
subgraph decode
direction TB
I{是视频帧?} --Yes--> J[发送帧给解码器]
J --> K[从解码器获取结果]
end
flowchart TB
F --Yes--> I
K --Next Frame--> F
I --No--> F
subgraph init
direction TB
A(Start) --> B[avformat_open_input]
B --> C[av_find_stream_info]
C --> D[avcodec_find_decoder]
D --> E[avcodec_open]
E --> F{av_read_frame}
F --No--> G(End)
end
subgraph decode
direction TB
I{Video Packet?} --Yes--> J[avcodec_send_packet]
J --> K[avcodec_receive_frame]
end
Qt显示流程图:
flowchart TB
A(开始) --> B[解码结果信号槽]
B --> C[接收解码数据]
C --> D[纹理填充]
D --> E[纹理填充]
E --> F(结束)
函数调用流程图如下:
flowchart TB
K --signals/slots--> L
L --> P
L --> Q
N --> R
subgraph decode
direction TB
A(Start) --> B[avformat_open_input]
B --> C[av_find_stream_info]
C --> D[avcodec_find_decoder]
D --> E[avcodec_open]
E --> F{av_read_frame}
F --No--> G(End)
F --Yes--> H[avcodec_send_packet]
H --> I[avcodec_receive_frame]
I --> J[sws_scale]
J --> K[QImage]
end
subgraph qml
direction TB
N[render]
O[createFramebufferObject]
L[synchronize]
end
subgraph texture
M[init]
P[updateTextureInfo]
Q[updateTextureData]
R[paint]
end
分为三个部分
软解码
主要流程和之前的一样,只是少了格式转换和多了数据填充部分,关键代码如下:
1 |
|
主要是将解码后的YUV(YUV420P)数据复制到指定的结构体中,并排入缓冲队列中。
OpenGL纹理渲染
1 |
|
QML显示部分
此部分需要两个类VideoItem、VideoFboItem,VideoItem是QML调用的接口,而VideoFboItem是由VideoItem自动调用。
VideoFboItem
1 |
|
render/createFramebufferObject/synchronize这三个函数是直接继承基类重写。render调用OpenGL渲染的paint函数绘制界面,createFramebufferObject写法固定,synchronize从VideoItem的接口中获取需要的信息(图像宽度高度、具体数据)。
这些函数由VideoItem函数自动调用。
VideoItem
此类是直接提供QML调用的接口,并且与Videoitem类由交互。
1 |
|
这样之后VideoItem就会自动调用VideoFboItem的函数。
QML调用
首先在QML格式文件中导入视频模块
1 |
|
然后在根组件中插件视频模块对象
1 |
|
之后如果需要调用视频模块的接口,直接使用videoitem就可以了。
1 |
|
按钮按下之后调用videoitem的setUrl/start接口。
效果
默认界面为:
点击Play按钮后,开始播放视频:
以上是PC下默认解码YUV420P显示方法,如果需要NV12(YUV420SP)显示可以使用之前的方法。
源码在ffmpeg_beginner中10.09.video_decode_by_cpu_display_by_qml
下。