Files
BPI-CM9-Linux/aml-comp/multimedia/aml_mp_sdk/player/Aml_MP_PlayerImpl.h
T

359 lines
12 KiB
C++

/*
* Copyright (c) 2020 Amlogic, Inc. All rights reserved.
*
* This source code is subject to the terms and conditions defined in the
* file 'LICENSE' which is part of this source code package.
*
* Description:
*/
#ifndef _AML_MP_PLAYER_IMPL_H_
#define _AML_MP_PLAYER_IMPL_H_
#include <Aml_MP/Aml_MP.h>
#include <utils/AmlMpRefBase.h>
#include <utils/AmlMpHandle.h>
#include <utils/AmlMpPlayerRoster.h>
#include <mutex>
#include <map>
#include "utils/AmlMpChunkFifo.h"
#include <condition_variable>
#include "cas/AmlCasBase.h"
#include "demux/AmlTsParser.h"
#include "Aml_MP_PlayerBase.h"
#ifdef ANDROID
#ifndef __ANDROID_VNDK__
#ifndef __ANDROID_RECOVERY__
#include <gui/Surface.h>
#include <gui/SurfaceComposerClient.h>
#endif
#endif
#ifndef __ANDROID_RECOVERY__
#include <system/window.h>
#include <utils/RefBase.h>
#endif
#endif
#ifdef CONFIG_AMP_SERVER
#include <fmq/AidlMessageQueue.h>
#include <aidl/com/amlogic/aml_mp/common/AmlMpBufPoolDataPacket.h>
using ::android::AidlMessageQueue;
using ::aidl::android::hardware::common::fmq::MQDescriptor;
using ::aidl::android::hardware::common::fmq::SynchronizedReadWrite;
using ::aidl::com::amlogic::aml_mp::common::AmlMpBufPoolDataPacket;
using DataQueueMQ = AidlMessageQueue<AmlMpBufPoolDataPacket, SynchronizedReadWrite>;
using FreeQueueMQ = AidlMessageQueue<int32_t, SynchronizedReadWrite>;
typedef struct {
uint8_t* ptr;
size_t size;
} BufPoolNode;
const int32_t AML_MP_PLAYER_EVENT_ECM_NOTIFY = ('necm'); // ('necm')
typedef struct {
bool async;
int32_t pid;
const uint8_t *data;
int32_t len;
} Amp_Mp_Player_Notify_EcmData;
#endif
namespace aml_mp {
class AmlPlayerBase;
class AmlMpConfig;
enum WaitingEcmMode {
kWaitingEcmSynchronous,
kWaitingEcmASynchronous,
};
//coverity[definition_tu]
class AmlMpPlayerImpl final : public Aml_MP_PlayerBase
{
public:
explicit AmlMpPlayerImpl(const Aml_MP_PlayerCreateParams* createParams, int32_t clientId = -1);
~AmlMpPlayerImpl();
int registerEventCallback(Aml_MP_PlayerEventCallback cb, void* userData) override;
int setVideoParams(const Aml_MP_VideoParams* params) override;
int setAudioParams(const Aml_MP_AudioParams* params) override;
int setADParams(Aml_MP_AudioParams* params) override;
int setSubtitleParams(const Aml_MP_SubtitleParams* params) override;
int setCasSession(AML_MP_CASSESSION casSession) override;
int setIptvCASParams(Aml_MP_CASServiceType serviceType, const Aml_MP_IptvCASParams* params) override;
int start() override;
int stop() override;
int pause() override;
int resume() override;
int flush() override;
int setPlaybackRate(float rate) override;
int setPlaybackRate2(float rate, Aml_MP_VideoDecodeMode decodeMode) override;
int getPlaybackRate(float* rate) override;
int switchAudioTrack(const Aml_MP_AudioParams* params) override;
int switchSubtitleTrack(const Aml_MP_SubtitleParams* params) override;
int writeData(const uint8_t* buffer, size_t size) override;
int writeEsData(Aml_MP_StreamType type, const uint8_t* buffer, size_t size, int64_t pts) override;
int getCurrentPts(Aml_MP_StreamType, int64_t* pts) override;
int getFirstPts(Aml_MP_StreamType, int64_t* pts) override;
int getBufferStat(Aml_MP_BufferStat* bufferStat) override;
int setANativeWindow(ANativeWindow* nativeWindow) override;
int setVideoWindow(int x, int y, int width, int height) override;
int setVolume(float volume) override;
int getVolume(float* volume) override;
int showVideo() override;
int hideVideo() override;
int showSubtitle() override;
int hideSubtitle() override;
int setParameter(Aml_MP_PlayerParameterKey key, void* parameter) override;
int getParameter(Aml_MP_PlayerParameterKey key, void* parameter) override;
int setAVSyncSource(Aml_MP_AVSyncSource syncSource) override;
int setPcrPid(int pid) override;
int startVideoDecoding() override;
int stopVideoDecoding() override;
int startAudioDecoding() override;
int stopAudioDecoding() override;
int startADDecoding() override;
int stopADDecoding() override;
int startSubtitleDecoding() override;
int stopSubtitleDecoding() override;
int setSubtitleWindow(int x, int y, int width, int height) override;
int getDecodingState(Aml_MP_StreamType streamType, AML_MP_DecodingState* streamState) override;
int setADVolume(float volume) override;
int getADVolume(float* volume) override;
#ifdef CONFIG_AMP_SERVER
int32_t setBuffs(int32_t fd, int32_t bufPoolBufCnt, int32_t bufPoolBufOne,
DataQueueMQ *bufPoolDataMq, FreeQueueMQ *bufPoolFreeMq);
void setEcmPids(const std::vector<int>& ecmPids);
#endif
private:
enum State {
STATE_IDLE,
STATE_PREPARING,
STATE_PREPARED,
STATE_RUNNING, //audio,video,subtitle at least one is running
STATE_PAUSED, //all paused
STATE_STOPPED,
};
static const int kStreamStateBits = 2;
static const int kStreamStateMask = 3;
enum PrepareWaitingType {
kPrepareWaitingNone = 0,
kPrepareWaitingCodecId = 1 << 0,
kPrepareWaitingEcm = 1 << 1,
};
struct WindowSize {
int x = 0;
int y = 0;
int width = -1;
int height = -1;
};
const char* stateString(State state);
std::string decodingStateString(uint32_t streamState);
void setState_l(State state);
void setDecodingState_l(Aml_MP_StreamType streamType, int state);
AML_MP_DecodingState getDecodingState_l(Aml_MP_StreamType streamType);
int setSidebandIfNeeded_l();
void openParser_l();
bool tryWaitEcm_l();
bool tryWaitCodecId_l();
bool tryMonitorPidChange_l();
int prepare_l();
int finishPreparingIfNeeded_l();
int resetIfNeeded_l(std::unique_lock<std::mutex>& lock, bool clearCasSession = true);
int reset_l(std::unique_lock<std::mutex>& lock, bool clearCasSession);
int applyParameters_l();
void setAudioCoreParameters_l();
void programEventCallback(Parser::ProgramEventType event, int param1, int param2, void* data);
int drainDataFromBuffer_l(std::unique_lock<std::mutex>& lock);
int doWriteData_l(const uint8_t* buffer, size_t size, std::unique_lock<std::mutex>& lock);
int setPlaybackRate_l(float rate, Aml_MP_VideoDecodeMode decodeMode, std::unique_lock<std::mutex>& lock);
void notifyListener(Aml_MP_PlayerEventType eventType, int64_t param);
int start_l();
int stop_l(std::unique_lock<std::mutex>& lock, bool clearCasSession = true);
int pause_l();
int resume_l();
int startVideoDecoding_l();
int startAudioDecoding_l();
int startSubtitleDecoding_l();
int startADDecoding_l();
int stopAudioDecoding_l(std::unique_lock<std::mutex>& lock);
int stopSubtitleDecoding_l(std::unique_lock<std::mutex>& lock);
int stopADDecoding_l(std::unique_lock<std::mutex>& lock);
int startDescrambling_l();
int stopDescrambling_l();
int switchDecodeMode_l(Aml_MP_VideoDecodeMode decodeMode, std::unique_lock<std::mutex>& lock);
int resetADCodec_l(bool callStart);
int resetAudioCodec_l(bool callStart);
int setAudioParams_l(const Aml_MP_AudioParams* params);
int setSubtitleParams_l(const Aml_MP_SubtitleParams* params);
int setParameter_l(Aml_MP_PlayerParameterKey key, void* parameter, std::unique_lock<std::mutex>& lock);
int enableAFD_l(bool enable);
int setVideoAFDAspectMode_l(Aml_MP_VideoAFDAspectMode aspectMode);
void statisticWriteDataRate_l(size_t size);
void collectBuffingInfos_l();
void resetVariables_l();
void resetDrmVariables_l();
void increaseDmxSecMemSize();
void recoverDmxSecMemSize();
const int mInstanceId;
int32_t mClientId = -1;
char mName[50];
std::mutex mEventLock;
Aml_MP_PlayerEventCallback mEventCb = nullptr;
void* mUserData = nullptr;
std::atomic<pid_t> mEventCbTid{-1};
mutable std::mutex mLock;
State mLastState{STATE_IDLE};
State mState{STATE_IDLE};
uint32_t mStreamState{0};
uint32_t mPrepareWaitingType{kPrepareWaitingNone};
WaitingEcmMode mWaitingEcmMode = kWaitingEcmSynchronous;
WaitingEcmMode mUserWaitingEcmMode = kWaitingEcmSynchronous;
std::atomic<bool> mWaitingEcmByServer{false};
bool mFirstEcmWritten = false;
bool mAudioStoppedInSwitching = false;
Aml_MP_PlayerCreateParams mCreateParams;
bool mNeedRecreatePlayer = false;
Aml_MP_VideoParams mVideoParams;
Aml_MP_AudioParams mAudioParams;
Aml_MP_SubtitleParams mSubtitleParams;
AML_MP_TeletextCtrlParam mTeletextCtrlParam;
WindowSize mSubtitleWindow;
Aml_MP_AudioParams mADParams;
std::vector<int32_t> mEcmPids;
Aml_MP_VideoDecodeMode mVideoDecodeMode{AML_MP_VIDEO_DECODE_MODE_NONE};
Aml_MP_VideoDisplayMode mVideoDisplayMode{(Aml_MP_VideoDisplayMode)-1};
int mBlackOut{-1};
int mVideoPtsOffset{-1};
Aml_MP_AudioOutputMode mAudioOutputMode{(Aml_MP_AudioOutputMode)-1};
Aml_MP_AudioOutputDevice mAudioOutputDevice{(Aml_MP_AudioOutputDevice)-1};
int mAudioPtsOffset{-1};
Aml_MP_AudioBalance mAudioBalance{(Aml_MP_AudioBalance)-1};
int mAudioMute{-1};
int mNetworkJitter{-1};
Aml_MP_ADVolume mADMixLevel{-1, -1};
Aml_MP_PlayerWorkMode mWorkMode{(Aml_MP_PlayerWorkMode)-1};
Aml_MP_VideoErrorRecoveryMode mVideoErrorRecoveryMode{(Aml_MP_VideoErrorRecoveryMode)-1};
Aml_MP_AudioLanguage mAudioLanguage;
int mAudioBlockAlign{-1};
int mAudioPatchAddress{-1};
float mVolume = -1.0;
float mADVolume = -1.0;
float mPlaybackRate = 1.0f;
NativeWindowHelper mNativeWindowHelper;
WindowSize mVideoWindow;
int mVideoTunnelId = -1;
void* mSurfaceHandle = nullptr;
int mAudioPresentationId = -1;
int mUseTif = -1;
int mSPDIFStatus = -1;
Aml_MP_Rect mVideoCrop{0, 0, -1, -1};
Aml_MP_AVSyncSource mSyncSource = AML_MP_AVSYNC_SOURCE_DEFAULT;
int mPcrPid = AML_MP_INVALID_PID;
sptr<AmlPlayerBase> mPlayer;
Aml_MP_CASServiceType mCasServiceType{AML_MP_CAS_SERVICE_TYPE_INVALID};
Aml_MP_IptvCASParams mIptvCasParams;
bool mIsStandaloneCas = false;
#ifdef BUILD_AMP_SERVER
void *mCasHandle = nullptr;
#else
sptr<AmlCasBase> mCasHandle;
#endif
static constexpr int kZorderBase = -2;
int mZorder;
#ifdef ANDROID
#ifndef __ANDROID_RECOVERY__
android::sp<ANativeWindow> mNativeWindow;
#endif
#ifndef __ANDROID_VNDK__
#ifndef __ANDROID_RECOVERY__
android::sp<android::SurfaceComposerClient> mComposerClient;
android::sp<android::SurfaceControl> mSurfaceControl;
android::sp<android::Surface> mSurface = nullptr;
#endif
#endif
#endif
sptr<Parser> mParser;
AmlMpChunkFifo mTsBuffer;
sptr<AmlMpBuffer> mWriteBuffer;
int64_t mLastBytesWritten = 0;
int64_t mLastWrittenTimeUs = 0;
bool mVideoShowState = true;
int mVideoCache{-1};
int mAudioCache{-1};
Aml_MP_VideoAFDAspectMode mVideoAFDAspectMode = AML_MP_VIDEO_AFD_ASPECT_MODE_NONE;
private:
AmlMpPlayerImpl(const AmlMpPlayerImpl&) = delete;
AmlMpPlayerImpl& operator= (const AmlMpPlayerImpl&) = delete;
int writeData_l(std::unique_lock<std::mutex>& lock, const uint8_t* buffer, size_t size);
#ifdef CONFIG_AMP_SERVER
void freeBuffs();
static void* writeDataThread(void *arg);
BufPoolNode *mBufPoolBufs = nullptr;
int32_t mBufPoolBufCnt = -1;
int32_t mBufPoolBufOne = -1;
std::atomic<bool> mBufPoolHasInit = false;
int32_t mBufPoolFd = -1;
void *mBufPoolPtr = nullptr;
DataQueueMQ *mBufPoolDataMq = nullptr;
FreeQueueMQ *mBufPoolFreeMq = nullptr;
std::atomic<bool> mWriteThreadExit = false;
std::atomic<bool> mCallingFlush = false;
pthread_t mWriteThread = 0;
void NotifyEcmData(bool async, int32_t pid, const uint8_t *data, int32_t len);
#endif
};
}
#endif