You are on page 1of 52

Tech

Android Camera

Revision History
Date
<13/05/201
0>

Issue

Description

<0.5>

Author
wylhistory

1. ABSTRACT ............................................................................................................................ 4
2. INTRODUCTION.................................................................................................................. 4
3. .......................................................................................................................................... 4
4. .......................................................................................................................... 4
5. .......................................................................................................................... 6
5.1 ............................................................................................................... 6
5.2 MEDIARECORDER....................................................................................................... 9
5.2.1 Java ......................................................................................................................... 9
5.2.2 JNI ................................................................................................................. 10
5.2.3 Service ................................................................................................................... 10
5.2.4 PV.......................................................................................................................... 11
5.3 SETCAMERA ......................................................................................................... 13
5.4 SETAUDIOSOURCE ................................................................................................... 15
5.4.1 ....................................................................................................... 17
5.4.2 ........................................................................................................... 18
5.5 SETVIDEOSOURCE................................................................................................ 20
5.6 SETOUTPUTFORMAT ................................................................................................ 22
5.7 SETVIDEOENCODER ............................................................................................. 25
5.8 SETAUDIOENCODER............................................................................................. 27
5.9 PREPARE .................................................................................................................. 28
5.9.1 ........................................................................................... 30
5.9.2 Surface .......................................................................................................... 30
5.9.3 prepare ...................................................................................................... 32
5.10
START ................................................................................................................... 36
5.10.1
........................................................................................................... 36
5.10.2
PV Driver........................................................................... 37
5.10.3
Author Driver ............................................................................................ 38
5.10.4
....................................................................................................... 39
5.10.5
....................................................................................................... 40
Tech, 2010-2-5

Page 2 of 52

6. ........................................................................................................................................ 50
7. .................................................................................................................................... 51
8. REFERENCE ....................................................................................................................... 52

Tech, 2010-2-5

Page 3 of 52

1.

Abstract
androidcameraopencore.

2.

Introduction

AndroidCamerajavaJNI
ServiceOpenCoreopencore

3.

Camera

Camera1
2
Cameracamera

A
B

4.

Tech, 2010-2-5

Page 4 of 52


A UIUI;
B)
Media Recorder
APIApp
MediaPlayer;
C)
JNIjavaC
CCjava
D)
LibmediaJNIServiceAPI
JNIservice
E)
ServiceJNIClientClientJava
ServicejavaClienbinderBBinder

F)
PVMediaRecorderPV
PV driver
G)
AuthorDriverPVMEdiaRecorderPV

H)
PVAuthorEnginePVAuthorEngineNodeUtility
initpreparestart

I)
PVAuthorEngineNodeUtility

J)

audioencodercomposer
K)
MIOMIO

AndroidAudioInputAndroidCameraInput
encoder
L)
Componentpv

UIVideoCamera.java
Media RecorderMediaRecorder.java
JNIandroid_media_MediaRecorder.cpp
Libmediamediarecorder.cpp
ServiceMediaPlayerService.cppMediaRecorderClient.cpp
PVMediaRecorderPVMediaRecorder.cpp
AuthorDriverauthordriver.cpp
pvauthorengine.cpp
PVAuthorEngineNodeUtilitypvaenodeutility.cpp
mpeg4
3gppvmf_media_input_node.cpppvmf_omx_enc_node.cpp
Tech, 2010-2-5

Page 5 of 52

pvmp4ffcn_node.cpp
MIOandroid_audio_input.cpp
android_camera_input.cpp
Componentmarvell

5.
5.1

Motodroidandroid

Switcher mListener.onSwitchChanged

