前面调用了 mRecorder.prepare(); ,准备好了一切之后,现在调用start()函数,开始录制。
mRecorder.start();
status_t StagefrightRecorder::start() {
ALOGV("start");
if (mOutputFd < 0) {
ALOGE("Output file descriptor is invalid");
return INVALID_OPERATION;
}
status_t status = OK;
//如果mVideoSource==VIDEO_SOURCE_SURFACE,则*mediaSource = NULL;
if (mVideoSource != VIDEO_SOURCE_SURFACE) {
status = prepareInternal();
if (status != OK) {
return status;
}
}
//当然mWriter不能为NULL
if (mWriter == NULL) {
ALOGE("File writer is not avaialble");
return UNKNOWN_ERROR;
}
switch (mOutputFormat) {
.....
case OUTPUT_FORMAT_AMR_NB:
case OUTPUT_FORMAT_AMR_WB:
case OUTPUT_FORMAT_AAC_ADIF:
case OUTPUT_FORMAT_AAC_ADTS:
case OUTPUT_FORMAT_RTP_AVP:
case OUTPUT_FORMAT_MPEG2TS:
{
//重点就是这里,调用writer.start()函数去开始录制
status = mWriter->start();
break;
}
default:
{
ALOGE("Unsupported output file format: %d", mOutputFormat);
status = UNKNOWN_ERROR;
break;
}
}
.....
return status;
}
重点看到这里:
status_t err = mSource->start();
这个mSource对象,是前面这个位置赋值的:
status_t MPEG2TSWriter::addSource(const sp<IMediaSource> &source) {
CHECK(!mStarted);
sp<MetaData> meta = source->getFormat();
const char *mime;
CHECK(meta->findCString(kKeyMIMEType, &mime));
if (strcasecmp(mime, MEDIA_MIMETYPE_VIDEO_AVC)
&& strcasecmp(mime, MEDIA_MIMETYPE_AUDIO_AAC)) {
return ERROR_UNSUPPORTED;
}
//addSource的时候,sp 指向了audioSource,和cameraSource
sp<SourceInfo> info = new SourceInfo(source);
mSources.push(info);
return OK;
}
MPEG2TSWriter::SourceInfo::SourceInfo(const sp<IMediaSource> &source)
: mSource(source),
mLooper(new ALooper),
mEOSReceived(false),
mStreamType(0),
mContinuityCounter(0) {
mLooper->setName("MPEG2TSWriter source");
所以我们的status_t err = mSource->start();
会call到MediaCodecSource::start
status_t MediaCodecSource::start(MetaData* params) {
//抛了一个kWhatStart的消息出去
sp<AMessage> msg = new AMessage(kWhatStart, mReflector);
msg->setObject("meta", params);
return postSynchronouslyAndReturnError(msg);
}
这个flow跟到后面,会引入一个puller的东西,这个其实就是一个继承自AHandler的东西。
还记得MediaRecorder系列之StagefrightRecorder录制TS流flow(一),最后要留意的一个东西吗?
//这里重点记住一下,MediaCodecSource把我们前面传过来的audioSource,cameraSource,给了mPuller构造函数做参数
if (!(mFlags & FLAG_USE_SURFACE_INPUT)) {
mPuller = new Puller(source);
}
MediaCodecSource::Puller::Puller(const sp<MediaSource> &source)
: mSource(source),
mLooper(new ALooper()),
mIsAudio(false)
这mSource
即指向了audioSource和CameraSource,在kWhatStart的handle中,call了自己的start函数。
mSource->start(static_cast(obj.get()));
接下来就要跑入audioSource和CameraSource各自的start函数中了,这个放到后面的章节中说~