android av media,利用 android mediaRecorder c++类进行视频编码

本例中media source为camera。(学习的平台是android sdk6.0)

调用关系图:

startRecording:recorder = New MediaRecorder(String16());

classMediaRecorder : public BnMediaRecorderClient,

public virtualIMediaDeathNotifier在创建mediaRecorder的时侯,我们先获取IMediaPlayerService指针,然后再创建IMediaRecorder

(关于的声明sp          mMediaRecorder;)

mMediaRecorder =service->createMediaRecorder(opPackageName);

在service->createMediaRecorder中会先把对象IMediaPlayerService序列话(利用data打包),然后把请求CREATE_MEDIA_RECORDER发送给remote(就是bpbinder)处理

remote()->transact(CREATE_MEDIA_RECORDER, data,&reply);最后根据远端的reply来创建本地对应的对象

interface_cast(reply.readStrongBinder());后续的方法都通过BpMediaRecorder(remote)来发送到BnMediaRecorder操作。

a)BnMediaRecorder继承了BnInterface,并实现了ontransact

classBnMediaRecorder: publicBnInterface

{

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

在对应的方法中最后都通过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()

在这里创建了MPEG4Writerwriter = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);

setupMediaSource将camera指定为encoder的input source

sp encoder;

err = setupVideoEncoder(mediaSource, &encoder);创建encodersetupVideoEncoder(mediaSource,&encoder);

首先将camera中的各项参数设定读出来设入到encoder中(camera为null则使用default值)

spmeta = 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 encoder =MediaCodecSource::Create(

mLooper, format, cameraSource,mPersistentSurface, flags);sp encoder

=MediaCodecSource::Create(

mLooper,

format,

cameraSource,

mPersistentSurface,;

在create函数中先new一个对象,

sp mediaSource =

new MediaCodecSource(looper, format, source, consumer, flags);

if (mediaSource->init() == OK) {

return mediaSource;

}MediaCodecSource::init()

status_t err = initEncoder();initEncoder(){

mReflector = new AHandlerReflector(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 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 msg = newAMessage(kWhatInit, this);

msg->setString("name", name);

msg->setInt32("nameIsType",nameIsType);

if (nameIsType) {

msg->setInt32("encoder",encoder);

}

status_t err;

Vector 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 response;

err = PostAndAwaitResponse(msg,&response);

if (!isResourceError(err)) {

break;

}

}

}

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值