mListenercamera.javaclass Camera
public boolean onSwitchChanged(Switcher source, boolean onOff) {
if (onOff == SWITCH_VIDEO) {
if (!isCameraIdle()) return false;
MenuHelper.gotoVideoMode(this);
finish();
}
return true;
}
gotoVideoMode
public static void gotoVideoMode(Activity activity) {
startCameraActivity(activity, MediaStore.INTENT_ACTION_VIDEO_CAMERA);
}
private static void startCameraActivity(Activity activity, String action) {
Intent intent = new Intent(action);
intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
intent.addFlags(Intent.FLAG_ACTIVITY_FORWARD_RESULT);

// Keep the camera instance for a while.


// This avoids re-opening the camera and saves time.
Tech, 2010-2-5

Page 6 of 52

CameraHolder.instance().keep();

activity.startActivity(intent);
}
activityVideoCamera.javaVideoCamera
onCreateactivity
SurfaceChanged1camera
,SurfaceChanged
mHandler.sendEmptyMessage(INIT_RECORDER);
MainHandlerhandleMessage
public void handleMessage(Message msg) {
switch (msg.what) {
case CLEAR_SCREEN_DELAY: {
getWindow().clearFlags(
WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
break;
}
case UPDATE_RECORD_TIME: {
updateRecordingTime();
break;
}
case INIT_RECORDER: {
initializeRecorder();
break;
}
default:
Log.v(TAG, "Unhandled message: " + msg.what);
break;
}
initializeRecorder
Tech, 2010-2-5

Page 7 of 52

private void initializeRecorder() {

mMediaRecorder = new MediaRecorder();


mMediaRecorder.setCamera(mCameraDevice);
mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.MIC);
mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
mMediaRecorder.setOutputFormat(mProfile.mOutputFormat);

createVideoPath();
mMediaRecorder.setOutputFile(mCameraVideoFilename);

mMediaRecorder.setVideoFrameRate(mProfile.mVideoFps);
mMediaRecorder.setVideoSize(
mProfile.mVideoWidth, mProfile.mVideoHeight);
mMediaRecorder.setParameters(String.format(
"video-param-encoding-bitrate=%d", mProfile.mVideoBitrate));
mMediaRecorder.setParameters(String.format(
"audio-param-encoding-bitrate=%d", mProfile.mAudioBitrate));
mMediaRecorder.setParameters(String.format(
"audio-param-number-of-channels=%d", mProfile.mAudioChannels));
mMediaRecorder.setParameters(String.format(
"audio-param-sampling-rate=%d", mProfile.mAudioSamplingRate));
mMediaRecorder.setVideoEncoder(mProfile.mVideoEncoder);
mMediaRecorder.setAudioEncoder(mProfile.mAudioEncoder);
mMediaRecorder.setPreviewDisplay(mSurfaceHolder.getSurface());

mMediaRecorder.prepare();

Tech, 2010-2-5

Page 8 of 52

}
MediaRecorder,CameraDevice1
camera,3gp
mp4bitratechannel
surface
prepare

12

5.2

MediaRecorder

5.2.1 Java
mMediaRecorder =
new
MediaRecorder();

mEventHandler =
new
EventHandler(this,
looper);

native_setup(new
WeakReference<Me
diaRecorder>(this));

javaMediaRecorder
native_setupJNIC++

Tech, 2010-2-5

Page 9 of 52

5.2.2 JNI
android_media_Med
iaRecorder_native_s
etup

p<MediaRecorder>
mr = new
MediaRecorder();

mMediaRecorder =
service>createMediaReco
rder(getpid());

sp<JNIMediaRecord
erListener> listener
= new
JNIMediaRecorderL
istener(env, thiz,
weak_this);

mr>setListener(li
stener);

mListener =
listener;

CMediaRecorderjavaMediaRecorder
JNI
sp<IMediaRecorder>
mMediaRecorder,
BinderbinderService
ServiceProxyLibMediamListenerJNI

5.2.3 Service

sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(pid_t pid)


{
#ifndef NO_OPENCORE
sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid);
wp<MediaRecorderClient> w = recorder;
Mutex::Autolock lock(mLock);
mMediaRecorderClients.add(w);
#else
sp<MediaRecorderClient> recorder = NULL;
#endif
LOGV("Create new media recorder client from pid %d", pid);
return recorder;
}
ServiceMediaRecorderClient
mMediaRecorderClients;
MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service,
pid_t pid)
{
LOGV("Client constructor");
mPid = pid;
Tech, 2010-2-5

Page 10 of 52

mRecorder = new PVMediaRecorder();


mMediaPlayerService = service;
}
new PVMediaRecorderPV

PV
5.2.4 PV
PVMediaRecorder::
PVMediaRecorder
mAuthorDriver =
new AuthorDriver();

mAuthorDriverWr
apper = new
AuthorDriverWrapp
er();

createThread(Autho
rDriver::startAutho
rThread, this);

AuthorDriverWrapp
er::AuthorDriverWr
apper

DrivermAuthorDriverWrapper
Driver mAuthorDriverDriver
mAuthorDriver->XXX()driver
driverdriver

Tech, 2010-2-5

Page 11 of 52

createThread(Autho
rDriver::startAutho
rThread, this);

AuthorDriver::start
AuthorThread

ed->authorThread();

OMX_MasterInit

mAuthor =
PVAuthorEngineFa
ctory::CreateAuthor
(this, this, this)

OsclScheduler::Init

sched>StartScheduler(mS
yncSem)

OMX_MasterInit2OsclScheduler::Init

OsclScheduler::Init

OsclExecScheduler:
:NewL(name, alloc,
nreserve)

sched->InstallScheduler()

OsclExecSchedulerCommonBase::I
nstallScheduler

OsclExecSchedulerCommonBas
e::InstallScheduler

SetScheduler(this);

PVSCHEDULER_REGIST
RY::registerInstance(a,
PVSCHEDULER_REGIST
RY_ID);

Tech, 2010-2-5

Page 12 of 52

registerInstanceScheduler
GetScheduler
GlibGSource
mAuthor
,StartScheduler

sched>StartScheduler(mSyncSem)

BlockingLoopL

while
(!iDoStop)

CallRunExec(pvacti
ve);

pvactive =
WaitForReadyAO();

pvactive->Run()
iReadyQ.PopTop();

timer
active

iReadyQ.WaitAndP
opTop(OsclTickCou
nt::TicksToMsec(wa
itTicks));

iExecTimerQ.Pop(
pvtimer);

run

Run;
OK,

5.3

SetCamera

Tech, 2010-2-5

Page 13 of 52

mMediaRecorder.se
tCamera(mCameraD
evice);

setCamera

JNI
android_media_Med
iaRecorder_setCame
ra

mr->setCamera(c>remote())

mMediaRecorder>setCamera(camera);

Binder
mRecorder>setCamera(camera);

set_camera_com
mand *ac = new
set_camera_com
mand();

mAuthorDrive
rWrapper>enqueueCom
mand(ac, 0, 0)

author_command(A
UTHOR_SET_CA
MERA)

Driver

Tech, 2010-2-5

Page 14 of 52

handleSetVideoSource

5.4

SetAudioSource

initializeRecorder
VideoCamera.java

mr>setAudioSource(as
)

mMediaRecorder.se
tAudioSource(Medi
aRecorder.AudioSo
urce.MIC);
1

mMediaRecorder>setAudioSource(a
s);

