本例中media source为camera。(学习的平台是android sdk6.0)
调用关系图:
startRecording:
1. recorder = New MediaRecorder(String16());
classMediaRecorder : public BnMediaRecorderClient,
public virtualIMediaDeathNotifier
a) 在创建mediaRecorder的时侯,我们先获取IMediaPlayerService指针,然后再创建IMediaRecorder
(关于的声明sp
mMediaRecorder =service->createMediaRecorder(opPackageName);
b) 在service->createMediaRecorder中会先把对象IMediaPlayerService序列话(利用data打包),然后把请求CREATE_MEDIA_RECORDER发送给remote(就是bpbinder)处理
remote()->transact(CREATE_MEDIA_RECORDER, data,&reply);
c) 最后根据远端的reply来创建本地对应的对象
interface_cast
2. 后续的方法都通过BpMediaRecorder(remote)来发送到BnMediaRecorder操作。
a) BnMediaRecorder继承了BnInterface
classBnMediaRecorder: publicBnInterface
{
public:
virtual status_t onTransact( uint32_t code,
constParcel& data,
Parcel*reply,
uint32_tflags = 0);
};
b) 在这个方法里,每个操作都有对应的处理分支
c) BnMediaRecorder是个虚函数,具体工作由MediaRecorderClient来完成:MediaRecorderClient : public BnMediaRecorder
d) class BpMediaRecorder: public BpInterface
在对应的方法中最后都通过remote送给Bn处理,如:
Parceldata, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
data.writeString8(params);
remote()->transact(SET_PARAMETERS,data, &reply);
e) recorder->setParameters(…….)
f) recorder->prepare()
g) recorder->start()
3. 在MediaRecorderClient中封装了MediaRecorderBase这个类,每一项任务都要它来完成
在MediaRecorderClient的构造函数中可以看到
mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);
a) 因此,具体的工作由StagefrightRecorder来完成
b) 在AVMediaServiceFactory.cpp中
StagefrightRecorder*AVMediaServiceFactory::createStagefrightRecorder(
const String16 &opPackageName) {
return newStagefrightRecorder(opPackageName);
}
4. StagefrightRecorder recorder->start()
在prepare中或者start中调用StagefrightRecorder::prepareInternal()
在这里根据输出编码设定,选择对应的编码器进行初始化。
我们以OUTPUT_FORMAT_MPEG_4为例进行分析
根据输出格式进入setupMPEG4orWEBMRecording()
5. setupMPEG4orWEBMRecording()
在这里创建了MPEG4Writer
a) writer = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);
b) setupMediaSource将camera指定为encoder的input source
c) sp
err = setupVideoEncoder(mediaSource, &encoder);创建encoder
d) setupVideoEncoder(mediaSource,&encoder);
首先将camera中的各项参数设定读出来设入到encoder中(camera为null则使用default值)
sp
int32_t width, height, stride,sliceHeight, colorFormat;
CHECK(meta->findInt32(kKeyWidth,&width));
CHECK(meta->findInt32(kKeyHeight,&height));
CHECK(meta->findInt32(kKeyStride,&stride));
CHECK(meta->findInt32(kKeySliceHeight, &sliceHeight));
CHECK(meta->findInt32(kKeyColorFormat, &colorFormat));
format->setInt32("width",width);
format->setInt32("height",height);
format->setInt32("stride",stride);
format->setInt32("slice-height", sliceHeight);
format->setInt32("color-format", colorFormat);
这里预留了custom参数设置函数,android中默认没有实现,是空函数
接着创建encoder。
sp
mLooper, format, cameraSource,mPersistentSurface, flags);
e) sp
=MediaCodecSource::Create(
mLooper,
format,
cameraSource,
mPersistentSurface,
flags);
在create函数中先new一个对象,
sp
new MediaCodecSource(looper, format, source, consumer, flags);
if (mediaSource->init() == OK) {
return mediaSource;
}
f) MediaCodecSource::init()
status_t err = initEncoder();
g) initEncoder(){
mReflector = new AHandlerReflector
mLooper->registerHandler(mReflector);
mCodecLooper = new ALooper;
mCodecLooper->setName("codec_looper");
mCodecLooper->start();
……………..
mEncoder =MediaCodec::CreateByType(
mCodecLooper,outputMIME.c_str(), true /* encoder */);
….
mEncoderActivityNotify =new AMessage(kWhatEncoderActivity, mReflector);
mEncoder->setCallback(mEncoderActivityNotify);
status_t err =mEncoder->configure(
mOutputFormat,
NULL /*nativeWindow */,
NULL /* crypto*/,
MediaCodec::CONFIGURE_FLAG_ENCODE);
…………………………
err = mEncoder->start();
}
h) MediaCodec::CreateByType(
mCodecLooper, outputMIME.c_str(), true /* encoder */) {
sp
const status_tret = codec->init(mime, true /* nameIsType */, encoder);
}
i) MediaCodec::init (const AString&name, bool nameIsType, bool encoder) {
………..
/// name 包含video, nameIsType is true
因此
mCodec =AVFactory::get()->createACodec();
…………..
mIsVideo =true;
…………..
mCodecLooper->registerHandler(mCodec);
mCodec->setNotificationMessage(newAMessage(kWhatCodecNotify, this));
sp
msg->setString("name", name);
msg->setInt32("nameIsType",nameIsType);
if (nameIsType) {
msg->setInt32("encoder",encoder);
}
status_t err;
Vector
const char *type = secureCodec ?kResourceSecureCodec : kResourceNonSecureCodec;
const char *subtype = mIsVideo ?kResourceVideoCodec : kResourceAudioCodec;
resources.push_back(MediaResource(String8(type), String8(subtype), 1));
for (int i = 0; i <= kMaxRetry; ++i) {
if (i > 0) {
// Don't try to reclaim resourcefor the first time.
if(!mResourceManagerService->reclaimResource(resources)) {
break;
}
}
sp
err = PostAndAwaitResponse(msg,&response);
if (!isResourceError(err)) {
break;
}
}
}