您好,登錄后才能下訂單哦!
本例中media source為camera。(學(xué)習(xí)的平臺是android sdk6.0)
調(diào)用關(guān)系圖:
startRecording:
recorder = New MediaRecorder(String16());
classMediaRecorder : public BnMediaRecorderClient,
public virtualIMediaDeathNotifier
在創(chuàng)建mediaRecorder的時侯,我們先獲取IMediaPlayerService指針,然后再創(chuàng)建IMediaRecorder
(關(guān)于的聲明sp<IMediaRecorder> mMediaRecorder;)
mMediaRecorder =service->createMediaRecorder(opPackageName);
在service->createMediaRecorder中會先把對象IMediaPlayerService序列話(利用data打包),然后把請求CREATE_MEDIA_RECORDER發(fā)送給remote(就是bpbinder)處理
remote()->transact(CREATE_MEDIA_RECORDER, data,&reply);
最后根據(jù)遠(yuǎn)端的reply來創(chuàng)建本地對應(yīng)的對象
interface_cast<IMediaRecorder>(reply.readStrongBinder());
后續(xù)的方法都通過BpMediaRecorder(remote)來發(fā)送到BnMediaRecorder操作。
a) BnMediaRecorder繼承了BnInterface<IMediaRecorder>,并實(shí)現(xiàn)了ontransact
classBnMediaRecorder: publicBnInterface<IMediaRecorder>
{
public:
virtual status_t onTransact( uint32_t code,
constParcel& data,
Parcel*reply,
uint32_tflags = 0);
};
在這個方法里,每個操作都有對應(yīng)的處理分支
c) BnMediaRecorder是個虛函數(shù),具體工作由MediaRecorderClient 來完成:MediaRecorderClient : public BnMediaRecorder
class BpMediaRecorder: public BpInterface<IMediaRecorder>
在對應(yīng)的方法中最后都通過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這個類,每一項(xiàng)任務(wù)都要它來完成
在MediaRecorderClient的構(gòu)造函數(shù)中可以看到
mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);
因此,具體的工作由StagefrightRecorder來完成
在AVMediaServiceFactory.cpp中
StagefrightRecorder*AVMediaServiceFactory::createStagefrightRecorder(
const String16 &opPackageName) {
return newStagefrightRecorder(opPackageName);
}
StagefrightRecorder recorder->start()
在prepare中或者start中調(diào)用StagefrightRecorder::prepareInternal()
在這里根據(jù)輸出編碼設(shè)定,選擇對應(yīng)的編碼器進(jìn)行初始化。
我們以OUTPUT_FORMAT_MPEG_4為例進(jìn)行分析
根據(jù)輸出格式進(jìn)入setupMPEG4orWEBMRecording()
setupMPEG4orWEBMRecording()
在這里創(chuàng)建了MPEG4Writer
writer = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);
setupMediaSource將camera指定為encoder的input source
sp<MediaSource> encoder;
err = setupVideoEncoder(mediaSource, &encoder);創(chuàng)建encoder
setupVideoEncoder(mediaSource,&encoder);
首先將camera中的各項(xiàng)參數(shù)設(shè)定讀出來設(shè)入到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);
這里預(yù)留了custom參數(shù)設(shè)置函數(shù),android中默認(rèn)沒有實(shí)現(xiàn),是空函數(shù)
接著創(chuàng)建encoder。
sp<MediaCodecSource> encoder =MediaCodecSource::Create(
mLooper, format, cameraSource,mPersistentSurface, flags);
sp<MediaCodecSource> encoder
=MediaCodecSource::Create(
mLooper,
format,
cameraSource,
mPersistentSurface,
;
在create函數(shù)中先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;
}
}
}
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。