利用androidmediaRecorderc++類進(jìn)行視頻編碼

本例中media source為camera。(學(xué)習(xí)的平臺(tái)是android sdk6.0)

網(wǎng)站建設(shè)哪家好,找創(chuàng)新互聯(lián)公司!專注于網(wǎng)頁設(shè)計(jì)、網(wǎng)站建設(shè)、微信開發(fā)、小程序制作、集團(tuán)企業(yè)網(wǎng)站建設(shè)等服務(wù)項(xiàng)目。為回饋新老客戶創(chuàng)新互聯(lián)還提供了清水河免費(fèi)建站歡迎大家使用!

調(diào)用關(guān)系圖:

startRecording:

  1. recorder = New MediaRecorder(String16());

classMediaRecorder : public BnMediaRecorderClient,

                      public virtualIMediaDeathNotifier

  1. 在創(chuàng)建mediaRecorder的時(shí)侯,我們先獲取IMediaPlayerService指針,然后再創(chuàng)建IMediaRecorder

(關(guān)于的聲明sp<IMediaRecorder>          mMediaRecorder;)

        mMediaRecorder =service->createMediaRecorder(opPackageName);

 

  1. 在service->createMediaRecorder中會(huì)先把對(duì)象IMediaPlayerService序列話(利用data打包),然后把請(qǐng)求CREATE_MEDIA_RECORDER發(fā)送給remote(就是bpbinder)處理

remote()->transact(CREATE_MEDIA_RECORDER, data,&reply);

  1. 最后根據(jù)遠(yuǎn)端的reply來創(chuàng)建本地對(duì)應(yīng)的對(duì)象

interface_cast<IMediaRecorder>(reply.readStrongBinder());

  1. 后續(xù)的方法都通過BpMediaRecorder(remote)來發(fā)送到BnMediaRecorder操作。

  2. 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);

};

  1. 在這個(gè)方法里,每個(gè)操作都有對(duì)應(yīng)的處理分支

  2. c)       BnMediaRecorder是個(gè)虛函數(shù),具體工作由MediaRecorderClient來完成:MediaRecorderClient : public BnMediaRecorder

  3. class BpMediaRecorder: public BpInterface<IMediaRecorder>

在對(duì)應(yīng)的方法中最后都通過remote送給Bn處理,如:

Parceldata, reply;

data.writeInterfaceToken(IMediaRecorder::getInterfaceDescriptor());

data.writeString8(params);

    remote()->transact(SET_PARAMETERS,data, &reply);

  1. recorder->setParameters(…….)

  2. recorder->prepare()

  3. recorder->start()

  4. 3.     在MediaRecorderClient中封裝了MediaRecorderBase這個(gè)類,每一項(xiàng)任務(wù)都要它來完成

在MediaRecorderClient的構(gòu)造函數(shù)中可以看到

   mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);

  1. 因此,具體的工作由StagefrightRecorder來完成

  2. 在AVMediaServiceFactory.cpp中

StagefrightRecorder*AVMediaServiceFactory::createStagefrightRecorder(

        const String16 &opPackageName) {

    return newStagefrightRecorder(opPackageName);

}

  1. StagefrightRecorder  recorder->start()

在prepare中或者start中調(diào)用StagefrightRecorder::prepareInternal()

在這里根據(jù)輸出編碼設(shè)定,選擇對(duì)應(yīng)的編碼器進(jìn)行初始化。

我們以O(shè)UTPUT_FORMAT_MPEG_4為例進(jìn)行分析

根據(jù)輸出格式進(jìn)入setupMPEG4orWEBMRecording()

  1. setupMPEG4orWEBMRecording()

在這里創(chuàng)建了MPEG4Writer

  1. writer = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);

  2. setupMediaSource將camera指定為encoder的input source

  3. sp<MediaSource> encoder;

err = setupVideoEncoder(mediaSource, &encoder);創(chuàng)建encoder

  1. 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);

  1.     sp<MediaCodecSource> encoder

=MediaCodecSource::Create(             

mLooper,

 format,

cameraSource,

 mPersistentSurface,

  1. ;

在create函數(shù)中先new一個(gè)對(duì)象,

   sp<MediaCodecSource> mediaSource =

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

 

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

       return mediaSource;

    }

  1. MediaCodecSource::init()

status_t err = initEncoder();

  1. 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();

  1.   MediaCodec::CreateByType(

mCodecLooper, outputMIME.c_str(), true /* encoder */) {

            sp<MediaCodec> codec = new MediaCodec(looper, pid);

 

    const status_tret = codec->init(mime, true /* nameIsType */, encoder);

}

 

  1. 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;

        }

    }

}

分享標(biāo)題:利用androidmediaRecorderc++類進(jìn)行視頻編碼
分享鏈接:http://bm7419.com/article20/jdijco.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供軟件開發(fā)動(dòng)態(tài)網(wǎng)站、網(wǎng)頁設(shè)計(jì)公司、手機(jī)網(wǎng)站建設(shè)、企業(yè)網(wǎng)站制作微信公眾號(hào)

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

營(yíng)銷型網(wǎng)站建設(shè)