You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
311 lines
8.8 KiB
311 lines
8.8 KiB
/*
|
|
* Copyright (C) 2020 Rockchip Electronics Co. LTD
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
#ifndef ANDROID_C2_RK_MPI_DEC_H_
|
|
#define ANDROID_C2_RK_MPI_DEC_H_
|
|
|
|
#include "C2RKComponent.h"
|
|
#include "C2RKInterface.h"
|
|
#include "rk_mpi.h"
|
|
|
|
#include <utils/Vector.h>
|
|
|
|
namespace android {
|
|
|
|
class C2RKDump;
|
|
class C2RKTunneledSession;
|
|
struct VTBuffer;
|
|
struct ColorAspects;
|
|
|
|
class C2RKMpiDec : public C2RKComponent {
|
|
public:
|
|
class IntfImpl;
|
|
C2RKMpiDec(
|
|
const char *name,
|
|
const char *mime,
|
|
c2_node_id_t id,
|
|
const std::shared_ptr<IntfImpl> &intfImpl);
|
|
virtual ~C2RKMpiDec();
|
|
|
|
// From SimpleC2Component
|
|
c2_status_t onInit() override;
|
|
c2_status_t onStop() override;
|
|
void onReset() override;
|
|
void onRelease() override;
|
|
c2_status_t onFlush_sm() override;
|
|
|
|
void process(
|
|
const std::unique_ptr<C2Work> &work,
|
|
const std::shared_ptr<C2BlockPool> &pool) override;
|
|
c2_status_t drain(
|
|
uint32_t drainMode,
|
|
const std::shared_ptr<C2BlockPool> &pool) override;
|
|
|
|
void postFrameReady();
|
|
c2_status_t onFrameReady();
|
|
|
|
private:
|
|
struct OutBuffer {
|
|
enum Status {
|
|
OWNED_BY_MPP = 0,
|
|
OWNED_BY_US,
|
|
};
|
|
|
|
/* index to find this buffer */
|
|
uint32_t mBufferId;
|
|
/* who own this buffer */
|
|
Status mStatus;
|
|
/* mpp buffer */
|
|
MppBuffer mMppBuffer;
|
|
/* tunneled playback buffer */
|
|
VTBuffer *mTunnelBuffer;
|
|
/* block shared by surface */
|
|
std::shared_ptr<C2GraphicBlock> mBlock;
|
|
|
|
/* signal buffer available to decoder */
|
|
void importThisBuffer();
|
|
/* signal buffer occupied by users */
|
|
void holdThisBuffer();
|
|
};
|
|
|
|
struct OutWorkEntry {
|
|
enum Flags {
|
|
FLAGS_EOS = 0x1,
|
|
FLAGS_ERROR_FRAME = 0x2,
|
|
FLAGS_INFO_CHANGE = 0x4,
|
|
};
|
|
|
|
std::shared_ptr<C2GraphicBlock> outblock;
|
|
uint64_t timestamp;
|
|
uint32_t flags;
|
|
};
|
|
|
|
/*
|
|
* low memory mode config from user
|
|
*
|
|
* 0x0: default value, normal device mode
|
|
* 0x1: low memory case, reduce smoothFactor count from frameworks only.
|
|
* 0x2: low memory case, use protocol delayRef.
|
|
*/
|
|
enum LowMemoryMode {
|
|
MODE_NONE = 0x0,
|
|
MODE_REDUCE_SMOOTH = 0x1,
|
|
MODE_USE_PROTOCOL_REF = 0x2,
|
|
};
|
|
|
|
class WorkHandler : public AHandler {
|
|
public:
|
|
enum {
|
|
kWhatFrameReady,
|
|
kWhatFlushMessage,
|
|
};
|
|
|
|
WorkHandler() {}
|
|
~WorkHandler() override = default;
|
|
|
|
void flushAllMessages();
|
|
|
|
protected:
|
|
void onMessageReceived(const sp<AMessage> &msg) override;
|
|
};
|
|
|
|
const char* mName;
|
|
const char* mMime;
|
|
std::shared_ptr<IntfImpl> mIntf;
|
|
|
|
Mutex mBufferLock;
|
|
C2RKDump *mDump;
|
|
|
|
Mutex mEosLock;
|
|
Condition mEosCondition;
|
|
|
|
sp<ALooper> mLooper;
|
|
sp<WorkHandler> mHandler;
|
|
|
|
/* MPI interface parameters */
|
|
MppCtx mMppCtx;
|
|
MppApi *mMppMpi;
|
|
MppCodingType mCodingType;
|
|
MppFrameFormat mColorFormat;
|
|
MppBufferGroup mFrmGrp;
|
|
// Indicates that these buffers should be decoded but not rendered.
|
|
Vector<uint64_t> mDropFrames;
|
|
Vector<OutBuffer*> mOutBuffers;
|
|
C2RKTunneledSession *mTunneledSession;
|
|
|
|
int32_t mWidth;
|
|
int32_t mHeight;
|
|
int32_t mHorStride;
|
|
int32_t mVerStride;
|
|
// fbc output has padding inside, set crop before display
|
|
int32_t mLeftCorner;
|
|
int32_t mTopCorner;
|
|
int32_t mOutputDelay;
|
|
// reduce factor for low memory mode
|
|
int32_t mReduceFactor;
|
|
int32_t mGrallocVersion;
|
|
int32_t mPixelFormat;
|
|
int32_t mScaleMode;
|
|
int32_t mFdPerf;
|
|
|
|
bool mStarted;
|
|
bool mFlushed;
|
|
bool mSignalledInputEos;
|
|
bool mOutputEos;
|
|
bool mSignalledError;
|
|
bool mIsGBSource;
|
|
bool mHdrMetaEnabled;
|
|
bool mTunneled;
|
|
|
|
/*
|
|
1. BufferMode: without surcace
|
|
2. SurfaceMode: render surface
|
|
*/
|
|
bool mBufferMode;
|
|
bool mUseRgaBlit;
|
|
|
|
struct AllocParams {
|
|
int32_t needUpdate;
|
|
int32_t width;
|
|
int32_t height;
|
|
int64_t usage;
|
|
int32_t format;
|
|
} mAllocParams;
|
|
|
|
struct ScaleThumbInfo {
|
|
int32_t width;
|
|
int32_t height;
|
|
int32_t hstride;
|
|
int32_t vstride;
|
|
int32_t format;
|
|
} mScaleInfo;
|
|
|
|
std::shared_ptr<C2GraphicBlock> mOutBlock;
|
|
std::shared_ptr<C2BlockPool> mBlockPool;
|
|
|
|
// Color aspects. These are ISO values and are meant to detect changes
|
|
// in aspects to avoid converting them to C2 values for each frame.
|
|
struct VuiColorAspects {
|
|
uint8_t primaries;
|
|
uint8_t transfer;
|
|
uint8_t coeffs;
|
|
uint8_t fullRange;
|
|
|
|
// default color aspects
|
|
VuiColorAspects()
|
|
: primaries(2), transfer(2), coeffs(2), fullRange(0) { }
|
|
|
|
bool operator==(const VuiColorAspects &o) {
|
|
return primaries == o.primaries && transfer == o.transfer &&
|
|
coeffs == o.coeffs && fullRange == o.fullRange;
|
|
}
|
|
} mBitstreamColorAspects;
|
|
|
|
c2_status_t setupAndStartLooper();
|
|
void stopAndReleaseLooper();
|
|
|
|
int32_t getFbcOutputMode(const std::unique_ptr<C2Work> &work = nullptr);
|
|
c2_status_t updateSurfaceConfig(const std::shared_ptr<C2BlockPool> &pool);
|
|
c2_status_t configOutputDelay(const std::unique_ptr<C2Work> &work = nullptr);
|
|
c2_status_t configTunneledPlayback(const std::unique_ptr<C2Work> &work);
|
|
void finishWork(OutWorkEntry entry);
|
|
|
|
c2_status_t initDecoder(const std::unique_ptr<C2Work> &work);
|
|
c2_status_t updateDecoderArgs(const std::shared_ptr<C2BlockPool> &pool);
|
|
c2_status_t updateMppFrameInfo(int32_t fbcMode);
|
|
void setMppPerformance(bool on);
|
|
void setDefaultCodecColorAspectsIfNeeded(ColorAspects &aspects);
|
|
void getVuiParams(MppFrame frame);
|
|
c2_status_t updateFbcModeIfNeeded();
|
|
c2_status_t updateAllocParamsIfNeeded(AllocParams *params);
|
|
c2_status_t importBufferToMpp(std::shared_ptr<C2GraphicBlock> block);
|
|
c2_status_t ensureTunneledState();
|
|
c2_status_t ensureDecoderState();
|
|
c2_status_t sendpacket(uint8_t *data, size_t size, uint64_t pts, uint32_t flags);
|
|
c2_status_t getoutframe(OutWorkEntry *entry);
|
|
|
|
c2_status_t configFrameScaleMeta(MppFrame frame, std::shared_ptr<C2GraphicBlock> block);
|
|
c2_status_t configFrameHdrMeta(MppFrame frame, std::shared_ptr<C2GraphicBlock> block);
|
|
c2_status_t checkUseScaleMeta(buffer_handle_t handle);
|
|
c2_status_t checkUseScaleDown(buffer_handle_t handle);
|
|
|
|
inline bool isDropFrame(uint64_t pts) {
|
|
Vector<uint64_t>::iterator it;
|
|
for (it = mDropFrames.begin(); it != mDropFrames.end(); it++) {
|
|
if (*it == pts) {
|
|
mDropFrames.erase(it);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/*
|
|
* OutBuffer vector operations
|
|
*/
|
|
OutBuffer* findOutBuffer(uint32_t bufferId) {
|
|
for (int i = 0; i < mOutBuffers.size(); i++) {
|
|
OutBuffer *buffer = mOutBuffers.editItemAt(i);
|
|
if (buffer->mBufferId == bufferId) {
|
|
return buffer;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
OutBuffer* findOutBuffer(MppBuffer mppBuffer) {
|
|
for (int i = 0; i < mOutBuffers.size(); i++) {
|
|
OutBuffer *buffer = mOutBuffers.editItemAt(i);
|
|
if (buffer->mMppBuffer == mppBuffer) {
|
|
return buffer;
|
|
}
|
|
}
|
|
return nullptr;
|
|
}
|
|
|
|
void clearOutBuffers() {
|
|
while (!mOutBuffers.isEmpty()) {
|
|
OutBuffer *buffer = mOutBuffers.editItemAt(0);
|
|
if (buffer != nullptr) {
|
|
if (buffer->mStatus != OutBuffer::OWNED_BY_MPP) {
|
|
buffer->importThisBuffer();
|
|
}
|
|
delete buffer;
|
|
}
|
|
mOutBuffers.removeAt(0);
|
|
}
|
|
}
|
|
|
|
int getOutBufferCountOwnByMpi() {
|
|
int count = 0;
|
|
for (int i = 0; i < mOutBuffers.size(); i++) {
|
|
OutBuffer *buffer = mOutBuffers.editItemAt(i);
|
|
if (buffer->mStatus == OutBuffer::OWNED_BY_MPP) {
|
|
count++;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
C2_DO_NOT_COPY(C2RKMpiDec);
|
|
};
|
|
|
|
C2ComponentFactory* CreateRKMpiDecFactory(std::string componentName);
|
|
|
|
} // namespace android
|
|
|
|
#endif // ANDROID_C2_SOFT_MPI_DEC_H_
|