ffmpeg播放器12(从7-11的实现)-中

89 阅读2分钟

1背景

上面这几篇,是从线程开始,加载视频流。上一篇处理了ffmpeg的msvc依赖库,这一篇,开始加载流。

源码存放位置 github.com/xcyxiner/xp…

2从线程开始读取流

这次在之前的基础上,继续(分支 ffmpeg_play_7_11)

2.1 ffmpeg头引入

新建c++头文件,名称为 ffmpeg_util.h,然后添加如下代码

extern "C" {
#include "libavutil/avutil.h"
#include "libavutil/pixdesc.h"
#include "libavcodec/avcodec.h"
#include "libavformat/avformat.h"
#include "libavdevice/avdevice.h"
#include "libswscale/swscale.h"
}

2.2 ffmpeg播放器7 中的线程开始

2.2.1 新增HThread

添加线程,头文件,右键添加新文件HThread

image.png

image.png

先添加状态

public:
    enum Status{
        STOP,
        RUNNING,
        PAUSE
    };

再补充,状态成员变量,线程变量,start,以及doPrepare方法

#include <atomic>
#include <thread>
class HThread
{
public:
    HThread();

public:
    enum Status{
        STOP,
        RUNNING,
        PAUSE
    };

    virtual int start(){
        if(status==STOP){
            thread = std::thread([this]{
                if(!doPrepare())return;

            });
        }
        return 0;
    }

    virtual bool doPrepare(){
        return true;
    }

    std::thread thread;
    std::atomic<Status> status;
};

image.png

2.2.2 hffplayer.h 继承 HThread

双击hffplayer.h

class HFFPlayer : public HVideoPlayer,public HThread

在HThread上右键,重构,插入virtual方法

image.png

全部勾选 image.png

2.2.3 hvideoplayer.h 添加start方法

双击hvideoplayer.h

#include "hmedia.h"
class HVideoPlayer
{
public:
    HVideoPlayer();


public:
    void set_media(HMedia& media);

    virtual int start()=0;
public:
    HMedia media;

};

image.png

2.2.4 hvideowidget.cpp 中的pImpl_player调用start

双击 hvideowidget.cpp

void HVideoWidget::start()
{
    this->pImpl_player=new HFFPlayer();
    this->pImpl_player->set_media(this->media);
    this->pImpl_player->start();
}

2.2.5 hffplayer.h 定义 start和doPrepare

选中start,右键,重构,添加定义

image.png

选中doPrepare,右键,重构,定义

image.png

在hffplayer.cpp中的start中添加如下代码

int HFFPlayer::start()
{
    HThread::start();
    return 0;
}

然后再在hffplayer.h中添加open方法以及AVFormatContext成员变量。上面调用start开启线程后,会调用子类中的doPrepare,这里就需要用到open方法了。

#include "ffmpeg_util.h"

private:

    int open();

private:
    AVFormatContext* fmt_ctx;

image.png

在open上右键,重构,添加定义后的效果如下

image.png

完善doPrepare

bool HFFPlayer::doPrepare()
{
    int ret=open();
    return ret;
}

然后在open里开始加载媒体流

int HFFPlayer::open()
{
    std::string ifile;
    AVInputFormat* ifmt=NULL;
    switch (media.type) {
    case MEDIA_TYPE_FILE:
        ifile=media.src;
        break;
    default:
        break;
        return -10;
    }
    int ret=0;

    fmt_ctx=avformat_alloc_context();
    if(fmt_ctx==NULL){
        ret=-10;
        return ret;
    }
}

2.2.6 追加断点运行

image.png

完整的代码 github.com/xcyxiner/xp…

未完待续