Skip to content
This repository has been archived by the owner on Jul 30, 2022. It is now read-only.

Commit

Permalink
RIO-7762: OMX_UseBuffer support buffers allocated in MIO.
Browse files Browse the repository at this point in the history
  • Loading branch information
Jianhong Jiang committed Oct 23, 2009
1 parent 2157f3c commit 903c9e2
Show file tree
Hide file tree
Showing 9 changed files with 354 additions and 6 deletions.
60 changes: 59 additions & 1 deletion android/author/android_camera_input.cpp
Expand Up @@ -37,13 +37,22 @@ using namespace android;
// Define entry point for this DLL
OSCL_DLL_ENTRY_POINT_DEFAULT()

PVRefBufferAlloc::~PVRefBufferAlloc()
{
if(numAllocated != 0)
{
LOGE("Ln %d ERROR PVRefBufferAlloc numAllocated %d",__LINE__, numAllocated );
}
}

// camera MIO
AndroidCameraInput::AndroidCameraInput()
: OsclTimerObject(OsclActiveObject::EPriorityNominal, "AndroidCameraInput"),
iWriteState(EWriteOK),
iAuthorClock(NULL),
iClockNotificationsInf(NULL),
iAudioFirstFrameTs(0)
iAudioFirstFrameTs(0),
pPmemInfo(NULL)
{
LOGV("constructor(%p)", this);
iCmdIdCounter = 0;
Expand Down Expand Up @@ -107,6 +116,11 @@ AndroidCameraInput::~AndroidCameraInput()
}
iFrameQueueMutex.Close();
mListener.clear();
if(pPmemInfo)
{
delete pPmemInfo;
pPmemInfo = NULL;
}
}

PVMFStatus AndroidCameraInput::connect(PvmiMIOSession& aSession,
Expand Down Expand Up @@ -547,6 +561,23 @@ PVMFStatus AndroidCameraInput::getParametersSync(PvmiMIOSession session,
// TODO:
// is it okay to hardcode this as the timescale?
params[0].value.uint32_value = 1000;
} else if (!pv_mime_strcmp(identifier, PVMF_BUFFER_ALLOCATOR_KEY)) {
/*
* if( camera MIO does NOT allocate YUV buffers )
* {
* OSCL_LEAVE(OsclErrNotSupported);
* return PVMFErrNotSupported;
* }
*/

params = (PvmiKvp*)oscl_malloc(sizeof(PvmiKvp));
if (!params )
{
OSCL_LEAVE(OsclErrNoMemory);
return PVMFErrNoMemory;
}
params [0].value.key_specific_value = (PVInterface*)&mbufferAlloc;
status = PVMFSuccess;
}

return status;
Expand Down Expand Up @@ -994,6 +1025,11 @@ PVMFStatus AndroidCameraInput::DoStop(const AndroidCameraInputCmd& aCmd)
mCamera->setListener(NULL);
mCamera->stopRecording();
ReleaseQueuedFrames();
if(pPmemInfo)
{
delete pPmemInfo;
pPmemInfo = NULL;
}
}
iState = STATE_STOPPED;
return PVMFSuccess;
Expand Down Expand Up @@ -1175,6 +1211,28 @@ PVMFStatus AndroidCameraInput::postWriteAsync(nsecs_t timestamp, const sp<IMemor
data.iXferHeader.flags = 0;
data.iXferHeader.duration = 0;
data.iXferHeader.stream_id = 0;

{//compose private data
//could size be zero?
if(NULL == pPmemInfo)
{
int iCalculateNoOfCameraPreviewBuffer = heap->getSize() / size;
LOGV("heap->getSize() = %d, size of each frame= %d, iCalculateNoOfCameraPreviewBuffer = %d", heap->getSize(), size, iCalculateNoOfCameraPreviewBuffer);
pPmemInfo = new CAMERA_PMEM_INFO[iCalculateNoOfCameraPreviewBuffer];
if(NULL == pPmemInfo)
{
LOGE("Failed to allocate the camera pmem info buffer array. iCalculateNoOfCameraPreviewBuffer %d",iCalculateNoOfCameraPreviewBuffer);
return PVMFFailure;
}
}

int iIndex = offset / size;
pPmemInfo[iIndex].pmem_fd = heap->getHeapID();
pPmemInfo[iIndex].offset = offset;
data.iXferHeader.private_data_ptr = ((OsclAny*)(&pPmemInfo[iIndex]));
LOGV("struct size %d, pmem_info - %x, &pmem_info[iIndex] - %x, iIndex =%d, pmem_info.pmem_fd = %d, pmem_info.offset = %d", sizeof(CAMERA_PMEM_INFO), pPmemInfo, &pPmemInfo[iIndex], iIndex, pPmemInfo[iIndex].pmem_fd, pPmemInfo[iIndex].offset );
}

data.iFrameBuffer = frame;
data.iFrameSize = size;

Expand Down
103 changes: 103 additions & 0 deletions android/author/android_camera_input.h
Expand Up @@ -190,6 +190,99 @@ class AndroidCameraInputListener : public CameraListener
AndroidCameraInput* mCameraInput;
};

