您当前的位置: 首页 > 学无止境 > 心得笔记 网站首页心得笔记
1. 完成facade模式的IPlayer并实现Open接口.~1
发布时间:2021-06-12 18:35:07编辑:雪饮阅读()
這次呀主要是新增兩個文件,一個頭文件一個對外提供門面接口的程序cpp這樣就實現了對後臺程序模塊對於用戶調用來説是不可見的:
#define XPLAY_IPLAYER_H
#include "XThread.h"
class IDemux;
class IAudioPlay;
class IVideoView;
class IResample;
class IDecode;
class IPlayer : public XThread
{
public:
static IPlayer *Get(unsigned char index=0);
virtual bool Open(const char *path);
virtual bool Start();
//是否视频硬解码
bool isHardDecode = true;
IDemux *demux = 0;
IDecode *vdecode = 0;
IDecode *adecode = 0;
IResample *resample = 0;
IVideoView *videoView = 0;
IAudioPlay *audioPlay = 0;
protected:
IPlayer(){};
};
#endif //XPLAY_IPLAYER_H
對於入口文件cpp/native-lib.cpp那就是重新調整下調用流程以及清理下之前的那些測試代碼:
對於綫程這塊來説,那麽這次就要依賴返回結果來做判斷了,不能像之前那樣直接void返回類型,這樣是沒有辦法判斷的,或者說非一般做法,一般做法都是boolean判斷。所以cpp/XThread.cpp:
那麽同樣的頭文件也需要聲明一下cpp/XThread.h:
接下來就是需要在cpp/CMakeLists.txt中引入剛才新增的IPlayer接口:
然後這次運行結果呢?其實不算太明顯:
#include "IDemux.h"
#include "IDecode.h"
#include "IAudioPlay.h"
#include "IVideoView.h"
#include "IResample.h"
#include "XLog.h"
IPlayer *IPlayer::Get(unsigned char index)
{
static IPlayer p[256];
return &p[index];
}
bool IPlayer::Open(const char *path)
{
//解封装
if(!demux || !demux->Open(path))
{
XLOGE("demux->Open %s failed!",path);
return false;
}
//解码 解码可能不需要,如果是解封之后就是原始数据
if(!vdecode || !vdecode->Open(demux->GetVPara(),isHardDecode))
{
XLOGE("vdecode->Open %s failed!",path);
//return false;
}
if(!adecode || !adecode->Open(demux->GetAPara()))
{
XLOGE("adecode->Open %s failed!",path);
//return false;
}
//重采样 有可能不需要,解码后或者解封后可能是直接能播放的数据
XParameter outPara = demux->GetAPara();
if(!resample || !resample->Open(demux->GetAPara(),outPara))
{
XLOGE("resample->Open %s failed!",path);
}
return true;
}
bool IPlayer::Start()
{
return true;
}
#include <string>
#include <android/native_window_jni.h>
#include "FFDemux.h"
#include "XLog.h"
#include "FFDecode.h"
#include "XEGL.h"
#include "XShader.h"
#include "IVideoView.h"
#include "GLVideoView.h"
#include "FFResample.h"
#include "IAudioPlay.h"
#include "SLAudioPlay.h"
#include "IPlayer.h"
IVideoView *view = NULL;
extern "C"
JNIEXPORT
jint JNI_OnLoad(JavaVM *vm,void *res)
{
FFDecode::InitHard(vm);
///////////////////////////////////
///测试用代码
IDemux *de = new FFDemux();
//de->AddObs(tobs);
//de->Open("/sdcard/1080.mp4");
IDecode *vdecode = new FFDecode();
//vdecode->Open(de->GetVPara(), true);
//vdecode->Open(de->GetVPara(), true);
IDecode *adecode = new FFDecode();
//adecode->Open(de->GetAPara());
de->AddObs(vdecode);
de->AddObs(adecode);
view = new GLVideoView();
vdecode->AddObs(view);
IResample *resample = new FFResample();
//XParameter outPara = de->GetAPara();
//resample->Open(de->GetAPara(),outPara);
adecode->AddObs(resample);
IAudioPlay *audioPlay = new SLAudioPlay();
//audioPlay->StartPlay(outPara);
resample->AddObs(audioPlay);
IPlayer::Get()->demux = de;
IPlayer::Get()->adecode = adecode;
IPlayer::Get()->vdecode = vdecode;
IPlayer::Get()->videoView = view;
IPlayer::Get()->resample = resample;
IPlayer::Get()->audioPlay = audioPlay;
IPlayer::Get()->Open("/sdcard/v1080.mp4");
//de->Start();
//vdecode->Start();
//adecode->Start();
return JNI_VERSION_1_4;
}
extern "C"
JNIEXPORT jstring
JNICALL
Java_com_example_xplay_MainActivity_stringFromJNI(
JNIEnv *env,
jobject /* this */) {
std::string hello = "Hello from C++";
//XLOGI("S begin!");
//XSleep(3000);
//XLOGI("S end!");
//return env->NewStringUTF(hello.c_str());
//XSleep(3000);
//de->Stop();
/*for(;;)
{
XData d = de->Read();
XLOGI("Read data size is %d",d.size);
}*/
return env->NewStringUTF(hello.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_example_xplay_XPlay_InitView(JNIEnv *env, jobject instance, jobject surface) {
// TODO
ANativeWindow *win = ANativeWindow_fromSurface(env,surface);
view->SetRender(win);
//XEGL::Get()->Init(win);
//XShader shader;
//shader.Init();
}
#include "XLog.h"
#include <thread>
using namespace std;
void XSleep(int mis)
{
chrono::milliseconds du(mis);
this_thread::sleep_for(du);
}
//启动线程
bool XThread::Start()
{
isExit = false;
thread th(&XThread::ThreadMain,this);
th.detach();
return true;
}
void XThread::ThreadMain()
{
isRuning = true;
XLOGI("线程函数进入");
Main();
XLOGI("线程函数退出");
isRuning = false;
}
//通过控制isExit安全停止线程(不一定成功)
void XThread::Stop()
{XLOGI("Stop 停止线程begin!");
isExit = true;
for(int i = 0; i < 200; i++)
{
if(!isRuning)
{
XLOGI("Stop 停止线程成功!");
return;
}
XSleep(1);
}
XLOGI("Stop 停止线程超时!");
}
#define XPLAY_XTHREAD_H
//sleep 毫秒
void XSleep(int mis);
//c++ 11 线程库
class XThread
{
public:
//启动线程
virtual bool Start();
//通过控制isExit安全停止线程(不一定成功)
virtual void Stop();
//入口主函数
virtual void Main() {}
protected:
bool isExit = false;
bool isRuning = false;
private:
void ThreadMain();
};
#endif //XPLAY_XTHREAD_H
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.10.2)
# Declares and names the project.
project("xplay")
# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
#添加頭文件路徑(括號中的include是相對於本文件路徑)
include_directories(../../../include)
#設置ffmpeg庫所在路徑的變量,這裏的FF是自定義的一個名字
set(FF ${CMAKE_CURRENT_SOURCE_DIR}/../../../libs/${ANDROID_ABI})
#avcodec這個是自定義的一個名字
add_library(avcodec SHARED IMPORTED)
set_target_properties(avcodec PROPERTIES IMPORTED_LOCATION ${FF}/libavcodec.so)
add_library(avformat SHARED IMPORTED)
set_target_properties(avformat PROPERTIES IMPORTED_LOCATION ${FF}/libavformat.so)
add_library(avutil SHARED IMPORTED)
set_target_properties(avutil PROPERTIES IMPORTED_LOCATION ${FF}/libavutil.so)
add_library(swscale SHARED IMPORTED)
set_target_properties(swscale PROPERTIES IMPORTED_LOCATION ${FF}/libswscale.so)
add_library(swresample SHARED IMPORTED)
set_target_properties(swresample PROPERTIES IMPORTED_LOCATION ${FF}/libswresample.so)
add_library( # Sets the name of the library.
native-lib
# Sets the library as a shared library.
SHARED
# Provides a relative path to your source file(s).
#src/main/cpp/native-lib.cpp
IDemux
FFDemux
XData
XLog
native-lib.cpp
XThread
IObserver
FFDecode
IDecode
XParameter
IVideoView
GLVideoView
XTexture
XEGL
XShader
FFResample
IResample
SLAudioPlay
IAudioPlay
IPlayer
)
# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
log-lib
# Specifies the name of the NDK library that
# you want CMake to locate.
log )
# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
native-lib
GLESv2 EGL
OpenSLES
android
avcodec avformat avutil swscale swresample
# Links the target library to the log library
# included in the NDK.
${log-lib} )
关键字词:facade
相关文章
-
无相关信息