setAudioSource

mRecorder>setAudioSource((
audio_source)as)

JNI
android_media_Med
iaRecorder_setAudi
oSource

new
set_audio_source_c
ommand

author_command(
AUTHOR_SET_A
UDIO_SOURCE)

Tech, 2010-2-5

Page 15 of 52

DriverAudioSource
javaCDriver
AuthorDriver::Run

AUTHOR_SET
_AUDIO_SOU
RCE

handleSetAudioSour
ce((set_audio_sourc
e_command *)ac);

mAudioInputMIO = new
AndroidAudioInput(ac->as)

PvmfMediaInputNo
deFactory::Create

mAudioInputMIO>setAudioSource(AUDIO_S
OURCE_CAMCORDER)

PvmfMediaInputNo
de::Create

iAudioSource =
iSource;

mAuthor>AddDataSource(*mA
udioNode, ac)

node>ConstructL(aIOInt
erfacePtr);

iMediaIOControl
= aIOInterfacePtr;

AndroidAudioInput MIO
MIONodeNode
PVAENodeContaineriDataSourcePoolUtilNode
Container
UtilUtilNode
IMediaIOControl
AndroidAudioInput
mAuthor->AddDataSource

Tech, 2010-2-5

Page 16 of 52

PVAuthorEngine::Run

audio
video

source
source

case PVAE_CMD_ADD_DATA_SOURCE:

DoAddDataSource

nodeContainer = AllocateNodeContainer

iDataSourcePool.p
ush_back(nodeCon
tainer)

iNodeUtil.Init

source
cmd.ConstructInit
aNode->ThreadLogon

aNode->Connect(session)

nodeContainer->iNode = aNode
iNode
node
PVMFNodeInterface
vide
audio node
node

iType =
PVAENU_CMD_INIT

AddCmdToQueue

iNodes.push_back(aN
odeContainer);

