Bug 935774 - Assertion failure: meta in mozilla::MediaEncoder::GetEncodedData. r=roc

This commit is contained in:
Randy Lin 2013-11-20 17:14:13 +08:00
parent 2fe52b1b3a
commit 4e505b7361
6 changed files with 45 additions and 18 deletions

View File

@ -79,11 +79,13 @@ class MediaRecorder::Session: public nsIObserver
MOZ_ASSERT(NS_IsMainThread());
MediaRecorder *recorder = mSession->mRecorder;
if (mSession->IsEncoderError()) {
recorder->NotifyError(NS_ERROR_UNEXPECTED);
}
nsresult rv = recorder->CreateAndDispatchBlobEvent(mSession);
if (NS_FAILED(rv)) {
recorder->NotifyError(rv);
}
return NS_OK;
}
@ -225,6 +227,13 @@ public:
return mEncodedBufferCache->ExtractBlob(mimeType);
}
bool IsEncoderError()
{
if (mEncoder && mEncoder->HasError()) {
return true;
}
return false;
}
private:
// Pull encoded meida data from MediaEncoder and put into EncodedBufferCache.

View File

@ -148,7 +148,7 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType)
* If this is the last packet of input stream
* Set mState to ENCODE_DONE
*
* If mState is ENCODE_DONE
* If mState is ENCODE_DONE or ENCODE_ERROR
* Stop the loop
*/
void
@ -164,17 +164,23 @@ MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
switch (mState) {
case ENCODE_METADDATA: {
nsRefPtr<TrackMetadataBase> meta = mAudioEncoder->GetMetadata();
MOZ_ASSERT(meta);
if (meta == nullptr) {
LOG("ERROR! AudioEncoder get null Metadata!");
mState = ENCODE_ERROR;
break;
}
nsresult rv = mWriter->SetMetadata(meta);
if (NS_FAILED(rv)) {
mState = ENCODE_DONE;
LOG("ERROR! writer can't accept audio metadata!");
mState = ENCODE_ERROR;
break;
}
rv = mWriter->GetContainerData(aOutputBufs,
ContainerWriter::GET_HEADER);
if (NS_FAILED(rv)) {
mState = ENCODE_DONE;
LOG("ERROR! writer fail to generate header!");
mState = ENCODE_ERROR;
break;
}
@ -188,7 +194,7 @@ MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
if (NS_FAILED(rv)) {
// Encoding might be canceled.
LOG("ERROR! Fail to get encoded data from encoder.");
mState = ENCODE_DONE;
mState = ENCODE_ERROR;
break;
}
rv = mWriter->WriteEncodedTrack(encodedData,
@ -196,7 +202,7 @@ MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
ContainerWriter::END_OF_STREAM : 0);
if (NS_FAILED(rv)) {
LOG("ERROR! Fail to write encoded track to the media container.");
mState = ENCODE_DONE;
mState = ENCODE_ERROR;
break;
}
@ -217,7 +223,11 @@ MediaEncoder::GetEncodedData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
mShutdown = true;
reloop = false;
break;
case ENCODE_ERROR:
LOG("ERROR! MediaEncoder got error!");
mShutdown = true;
reloop = false;
break;
default:
MOZ_CRASH("Invalid encode state");
}

View File

@ -54,6 +54,7 @@ public :
ENCODE_METADDATA,
ENCODE_TRACK,
ENCODE_DONE,
ENCODE_ERROR,
};
MediaEncoder(ContainerWriter* aWriter,
@ -121,6 +122,11 @@ public :
}
}
bool HasError()
{
return mState == ENCODE_ERROR;
}
private:
nsAutoPtr<ContainerWriter> mWriter;
nsAutoPtr<AudioTrackEncoder> mAudioEncoder;

View File

@ -132,18 +132,17 @@ OpusTrackEncoder::~OpusTrackEncoder()
nsresult
OpusTrackEncoder::Init(int aChannels, int aSamplingRate)
{
// The track must have 1 or 2 channels.
if (aChannels <= 0 || aChannels > MAX_CHANNELS) {
LOG("[Opus] Fail to create the AudioTrackEncoder! The input has"
" %d channel(s), but expects no more than %d.", aChannels, MAX_CHANNELS);
return NS_ERROR_INVALID_ARG;
}
// This monitor is used to wake up other methods that are waiting for encoder
// to be completely initialized.
ReentrantMonitorAutoEnter mon(mReentrantMonitor);
mChannels = aChannels;
// This version of encoder API only support 1 or 2 channels,
// So set the mChannels less or equal 2 and
// let InterleaveTrackData downmix pcm data.
mChannels = aChannels > 2 ? 2 : aChannels;
if (aChannels <= 0) {
return NS_ERROR_FAILURE;
}
// The granule position is required to be incremented at a rate of 48KHz, and
// it is simply calculated as |granulepos = samples * (48000/source_rate)|,
// that is, the source sampling rate must divide 48000 evenly.

View File

@ -141,8 +141,10 @@ protected:
uint32_t aOutputChannels, AudioDataValue* aOutput);
/**
* The number of channels in the first valid audio chunk, and is being used
* to initialize the audio encoder.
* The number of channels are used for processing PCM data in the audio encoder.
* This value comes from the first valid audio chunk. If encoder can't support
* the channels in the chunk, downmix PCM stream can be performed.
* This value also be used to initialize the audio encoder.
*/
int mChannels;
int mSamplingRate;

View File

@ -169,6 +169,7 @@ OggWriter::GetContainerData(nsTArray<nsTArray<uint8_t> >* aOutputBufs,
nsresult
OggWriter::SetMetadata(TrackMetadataBase* aMetadata)
{
MOZ_ASSERT(aMetadata);
if (aMetadata->GetKind() != TrackMetadataBase::METADATA_OPUS) {
LOG("wrong meta data type!");
return NS_ERROR_FAILURE;