通过一个简单的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);
}
今天就到这吧,有时间可以继续往下跟...