ffplay实现原理
1. ffmpeg是音视频界的瑞士军刀:
- 它提供了从录制、编码、封装、推流到拉流、解封装、解码、滤镜、播放的完整解决方案。
- 它是跨平台的解决方案,一套代码适配Windows、Linux、Mac OS、iOS、Andriod。
- 它原生支持hls、dash、rtmp、rtsp、http、tcp等主流协议,并提供统一的扩展方式方便扩展自己的协议,比如tutk、webrtc等,目前已经有开源库metaRTC可通过扩展集成到ffmpeg中实现webrtc的推拉流。
- 它支持或插件支持所有封装格式的封装和解封装。
- 它支持或插件支持所有音视频编码格式的编码和解码。主要视频代表有H264、H265,主要音频代表有aac、opus。
- 它已经内置一百多种滤镜并提供方式可以添加自定义滤镜。也可以在这个地方添加OpenGL,支持自定义GPU管线。
- 它解码后的音视频数据可以通过SDL(对不同平台提供一套统一的接口,调用不同的底层API库)去渲染视频和播放音频。可以通过OpenGLES去渲染视频,OpenGLES是OpenGL的子集,所以OpenGLES也可以在PC端渲染。
2. ffplay实现原理
1. ffplay是ffmpeg官方提供的播放器
它基于ffmpeg的强大功能,结合SDL实现了从拉流、解协议、解封装、音频解码、视频解码、音频播放、视频播放的一体化功能。
2. 以下是ffplay整体播放流程图:
3. ffplay有5个主要线程:
- 解协议、解封装线程: read_thread
- 音频解码线程:audio_thread
- 音频播放线程:sdl_audio_callback
- 视频解码线程:video_thread
- 视频播放线程(主线程):video_refresh
以上各线程之间各司其职、通力合作、有任务处理任务、无任务休眠等待其他线程唤醒继续执行任务。
4. 以下是各线程执行结构体关系图:
1. read_thread
负责解协议、解封装、将AVPacket放入音频PacketQueue或视频PacketQueue:
#mermaid-svg-dwXFHp8YEZBBpkpa {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .error-icon{fill:#552222;}#mermaid-svg-dwXFHp8YEZBBpkpa .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-dwXFHp8YEZBBpkpa .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-dwXFHp8YEZBBpkpa .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-dwXFHp8YEZBBpkpa .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-dwXFHp8YEZBBpkpa .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-dwXFHp8YEZBBpkpa .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-dwXFHp8YEZBBpkpa .marker{fill:#333333;stroke:#333333;}#mermaid-svg-dwXFHp8YEZBBpkpa .marker.cross{stroke:#333333;}#mermaid-svg-dwXFHp8YEZBBpkpa svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-dwXFHp8YEZBBpkpa .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .cluster-label text{fill:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .cluster-label span{color:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .label text,#mermaid-svg-dwXFHp8YEZBBpkpa span{fill:#333;color:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .node rect,#mermaid-svg-dwXFHp8YEZBBpkpa .node circle,#mermaid-svg-dwXFHp8YEZBBpkpa .node ellipse,#mermaid-svg-dwXFHp8YEZBBpkpa .node polygon,#mermaid-svg-dwXFHp8YEZBBpkpa .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-dwXFHp8YEZBBpkpa .node .label{text-align:center;}#mermaid-svg-dwXFHp8YEZBBpkpa .node.clickable{cursor:pointer;}#mermaid-svg-dwXFHp8YEZBBpkpa .arrowheadPath{fill:#333333;}#mermaid-svg-dwXFHp8YEZBBpkpa .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-dwXFHp8YEZBBpkpa .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-dwXFHp8YEZBBpkpa .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-dwXFHp8YEZBBpkpa .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-dwXFHp8YEZBBpkpa .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-dwXFHp8YEZBBpkpa .cluster text{fill:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa .cluster span{color:#333;}#mermaid-svg-dwXFHp8YEZBBpkpa div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-dwXFHp8YEZBBpkpa :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
2. audio_thread
负责将音频队列里的AVPacket解码成AVFrame,经过滤镜处理后放入音频FrameQueue:
1. decoder_decode_frame:
#mermaid-svg-ej1EJegvipvGTc9r {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ej1EJegvipvGTc9r .error-icon{fill:#552222;}#mermaid-svg-ej1EJegvipvGTc9r .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ej1EJegvipvGTc9r .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ej1EJegvipvGTc9r .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ej1EJegvipvGTc9r .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ej1EJegvipvGTc9r .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ej1EJegvipvGTc9r .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ej1EJegvipvGTc9r .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ej1EJegvipvGTc9r .marker.cross{stroke:#333333;}#mermaid-svg-ej1EJegvipvGTc9r svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ej1EJegvipvGTc9r .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ej1EJegvipvGTc9r .cluster-label text{fill:#333;}#mermaid-svg-ej1EJegvipvGTc9r .cluster-label span{color:#333;}#mermaid-svg-ej1EJegvipvGTc9r .label text,#mermaid-svg-ej1EJegvipvGTc9r span{fill:#333;color:#333;}#mermaid-svg-ej1EJegvipvGTc9r .node rect,#mermaid-svg-ej1EJegvipvGTc9r .node circle,#mermaid-svg-ej1EJegvipvGTc9r .node ellipse,#mermaid-svg-ej1EJegvipvGTc9r .node polygon,#mermaid-svg-ej1EJegvipvGTc9r .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ej1EJegvipvGTc9r .node .label{text-align:center;}#mermaid-svg-ej1EJegvipvGTc9r .node.clickable{cursor:pointer;}#mermaid-svg-ej1EJegvipvGTc9r .arrowheadPath{fill:#333333;}#mermaid-svg-ej1EJegvipvGTc9r .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ej1EJegvipvGTc9r .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ej1EJegvipvGTc9r .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-ej1EJegvipvGTc9r .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-ej1EJegvipvGTc9r .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ej1EJegvipvGTc9r .cluster text{fill:#333;}#mermaid-svg-ej1EJegvipvGTc9r .cluster span{color:#333;}#mermaid-svg-ej1EJegvipvGTc9r div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ej1EJegvipvGTc9r :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
2. audio_thread:
#mermaid-svg-6Kq1sMp2N3WZjQIF {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .error-icon{fill:#552222;}#mermaid-svg-6Kq1sMp2N3WZjQIF .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6Kq1sMp2N3WZjQIF .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .marker.cross{stroke:#333333;}#mermaid-svg-6Kq1sMp2N3WZjQIF svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .cluster-label text{fill:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .cluster-label span{color:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .label text,#mermaid-svg-6Kq1sMp2N3WZjQIF span{fill:#333;color:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .node rect,#mermaid-svg-6Kq1sMp2N3WZjQIF .node circle,#mermaid-svg-6Kq1sMp2N3WZjQIF .node ellipse,#mermaid-svg-6Kq1sMp2N3WZjQIF .node polygon,#mermaid-svg-6Kq1sMp2N3WZjQIF .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .node .label{text-align:center;}#mermaid-svg-6Kq1sMp2N3WZjQIF .node.clickable{cursor:pointer;}#mermaid-svg-6Kq1sMp2N3WZjQIF .arrowheadPath{fill:#333333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-6Kq1sMp2N3WZjQIF .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-6Kq1sMp2N3WZjQIF .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-6Kq1sMp2N3WZjQIF .cluster text{fill:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF .cluster span{color:#333;}#mermaid-svg-6Kq1sMp2N3WZjQIF div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-6Kq1sMp2N3WZjQIF :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
3. sdl_audio_callback
音频播放回调线程:
1. synchronize_audio:
#mermaid-svg-1jHK6FC1gVsycId4 {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .error-icon{fill:#552222;}#mermaid-svg-1jHK6FC1gVsycId4 .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-1jHK6FC1gVsycId4 .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-1jHK6FC1gVsycId4 .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-1jHK6FC1gVsycId4 .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-1jHK6FC1gVsycId4 .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-1jHK6FC1gVsycId4 .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-1jHK6FC1gVsycId4 .marker{fill:#333333;stroke:#333333;}#mermaid-svg-1jHK6FC1gVsycId4 .marker.cross{stroke:#333333;}#mermaid-svg-1jHK6FC1gVsycId4 svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-1jHK6FC1gVsycId4 .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .cluster-label text{fill:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .cluster-label span{color:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .label text,#mermaid-svg-1jHK6FC1gVsycId4 span{fill:#333;color:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .node rect,#mermaid-svg-1jHK6FC1gVsycId4 .node circle,#mermaid-svg-1jHK6FC1gVsycId4 .node ellipse,#mermaid-svg-1jHK6FC1gVsycId4 .node polygon,#mermaid-svg-1jHK6FC1gVsycId4 .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-1jHK6FC1gVsycId4 .node .label{text-align:center;}#mermaid-svg-1jHK6FC1gVsycId4 .node.clickable{cursor:pointer;}#mermaid-svg-1jHK6FC1gVsycId4 .arrowheadPath{fill:#333333;}#mermaid-svg-1jHK6FC1gVsycId4 .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-1jHK6FC1gVsycId4 .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-1jHK6FC1gVsycId4 .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-1jHK6FC1gVsycId4 .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-1jHK6FC1gVsycId4 .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-1jHK6FC1gVsycId4 .cluster text{fill:#333;}#mermaid-svg-1jHK6FC1gVsycId4 .cluster span{color:#333;}#mermaid-svg-1jHK6FC1gVsycId4 div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-1jHK6FC1gVsycId4 :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
2. audio_decode_frame:
#mermaid-svg-Ao21bZfEJeO6Cs6X {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .error-icon{fill:#552222;}#mermaid-svg-Ao21bZfEJeO6Cs6X .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-Ao21bZfEJeO6Cs6X .marker{fill:#333333;stroke:#333333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .marker.cross{stroke:#333333;}#mermaid-svg-Ao21bZfEJeO6Cs6X svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .cluster-label text{fill:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .cluster-label span{color:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .label text,#mermaid-svg-Ao21bZfEJeO6Cs6X span{fill:#333;color:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .node rect,#mermaid-svg-Ao21bZfEJeO6Cs6X .node circle,#mermaid-svg-Ao21bZfEJeO6Cs6X .node ellipse,#mermaid-svg-Ao21bZfEJeO6Cs6X .node polygon,#mermaid-svg-Ao21bZfEJeO6Cs6X .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .node .label{text-align:center;}#mermaid-svg-Ao21bZfEJeO6Cs6X .node.clickable{cursor:pointer;}#mermaid-svg-Ao21bZfEJeO6Cs6X .arrowheadPath{fill:#333333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-Ao21bZfEJeO6Cs6X .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-Ao21bZfEJeO6Cs6X .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-Ao21bZfEJeO6Cs6X .cluster text{fill:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X .cluster span{color:#333;}#mermaid-svg-Ao21bZfEJeO6Cs6X div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-Ao21bZfEJeO6Cs6X :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
3. sdl_audio_callback:
#mermaid-svg-QJaSBUTPkkBlDext {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QJaSBUTPkkBlDext .error-icon{fill:#552222;}#mermaid-svg-QJaSBUTPkkBlDext .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QJaSBUTPkkBlDext .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-QJaSBUTPkkBlDext .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QJaSBUTPkkBlDext .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QJaSBUTPkkBlDext .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QJaSBUTPkkBlDext .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QJaSBUTPkkBlDext .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QJaSBUTPkkBlDext .marker.cross{stroke:#333333;}#mermaid-svg-QJaSBUTPkkBlDext svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QJaSBUTPkkBlDext .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QJaSBUTPkkBlDext .cluster-label text{fill:#333;}#mermaid-svg-QJaSBUTPkkBlDext .cluster-label span{color:#333;}#mermaid-svg-QJaSBUTPkkBlDext .label text,#mermaid-svg-QJaSBUTPkkBlDext span{fill:#333;color:#333;}#mermaid-svg-QJaSBUTPkkBlDext .node rect,#mermaid-svg-QJaSBUTPkkBlDext .node circle,#mermaid-svg-QJaSBUTPkkBlDext .node ellipse,#mermaid-svg-QJaSBUTPkkBlDext .node polygon,#mermaid-svg-QJaSBUTPkkBlDext .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QJaSBUTPkkBlDext .node .label{text-align:center;}#mermaid-svg-QJaSBUTPkkBlDext .node.clickable{cursor:pointer;}#mermaid-svg-QJaSBUTPkkBlDext .arrowheadPath{fill:#333333;}#mermaid-svg-QJaSBUTPkkBlDext .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QJaSBUTPkkBlDext .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QJaSBUTPkkBlDext .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-QJaSBUTPkkBlDext .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-QJaSBUTPkkBlDext .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QJaSBUTPkkBlDext .cluster text{fill:#333;}#mermaid-svg-QJaSBUTPkkBlDext .cluster span{color:#333;}#mermaid-svg-QJaSBUTPkkBlDext div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QJaSBUTPkkBlDext :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
3. video_thread
负责将视频队列里的AVPacket解码成AVFrame,经过滤镜处理后放入视频FrameQueue:
#mermaid-svg-QoCKs6BkCYwDcGXB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .error-icon{fill:#552222;}#mermaid-svg-QoCKs6BkCYwDcGXB .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-QoCKs6BkCYwDcGXB .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-QoCKs6BkCYwDcGXB .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-QoCKs6BkCYwDcGXB .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-QoCKs6BkCYwDcGXB .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-QoCKs6BkCYwDcGXB .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-QoCKs6BkCYwDcGXB .marker{fill:#333333;stroke:#333333;}#mermaid-svg-QoCKs6BkCYwDcGXB .marker.cross{stroke:#333333;}#mermaid-svg-QoCKs6BkCYwDcGXB svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-QoCKs6BkCYwDcGXB .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .cluster-label text{fill:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .cluster-label span{color:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .label text,#mermaid-svg-QoCKs6BkCYwDcGXB span{fill:#333;color:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .node rect,#mermaid-svg-QoCKs6BkCYwDcGXB .node circle,#mermaid-svg-QoCKs6BkCYwDcGXB .node ellipse,#mermaid-svg-QoCKs6BkCYwDcGXB .node polygon,#mermaid-svg-QoCKs6BkCYwDcGXB .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-QoCKs6BkCYwDcGXB .node .label{text-align:center;}#mermaid-svg-QoCKs6BkCYwDcGXB .node.clickable{cursor:pointer;}#mermaid-svg-QoCKs6BkCYwDcGXB .arrowheadPath{fill:#333333;}#mermaid-svg-QoCKs6BkCYwDcGXB .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-QoCKs6BkCYwDcGXB .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-QoCKs6BkCYwDcGXB .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-QoCKs6BkCYwDcGXB .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-QoCKs6BkCYwDcGXB .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-QoCKs6BkCYwDcGXB .cluster text{fill:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB .cluster span{color:#333;}#mermaid-svg-QoCKs6BkCYwDcGXB div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-QoCKs6BkCYwDcGXB :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
4. video_refresh
视频播放线程负责从pictq队列取AVFrame渲染到SDLWindow中:
#mermaid-svg-04oyY1Xyj6IpUSvQ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .error-icon{fill:#552222;}#mermaid-svg-04oyY1Xyj6IpUSvQ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-04oyY1Xyj6IpUSvQ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .marker.cross{stroke:#333333;}#mermaid-svg-04oyY1Xyj6IpUSvQ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .cluster-label text{fill:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .cluster-label span{color:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .label text,#mermaid-svg-04oyY1Xyj6IpUSvQ span{fill:#333;color:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .node rect,#mermaid-svg-04oyY1Xyj6IpUSvQ .node circle,#mermaid-svg-04oyY1Xyj6IpUSvQ .node ellipse,#mermaid-svg-04oyY1Xyj6IpUSvQ .node polygon,#mermaid-svg-04oyY1Xyj6IpUSvQ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .node .label{text-align:center;}#mermaid-svg-04oyY1Xyj6IpUSvQ .node.clickable{cursor:pointer;}#mermaid-svg-04oyY1Xyj6IpUSvQ .arrowheadPath{fill:#333333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-04oyY1Xyj6IpUSvQ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-04oyY1Xyj6IpUSvQ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-04oyY1Xyj6IpUSvQ .cluster text{fill:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ .cluster span{color:#333;}#mermaid-svg-04oyY1Xyj6IpUSvQ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-04oyY1Xyj6IpUSvQ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}
3. 优势分析
- ffmpeg实际是一个音视频框架,如果想要自定义一个协议进行播放只要按照规则实现一套对应的协议即可实现ffmpeg对此协议的支持,可以参考metaRTC这个例子。
- ffmpeg有统一的编解码代码实现,使得切换编解码器简直不要太容易,只需要将此编解码器编译到ffmpeg库中,然后修改一下编解码器对应的ID即可实现底层编解码器的切换,比如H264升级到H265将大幅降低服务器存储空间及传输带宽的占用,对直播和录播场景将节约不可估量的成本。
- ffmpeg配合SDL、OpenGLES将实现全平台的视频播放及特效处理。
ffplay实现原理相关推荐
- 至简播放器ffplay工作原理
下载,编译及运行 参考博文 http://blog.csdn.net/ericbar/article/details/79382783 即可完成ffplay的基本测试. 如果要进行GDB调试,需要先编 ...
- FFPLAY的原理(一)
概要 电影文件有很多基本的组成部分.首先,文件本身被称为容器Container,容器的类型决定了信息被存放在文件中的位置.AVI和Quicktime就是容器的例子.接着,你有一组流,例如,你经常有的是 ...
- 直播--FFPLAY 的原理
电影文件有很多基本的组成部分.首先,文件本身被称为容器Container,容器的类型决定了信息被存放在文件中的位置.AVI和 Quicktime就是容器的例子.接着,你有一组流,例如,你经常有的是一个 ...
- FFPLAY的原理(二)
关于包Packets的注释 从技术上讲一个包可以包含部分或者其它的数据,但是ffmpeg的解释器保证了我们得到的包Packets包含的要么是完整的要么是多种完整的帧. 现在我们需要做的是让SaveFr ...
- ffmpeg相关资源
FFPLAY的原理(一) http://blog.csdn.net/shenbin1430/article/details/4291893 ubuntu12.04下命令安装ffplay等: sudo ...
- 面向大规模数据的云端管理,百度沧海存储产品解析
导读:本文整理自同名<云智公开课>系列分享,详细介绍百度沧海·存储如何进行大规模数据,流转上云.智能分级存储.安全管理.多业务应用. 全文5657字,预计阅读时间20分钟. 01 ABC ...
- 从零到一了解APP速度测评
作者 | 龙霸天 一.引言 为了知道「为什么会打雷下雨」,我们拿起了手机,使用百度 APP 进行搜索: 小小的一个搜索诉求,却需要经历一个不短的交互过程.就跟去银行办业务一样,只想改个银行预留手机号, ...
- 基于 TLS 1.3的百度安全通信协议 bdtls 介绍
作者 | 金媛宝.孤独键盘手 导读: 百度小程序已经在百度开源联盟的多家宿主APP上运行,为了保证小程序框架.小程序.宿主APP等业务方相互之间的通信服务不被恶意攻击,运营类活动不被薅羊毛,基于最新的 ...
- ffplay.c源码阅读之解码模块实现原理
前言 解码作为渲染模块和拉流模块的中间模块,它一方面要不停的从拉流模块的压缩数据缓冲区中获取待解码数据包,让后将这个数据包送入自己的解码模块,获得解码数据后再送入自己的解码缓冲区,这就是整个解码模块的 ...
最新文章
- 高德地图-搜索服务-POI搜索
- 【蓝桥杯】基础练习 数列排序
- 工业级光纤收发器和协议转换器有什么区别呢?
- 【图说word】宏二
- SAP License:心情
- QLabel显示图像
- iis php7页面空白,iis 无法显示htm页面问题解决
- 关系型数据库中主键(primary key)和外键(foreign key)的概念。
- fixdown down,一个时代的终结。
- 前端需要学习c语言吗,我应该在学习C语言之前学习HTML或CSS吗?
- 读书笔记-计算机视觉
- Python unrar解压rar压缩文件
- 对话阿里云张建锋:云计算正在内卷吗?丨钛度专访
- C#窗体程序随电脑分辨率自动调整大小
- 后端优化 | VINS-Mono 论文公式推导与代码解析分讲
- One-Lin3r:懒人的福音,渗透测试单行化工具
- OneNote 与 OneNote 2016 有什么区别?
- 【BT】经典蓝牙连接速度优化
- Makefile depend规则
- 分享66个JS时间轴特效,总有一款适合您