#ifndef PVMF_FIXEDSIZE_BUFFER_ALLOC_H_INCLUDED
#include "pvmf_fixedsize_buffer_alloc.h"
#endif

/* A MIO allocater class for two purposes:
* 1. Provide the number of buffers MIO will use;
* 2. Allocate the buffers for OMX_UseBuffer for "buffer pre-announcement". In case MIO cannot
* provide the buffer address, a dummy address is used. The OMX component has to support
* movable buffer(iOMXComponentSupportsMovableInputBuffers) in that case.
*/
class PVRefBufferAlloc: public PVInterface, public PVMFFixedSizeBufferAlloc
{
public:
PVRefBufferAlloc()
:refCount(0),
bufferSize(0),
maxBuffers(4), //QCOM camera will use 4 buffers, although it actually only has 3 right now.
numAllocated(0),
pMagicAddr( (OsclAny*)0xDEADBEEF )
{
}

virtual ~PVRefBufferAlloc();

virtual void addRef() {++refCount;};

virtual void removeRef()
{
--refCount;
if (refCount <= 0)
{//cleanup
LOGW("refCount %d", refCount );
}
}

virtual bool queryInterface(const PVUuid& uuid, PVInterface*& aInterface)
{
aInterface = NULL; // initialize aInterface to NULL in case uuid is not supported

if (PVMFFixedSizeBufferAllocUUID == uuid)
{
// Send back ptr to the allocator interface object
PVMFFixedSizeBufferAlloc* myInterface = OSCL_STATIC_CAST(PVMFFixedSizeBufferAlloc*, this);
refCount++; // increment interface refcount before returning ptr
aInterface = OSCL_STATIC_CAST(PVInterface*, myInterface);
return true;
}

return false;
}

virtual OsclAny* allocate()
{
if (numAllocated < maxBuffers)
{
//MIO does NOT provide mem allocator impl.
//return dummy address for OMX buffer pre-announcement.
++numAllocated;
return (OsclAny*)pMagicAddr;
}
return NULL;
}

virtual void deallocate(OsclAny* ptr)
{
if( pMagicAddr == ptr )
{
--numAllocated;
}
else
{
LOGE("Ln %d ERROR PVRefBufferAlloc ptr corrupted 0x%x numAllocated %d", __LINE__, ptr, numAllocated );
}
}

virtual uint32 getBufferSize()
{
return bufferSize;
}

virtual uint32 getNumBuffers()
{
return maxBuffers;
}

private:
int32 refCount;
int32 bufferSize;
int32 maxBuffers;
int32 numAllocated;
const OsclAny *pMagicAddr;
};

class AndroidCameraInput
: public OsclTimerObject,
public PvmiMIOControl,
Expand Down Expand Up @@ -438,6 +531,16 @@ class AndroidCameraInput
PVMFMediaClockNotificationsInterface *iClockNotificationsInf;

uint32 iAudioFirstFrameTs;
PVRefBufferAlloc mbufferAlloc;

// data structures for tunneling buffers
struct CAMERA_PMEM_INFO
{
/* pmem file descriptor */
uint32 pmem_fd;
uint32 offset;
} *pPmemInfo;

};

#ifdef HIDE_MIO_SYMBOLS
Expand Down
5 changes: 5 additions & 0 deletions nodes/pvmediainputnode/src/pvmf_media_input_node.h
Expand Up @@ -211,6 +211,11 @@ class PvmfMediaInputNode : public OsclActiveObject,