5.4.1
ThreadLogonConnect
ThreadLogon:
{

if (!IsAdded())
AddToScheduler();
if (iMediaIOControl)
iMediaIOControl->ThreadLogon();

OSCL_EXPORT_REF void OsclActiveObject::AddToScheduler()


{
PVActiveBase::AddToScheduler();
}
void PVActiveBase::AddToScheduler()
{
iThreadContext.EnterThreadContext();
if (iThreadContext.iScheduler)
{
iAddedNum = iThreadContext.iScheduler->iNumAOAdded++;

}
Tech, 2010-2-5

Page 17 of 52

}
iThreadContext.EnterThreadContext,
OSCL_EXPORT_REF void PVThreadContext::EnterThreadContext()
{
//Save thread ID.
int32 result = OsclThread::GetId(iThreadId);
if (result != OsclProcStatus::SUCCESS_ERROR)
OsclError::Leave(OsclErrSystemCallFailed);

//Set current thread scheduler.


iScheduler = OsclExecScheduler::GetScheduler();
if (!iScheduler)
{
//There must be a pv scheduler.
OsclError::Leave(OsclErrNotInstalled);
}
iOpen = true;
}
SchedulerAuthorDriver::startAuthorThread

MIO
void AndroidAudioInput::ThreadLogon()
{
LOGV("ThreadLogon %p", this);
if(!iThreadLoggedOn)
{
AddToScheduler();
iThreadLoggedOn = true;
}
}
MIO
run
ConnectSession
Session id;MIOConnectDoinit
Container
SetAudioSource
5.4.2
ContainerContainer
SourceContainer
Utilty
Tech, 2010-2-5

Page 18 of 52


PVAuthorEngineNodeUtility::Run

case PVAENU_CMD_INIT

status = DoInit(cmd);

nodeContainer->iNode->Init(nodeContainer->iSessionId, aCmd.iContext)

InitInit
PvmfMediaInputNode::DoInit

if (iMediaIOControl->connect(iMediaIOSession, this) != PVMFSuccess)


{
PVLOGGER_LOGMSG(PVLOGMSG_INST_LLDBG, iLogger,
PVLOGMSG_ERR,
(0, "PvmfMediaInputNode::DoInit: Error - iMediaIOControl->connect
failed"));
aCmd.iEventCode = PvmfMediaInputNodeErr_MediaIOConnect;
return PVMFFailure;
}
//Query for MIO capability and config interface
return SendMioRequest(aCmd, EQueryCapability);

}
iMediaControl
AndroidAudioInput,AndroidAudioInput::connect

iObservers.push_back(aObserver)
aSession = (PvmiMIOSession)(iObservers.size() - 1);
aObserverPvmfMediaInputNode

aSession0
SendMioRequest
iMediaIOControl->QueryInterface(PVMI_CAPABILITY_AND_CONFIG_PVUUI
D,
iMediaIOConfigPVI, NULL)
Tech, 2010-2-5

Page 19 of 52

iMediaIOControl

OKSetAudioSource

5.5

SetVideoSource
PV

initializeRecorder
VideoCamera.java

mMediaRecorder.se
tVideoSource(Medi
aRecorder.VideoSo
urce.CAMERA);
1

mr>setVideoSource(vs
)

mMediaRecorder>setVideoSource

setVideoSource
mRecorder>setVideoSource((vi
deo_source)vs)
JNI
android_media_Med
iaRecorder_setVide
oSource

new
set_video_source_c
ommand

author_command(A
UTHOR_SET_VI
DEO_SOURCE)

AUTHOR_SET_VIDEO_SOURCEDriverDriver

Tech, 2010-2-5

Page 20 of 52

AuthorDriver::Run

case
AUTHOR_SET
_VIDEO_SOU
RCE

handleSetVideoSour
ce((set_video_sourc
e_command *)ac);

AndroidCameraIn
put* cameraInput
= new
AndroidCameraIn
put()

mListener =
new
AndroidCameraI
nputListener(this
)

PvmfMediaIn
putNodeFact
ory::Create(c
ameraInput)

cameraInput>SetCamera(m
Camera)

PvmfMediaInp
utNode::Create
pvmf_media_i
nput_node.cpp

mCamera =
Camera::creat
e(camera)

node>ConstructL(aI
OInterfacePtr)

sp<Camera> c
= new Camera()
camera>connectc
Return c

Binder
iMediaIOCont
rol =
aIOInterfacePtr
;

mAudioInputM
IO>setAudioSourc
e(AUDIO_SO
URCE_CAMC
ORDER)

mAuthor>AddDataS
ource(*mVi
deoNode,
ac)

iAudioSource =
iSource;

Icameara.cpp

CameraService::Client::conne
ct
CameraService.cpp

mCameraClient = client;
mClientPid = callingPid;
Camaera
c
pid

A AndroidCameraInputvideoMIO
B iMediaIOControlMIO
Tech, 2010-2-5

Page 21 of 52


C CameraCameraSetCamera
D

E SourceContainer

5.6

SetOutputFormat
Driver

initializeRecorder
VideoCamera.java

mMediaRecorder.se
tOutputFormat(mP
rofile.mOutputFor
mat);0
3gp

setOutputFormat

mr>setOutputFormat(o
f)

mMediaRecorder>setVideoSource(vs
)

mRecorder>setOutputFormat((
output_format)of)

JNI
android_media_Med
iaRecorder_setOutp
utFormat(JNIEnv
*env, jobject thiz,
jint of)

new
set_output_format_c
ommand

author_command(A
UTHOR_SET_OU
TPUT_FORMAT)

AUTHOR_SET_OUTPUT_FORMATRun
Driver

Tech, 2010-2-5

Page 22 of 52

AuthorDriver::Run

case
AUTHOR_SET
_OUTPUT_FO
RMAT

handleSetOutputFor
mat

if (ac->of ==
OUTPUT_FOR
MAT_DEFAUL
T)

case
OUTPUT_FOR
MAT_THREE_
GPP

ac->of =
OUTPUT_FORMA
T_THREE_GPP

mComposerMimeT
ype = "/x-pvmf/ffmux/3gp"

mOutputFormat =
ac->of;

mAuthor>SelectComposer(mCo
mposerMimeType,
mComposerConfig, ac)

PVEngineCommand
cmd(PVAE_CMD_SELECT_COMP
OSER, iCommandId,
(OsclAny*)aContextData,
(OsclAny*)(&aConfigInterface));
cmd.SetMimeType(aComposerType);
Dispatch(cmd);
aConfigInterface
composer

3gp,Mime
"/x-pvmf/ff-mux/3gp",Mime
Composer
mpeg4amr

Tech, 2010-2-5

Page 23 of 52

PVAuthorEngine::R
un

case
PVAE_CMD_S
ELECT_COM
POSER:

DoSelectComposer

if
(aCmd.GetUuid(
) == uuid)

PVAuthorEngineNo
deFactoryUtility::Q
ueryRegistry(mime
Type, uuid);

PVAuthorEngi
neNodeFactory
Utility::Create
Composer(uui
d)

if (aUuid ==
KPVMp4FFCo
mposerNodeUu
id)

K3gpComposer
MimeType

PVMp4FFComp
oserNodeFactor
y::CreateMp4F
FComposer

aUuid =
KPVMp4FFComp
oserNodeUuid;

OSCL_NEW(PV
Mp4FFCompos
erNode,
(aPriority))

AllocateNode
Container(nod
e)

aNode>ThreadLogon

nodeContain
er->iUuid =
uuid;
iComposerN
odes.push_ba
ck(nodeCont
ainer)

QueryNodeConfi
g(nodeContainer,
*((PVInterface**)
aCmd.GetParam
1()))

iNodeUtil.Init(
nodeContainer)

aNode>Connect
PVAuthorEngine
NodeFactoryUtili
ty::QueryNodeC
onfigUuid(aNode
Container>iUuid, uuid)

iNodeUtil.Que
ryInterface(aN
odeContainer,
uuid,
aInterface)

QueryNodeCon
figUuid

if (aNodeUuid
==
KPVMp4FFCo
mposerNodeUu
id)
aConfigUuid =
KPVMp4FFCNCli
pConfigUuid;

aMimeTypeUUid
b) UUIDComposer
c
d
e composerComposer
finit

Tech, 2010-2-5

Page 24 of 52

5.7

setVideoEncoder

Driver

Driver

Tech, 2010-2-5

Page 25 of 52

AuthorDriver::Run

case
AUTHOR_SET
_VIDEO_ENC
ODER:

handleSetVideoEncode
r((set_video_encoder_
command *)ac);

if (ac->ve ==
VIDEO_ENCO
DER_DEFAUL
T)

case
VIDEO_EN
CODER_M
PEG_4_SP:

ac->ve =
VIDEO_ENC
ODER_H263;

iVideoEncoder
MimeType =
"/x-pvmf/
video/encode/
mp4";

0
h263

if
(mVideoIn
putMIO)

clipVideoF
rameRate

((AndroidCa
meraInput
*)mVideoIn
putMIO)>SetFrameR
ate(mVideoF
rameRate);
20
5
20

(AndroidCa
meraInput
*)mVideoIn
putMIO)>SetFrame
Size
352
288

