Bug 879668 - Part 5: Add OmxAudioTrackEncoder to file OmxTrackEncoder. r=roc

This commit is contained in:
John Lin 2014-01-17 14:30:13 -05:00
parent fa29418b0a
commit da86bab01e
2 changed files with 134 additions and 1 deletions

View File

@ -147,4 +147,115 @@ OmxVideoTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
return NS_OK;
}
nsresult
OmxAudioTrackEncoder::Init(int aChannels, int aSamplingRate)
{
mChannels = aChannels;
mSamplingRate = aSamplingRate;
mEncoder = OMXCodecWrapper::CreateAACEncoder();
NS_ENSURE_TRUE(mEncoder, NS_ERROR_FAILURE);
nsresult rv = mEncoder->Configure(mChannels, mSamplingRate);
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mInitialized = (rv == NS_OK);
mReentrantMonitor.NotifyAll();
return NS_OK;
}
already_AddRefed<TrackMetadataBase>
OmxAudioTrackEncoder::GetMetadata()
{
{
// Wait if mEncoder is not initialized nor is being canceled.
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
while (!mCanceled && !mInitialized) {
mReentrantMonitor.Wait();
}
}
if (mCanceled || mEncodingComplete) {
return nullptr;
}
nsRefPtr<AACTrackMetadata> meta = new AACTrackMetadata();
meta->Channels = mChannels;
meta->SampleRate = mSamplingRate;
meta->FrameSize = OMXCodecWrapper::kAACFrameSize;
meta->FrameDuration = OMXCodecWrapper::kAACFrameDuration;
return meta.forget();
}
nsresult
OmxAudioTrackEncoder::AppendEncodedFrames(EncodedFrameContainer& aContainer)
{
nsTArray<uint8_t> frameData;
int outFlags = 0;
int64_t outTimeUs = -1;
nsresult rv = mEncoder->GetNextEncodedFrame(&frameData, &outTimeUs, &outFlags,
3000); // wait up to 3ms
NS_ENSURE_SUCCESS(rv, rv);
if (!frameData.IsEmpty()) {
bool isCSD = false;
if (outFlags & OMXCodecWrapper::BUFFER_CODEC_CONFIG) { // codec specific data
isCSD = true;
} else if (outFlags & OMXCodecWrapper::BUFFER_EOS) { // last frame
mEncodingComplete = true;
} else {
MOZ_ASSERT(frameData.Length() == OMXCodecWrapper::kAACFrameSize);
}
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
audiodata->SetFrameType(isCSD ?
EncodedFrame::AAC_CSD : EncodedFrame::AUDIO_FRAME);
audiodata->SetTimeStamp(outTimeUs);
audiodata->SetFrameData(&frameData);
aContainer.AppendEncodedFrame(audiodata);
}
return NS_OK;
}
nsresult
OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
{
AudioSegment segment;
// Move all the samples from mRawSegment to segment. We only hold
// the monitor in this block.
{
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
// Wait if mEncoder is not initialized nor canceled.
while (!mInitialized && !mCanceled) {
mReentrantMonitor.Wait();
}
if (mCanceled || mEncodingComplete) {
return NS_ERROR_FAILURE;
}
segment.AppendFrom(&mRawSegment);
}
if (!mEosSetInEncoder) {
if (mEndOfStream) {
mEosSetInEncoder = true;
}
if (segment.GetDuration() > 0 || mEndOfStream) {
// Notify EOS at least once, even when segment is empty.
nsresult rv = mEncoder->Encode(segment,
mEndOfStream ? OMXCodecWrapper::BUFFER_EOS : 0);
NS_ENSURE_SUCCESS(rv, rv);
}
}
return AppendEncodedFrames(aData);
}
}

View File

@ -10,12 +10,13 @@
namespace android {
class OMXVideoEncoder;
class OMXAudioEncoder;
}
/**
* There are two major classes defined in file OmxTrackEncoder;
* OmxVideoTrackEncoder and OmxAudioTrackEncoder, the video and audio track
* encoder for media type AVC/h.264 and AAC. OMXCodecWrapper wraps and controls
* encoder for media type AVC/H.264 and AAC. OMXCodecWrapper wraps and controls
* an instance of MediaCodec, defined in libstagefright, runs on Android Jelly
* Bean platform.
*/
@ -40,5 +41,26 @@ private:
nsAutoPtr<android::OMXVideoEncoder> mEncoder;
};
class OmxAudioTrackEncoder MOZ_FINAL : public AudioTrackEncoder
{
public:
OmxAudioTrackEncoder()
: AudioTrackEncoder()
{}
already_AddRefed<TrackMetadataBase> GetMetadata() MOZ_OVERRIDE;
nsresult GetEncodedTrack(EncodedFrameContainer& aData) MOZ_OVERRIDE;
protected:
nsresult Init(int aChannels, int aSamplingRate) MOZ_OVERRIDE;
private:
// Append encoded frames to aContainer.
nsresult AppendEncodedFrames(EncodedFrameContainer& aContainer);
nsAutoPtr<android::OMXAudioEncoder> mEncoder;
};
}
#endif