// function used in getParametersSync of capability class
PVMFStatus GetConfigParameter(PvmiKvp*& aParameters, int& aNumParamElements, int32 aIndex, PvmiKvpAttr reqattr);
// To support config interface
void QueryInterface(const PVUuid &aUuid, OsclAny*&aPtr)
{
aPtr = (aUuid == PVMI_CAPABILITY_AND_CONFIG_PVUUID) ? ((PvmiCapabilityAndConfig*)this) : NULL;
}
private:
typedef enum
{
Expand Down
25 changes: 24 additions & 1 deletion nodes/pvmediainputnode/src/pvmf_media_input_node_outport.cpp
Expand Up @@ -65,6 +65,9 @@ PvmfMediaInputNodeOutPort::PvmfMediaInputNodeOutPort(PvmfMediaInputNode* aNode,
iMediaDataMemPool = OSCL_NEW(OsclMemPoolFixedChunkAllocator, (PVMIO_MEDIADATA_POOLNUM));
iMediaDataAlloc = OSCL_NEW(PvmfMediaInputDataBufferAlloc, (iMediaDataAllocMemPool));
iDataPathLogger = PVLogger::GetLoggerObject("datapath.sourcenode");

//OSCL_TRY(err, iPrivateDataFsiFragmentAlloc.size(4, sizeof(OsclAny *))); //TODO REMOVE THE HARDCODED VALUE
iPrivateDataFsiFragmentAlloc.size(4, sizeof(OsclAny *)); //TODO REMOVE THE HARDCODED VALUE
#ifdef _TEST_AE_EROR_HANDLING
iTimeStampJunk = 0x000FFFFF;
#endif
Expand Down Expand Up @@ -405,14 +408,34 @@ PVMFCommandId PvmfMediaInputNodeOutPort::writeAsync(uint8 format_type, int32 for
mediaData->setMediaFragFilledLen(0, data_len);
mediaData->setStreamID(data_header_info.stream_id);

PVMFStatus status = PVMFFailure;
{
OsclRefCounterMemFrag privatedataFsiMemFrag;
OsclLeaveCode fsiErrorCode = OsclErrNone;

OSCL_TRY(fsiErrorCode, privatedataFsiMemFrag = iPrivateDataFsiFragmentAlloc.get(););

OSCL_FIRST_CATCH_ANY(fsiErrorCode,
LOG_ERR((0, "Failed to allocate memory for FSI for private data"));
status = PVMFErrNoMemory;
iNode->ReportErrorEvent(PVMFErrPortProcessing, (OsclAny*)status);
OSCL_LEAVE(OsclErrNoMemory);
return -1; // this is going to make everything go out of scope
);

uint8 *fsiptr = (uint8*) privatedataFsiMemFrag.getMemFragPtr();
privatedataFsiMemFrag.getMemFrag().len = sizeof(OsclAny*);
oscl_memcpy(fsiptr, &(data_header_info.private_data_ptr), sizeof(OsclAny *)); // store ptr data into fsi
mediaData->setFormatSpecificInfo(privatedataFsiMemFrag);
}

LOGDATATRAFFIC((0, "PvmfMediaInputNodeOutPort::writeAsync:"
"StreamID=%d, TS=%d, Len=%d, SN=%d, MimeType=%s",
data_header_info.stream_id, data_header_info.timestamp, data_len,
data_header_info.seq_num, iMimeType.get_cstr()));
// Convert media data to MediaMsg
PVMFSharedMediaMsgPtr mediaMsg;
convertToPVMFMediaMsg(mediaMsg, mediaData);
PVMFStatus status;
#ifdef _TEST_AE_ERROR_HANDLING

if ((iNode->iErrorTrackID > 0) && (data_header_info.stream_id == (uint32)iNode->iErrorTrackID))
Expand Down
3 changes: 3 additions & 0 deletions nodes/pvmediainputnode/src/pvmf_media_input_node_outport.h
Expand Up @@ -59,6 +59,8 @@
#include "pvmf_media_input_data_buffer.h"
#endif

#include "pvmf_pool_buffer_allocator.h"

// Forward declaration
class PvmfMediaInputNode;

Expand Down Expand Up @@ -183,6 +185,7 @@ class PvmfMediaInputNodeOutPort : public OsclTimerObject,
//logging
OSCL_HeapString<OsclMemAllocator> iMimeType;
PVLogger* iDataPathLogger;
PVMFBufferPoolAllocator iPrivateDataFsiFragmentAlloc;
};

#endif // PVMF_MEDIA_INPUT_NODE_INPORT_H_INCLUDED
2 changes: 2 additions & 0 deletions nodes/pvomxencnode/include/pvmf_omx_enc_port.h
Expand Up @@ -81,6 +81,8 @@ class PVMFOMXEncPort : public PvmfPortBaseImpl
}

bool pvmiSetPortFormatSpecificInfoSync(OsclRefCounterMemFrag& aMemFrag);
bool pvmiGetBufferAllocatorSpecificInfoSync(PvmiKeyType aIdentifier, PvmiKvp*& aParameters, int& aNumParamElements);
bool releaseParametersSync(PvmiKvp*& aParameters, int& aNumParamElements);

PVMFStatus Connect(PVMFPortInterface* aPort);
void setParametersSync(PvmiMIOSession aSession,
Expand Down

0 comments on commit 903c9e2

Please sign in to comment.