您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
3. FFDemux的Open实现打开媒体文件~1
发布时间:2021-06-08 22:03:55编辑:雪饮阅读()
上一篇把xplay項目的整體代碼結構設計好了。這次就來實現部分功能。
# as it contains information specific to your local configuration.
#
# Location of the SDK. This is only used by Gradle.
# For customization when using a Version Control System, please read the
# header note.
#Tue Jun 08 21:10:29 CST 2021
ndk.dir=C\:\\Program Files (x86)\\Android\\android-sdk\\ndk\\android-ndk-r14b
sdk.dir=C\:\\Program Files (x86)\\Android\\android-sdk
FFDemux的頭文件FFDemux.h的實現: cpp/XData.cpp實現下drop方法:
cpp/XData.h:聲明drop方法,這裏你可以看到這是利用結構體來實現的:
cpp/IDemux.h中聲明一個統計縂時長的變量,用來統計視頻文件打開所消耗的時間:
最後我們編譯運行到我們的雷電4上面
#include "XLog.h"
extern "C"{
#include <libavformat/avformat.h>
}
//打开文件,或者流媒体 rmtp http rtsp
bool FFDemux::Open(const char *url)
{
XLOGI("Open file %s begin",url);
int re = avformat_open_input(&ic,url,0,0);
if(re != 0 )
{
char buf[1024] = {0};
av_strerror(re,buf,sizeof(buf));
XLOGE("FFDemux open %s failed!",url);
return false;
}
XLOGI("FFDemux open %s success!",url);
//读取文件信息
re = avformat_find_stream_info(ic,0);
if(re != 0 )
{
char buf[1024] = {0};
av_strerror(re,buf,sizeof(buf));
XLOGE("avformat_find_stream_info %s failed!",url);
return false;
}
//ffmpeg内部的時間單位是微秒,AVFormatContext =》duration的單位是AV_TIME_BASE
this->totalMs = ic->duration/(AV_TIME_BASE/1000);
XLOGI("total ms = %d!",totalMs);
return true;
}
//读取一帧数据,数据由调用者清理
XData FFDemux::Read()
{
if(!ic)return XData();
XData d;
AVPacket *pkt = av_packet_alloc();
int re = av_read_frame(ic,pkt);
if(re != 0)
{
av_packet_free(&pkt);
return XData();
}
XLOGI("pack size is %d ptss %lld",pkt->size,pkt->pts);
d.data = (unsigned char*)pkt;
d.size = pkt->size;
return d;
}
FFDemux::FFDemux()
{
static bool isFirst = true;
if(isFirst)
{
isFirst = false;
//注册所有封装器
av_register_all();
//注册所有的解码器
avcodec_register_all();
//初始化网络
avformat_network_init();
XLOGI("register ffmpeg!");
}
}
#define XPLAY_FFDEMUX_H
#include "IDemux.h"
struct AVFormatContext;
class FFDemux: public IDemux {
public:
//打开文件,或者流媒体 rmtp http rtsp
virtual bool Open(const char *url);
//读取一帧数据,数据由调用者清理
virtual XData Read();
FFDemux();
private:
AVFormatContext *ic = 0;
};
#endif //XPLAY_FFDEMUX_H
extern "C"{
#include <libavformat/avformat.h>
}
void XData::Drop()
{
if(!data) return;
av_packet_free((AVPacket **)&data);
data = 0;
size = 0;
}
#define XPLAY_XDATA_H
struct XData {
unsigned char *data = 0;
int size = 0;
void Drop();
};
#endif //XPLAY_XDATA_H
#define XPLAY_IDEMUX_H
#include "XData.h"
//解封装接口
class IDemux {
public:
//打开文件,或者流媒体 rmtp http rtsp
virtual bool Open(const char *url) = 0;
//读取一帧数据,数据由调用者清理
virtual XData Read() = 0;
//总时长(毫秒)
int totalMs = 0;
};
#endif //XPLAY_IDEMUX_H
关键字词:FFDemux,雷電4
相关文章
-
无相关信息