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

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

调用关系图:

startRecording:

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

classMediaRecorder : public BnMediaRecorderClient,

public virtualIMediaDeathNotifier

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

(关于的声明sp<IMediaRecorder>          mMediaRecorder;)

mMediaRecorder =service->createMediaRecorder(opPackageName);

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

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

  1. 最后根据远端的reply来创建本地对应的对象

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

  1. 后续的方法都通过BpMediaRecorder(remote)来发送到BnMediaRecorder操作。
  2. a)      BnMediaRecorder继承了BnInterface<IMediaRecorder>,并实现了ontransact

classBnMediaRecorder: publicBnInterface<IMediaRecorder>

{

public:

virtual status_t    onTransact( uint32_t code,

constParcel& data,

Parcel*reply,

uint32_tflags = 0);

};

  1. 在这个方法里,每个操作都有对应的处理分支
  2. c)       BnMediaRecorder是个虚函数,具体工作由MediaRecorderClient 来完成:MediaRecorderClient : public BnMediaRecorder
  3. class BpMediaRecorder: public BpInterface<IMediaRecorder>

在对应的方法中最后都通过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这个类,每一项任务都要它来完成

在MediaRecorderClient的构造函数中可以看到

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中调用StagefrightRecorder::prepareInternal()

在这里根据输出编码设定,选择对应的编码器进行初始化。

我们以OUTPUT_FORMAT_MPEG_4为例进行分析

根据输出格式进入setupMPEG4orWEBMRecording()

  1. setupMPEG4orWEBMRecording()

在这里创建了MPEG4Writer

  1. writer = mp4writer =AVFactory::get()->CreateMPEG4Writer(mOutputFd);
  2. setupMediaSource将camera指定为encoder的input source
  3. sp<MediaSource> encoder;

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

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

  1. sp<MediaCodecSource> encoder

=MediaCodecSource::Create(

mLooper,

format,

cameraSource,

mPersistentSurface,

  1. ;

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

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;

}

}

}

时间: 2024-10-13 11:10:46

利用 android mediaRecorder c++类进行视频编码的相关文章

Android:通过ThumbnailUtils类获取视频文件的缩略图

在视频播放器上经常会看到,有很多的视频缩略图,本文讲的就是通过ThumbnailUtils类获取视频文件的缩略图; 运行截图如下: 代码如下: MainActivity.java: package com.vrinux.thumbnailutilsdemo; import android.app.Activity; import android.graphics.Bitmap; import android.media.ThumbnailUtils; import android.os.Bund

Android之使用MediaMetadataRetriever类获取视频第一帧

一.首先,来介绍一下MediaMetadataRetriever类,此类位于android.media包下,这里,先附上可查看此类的API地址:MediaMetadataRetriever类.大家能够自行查看. 1.MediaMetadataRetriever类概述:MediaMetadataRetriever class provides a unified interface for retrieving frame and meta data from an input media fil

Jquery Mobile实例--利用优酷JSON接口读取视频数据

本文将介绍,如何利用JqueryMobile调用优酷API JSON接口显示视频数据. (1)注册用户接口. 首页,到 http://open.youku.com 注册一个账户,并通过验证.然后找到API接口 (http://open.youku.com/docs/tech_doc.html) 可以看到优酷提供不少API,本文将演示“通过视频关键词”接口. 点击进去后,会发现client_id和keyword是必填的,因此,未来构造的URL应该类似 https://openapi.youku.c

音视频编码基础知识

本文转载自 http://blog.csdn.net/ljzcom/article/details/7336258 ,如有需要,请移步查看. Technorati 标签: 音视频 编码 基础知识 --------------------------------分割线开始----------------------------------------------- 编解码学习笔记(一):基本概念 媒体业务是网络的主要业务之间.尤其移动互联网业务的兴起,在运营商和应用开发商中,媒体业务份量极重,其中

3D-HEVC视频编码技术

3D-HEVC编码框架 3D-HEVC编码结构是对HEVC的扩展,每个视点纹理及深度图编码主要采用HEVC编码框架,但在其基础上增加了一些新的编码技术,使其更有利于深度图和多视点的编码. 图1 3D-HEVC编码结构 如上图所示,3D-HEVC编解码结构和MVC类似.图中所有输入的视频图像和深度图像是同一时刻,不同拍摄位置的场景,这些图像组成一个存取层.在同一个存取层中,首先对独立视点(基准视点)编码,接着是该视点的深度图,再编码其他视点视频图像和深度图.原理上来说,每个视点的图像,包括视频图像

Android 系统工具类SystemUtils收集整理(持续更新)

最近做的功能中涉及到了一些关于系统方面的东西,自己摸索以及网上搜集整理出来了一个工具类方便调用 包含的功能有: 获取系统中所有APP应用.获取用户安装的APP应用.根据包名和Activity启动类查询应用信息.跳转到WIFI设置.WIFI网络开关.移动网络开关.GPS开关 当前若关则打开 当前若开则关闭.调节系统音量.设置亮度.获取屏幕的亮度.跳转到系统设置.获取文件夹下所有文件.获取视频的缩略图 .打开视频文件... 工具类会持续更新,与大家共同学习进步. SystemUtils.java p

视频编码未来简史

转自:http://blog.csdn.net/agora_cloud/article/details/78136259 首先我们回顾一下视频编码的历史,视频编码起源于广播电视,在很长一段时间里视频编解码的变革主要推动力是来自于广播电视.当然,今天我们看互联网的视频编码是速度越来越快,昨天在ICET2017年世界大会上,ICET的主席还说到以前一个编码是十年更新一版,但是现在从H.265最新进展的来看,可能不到十年. 我们看到这个图,大家可能在小的时候见到过,电视上一个圆盘,这是最主要的电视测试

转 常见视频编码方式以及封装格式

常见视频编码方式以及封装格式 常见视频编码方式 所谓视频编码方式就是指通过特定的压缩技术,将某个视频格式的文件转换成另一种视频格式文件的方式.视频流传输中最为重要的编解码标准有国际电联的H.261.H.263.H.264.H.265,运动静止图像专家组的M-JPEG和国际标准化组织运动图像专家组的MPEG系列标准,此外在互联网上被广泛应用的还有Real-Networks的RealVideo.微软公司的WMV以及Apple公司的QuickTime等. AVI AVI 是 Audio Video I

视频编码与封装方式详解

http://blog.csdn.net/attilax/article/details/5807047 1.    编码方式和封装格式    1 2.    视频编码标准两大系统    2 MPEG-1. 2 MPEG-2. 3 MPEG-3. 3 MPEG-4. 3 ITU-T. 4 WMV.. 4 3.    常用视频编码方式有Xvid( 4 4.    常见存储封装格式    6 5.    几种常见的转换格式设置    7 6.    无损视频编码    9 1.   编码方式和封装格