Android MediaRecorder调用AudioRecord流程
2023-09-14 09:09:54 时间
通过一个简单的api来看下调用流程,就看MediaRecorder类的setAudioChannels()设置通道数的方法.
废话不多说,直接来看流程.
栗子:
MediaRecorder mRecorder = new MediaRecorder();
mRecorder.setAudioChannels(mChannels);
1.frameworks/base/media/java/android/media/MediaRecorder.java
public void setAudioChannels(int numChannels) {
setParameter("audio-param-number-of-channels=" + numChannels);
}
private native void setParameter(String nameValuePair);
2.frameworks/base/media/jni/android_media_MediaRecorder.cpp
static void android_media_MediaRecorder_setParameter(JNIEnv *env, jobject thiz, jstring params){
sp<MediaRecorder> mr = getMediaRecorder(env, thiz);
process_media_recorder_call(env, mr->setParameters(String8(params8)), "java/lang/RuntimeException", "setParameter failed.");
}
3.
<1>.frameworks/av/include/media/mediarecorder.h
class MediaRecorder : public BnMediaRecorderClient, public virtual IMediaDeathNotifier{
sp<IMediaRecorder> mMediaRecorder;
}
<2>.frameworks/av/media/libmedia/mediarecorder.cpp
MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL){
const sp<IMediaPlayerService> service(getMediaPlayerService());
mMediaRecorder = service->createMediaRecorder(opPackageName);
}
status_t MediaRecorder::setParameters(const String8& params) {
status_t ret = mMediaRecorder->setParameters(params);
}
4.frameworks/av/media/libmedia/IMediaDeathNotifier.cpp
//Binder通信
<1>.const sp<IMediaPlayerService> IMediaDeathNotifier::getMediaPlayerService(){
sMediaPlayerService == 0;
sp<IServiceManager> sm = defaultServiceManager();
sp<IBinder> binder;
//此处为代理获取media.player对应的服务
binder = sm->getService(String16("media.player"));
sMediaPlayerService = interface_cast<IMediaPlayerService>(binder);
}
<2>.frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
void MediaPlayerService::instantiate() {
//添加media.player字符串对应的MediaPlayerService服务
defaultServiceManager()->addService(String16("media.player"), new
MediaPlayerService());
}
}
<3>.frameworks/av/media/mediaserver/main_mediaserver.cpp
int main(int argc __unused, char **argv __unused){
//启动MediaPlayerService服务
MediaPlayerService::instantiate();
ResourceManagerService::instantiate();
//启动线程池
ProcessState::self()->startThreadPool();
//添加到线程池
IPCThreadState::self()->joinThreadPool();
}
<4>.frameworks/av/media/libmedia/mediarecorder.cpp
接着上边继续追service->createMediaRecorder()
MediaRecorder::MediaRecorder(const String16& opPackageName) : mSurfaceMediaSource(NULL){
const sp<IMediaPlayerService> service(getMediaPlayerService());
mMediaRecorder = service->createMediaRecorder(opPackageName);
}
5.frameworks/av/media/libmediaplayerservice/MediaPlayerService.cpp
sp<IMediaRecorder> MediaPlayerService::createMediaRecorder(const String16 &opPackageName){
sp<MediaRecorderClient> recorder = new MediaRecorderClient(this, pid, opPackageName);
wp<MediaRecorderClient> w = recorder;
mMediaRecorderClients.add(w);
return recorder;
}
6.frameworks/av/media/libmediaplayerservice/MediaRecorderClient.cpp
MediaRecorderClient::MediaRecorderClient(const sp<MediaPlayerService>& service, pid_t
pid, const String16& opPackageName){
mRecorder = AVMediaServiceFactory::get()->createStagefrightRecorder(opPackageName);
mMediaPlayerService = service;
}
7.frameworks/av/media/libavextensions/mediaplayerservice/AVMediaServiceFactory.cpp
StagefrightRecorder *AVMediaServiceFactory::createStagefrightRecorder(const String16
&opPackageName) {
return new StagefrightRecorder(opPackageName);
}
8.frameworks/av/media/libmediaplayerservice/StagefrightRecorder.cpp
<1>.构造函数
StagefrightRecorder::StagefrightRecorder(const String16 &opPackageName)
: MediaRecorderBase(opPackageName),
mWriter(NULL), mOutputFd(-1), mAudioSource(AUDIO_SOURCE_CNT),
mVideoSource(VIDEO_SOURCE_LIST_END),mStarted(false)
{
ALOGV("Constructor");
reset();
}
注意:所以frameworks/av/media/libmedia/mediarecorder.cpp里的
mMediaRecorder->setParameters(params);调用的是StagefrightRecorder.cpp里的
<2>.status_t StagefrightRecorder::setParameters(const String8 ¶ms){
const char *cparams = params.string();
const char *key_start = cparams;
String8 key(key_start, equal_pos - key_start);
setParameter(key, value);
}
<3>.status_t StagefrightRecorder::setParameter(const String8 &key, const String8 &value)
{
//由上文得出,走此分支
else if (key == "audio-param-number-of-channels") {
int32_t number_of_channels;
if (safe_strtoi32(value.string(), &number_of_channels)) {
return setParamAudioNumberOfChannels(number_of_channels);
}
}
}
<4>.status_t StagefrightRecorder::setParamAudioNumberOfChannels(int32_t channels) {
mAudioChannels = channels;//将mAudioChannels传出来
}
<5>.sp<MediaCodecSource> StagefrightRecorder::createAudioSource() {
sp<AudioSource> audioSource = AVFactory::get()->createAudioSource(
mAudioSource,
mOpPackageName,
sourceSampleRate,
mAudioChannels,
mSampleRate,
mClientUid,
mClientPid);
}
9.frameworks/av/media/libavextensions/stagefright/AVFactory.cpp
AudioSource* AVFactory::createAudioSource(audio_source_t inputSource,
const String16 &opPackageName,
uint32_t sampleRate,
uint32_t channels,
uint32_t outSampleRate,
uid_t clientUid,
pid_t clientPid) {
return new AudioSource(inputSource, opPackageName, sampleRate,
channels, outSampleRate, clientUid, clientPid);
}
10.frameworks/av/media/libstagefright/AudioSource.cpp
AudioSource::AudioSource( audio_source_t inputSource, const String16 &opPackageName,
uint32_t sampleRate, uint32_t channelCount, uint32_t outSampleRate,
uid_t uid, pid_t pid)
{
status_t status = AudioRecord::getMinFrameCount(&minFrameCount,
sampleRate,
AUDIO_FORMAT_PCM_16_BIT,
audio_channel_in_mask_from_count(channelCount));
mRecord = new AudioRecord(
inputSource, sampleRate, AUDIO_FORMAT_PCM_16_BIT,
audio_channel_in_mask_from_count(channelCount),
opPackageName,
(size_t) (bufCount * frameCount),
AudioRecordCallbackFunction,
this,
frameCount /*notificationFrames*/,
AUDIO_SESSION_ALLOCATE,
AudioRecord::TRANSFER_DEFAULT,
AUDIO_INPUT_FLAG_NONE,
uid,
pid);
}
11.frameworks/av/media/libmedia/AudioRecord.cpp
AudioRecord::AudioRecord( audio_source_t inputSource,
uint32_t sampleRate,
audio_format_t format,
audio_channel_mask_t channelMask,
const String16& opPackageName,
size_t frameCount,
callback_t cbf,
void* user,
uint32_t notificationFrames,
audio_session_t sessionId,
transfer_type transferType,
audio_input_flags_t flags,
int uid,
pid_t pid,
const audio_attributes_t* pAttributes){
set(inputSource, sampleRate, format, channelMask, frameCount, cbf, user,
notificationFrames, false /*threadCanCallJava*/, sessionId, transferType,
flags, uid, pid, pAttributes);
}
今天就到这吧,有时间可以继续往下跟...
相关文章
- Android中View绘制流程以及invalidate()等相关方法分析
- Android中View绘制流程以及invalidate()等相关方法分析
- EasyPlayerPro安卓流媒体播放器实现Android H.265硬解码流程
- Weex Android Border绘制
- android:整理drawable(余下的)(三)
- Android GIS开发系列-- 入门季(14)FeatureLayer之范围查询
- android Recovery流程整理
- android启动流程本地阶段
- Android图形显示系统——一张图片的显示流程
- Android 9.0 代码实现对屏幕亮屏和灭屏的控制和显示电量百分比
- android 9.0 10.0 添加自定义系统服务接口给app调用
- Android Gradle动态打32位或者64位的包
- 【Android 逆向】加壳的 Android 应用启动流程 | 使用反射替换 LoadedApk 中的类加载器流程
- 【Android 逆向】APK 加壳脱壳现状 | 判断 APK 是否加壳 | APK 逆向流程
- 【Android 逆向】函数拦截实例 ( 函数拦截流程 | ① 定位动态库及函数位置 )
- 【Android 逆向】Android 进程代码注入原理 ( 进程注入原理 | 远程调用流程 | 获取函数地址 | 设置 IP 寄存器 | mmap 申请内存 | 设置 SP 寄存器 )
- 【Android 安装包优化】APK 打包流程 ( 文件结构 | 打包流程 | 安装流程 | 安卓虚拟机 )
- 【Android 安装包优化】资源混淆 ( 资源混淆效果 | APK 构建流程简介 | 资源 ID 组成 )
- Android Studio 经常使用功能介绍
- Android 儿子Activity在启动过程中的流程组件 && 儿子Activity在一个新的进程组件启动过程
- android:onClick="xxx"
- Android面试复习框架及题型解析,最新Android中高级面试题合集
- 【Android-JetpackCompose】4、可组合项的生命周期、@Composable 修饰符、附带效应
- Android Camera 运行流程
- Android之style样式文件的编写