176144

mAuthor>AddMediaTrack(*
mVideoNode,
iVideoEncoderMime
Type,
mSelectedComposer,
mVideoEncoderConf
ig, ac)
video

0
h263
java
MimeTypeMIO

20352288
AddMediaTrack

A MimeTypeUUIDUUIDEncoder
B NodeContainer
C Node
D
init
E srcencodercomposerportsrcport
encoderportencoderPortComposerport

Tech, 2010-2-5

Page 26 of 52

OK
5.8

SetAudioEncoder
Driver

initializeRecorder
VideoCamera.java

mMediaRecor
der.setAudio
Encoder(mPr
ofile.mAudio
Encoder);

setAudioEncod
er

android_media_Med
iaRecorder_setAudi
oEncoder(JNIEnv
*env, jobject thiz,
jint ae)

mr>setAudioEncoder(a
e)

mMediaRecorder>setAudioEncoder(a
e)

mRecorder>setAudioEncoder(
(audio_encoder)ae)

new
set_audio_encoder_
command

author_command(A
UTHOR_SET_AU
DIO_ENCODER)

Driver

Tech, 2010-2-5

Page 27 of 52

AuthorDriver::Run

case
AUTHOR_SET
_AUDIO_ENC
ODER

handleSetAudioEnc
oder

case
AUDIO_ENCO
DER_AMR_NB

if (ac->ae ==
AUDIO_ENCO
DER_DEFAUL
T)

ac->ae =
AUDIO_ENCO
DER_AMR_N
B

iAudioEncoder
MimeType = "/
x-pvmf/audio/
encode/amr-nb"

mSamplingR
ate = 8000

mAudioInput
MIO>setAudioSam
plingRate

mAudioInputM
IO>setAudioNum
Channels

AndroidAudioI
nput::setAudio
SamplingRate

AndroidAudioI
nput::setAudio
NumChannels

iAudioSamplin
gRate =
iSamplingRate

iAudioNumCh
annels =
iNumChannels;

mAuthor>AddMediaTrack(*mA
udioNode,
iAudioEncoderMimeT
ype,
mSelectedComposer,
mAudioEncoderConfig
, ac)

cmd(PVAE_CMD_ADD_MEDIA_T
RACK, iCommandId,
(OsclAny*)aContextData,
(OsclAny*)&aDataSource,
(OsclAny*)aComposer,
(OsclAny*)&aConfigInterface);
cmd.SetMimeType(aEncoderType);
"/x-pvmf/audio/encode/amrnb"

aamr
b8000
cMIO
dAddMediaTrackportsrcencodercomposer

portAddMediaTrack

5.9

prepare
Surface
mSurface = sv,prepare
Driver

Tech, 2010-2-5

Page 28 of 52

Dispatch(
cmd);

mMediaRecord
er.prepare()

new
FileOutputStrea
m(mPath)

_setOutput
File(fos.ge
tFD(), 0,
0)

_prepare

android_media_
MediaRecorder
_prepare

android_med
ia_MediaRec
order_setOut
putFileFD

mr>setOutputFile

mr>setPreviewSurface(na
tive_surface)
native_surfac

mr->prepare()

surface
mMediaRecorder>setOutputFile(fd,
offset, length)

mRecorder>setOutputFile(
fd, offset,
length)

mMediaRecor
der>setPreviewS
urface

mRecorder>setPreviewSurfa
ce

new
set_output_file_
command

new
set_preview_su
rface_comman
d

author_comman
d(AUTHOR_S
ET_OUTPUT_
FILE)

author_comma
nd(AUTHOR_
SET_PREVIE
W_SURFACE
)

mMediaRecord
er->prepare

mRecorder>prepare

new
author_comman
d(AUTHOR_P
REPARE)

Driver
A AUTHOR_SET_OUTPUT_FILEComposer

B AUTHOR_SET_PREVIEW_SURFACEMIOSurface
1camera
C AUTHOR_PREPARE,Nodeprepare

Tech, 2010-2-5

Page 29 of 52

5.9.1

AuthorDriver::Run

case AUTHOR_SET_OUTPUT_FILE

handleSetOutputFile

