sdk-hwV1.3/external/eyesee-mpp/framework/sun8iw21/media/thumbretriever/EyeseeThumbRetriever.cpp

882 lines
24 KiB
C++
Executable File

/******************************************************************************
Copyright (C), 2001-2017, Allwinner Tech. Co., Ltd.
******************************************************************************
File Name : EyeseeThumRetriever.cpp
Version : Initial Draft
Author : Allwinner BU3-PD2 Team
Created : 2017/10/27
Last Modified :
Description :
Function List :
History :
******************************************************************************/
//#define LOG_NDEBUG 0
#define LOG_TAG "EyeseeThumbRetriever"
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h>
#include <limits.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <fcntl.h>
#include <EyeseeThumbRetriever.h>
#include <plat_log.h>
#include <plat_type.h>
#include <mpi_sys.h>
#include <mpi_demux.h>
#include <mpi_venc.h>
#include <mpi_vdec.h>
#include <mpi_clock.h>
#include <Clock_Component.h>
static bool IsJpegSource(int fd)
{
char szJpegContent[10] = {0};
bool bJpegSource = true;
char szExif[4] = {0x45, 0x78, 0x69, 0x66};
char szJFIF[4] = {0x4A, 0x46, 0x49, 0x46};
struct stat JpegStat;
if (fstat(fd, &JpegStat) != 0 || JpegStat.st_size < 10)
{
return false;
}
lseek(fd, 0, SEEK_SET);
read(fd, szJpegContent, 10);
lseek(fd, 0, SEEK_SET);
// Check SOI
if (szJpegContent[0] != 0xFF || szJpegContent[1] != 0xD8)
{
bJpegSource = false;
}
if (szJpegContent[2] == 0xFF && szJpegContent[3] == 0xE0)
{// JFIF
if (memcmp(&szJpegContent[6], szJFIF, 4) != 0)
{
bJpegSource = false;
}
}
else if (szJpegContent[2] == 0xFF && szJpegContent[3] == 0xE1)
{// Exif
if (memcmp(&szJpegContent[6], szExif, 4) != 0)
{
bJpegSource = false;
}
}
else if (szJpegContent[2] == 0xFF && szJpegContent[3] == 0xDB)
{// no header
alogv("this jpg file doesn't have header");
}
else
{
bJpegSource = false;
}
return bJpegSource;
}
static bool GetJpegInfo(int fd, int* pWidth, int* pHeight, int* pFileSize)
{
*pWidth = 0;
*pHeight = 0;
*pFileSize = 0;
char cJpegFlag;
char szJpegContent[512];
struct stat JpegStat;
if (fstat(fd, &JpegStat) != 0 || JpegStat.st_size < 4)
{
return false;
}
*pFileSize = JpegStat.st_size;
int readlen = 0;
lseek(fd, 0, SEEK_SET);
while (1)
{
if (1 != read(fd, &cJpegFlag, 1))
{//eof
return false;
}
// Sync 0xFF
if (cJpegFlag != 0xFF)
{
continue;
}
if (1 != read(fd, &cJpegFlag, 1))
{//eof
return false;
}
if (cJpegFlag == 0xD8 || cJpegFlag == 0xD9 || cJpegFlag == 0x00)
{// head, eof or data
continue;
}
else if (cJpegFlag == 0xE0 || cJpegFlag == 0xE1)
{
read(fd, &szJpegContent, 2);
int len = szJpegContent[0] * 256 + szJpegContent[1];
lseek(fd, len, SEEK_CUR);
continue;
}
else if (cJpegFlag == 0xC4)
{// Huffman Table
return false;
}
else if (cJpegFlag == 0xC0 || cJpegFlag == 0xC2)
{// SOF0 or SOF2, Start of Frame
int iSOF_len = 0;
if (2 == read(fd, szJpegContent, 2))
{
iSOF_len = szJpegContent[0] * 256 + szJpegContent[1];
}
else
{
return false;
}
if (iSOF_len - 2 == read(fd, szJpegContent, iSOF_len - 2))
{
*pHeight = szJpegContent[1] * 256 + szJpegContent[2];
*pWidth = szJpegContent[3] * 256 + szJpegContent[4];
}
else
{
return false;
}
return true;
}
else
{
read(fd, &cJpegFlag, 1);
}
}
}
namespace EyeseeLinux {
EyeseeThumbRetriever::EyeseeThumbRetriever()
{
mDmxChn = MM_INVALID_CHN;
mVdecChn = MM_INVALID_CHN;
mVecChn = MM_INVALID_CHN;
mClockChn = MM_INVALID_CHN;
bJpegSource = false;
mJpegWidth = 0;
mJpegHeight = 0;
mSeekStartPosition = 0;
memset(&mDmxChnAttr, 0, sizeof(DEMUX_CHN_ATTR_S));
mDmxChnAttr.mFd = -1;
mCurrentState = MEDIA_THUMB_IDLE;
}
EyeseeThumbRetriever::~EyeseeThumbRetriever()
{
}
status_t EyeseeThumbRetriever::setDataSource(int fd, int64_t offset, int64_t length)
{
Mutex::Autolock _l(mLock);
if(!(mCurrentState & MEDIA_THUMB_IDLE || mCurrentState == MEDIA_THUMB_STATE_ERROR))
{
aloge("called in wrong state %d", mCurrentState);
return INVALID_OPERATION;
}
memset(&mDmxChnAttr, 0, sizeof(mDmxChnAttr));
// Check JPEG file
if (IsJpegSource(fd))
{
bJpegSource = true;
//mDmxChnAttr.mStreamType = STREAMTYPE_LOCALFILE;
mDmxChnAttr.mSourceType = SOURCETYPE_FD;
mDmxChnAttr.mSourceUrl = NULL;
mDmxChnAttr.mFd = dup(fd);
mDmxChnAttr.mDemuxDisableTrack |= DEMUX_DISABLE_AUDIO_TRACK;
mDmxChnAttr.mDemuxDisableTrack |= DEMUX_DISABLE_SUBTITLE_TRACK;
mCurrentState = MEDIA_THUMB_INITIALIZED;
return NO_ERROR;
}
ERRORTYPE ret;
bool nSuccessFlag = false;
//mDmxChnAttr.mStreamType = STREAMTYPE_LOCALFILE;
mDmxChnAttr.mSourceType = SOURCETYPE_FD;
mDmxChnAttr.mSourceUrl = NULL;
mDmxChnAttr.mFd = dup(fd);
mDmxChnAttr.mDemuxDisableTrack |= DEMUX_DISABLE_AUDIO_TRACK;
mDmxChnAttr.mDemuxDisableTrack |= DEMUX_DISABLE_SUBTITLE_TRACK;
mDmxChn = 0;
while(mDmxChn < DEMUX_MAX_CHN_NUM)
{
ret = AW_MPI_DEMUX_CreateChn(mDmxChn, &mDmxChnAttr);
if(SUCCESS == ret)
{
nSuccessFlag = TRUE;
alogd("create demux channel[%d] success!", mDmxChn);
break;
}
else if(ERR_DEMUX_EXIST == ret)
{
alogd("demux channel[%d] is exist, find next!", mDmxChn);
mDmxChn++;
}
else if(ERR_DEMUX_FILE_EXCEPTION == ret)
{
aloge("demux detect media file exception!");
if(0 == mDmxChnAttr.mFd)
{
alogd("Be careful! mFd == 0!");
}
close(mDmxChnAttr.mFd);
mDmxChnAttr.mFd = -1;
return BAD_FILE;
}
else
{
alogd("create demux channel[%d] ret[0x%x]!", mDmxChn, ret);
break;
}
}
if(false == nSuccessFlag)
{
mDmxChn = MM_INVALID_CHN;
aloge("fatal error! create demux channel fail!");
if(0 == mDmxChnAttr.mFd)
{
alogd("Be careful! mFd == 0!");
}
close(mDmxChnAttr.mFd);
mDmxChnAttr.mFd = -1;
return UNKNOWN_ERROR;
}
mCurrentState = MEDIA_THUMB_INITIALIZED;
return NO_ERROR;
}
status_t EyeseeThumbRetriever::setDataSource(const char *url)
{
alogv("setDataSource, path=%s", url);
status_t opStatus;
if (access(url, F_OK) == 0)
{
int fd = open(url, O_RDONLY);
if (fd < 0)
{
aloge("Failed to open file %s(%s)", url, strerror(errno));
return UNKNOWN_ERROR;
}
opStatus = setDataSource(fd, 0, 0x7ffffffffffffffL);
close(fd);
}
else
{
aloge("fatal error! open file path[%s] fail!", url);
opStatus = INVALID_OPERATION;
}
return opStatus;
}
std::shared_ptr<CMediaMemory> EyeseeThumbRetriever::getThmPicInfo(char *p_fname)
{
int tmp_ret = 0;
int fd = -1;
std::shared_ptr<CMediaMemory> spJpegBuf;
aloge("thum_pic:%s",p_fname);
fd = open(p_fname,O_RDONLY);
if(-1 == fd)
{
aloge("oen_file_failed");
return NULL;
}
unsigned int atom_size = 0;
char atom_type[5] = {0};
tmp_ret = read(fd,&atom_size,sizeof(unsigned int));
if(tmp_ret != sizeof(unsigned int))
{
aloge("get_thm_pic_read_failed,r:%d,t:%u",tmp_ret,sizeof(unsigned int));
}
atom_size = (atom_size&0xff000000)>>24|((atom_size&0x00ff0000)>>16)<<8|
((atom_size&0x0000ff00)>>8)<<16 | (atom_size&0xff)<<24;
tmp_ret = read(fd,atom_type,4);
if(tmp_ret != 4)
{
aloge("get_thm_pic_read_atom_type_fail!");
}
atom_type[4] = '\0';
if(strcmp(atom_type,"ftyp"))
{
aloge("get_thm_pic_chk_file_type_fail,c:%s",atom_type);
if(-1 != fd)
{
close(fd);
}
return NULL;
}
else
{
lseek(fd,atom_size-8,SEEK_CUR);
}
while(1)
{
tmp_ret = read(fd,&atom_size,sizeof(unsigned int));
if(tmp_ret != sizeof(unsigned int))
{
aloge("get_thm_pic_read_failed,r:%d,t:%u",tmp_ret,sizeof(unsigned int));
}
atom_size = (atom_size&0xff000000)>>24|((atom_size&0x00ff0000)>>16)<<8|
((atom_size&0x0000ff00)>>8)<<16 | (atom_size&0xff)<<24;
tmp_ret = read(fd,atom_type,4);
if(tmp_ret != 4)
{
aloge("get_thm_pic_read_atom_type_fail!");
}
atom_type[4] = '\0';
if(!strcmp(atom_type,"thm "))
{
spJpegBuf = std::make_shared<CMediaMemory>(atom_size-8);
char *ptr = (char *)spJpegBuf->getPointer();
tmp_ret = read(fd,ptr,atom_size-8);
if((unsigned int)tmp_ret != atom_size-8)
{
aloge("get_thm_pic_read_data_fail,r:%d,t:%d",tmp_ret,atom_size-4);
}
if(-1 != fd)
{
close(fd);
}
return spJpegBuf;
}
else
{
tmp_ret = lseek(fd,atom_size-8,SEEK_CUR);
if(-1 == tmp_ret)
{
aloge("get_thm_pic_seek_failed,t:%s,s:%d",atom_type,atom_size);
if(-1 != fd)
{
close(fd);
}
return NULL;
}
}
}
}
status_t EyeseeThumbRetriever::getMediaInfo(DEMUX_MEDIA_INFO_S * pMediaInfo)
{
Mutex::Autolock _l(mLock);
memset(pMediaInfo, 0, sizeof(DEMUX_MEDIA_INFO_S));
if (mCurrentState != MEDIA_THUMB_INITIALIZED)
{// make sure data source is ready
return NO_INIT;
}
if (bJpegSource)
{
int iWidth, iHeight, iFileSize;
if (!GetJpegInfo(mDmxChnAttr.mFd, &iWidth, &iHeight, &iFileSize))
{
aloge("fatal error! couldn't get jpeg file info");
return UNKNOWN_ERROR;
}
pMediaInfo->mFileSize = iFileSize;
pMediaInfo->mDuration = 0;
pMediaInfo->mVideoIndex = 0;
pMediaInfo->mVideoNum = 1;
pMediaInfo->mVideoStreamInfo[0].mCodecType = PT_JPEG;
pMediaInfo->mVideoStreamInfo[0].mWidth = iWidth;
pMediaInfo->mVideoStreamInfo[0].mHeight = iHeight;
pMediaInfo->mVideoStreamInfo[0].mFrameRate = 0;
pMediaInfo->mVideoStreamInfo[0].mAvgBitsRate = 0;
pMediaInfo->mVideoStreamInfo[0].mMaxBitsRate = 0;
return NO_ERROR;
}
ERRORTYPE ret = AW_MPI_DEMUX_GetMediaInfo(mDmxChn, pMediaInfo);
if (ret == SUCCESS)
{
if( (pMediaInfo->mVideoNum > 0 && pMediaInfo->mVideoIndex >= pMediaInfo->mVideoNum)
|| (pMediaInfo->mAudioNum > 0 && pMediaInfo->mAudioIndex >= pMediaInfo->mAudioNum)
|| (pMediaInfo->mSubtitleNum > 0 && pMediaInfo->mSubtitleIndex >= pMediaInfo->mSubtitleNum)
)
{
alogd("fatal error, trackIndex wrong! [%d][%d],[%d][%d],[%d][%d]",
pMediaInfo->mVideoNum, pMediaInfo->mVideoIndex, pMediaInfo->mAudioNum, pMediaInfo->mAudioIndex, pMediaInfo->mSubtitleNum, pMediaInfo->mSubtitleIndex);
return UNKNOWN_ERROR;
}
return NO_ERROR;
}
else
{
return UNKNOWN_ERROR;
}
}
std::shared_ptr<CMediaMemory> EyeseeThumbRetriever::getJpegAtTime(int64_t timeUs, int reqWidth, int reqHeight)
{
Mutex::Autolock _l(mLock);
if (bJpegSource)
{
aloge("fatal error! JPEG source don't support thumb retrive");
return NULL;
}
mJpegWidth = reqWidth;
mJpegHeight = reqHeight;
mSeekStartPosition = timeUs / 1000; //ms
if(!(mJpegWidth>0 && mJpegHeight>0))
{
aloge("fatal error! wrong jpegSize[%dx%d]", mJpegWidth, mJpegHeight);
return NULL;
}
std::shared_ptr<CMediaMemory> spJpegBuf;
prepare();
seekTo();
start();
if(mVecChn >= 0)
{
VENC_STREAM_S JpegStream;
VENC_PACK_S Jpeg_pack;
JpegStream.mPackCount = 1;
JpegStream.mpPack = &Jpeg_pack;
ERRORTYPE ret = AW_MPI_VENC_GetStream(mVecChn, &JpegStream, 500);
if(SUCCESS == ret)
{
int JpegSize = JpegStream.mpPack[0].mLen0 + JpegStream.mpPack[0].mLen1;
spJpegBuf = std::make_shared<CMediaMemory>(JpegSize);
char *ptr = (char *)spJpegBuf->getPointer();
memcpy(ptr, JpegStream.mpPack[0].mpAddr0, JpegStream.mpPack[0].mLen0);
ptr += JpegStream.mpPack[0].mLen0;
memcpy(ptr, JpegStream.mpPack[0].mpAddr1, JpegStream.mpPack[0].mLen1);
if(AW_MPI_VENC_ReleaseStream(mVecChn, &JpegStream) != SUCCESS)
{
aloge("jpeg stream data return fail!");
}
}
else
{
aloge("get jpeg stream data fail!");
}
}
else
{
aloge("fatal error! jpeg vencode channel do not creat!!!");
}
stop();
return spJpegBuf;
}
status_t EyeseeThumbRetriever::reset()
{
Mutex::Autolock _l(mLock);
if(!(mCurrentState & (MEDIA_THUMB_INITIALIZED | MEDIA_THUMB_STOPPED)))
{
aloge("called in wrong state 0x%x", mCurrentState);
return INVALID_OPERATION;
}
if(mVecChn >= 0)
{
AW_MPI_VENC_DestroyChn(mVecChn);
mVecChn = MM_INVALID_CHN;
}
if(mVdecChn >= 0)
{
AW_MPI_VDEC_DestroyChn(mVdecChn);
mVdecChn = MM_INVALID_CHN;
}
if(mDmxChn >= 0)
{
AW_MPI_DEMUX_DestroyChn(mDmxChn);
mDmxChn = MM_INVALID_CHN;
}
if(mDmxChnAttr.mFd >= 0)
{
if(0 == mDmxChnAttr.mFd)
{
alogd("Be careful! mFd == 0!");
}
close(mDmxChnAttr.mFd);
mDmxChnAttr.mFd = -1;
}
if(mClockChn >= 0)
{
AW_MPI_CLOCK_DestroyChn(mClockChn);
mDmxChn = MM_INVALID_CHN;
}
if(mClockChn >= 0)
{
AW_MPI_CLOCK_DestroyChn(mClockChn);
mClockChn = MM_INVALID_CHN;
}
mCurrentState = MEDIA_THUMB_IDLE;
bJpegSource = false;
return NO_ERROR;
}
status_t EyeseeThumbRetriever::prepare()
{
status_t result = NO_ERROR;
if(!(mCurrentState & (MEDIA_THUMB_INITIALIZED | MEDIA_THUMB_STOPPED)))
{
aloge("called in wrong state 0x%x", mCurrentState);
return INVALID_OPERATION;
}
mClockChnAttr.nWaitMask = 0;
DEMUX_MEDIA_INFO_S DemuxMediaInfo;
if(AW_MPI_DEMUX_GetMediaInfo(mDmxChn, &DemuxMediaInfo) != SUCCESS)
{
aloge("fatal error! get media info fail!");
return UNKNOWN_ERROR;
}
if((DemuxMediaInfo.mVideoNum > 0 && DemuxMediaInfo.mVideoIndex >= DemuxMediaInfo.mVideoNum)
|| (DemuxMediaInfo.mAudioNum > 0 && DemuxMediaInfo.mAudioIndex >= DemuxMediaInfo.mAudioNum)
|| (DemuxMediaInfo.mSubtitleNum > 0 && DemuxMediaInfo.mSubtitleIndex >= DemuxMediaInfo.mSubtitleNum)
)
{
alogd("fatal error, trackIndex wrong! [%d][%d],[%d][%d],[%d][%d]",
DemuxMediaInfo.mVideoNum, DemuxMediaInfo.mVideoIndex, DemuxMediaInfo.mAudioNum, DemuxMediaInfo.mAudioIndex, DemuxMediaInfo.mSubtitleNum, DemuxMediaInfo.mSubtitleIndex);
return UNKNOWN_ERROR;
}
ERRORTYPE ret;
if(DemuxMediaInfo.mVideoNum > 0 && !(mDmxChnAttr.mDemuxDisableTrack & DEMUX_DISABLE_VIDEO_TRACK))
{
DEMUX_VIDEO_STREAM_INFO_S *pStreamInfo = &DemuxMediaInfo.mVideoStreamInfo[DemuxMediaInfo.mVideoIndex];
memset(&mVdecChnAttr, 0, sizeof(VDEC_CHN_ATTR_S));
mVdecChnAttr.mType = pStreamInfo->mCodecType;
mVdecChnAttr.mPicWidth = 0;
mVdecChnAttr.mPicHeight = 0;
mVdecChnAttr.mInitRotation = (ROTATE_E)0;
mVdecChnAttr.mOutputPixelFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
mVdecChnAttr.mVdecVideoAttr.mMode = VIDEO_MODE_FRAME;
mVdecChnAttr.mVdecVideoAttr.mSupportBFrame = 1;
bool nSuccessFlag = false;
mVdecChn = 0;
while(mVdecChn < VDEC_MAX_CHN_NUM)
{
ret = AW_MPI_VDEC_CreateChn(mVdecChn, &mVdecChnAttr);
if(SUCCESS == ret)
{
nSuccessFlag = true;
alogd("create vdec channel[%d] success!", mVdecChn);
break;
}
else if(ERR_VDEC_EXIST == ret)
{
alogd("vdec channel[%d] is exist, find next!", mVdecChn);
mVdecChn++;
}
else
{
alogd("error, create vdec channel[%d] ret[0x%x]!", mVdecChn, ret);
break;
}
}
if(!nSuccessFlag)
{
mVdecChn = MM_INVALID_CHN;
aloge("fatal error! create vdec channel failed");
result = UNKNOWN_ERROR;
goto _err0;
}
MPP_CHN_S DmxChn{MOD_ID_DEMUX, 0, mDmxChn};
MPP_CHN_S VdecChn{MOD_ID_VDEC, 0, mVdecChn};
AW_MPI_SYS_Bind(&DmxChn, &VdecChn);
mClockChnAttr.nWaitMask |= 1<<CLOCK_PORT_INDEX_VIDEO;
}
if(mJpegWidth > 0 && mJpegHeight > 0 && mVdecChn >= 0)
{
memset(&mVecChnAttr, 0, sizeof(VENC_CHN_ATTR_S));
unsigned int mPictureNum = 1;
unsigned int minVbvBufSize = mJpegWidth * mJpegHeight * 3/2;
unsigned int vbvThreshSize = mJpegWidth*mJpegHeight;
unsigned int vbvBufSize = (mJpegWidth * mJpegHeight * 3/2 /10 * mPictureNum) + vbvThreshSize;
if(vbvBufSize < minVbvBufSize)
{
vbvBufSize = minVbvBufSize;
}
if(vbvBufSize > 16*1024*1024)
{
alogd("Be careful! vbvSize[%d]MB is too large, decrease to threshSize[%d]MB + 1MB", vbvBufSize/(1024*1024), vbvThreshSize/(1024*1024));
vbvBufSize = vbvThreshSize + 1*1024*1024;
}
mVecChnAttr.VeAttr.Type = PT_JPEG;
mVecChnAttr.VeAttr.AttrJpeg.MaxPicWidth = 0;
mVecChnAttr.VeAttr.AttrJpeg.MaxPicHeight = 0;
mVecChnAttr.VeAttr.AttrJpeg.BufSize = ((vbvBufSize + 1023) >> 10) << 10;
mVecChnAttr.VeAttr.AttrJpeg.mThreshSize = vbvThreshSize;
mVecChnAttr.VeAttr.AttrJpeg.bByFrame = TRUE;
mVecChnAttr.VeAttr.AttrJpeg.PicWidth = mJpegWidth;
mVecChnAttr.VeAttr.AttrJpeg.PicHeight = mJpegHeight;
mVecChnAttr.VeAttr.AttrJpeg.bSupportDCF = FALSE;
mVecChnAttr.VeAttr.MaxKeyInterval = 1;
mVecChnAttr.VeAttr.SrcPicWidth = AWALIGN(DemuxMediaInfo.mVideoStreamInfo[DemuxMediaInfo.mVideoIndex].mWidth, 32);
mVecChnAttr.VeAttr.SrcPicHeight = AWALIGN(DemuxMediaInfo.mVideoStreamInfo[DemuxMediaInfo.mVideoIndex].mHeight, 32);
mVecChnAttr.VeAttr.Field = VIDEO_FIELD_FRAME;
mVecChnAttr.VeAttr.PixelFormat = MM_PIXEL_FORMAT_YVU_SEMIPLANAR_420;
ERRORTYPE ret;
bool bSuccessFlag = false;
mVecChn = 0;
while(mVecChn < VENC_MAX_CHN_NUM)
{
ret = AW_MPI_VENC_CreateChn(mVecChn, &mVecChnAttr);
if(SUCCESS == ret)
{
bSuccessFlag = true;
alogd("create venc channel[%d] success!", mVecChn);
break;
}
else if(ERR_VENC_EXIST == ret)
{
alogd("venc channel[%d] is exist, find next!", mVecChn);
mVecChn++;
}
else
{
alogd("create venc channel[%d] ret[0x%x], find next!", mVecChn, ret);
break;
}
}
if(!bSuccessFlag)
{
mVecChn = MM_INVALID_CHN;
aloge("fatal error! create venc channel fail!");
result = UNKNOWN_ERROR;
goto _err0;
}
VENC_CROP_CFG_S stVencCrop;
memset(&stVencCrop, 0, sizeof(VENC_CROP_CFG_S));
stVencCrop.bEnable = 1;
stVencCrop.Rect.X = 0;
stVencCrop.Rect.Y = 0;
stVencCrop.Rect.Width = DemuxMediaInfo.mVideoStreamInfo[DemuxMediaInfo.mVideoIndex].mWidth;
stVencCrop.Rect.Height = DemuxMediaInfo.mVideoStreamInfo[DemuxMediaInfo.mVideoIndex].mHeight;
AW_MPI_VENC_SetCrop(mVecChn, &stVencCrop);
MPP_CHN_S VdecChn{MOD_ID_VDEC, 0, mVdecChn};
MPP_CHN_S VencChn{MOD_ID_VENC, 0, mVecChn};
AW_MPI_SYS_Bind(&VdecChn, &VencChn);
}
if(mVdecChn >=0 && mVecChn >= 0)
{
bool bSuccessFlag = false;
mClockChn = 0;
while(mClockChn < CLOCK_MAX_CHN_NUM)
{
ret = AW_MPI_CLOCK_CreateChn(mClockChn, &mClockChnAttr);
if(SUCCESS == ret)
{
bSuccessFlag = true;
alogd("creat clock channel[%d] success!", mClockChn);
break;
}
else if(ERR_CLOCK_EXIST == ret)
{
alogd("clock channel[%d] is exist, find next!", mClockChn);
++mClockChn;
}
else
{
alogd("creat clock channel[%d] ret[0x%x]", mClockChn, ret);
break;
}
}
if(!bSuccessFlag)
{
mClockChn = MM_INVALID_CHN;
aloge("fatal error! create clock channel fail!");
result = UNKNOWN_ERROR;
goto _err0;
}
MPP_CHN_S ClockChn{MOD_ID_CLOCK, 0, mClockChn};
MPP_CHN_S DmxChn{MOD_ID_DEMUX, 0, mDmxChn};
AW_MPI_SYS_Bind(&ClockChn, &DmxChn);
}
mCurrentState = MEDIA_THUMB_PREPARED;
_err0:
return result;
}
status_t EyeseeThumbRetriever::start()
{
status_t opStatus = NO_ERROR;
if(!(mCurrentState & MEDIA_THUMB_PREPARED))
{
aloge("called in wrong state 0x%x", mCurrentState);
return INVALID_OPERATION;
}
if(mVecChn >= 0)
{
VENC_RECV_PIC_PARAM_S RecvParam;
RecvParam.mRecvPicNum = 1;
AW_MPI_VENC_StartRecvPicEx(mVecChn, &RecvParam);
}
if(mVdecChn >= 0)
{
//AW_MPI_VDEC_StartRecvStream(mVdecChn);
VDEC_DECODE_FRAME_PARAM_S DecodeParam;
DecodeParam.mDecodeFrameNum = 1;
AW_MPI_VDEC_StartRecvStreamEx(mVdecChn, &DecodeParam);
}
if(mDmxChn >= 0)
{
AW_MPI_DEMUX_Start(mDmxChn);
}
if(mClockChn >= 0)
{
AW_MPI_CLOCK_Start(mClockChn);
}
mCurrentState = MEDIA_THUMB_STARTED;
return opStatus;
}
status_t EyeseeThumbRetriever::stop()
{
status_t opStatus = NO_ERROR;
if(mCurrentState & MEDIA_THUMB_STOPPED)
{
alogv("already stopped");
return SUCCESS;
}
if(!(mCurrentState & (MEDIA_THUMB_PREPARED|MEDIA_THUMB_STARTED)))
{
aloge("called in wrong state 0x%x", mCurrentState);
return INVALID_OPERATION;
}
if(mClockChn >= 0)
{
AW_MPI_CLOCK_Stop(mClockChn);
}
if(mDmxChn >= 0)
{
AW_MPI_DEMUX_Stop(mDmxChn);
}
if(mVdecChn >= 0)
{
AW_MPI_VDEC_StopRecvStream(mVdecChn);
}
if(mVecChn >= 0)
{
AW_MPI_VENC_StopRecvPic(mVecChn);
}
if(mVecChn >= 0)
{
AW_MPI_VENC_DestroyChn(mVecChn);
mVecChn = MM_INVALID_CHN;
}
if(mVdecChn >= 0)
{
AW_MPI_VDEC_DestroyChn(mVdecChn);
mVdecChn = MM_INVALID_CHN;
}
if(mDmxChn >= 0)
{
AW_MPI_DEMUX_DestroyChn(mDmxChn);
mDmxChn = MM_INVALID_CHN;
}
if(mDmxChnAttr.mFd >= 0)
{
if(0 == mDmxChnAttr.mFd)
{
alogd("Be careful! mFd == 0!");
}
close(mDmxChnAttr.mFd);
mDmxChnAttr.mFd = -1;
}
if(mClockChn >= 0)
{
AW_MPI_CLOCK_DestroyChn(mClockChn);
mClockChn = MM_INVALID_CHN;
}
mCurrentState = MEDIA_THUMB_STOPPED;
return opStatus;
}
status_t EyeseeThumbRetriever::seekTo()
{
status_t opStatus = NO_ERROR;
if(!(mCurrentState & MEDIA_THUMB_PREPARED))
{
aloge("called in wrong state 0x%x", mCurrentState);
return INVALID_OPERATION;
}
if(mSeekStartPosition > 0 && mDmxChn >= 0)
{
AW_MPI_DEMUX_Seek(mDmxChn, mSeekStartPosition);
alogd("the demux had set %d ms!", mSeekStartPosition);
}
return opStatus;
}
};