зеркало из https://github.com/mozilla/gecko-dev.git
Bug 963502 - [MediaEncoder] OMXAudioEncoder will be out of input buffers if input segment is too big. r=roc
This commit is contained in:
Родитель
dd066d6108
Коммит
32620ae17c
|
@ -207,8 +207,6 @@ OmxAudioTrackEncoder::AppendEncodedFrames(EncodedFrameContainer& aContainer)
|
|||
isCSD = true;
|
||||
} else if (outFlags & OMXCodecWrapper::BUFFER_EOS) { // last frame
|
||||
mEncodingComplete = true;
|
||||
} else {
|
||||
MOZ_ASSERT(frameData.Length() == OMXCodecWrapper::kAACFrameSize);
|
||||
}
|
||||
|
||||
nsRefPtr<EncodedFrame> audiodata = new EncodedFrame();
|
||||
|
@ -243,19 +241,31 @@ OmxAudioTrackEncoder::GetEncodedTrack(EncodedFrameContainer& aData)
|
|||
segment.AppendFrom(&mRawSegment);
|
||||
}
|
||||
|
||||
if (!mEosSetInEncoder) {
|
||||
if (mEndOfStream) {
|
||||
nsresult rv;
|
||||
if (segment.GetDuration() == 0) {
|
||||
// Notify EOS at least once, even if segment is empty.
|
||||
if (mEndOfStream && !mEosSetInEncoder) {
|
||||
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);
|
||||
rv = mEncoder->Encode(segment, OMXCodecWrapper::BUFFER_EOS);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
// Nothing to encode but encoder could still have encoded data for earlier
|
||||
// input.
|
||||
return AppendEncodedFrames(aData);
|
||||
}
|
||||
|
||||
return AppendEncodedFrames(aData);
|
||||
// OMX encoder has limited input buffers only so we have to feed input and get
|
||||
// output more than once if there are too many samples pending in segment.
|
||||
while (segment.GetDuration() > 0) {
|
||||
rv = mEncoder->Encode(segment,
|
||||
mEndOfStream ? OMXCodecWrapper::BUFFER_EOS : 0);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
|
||||
rv = AppendEncodedFrames(aData);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -420,7 +420,7 @@ private:
|
|||
};
|
||||
|
||||
nsresult
|
||||
OMXAudioEncoder::Encode(const AudioSegment& aSegment, int aInputFlags)
|
||||
OMXAudioEncoder::Encode(AudioSegment& aSegment, int aInputFlags)
|
||||
{
|
||||
#ifndef MOZ_SAMPLE_TYPE_S16
|
||||
#error MediaCodec accepts only 16-bit PCM data.
|
||||
|
@ -433,6 +433,11 @@ OMXAudioEncoder::Encode(const AudioSegment& aSegment, int aInputFlags)
|
|||
// Get input buffer.
|
||||
InputBufferHelper buffer(mCodec, mInputBufs);
|
||||
status_t result = buffer.Dequeue();
|
||||
if (result == -EAGAIN) {
|
||||
// All input buffers are full. Caller can try again later after consuming
|
||||
// some output buffers.
|
||||
return NS_OK;
|
||||
}
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
size_t samplesCopied = 0; // Number of copied samples.
|
||||
|
@ -448,14 +453,20 @@ OMXAudioEncoder::Encode(const AudioSegment& aSegment, int aInputFlags)
|
|||
if (bytesToCopy > buffer.AvailableSize()) {
|
||||
// Not enough space left in input buffer. Send it to encoder and get a
|
||||
// new one.
|
||||
// Don't signal EOS since there is more data to copy.
|
||||
result = buffer.Enqueue(mTimestamp, aInputFlags & ~BUFFER_EOS);
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
result = buffer.Dequeue();
|
||||
if (result == -EAGAIN) {
|
||||
// All input buffers are full. Caller can try again later after
|
||||
// consuming some output buffers.
|
||||
aSegment.RemoveLeading(samplesCopied);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
mTimestamp += samplesCopied * mSampleDuration;
|
||||
samplesCopied = 0;
|
||||
|
||||
result = buffer.Dequeue();
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
}
|
||||
|
||||
|
@ -473,6 +484,9 @@ OMXAudioEncoder::Encode(const AudioSegment& aSegment, int aInputFlags)
|
|||
buffer.IncreaseOffset(bytesToCopy);
|
||||
iter.Next();
|
||||
}
|
||||
if (samplesCopied > 0) {
|
||||
aSegment.RemoveLeading(samplesCopied);
|
||||
}
|
||||
} else if (aInputFlags & BUFFER_EOS) {
|
||||
// No audio data left in segment but we still have to feed something to
|
||||
// MediaCodec in order to notify EOS.
|
||||
|
@ -483,7 +497,12 @@ OMXAudioEncoder::Encode(const AudioSegment& aSegment, int aInputFlags)
|
|||
}
|
||||
|
||||
if (samplesCopied > 0) {
|
||||
result = buffer.Enqueue(mTimestamp, aInputFlags);
|
||||
int flags = aInputFlags;
|
||||
if (aSegment.GetDuration() > 0) {
|
||||
// Don't signal EOS until source segment is empty.
|
||||
flags &= ~BUFFER_EOS;
|
||||
}
|
||||
result = buffer.Enqueue(mTimestamp, flags);
|
||||
NS_ENSURE_TRUE(result == OK, NS_ERROR_FAILURE);
|
||||
|
||||
mTimestamp += samplesCopied * mSampleDuration;
|
||||
|
|
|
@ -177,9 +177,11 @@ public:
|
|||
|
||||
/**
|
||||
* Encode 16-bit PCM audio samples stored in aSegment. To notify end of
|
||||
* stream, set aInputFlags to BUFFER_EOS.
|
||||
* stream, set aInputFlags to BUFFER_EOS. Since encoder has limited buffers,
|
||||
* this function might not be able to encode all chunks in one call, however
|
||||
* it will remove chunks it consumes from aSegment.
|
||||
*/
|
||||
nsresult Encode(const mozilla::AudioSegment& aSegment, int aInputFlags = 0);
|
||||
nsresult Encode(mozilla::AudioSegment& aSegment, int aInputFlags = 0);
|
||||
|
||||
protected:
|
||||
virtual status_t AppendDecoderConfig(nsTArray<uint8_t>* aOutputBuf,
|
||||
|
|
Загрузка…
Ссылка в новой задаче