else
if((OUTPUT_FORMAT_TH
REE_GPP ==
mOutputFormat)

config =
OSCL_DYNAMIC_CAST(PVMp4FF
CNClipConfigInterface*,
mComposerConfig)

config>SetOutputFileDescriptor(&Os
clFileHandle(ifpOutput))
mp4
PVMp4FFComposerNode::Se
tOutputFileDescriptor

iFileObject>SetFileHandle((OsclFileHandle*
)aFileHandle)

iFileObject->Open

CallNativeOpen(*iOpenFileHa
ndle, mode, params, fileserv)

iNativeFile->Open(handle,
mode, params, fileserv)

iFile =
aHandle.Handle();
iFile
handle

IFile
PV
5.9.2 Surface

Tech, 2010-2-5

Page 30 of 52

AuthorDriver::Run

case
AUTHOR_SET_PREV
IEW_SURFACE

handleSetPreviewSurface

((AndroidCameraInput
*)mVideoInputMIO)>SetPreviewSurface(ac->surface)

mSurface = surface

if (mCamera != NULL)

mCamera->setPreviewDisplay(surface)

setPreviewDisplay

startPreviewMode
mSurface = surface;

if (mHardware>previewEnabled())

if
(mUseOverlay)

result = setOverlay()

mOverlayRef = mSurface>createOverlay(w, h,
OVERLAY_FORMAT_DEFAULT)

mHardware->setOverlay(new
Overlay(mOverlayRef))
overlay

registerPreviewBuffers

ISurface::BufferHeap
buffers(w, h, w, h,
PIXEL_FORMAT_RGB_56
5,SP, transform, 0,
mHardware>getPreviewHeap());
buffer

mSurface>registerBuffers(b
uffers)
LayerBuffer
surface
surfaceflinger

Surfaceoverlayoverlayoverlay
CreateOverLayoverlayMIO
Tech, 2010-2-5

Page 31 of 52

surfacefLinger1camera
5.9.3 prepare

preparePVAE_CMD_INIT
init
PVAuthorEngine::Run

prepare
case PVAE_CMD_INIT
composer
encoder
source

DoInit(cmd)

iNodeUtil.Prepare(iComposerNodes)

iNodeUtil.Prepare(iEncoderNodes)

iNodeUtil.Prepare(iDataSourceNodes);

cmd.Construct(PVAENU_CMD_P
REPARE, aNodes, aContext)

Tech, 2010-2-5

Page 32 of 52

Util
prepareComposerencoder,src
Composer

Encoder

PVMFOMXEncNod
e::ProcessCommand

PVOMXENC_N
ODE_CMD_PR
EPARE

DoPrepare

DoPrepareRole

Tech, 2010-2-5

Page 33 of 52

DoPrepare

else if
(iOutFormat ==
PVMF_MIME_
M4V)

else if
(iOutFormat ==
PVMF_MIME_
AMRWB_IETF)

Role =
(OMX_STRIN
G)"video_enco
der.mpeg4"

Role =
(OMX_STRIN
G)"audio_enco
der.amrwb"

Rolevideo_encoder.mpeg4
audio_encoder.amrwb

DoPrepare

OMX_MasterGetCo
mponentsOfRole(Ro
le, &num_comps,
NULL);
component

role
component

role
component

OMX_MasterGetHandle(&iO
MXEncoder,
(OMX_STRING)
CompOfRole[ii],
(OMX_PTR) this,
(OMX_CALLBACKTYPE *)
& iCallbacks)
iOMXEncoder

component
CompName

iOMXEn
coder

NegotiateAu
dioCompone
ntParameters

component
CompOfRole
component
iCallbacks
component
EventHandler
EmptyBufferDone
FillBufferDone

component
port

CreateInputMemP
ool
1
node
2
node
3
component

component
ProvideBuffersTo
Component

port
get
set

component
"OMX.MARVEL
L.VIDEO.MPEG4
ENCODERMVED
"
"OMX.MARVEL
L.VIDEO.MPEG4
ENCODER"

NegotiateV
ideoCompo
nentParam
eters

OMX_SendC
ommand(iOM
XEncoder,
OMX_Comm
andStateSet,
OMX_StateId
le, NULL)

idle

set

CallbackEventHandlerEnc
component

CallbackEmptyBufferDoneE
nc
copy

CallbackFillBufferDoneEnc

iCallbacks.EventHandler =
CallbackEventHandlerEnc; //
event_handler;
iCallbacks.EmptyBufferDone =
CallbackEmptyBufferDoneEnc; //
empty_buffer_done;
iCallbacks.FillBufferDone =
CallbackFillBufferDoneEnc; //
fill_buffer_done;

API

component

composer

rolecomponent
component

Tech, 2010-2-5

Page 34 of 52

component
node2
Src

PrepareInputMIOEInit
Prepare
MIOMIODoInit

AndroidCameraInput::Run

case CMD_INIT

AndroidCameraInput::DoInit

mCamera>setPreviewDisplay(mSurface);

mCamera->setParameters

mCamera->startPreview()
prepare

Surface
Tech, 2010-2-5

Page 35 of 52

previewprepare
audioPreview1camera

OK

5.10

Start

5.10.1

public boolean performClick() {


boolean result = super.performClick();
if (mListener != null) {
mListener.onShutterButtonClick(this);
}
return result;
}
mListener

mListenerVideoCamera
VideoCamera.java
public void onShutterButtonClick(ShutterButton button) {
switch (button.getId()) {
case R.id.shutter_button:
if (mMediaRecorderRecording) {
if (mIsVideoCaptureIntent) {
stopVideoRecordingAndShowAlert();
} else {
stopVideoRecordingAndGetThumbnail();
initializeRecorder();
Tech, 2010-2-5

Page 36 of 52

}
} else if (mMediaRecorder != null) {
// If the click comes before recorder initialization, it is
// ignored. If users click the button during initialization,
// the event is put in the queue and record will be started
// eventually.
startVideoRecording();
}
break;
}
startVideoRecording
5.10.2 PV Driver

startVideoRecording

pauseAudioPlayback

mMediaRecorder.setO
nErrorListener(this);
mMediaRecorder.setO
nInfoListener(this);

mMediaRecorder.st
art()

JNI
android_media_Med
iaPlayer_start
android_media_Med
iaPlayer.cpp

mMediaRecorder->start
Binder
mRecorder->start

p->start()

new
author_command(A
UTHOR_START)

Intent

Tech, 2010-2-5

Page 37 of 52

mMEdiaRecordermMediaRecorder
VideoCameraonErroronInfo

Driver
AUTHOR_START
5.10.3 Author Driver

AuthorDriver::Run

case
AUTHOR_STA
RT

AuthorDriver::handleStart

mAuthor->Start(ac)

PVEngineCommand
cmd(PVAE_CMD_START,
iCommandId,
(OsclAny*)aContextData);

Dispatch(cmd);

mAuthor->startmAuthor

Tech, 2010-2-5

Page 38 of 52

5.10.4
PVAuthorEngine::Run

case PVAE_CMD_START:

DoStart

iNodeUtil.Start(iComposerNodes);

iNodeUtil.Start(iEncoderNodes)

iNodeUtil.Start(iDataSourceNodes);

composeencodesrcnodestart

cmd.Construct(PVAENU_CMD_ST
ART, aNodes, aContext);

AddCmdToQueue(cmd);

DoStartstartUtilstart
ComposerEncodersource

PVMFStatus PVAuthorEngineNodeUtility::DoStart(const
PVAENodeUtilCmd& aCmd)
{
LOG_STACK_TRACE((0, "PVAuthorEngineNodeUtility::DoStart"));
int32 err = 0;
PVAENodeContainer* nodeContainer = NULL;
OSCL_TRY(err,
for (uint32 i = 0; i < aCmd.iNodes.size(); i++)
{
nodeContainer = aCmd.iNodes[i];
nodeContainer->iNode->Start(nodeContainer->iSessionId,
aCmd.iContext);
}
);
OSCL_FIRST_CATCH_ANY(err,
LOG_ERR((0, "PVAuthorEngineNodeUtility::DoStart: Error Start failed. node=0x%x",
Tech, 2010-2-5

Page 39 of 52

nodeContainer->iNode));
return PVMFFailure;
);
return PVMFPending;
}
nodeContainer->iNode->startiNode
ContainerComposerencodersrc

5.10.5
5.10.5.1 Composerstart

PVMp4FFCompose
rNode::Run

PVMp4FFCompose
rNode::ProcessCom
mand

PVMF_GENE
RIC_NODE_S
TART

DoStart

iMpeg4File =
PVA_FF_IMpeg4File::create
MP4File(iFileType,
iAuthoringMode, iFileObject,
iCacheSize)

AddTrack(iInP
orts[i])

iMpeg4File>addTrackRefer
ence

iMpeg4File>prepareToEncode

SetState(EPVMFNo
deStarted)

iMpeg4File
iMpeg4Fil
e>addTrack

channels bitrate
framerate width
height

port,
Tech, 2010-2-5

Page 40 of 52

PVMp4FFCompose
rPort::Run

status = iNode>ProcessIncoming
Msg(this)

PVMp4FFCompose
rNode::ProcessInco
mingMsg

case
PVMF_MP4FF
CN_PORT_TYP
E_SINK

port>DequeueIncoming
Msg

convertToPVMFMe
diaData

iFragmentWriter>enqueueMemFrag
ToTrack

mLast->set(aFrame,
aMemFrag,
aFormat,
aTimestamp,
aTrackId, aPort);

mRequestCv.signal(
);

composerencoder
track
track
signal

Tech, 2010-2-5

Page 41 of 52

threadLoop
PVMp4FFComposerNode::PVMp4FFComposerNode

iFragmentWriter = new
android::FragmentWriter(this)

iFragmentWriter->run(LOG_TAG);

while
(!doneWaiting)
for (size_t i = 0; i <
numFrags; ++i)

mRequestCv.wait

doneWaiting = mSize > 0 ||


mExitRequested

mPrevWriteStatus = mComposer>AddMemFragToTrack(
mFirst->mFrame, mFirst->mFrag, mFirst>mFormat,
mFirst->mTimestamp, mFirst->mTrackId, mFirst>mPort)

iMpeg4File>addSampleToTrack(aTrackId,
amrfrags, amrts, flags)

Composer
waitstart

timestamp

5.10.5.2 Encoderstart

encodercomponentMIO
OMX_filebufferdone
emptybufferdonenode

Tech, 2010-2-5

Page 42 of 52

PVMFOMXEncNode::Run

Do...while

if ((iDataIn.GetRep() != NULL) ||
((iNumOutstandingOutputBuffers <
iNumOutputBuffers) &&
(iProcessingState ==
EPVMFOMXEncNodeProcessingState_ReadyToEncode
) &&
(iResetMsgSent == false)) ||
((iDynamicReconfigInProgress == true) &&
(iResetMsgSent == false))
component

ProcessIncomingMsg(iInPort)

aPort>DequeueIn
comingMsg(
msg)

convertToPV
MFMediaDat
a(iDataIn,
msg)

iDataIn

HandleProcessingState
FillBufferDoneProcessing
case
EPVMFOMXEncNodeProcessingSta
te_ReadyToEncode
MediaDataCurr =
WrapOutputBuffer(pB
ufdata, bufLen,
pContext);

QueueOutputBuffer(
MediaDataOut,
iBufferLenOut)

while
(iNumOutstandingOutputB
uffers <
iNumOutputBuffers)

else if
((iNumOutstandingInputBuffers <
iNumInputBuffers) &&
(iDataIn.GetRep() != NULL))

QueueOutputBuffer
SendOutputBufferToOMXComponent
SendInputBufferTo
OMXComponent();
convertToPVMFMe
diaMsg(mediaMsgO
ut, mediaDataOut)

iOutPort>QueueOutgoingM
sg(mediaMsgOut)

OMX_FillThisBuffer(iOMXE
ncoder, output_buf>pBufHdr);

component

OMX_EmptyThisBuffer(i
OMXEncoder, input_buf>pBufHdr);

component

portcopycomponent
componentOMX_EmptyThisBuffer
emptybufferdone
node
OMX_FIllThisBufferFillThisBufferDone
node

Tech, 2010-2-5

Page 43 of 52

PVMFOMXEncNode::Run

while (iOutPort>OutgoingMsgQueueSize
())

ProcessOutgoingMsg(iOutPort)

composer node

aPort->Send()

PvmfPortBaseImpl::Send

iConnectedPort>Receive(iOutgoingQ
ueue.iQ.front())
node

OutgoingMsgQueueProcessOutgoingMsg
aPortsendComposer
composerportReceive
2
5.10.5.3 Sourcestart

Tech, 2010-2-5

Page 44 of 52

PvmfMediaInputNode::Start
PvmfMediaInputNode::
ProcessCommand

cmd.PvmfMediaInputNodeC
mdBase::Construct(s,
PVMF_GENERIC_NODE_
START, aContext);

QueueCommandL(cmd);

case
PVMF_GENERIC_N
ODE_START:

DoStart

SendMioRequest(aC
md, EStart);

for (i = 0; i <
iOutPortVector
.size(); i++)

PvmfMediaInputNod
e::SendMioRequest
iOutPortVector[i]->Start();

case EStart:

iMediaIOControl->Start()

runrun
ProcessCommandSTARTDoStart
MIOstartportstart
MIO
MIOstart

Tech, 2010-2-5

Page 45 of 52

AndroidAudioInput::Run
AndroidAudioInput::Start

AddCmdToQueue(AI_
CMD_START,
aContext);

case
AI_CMD_STA
RT:

AndroidAudioI
nput::DoStart

AudioInput_Thread.Create(
(TOsclThreadFuncPtr)start_a
udin_thread_func, 0,
(TOsclThreadFuncArg)this,
Start_on_creation);

start_audin_thread_func

obj->audin_thread_func();

audin_thread_func

Tech, 2010-2-5

Page 46 of 52

AudioRecord
startwhile

AndroidAudioInput::Run

if((iState == STATE_STARTED)
&& (iFirstFrameReceived))

AndroidAudioInput::SendMicData

MicData &data =
iWriteResponseQue
ue[0]

iPeer>writeAsync(PVMI
_MEDIAXFER_FM
T_TYPE_DATA, 0,
data.iData,
data.iDataLen,
data_hdr)

iWriteResponseQue
ue.erase(&iWriteRe
sponseQueue[0])

iSentMediaData.pus
h_back(sentData);

iPeerwriteAsync2
AddMediaTrackPortsetPeer
AudioRecord

MIOstart
AndroidCameraInput::Run

case CMD_START:

status = DoStart();

mCamera->setListener(mListener);

mCamera->startRecording()

AddDataEventToQueue(iMilliSecondsPerDataEvent)

JNI

beep

mHardware>enableMsgType(CAMERA_MSG_VI
DEO_FRAME)

startCameraMode(CAMERA_RECORDING_MODE);

beep
enableMsgTypestartCameraMode
Tech, 2010-2-5

Page 47 of 52


startCameraMode(C
AMERA_RECORD
ING_MODE);

case CAMERA_RECORDING_MODE

default:

startPreviewMode();
camera

if
(!mHardware>previewEnabl
ed())

startRecordingMode

mHardware->startRecording();

mRecordingEnabled = true;

case
startPrevieMode
1camera

mRecordingEnabled=true;

Tech, 2010-2-5

Page 48 of 52

CameraHardware::p
reviewThread

mHardware>setCallbacks(notifyCallback,
dataCallback,
dataCallbackTimestamp,
mCameraService.get());
camera

mMrvlCamera>getPreview((unsigned
char *)frame,
mPreviewFrameSize,
1);

CameraHardware::s
etCallbacks

mNotifyCb = notify_cb;
mDataCb = data_cb;
mDataCbTimestamp =
data_cb_timestamp;

if (mRecordingEnabled
== true)

if (mMsgEnabled &
CAMERA_MSG_VIDE
O_FRAME)

mDataCbTimestamp(system
Time(),
CAMERA_MSG_VIDEO_FR
AME, buffer,
mCallbackCookie);

CameraService::Cl
ient::dataCallback
Timestamp

c>dataCallbackTimestamp(tim
estamp, msgType, dataPtr);

Camera::dataCallba
ckTimestamp

listener->postDataTimestamp(timestamp,
msgType, dataPtr);
listenermListener

mCameraInput>postWriteAsync(timestamp, dataPtr);

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

Tech, 2010-2-5

iFrameQueue.push_back(data);

Page 49 of 52

mRecordingEnabled
enableMsgTypeCAMERA_MSG_VIDEO_FRAME

iFrameQueue

MIO
writeAsyncencoderencoder
composer

OK

6.

compose
AndroidjavaC
JNIService
binderPV
audioflingerCamera

A MediaRecorder
PV
Tech, 2010-2-5

Page 50 of 52

listener

B CameraAuthorDriver

C MIO
MIO
container

D PV
MIO
sp<android::Camera> mCamera
CameraService
CamerastartPreview
E
composerRun
F

H
encoderportport
src>encoder>composer;
port
I
J SurfaceoverlayLayerBuffercamera
prepare
K Preparecomposer
encodercomponent
encoder
camera
L Start

7.

1
Tech, 2010-2-5

Page 51 of 52

2
3Composer
4

8.

reference
1Android_camera.doc
2Android.pdf

wylhistory
wylhistory@gmail.com

Tech, 2010-2-5

Page 52 of 52

You might also like