青春须早为,岂能长少年。这篇文章主要讲述利用 android mediaRecorder c++类进行视频编码相关的知识,希望能为你提供帮助。
本例中media source为camera。(学习的平台是android sdk6.0)
调用关系图:
startRecording:
- recorder = New MediaRecorder(String16());
public virtualIMediaDeathNotifier
- 在创建mediaRecorder的时侯,我们先获取IMediaPlayerService指针,然后再创建IMediaRecorder
mMediaRecorder =service-> createMediaRecorder(opPackageName);
- 在service->
createMediaRecorder中会先把对象IMediaPlayerService序列话(利用data打包),然后把请求CREATE_MEDIA_RECORDER发送给remote(就是bpbinder)处理
- 最后根据远端的reply来创建本地对应的对象
- 后续的方法都通过BpMediaRecorder(remote)来发送到BnMediaRecorder操作。
- a)
BnMediaRecorder继承了BnInterface<
IMediaRecorder>
,并实现了ontransact
{
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>
Parceldata, reply;
data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());
data.writeString8(params);
remote()-> transact(SET_PARAMETERS,data, & reply);
- recorder->
setParameters(…….)
- recorder->
prepare()
- recorder->
start()
- 3.
在MediaRecorderClient中封装了MediaRecorderBase这个类,每一项任务都要它来完成
mRecorder = AVMediaServiceFactory::get()-> createStagefrightRecorder(opPackageName);
- 因此,具体的工作由StagefrightRecorder来完成
- 在AVMediaServiceFactory.cpp中
const String16 & opPackageName) {
return newStagefrightRecorder(opPackageName);
}
- StagefrightRecorder
recorder->
start()
在这里根据输出编码设定,选择对应的编码器进行初始化。
我们以OUTPUT_FORMAT_MPEG_4为例进行分析
根据输出格式进入setupMPEG4orWEBMRecording()
- setupMPEG4orWEBMRecording()
- writer = mp4writer =AVFactory::get()->
CreateMPEG4Writer(mOutputFd);
- setupMediaSource将camera指定为encoder的input source
- sp<
MediaSource>
encoder;
- setupVideoEncoder(mediaSource,&
encoder);
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
mLooper,
format,
cameraSource,
mPersistentSurface,
- ;
sp< MediaCodecSource> mediaSource =
new MediaCodecSource(looper, format, source, consumer, flags);
if (mediaSource-> init() == OK) {
return mediaSource;
}
- MediaCodecSource::init()
- initEncoder(){
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(
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;
}
}
}
【利用 android mediaRecorder c++类进行视频编码】本文出自 “龙骑舞” 博客,请务必保留此出处http://westfisher.blog.51cto.com/3396434/1945121
推荐阅读
- Android 如何让EditText不自动获取焦点
- Android 游标
- android之GMS认证
- webservice有关application/xop+xml的异常
- netapp网络接口聚合的3种模式
- 一键将Web应用发布到云-Azure Web App
- Another app is currently holding the yum lock; waiting for it to exit 解决方法
- Android之Activity之间传递对象
- Mybatis Mapper.java和Mapper.xml能否分离问题