Bug 1523563 - Pass in mime type to MediaEncoder and give preference to it when passed. r=jib

Somewhere along the way this must have gotten broken.
Until this, passing mime type to MediaRecorder has had no effect.

This patch does two things:
1) Passes the mime type through from MediaRecorder to MediaEncoder
2) Gives preference to the mime type when passed, wrt picking codecs,
   however, we still yield to a video mime type when given a video track
   since that's how both Firefox and Chromium function today.

Proper spec handling of mime type will be fixed in bug 1512175.

Differential Revision: https://phabricator.services.mozilla.com/D35171

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Andreas Pehrson 2019-06-19 16:09:35 +00:00
Родитель 1b58bc5b84
Коммит 82a2eb17d3
2 изменённых файлов: 66 добавлений и 20 удалений

Просмотреть файл

@ -474,6 +474,7 @@ class MediaRecorder::Session : public PrincipalChangeObserver<MediaStreamTrack>,
mRunningState(RunningState::Idling) {
MOZ_ASSERT(NS_IsMainThread());
aRecorder->GetMimeType(mMimeType);
mMaxMemory = Preferences::GetUint("media.recorder.max_memory",
MAX_ALLOW_MEMORY_BUFFER);
mLastBlobTimeStamp = TimeStamp::Now();
@ -950,9 +951,9 @@ class MediaRecorder::Session : public PrincipalChangeObserver<MediaStreamTrack>,
// At this stage, the API doesn't allow UA to choose the output mimeType
// format.
mEncoder = MediaEncoder::CreateEncoder(
mEncoderThread, NS_LITERAL_STRING(""), audioBitrate, videoBitrate,
aTrackTypes, aTrackRate);
mEncoder =
MediaEncoder::CreateEncoder(mEncoderThread, mMimeType, audioBitrate,
videoBitrate, aTrackTypes, aTrackRate);
if (!mEncoder) {
LOG(LogLevel::Error, ("Session.InitEncoder !mEncoder %p", this));

Просмотреть файл

@ -637,33 +637,76 @@ already_AddRefed<MediaEncoder> MediaEncoder::CreateEncoder(
}
#ifdef MOZ_WEBM_ENCODER
else if (MediaEncoder::IsWebMEncoderEnabled() &&
(aMIMEType.EqualsLiteral(VIDEO_WEBM) ||
(aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK))) {
aMIMEType.EqualsLiteral(VIDEO_WEBM)) {
if (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK &&
MediaDecoder::IsOpusEnabled()) {
audioEncoder = MakeAndAddRef<OpusTrackEncoder>(aTrackRate);
NS_ENSURE_TRUE(audioEncoder, nullptr);
}
if (Preferences::GetBool("media.recorder.video.frame_drops", true)) {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::ALLOW);
} else {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::DISALLOW);
if (aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK) {
if (Preferences::GetBool("media.recorder.video.frame_drops", true)) {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::ALLOW);
} else {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::DISALLOW);
}
}
writer = MakeUnique<WebMWriter>(aTrackTypes);
mimeType = NS_LITERAL_STRING(VIDEO_WEBM);
} else if (MediaEncoder::IsWebMEncoderEnabled() &&
aMIMEType.EqualsLiteral(AUDIO_WEBM) &&
aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK) {
if (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK &&
MediaDecoder::IsOpusEnabled()) {
audioEncoder = MakeAndAddRef<OpusTrackEncoder>(aTrackRate);
}
if (aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK) {
if (Preferences::GetBool("media.recorder.video.frame_drops", true)) {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::ALLOW);
} else {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::DISALLOW);
}
mimeType = NS_LITERAL_STRING(VIDEO_WEBM);
} else {
mimeType = NS_LITERAL_STRING(AUDIO_WEBM);
}
writer = MakeUnique<WebMWriter>(aTrackTypes);
}
#endif // MOZ_WEBM_ENCODER
else if (MediaDecoder::IsOggEnabled() && MediaDecoder::IsOpusEnabled() &&
aMIMEType.EqualsLiteral(AUDIO_OGG) &&
aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK) {
writer = MakeUnique<OggWriter>();
audioEncoder = MakeAndAddRef<OpusTrackEncoder>(aTrackRate);
mimeType = NS_LITERAL_STRING(AUDIO_OGG);
}
#ifdef MOZ_WEBM_ENCODER
else if (MediaEncoder::IsWebMEncoderEnabled() &&
(aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK ||
!MediaDecoder::IsOggEnabled())) {
if (aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK &&
MediaDecoder::IsOpusEnabled()) {
audioEncoder = MakeAndAddRef<OpusTrackEncoder>(aTrackRate);
}
if (aTrackTypes & ContainerWriter::CREATE_VIDEO_TRACK) {
if (Preferences::GetBool("media.recorder.video.frame_drops", true)) {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::ALLOW);
} else {
videoEncoder = MakeAndAddRef<VP8TrackEncoder>(
driftCompensator, aTrackRate, FrameDroppingMode::DISALLOW);
}
}
writer = MakeUnique<WebMWriter>(aTrackTypes);
NS_ENSURE_TRUE(writer, nullptr);
NS_ENSURE_TRUE(videoEncoder, nullptr);
mimeType = NS_LITERAL_STRING(VIDEO_WEBM);
}
#endif // MOZ_WEBM_ENCODER
else if (MediaDecoder::IsOggEnabled() && MediaDecoder::IsOpusEnabled() &&
(aMIMEType.EqualsLiteral(AUDIO_OGG) ||
(aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK))) {
aTrackTypes & ContainerWriter::CREATE_AUDIO_TRACK) {
writer = MakeUnique<OggWriter>();
audioEncoder = MakeAndAddRef<OpusTrackEncoder>(aTrackRate);
NS_ENSURE_TRUE(writer, nullptr);
NS_ENSURE_TRUE(audioEncoder, nullptr);
mimeType = NS_LITERAL_STRING(AUDIO_OGG);
} else {
LOG(LogLevel::Error,
@ -672,7 +715,8 @@ already_AddRefed<MediaEncoder> MediaEncoder::CreateEncoder(
}
LOG(LogLevel::Info,
("Create encoder result:a[%p](%u bps) v[%p](%u bps) w[%p] mimeType = %s.",
("Create encoder result:a[%p](%u bps) v[%p](%u bps) w[%p] mimeType = "
"%s.",
audioEncoder.get(), aAudioBitrate, videoEncoder.get(), aVideoBitrate,
writer.get(), NS_ConvertUTF16toUTF8(mimeType).get()));
@ -801,7 +845,8 @@ nsresult MediaEncoder::GetEncodedData(
}
}
// In audio only or video only case, let unavailable track's flag to be true.
// In audio only or video only case, let unavailable track's flag to be
// true.
bool isAudioCompleted = !mAudioEncoder || mAudioEncoder->IsEncodingComplete();
bool isVideoCompleted = !mVideoEncoder || mVideoEncoder->IsEncodingComplete();
rv = mWriter->GetContainerData(