本例中media source为camera。(学习的平台是android sdk6.0)
调用关系图:
startRecording:
- recorder = New MediaRecorder(String16());
classMediaRecorder : public BnMediaRecorderClient,
public virtualIMediaDeathNotifier
- 在创建mediaRecorder的时侯,我们先获取IMediaPlayerService指针,然后再创建IMediaRecorder
(关于的声明sp<IMediaRecorder> mMediaRecorder;)
mMediaRecorder =service->createMediaRecorder(opPackageName);
- 在service->createMediaRecorder中会先把对象IMediaPlayerService序列话(利用data打包),然后把请求CREATE_MEDIA_RECORDER发送给remote(就是bpbinder)处理
remote()->transact(CREATE_MEDIA_RECORDER, data,&reply);
- 最后根据远端的reply来创建本地对应的对象
interface_cast<IMediaRecorder>(reply.readStrongBinder());
- 后续的方法都通过BpMediaRecorder(remote)来发送到BnMediaRecorder操作。
- a) BnMediaRecorder继承了BnInterface<IMediaRecorder>,并实现了ontransact
classBnMediaRecorder: publicBnInterface<IMediaRecorder>
{
public:
virtual status_t onTransact( uint32_t code,
constParcel& data,
Parcel*reply,
uint32_tflags = 0);
};
- 在这个方法里,每个操作都有对应的处理分支
- c) BnMediaRecorder是个虚函数,具体工作由MediaRecorderClient 来完成:MediaRecorderClient : public BnMediaRecorder
- class BpMediaRecorder: public BpInterface<IMediaRecorder>
在对应的方法中最后都通过remote送给Bn处理,如:
Parceldata, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
data.writeString8(params);
remote()->transact(SET_PARAMETERS,data, &reply);
- recorder->setParameters(…….)
- recorder->prepare()
- recorder->start()
- 3. 在MediaRecorderClient中封装了MediaRecorderBase这个类,每一项任务都要它来完成
在MediaRecorderClient的构造函数中可以看到
mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);
- 因此,具体的工作由StagefrightRecorder来完成
- 在AVMediaServiceFactory.cpp中
StagefrightRecorder*AVMediaServiceFactory::createStagefrightRecorder(
const String16 &opPackageName) {
return newStagefrightRecorder(opPackageName);
}
- StagefrightRecorder recorder->start()
在prepare中或者start中调用StagefrightRecorder::prepareInternal()
在这里根据输出编码设定,选择对应的编码器进行初始化。
我们以OUTPUT_FORMAT_MPEG_4为例进行分析
根据输出格式进入setupMPEG4orWEBMRecording()
- setupMPEG4orWEBMRecording()
在这里创建了MPEG4Writer
- writer = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);
- setupMediaSource将camera指定为encoder的input source
- sp<MediaSource> encoder;
err = setupVideoEncoder(mediaSource, &encoder);创建encoder
- setupVideoEncoder(mediaSource,&encoder);
首先将camera中的各项参数设定读出来设入到encoder中(camera为null则使用default值)
sp<MetaData>meta = cameraSource->getFormat();
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<MediaCodecSource> encoder =MediaCodecSource::Create(
mLooper, format, cameraSource,mPersistentSurface, flags);
- sp<MediaCodecSource> encoder
=MediaCodecSource::Create(
mLooper,
format,
cameraSource,
mPersistentSurface,
- ;
在create函数中先new一个对象,
sp<MediaCodecSource> mediaSource =
new MediaCodecSource(looper, format, source, consumer, flags);
if (mediaSource->init() == OK) {
return mediaSource;
}
- MediaCodecSource::init()
status_t err = initEncoder();
- initEncoder(){
mReflector = new AHandlerReflector<MediaCodecSource>(this);
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();
}
- MediaCodec::CreateByType(
mCodecLooper, outputMIME.c_str(), true /* encoder */) {
sp<MediaCodec> codec = new MediaCodec(looper, pid);
const status_tret = codec->init(mime, true /* nameIsType */, encoder);
}
- 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<AMessage> msg = newAMessage(kWhatInit, this);
msg->setString("name", name);
msg->setInt32("nameIsType",nameIsType);
if (nameIsType) {
msg->setInt32("encoder",encoder);
}
status_t err;
Vector<MediaResource> resources;
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<AMessage> response;
err = PostAndAwaitResponse(msg,&response);
if (!isResourceError(err)) {
break;
}
}
}