gecko-dev/dom/media/encoder/Muxer.h
Andreas Pehrson 8491bedfad Bug 1014393 - Break out muxing and queueing of track data from MediaEncoder to new Muxer class. r=bryce
This first of all does some refactoring of how metadata is encoded in
MediaEncoder. This is now guided by the new Muxer class. If we're ready to pass
data to the muxer and it does not have metadata yet, we provide metadata before
giving it any media data. This metadata is passed to the muxer in a single call.
The metadata provided in this call must stay valid for the entire recording.
This removes MediaEncoder::GetEncodedMetadata().

This also removes the ctor argument from the WebMWriter since it can now rely on
the single SetMetadata() instead.
To comply with the ContainerWriter::SetMetadata() docs,
WebMWriter::SetMetadata() will now also sanity check metadata.

ContainerWriter instances are updated somewhat, to accommodate these changes.

Lastly, and most important, the new Muxer class manages muxing of the (up to)
two tracks into a single container, ensuring that timestamps increase
monotonically throughout a recording.

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

--HG--
extra : moz-landing-system : lando
2019-08-03 17:27:14 +00:00

75 lines
2.7 KiB
C++

/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-*/
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef DOM_MEDIA_ENCODER_MUXER_H_
#define DOM_MEDIA_ENCODER_MUXER_H_
#include "MediaQueue.h"
namespace mozilla {
class ContainerWriter;
// Generic Muxer class that helps pace the output from track encoders to the
// ContainerWriter, so time never appears to go backwards.
// Note that the entire class is written for single threaded access.
class Muxer {
public:
explicit Muxer(UniquePtr<ContainerWriter> aWriter);
~Muxer() = default;
// Returns true when all tracks have ended, and all data has been muxed and
// fetched.
bool IsFinished();
// Returns true if this muxer has not been given metadata yet.
bool NeedsMetadata() const { return !mMetadataSet; }
// Sets metadata for all tracks. This may only be called once.
nsresult SetMetadata(const nsTArray<RefPtr<TrackMetadataBase>>& aMetadata);
// Adds an encoded audio frame for muxing
void AddEncodedAudioFrame(EncodedFrame* aFrame);
// Adds an encoded video frame for muxing
void AddEncodedVideoFrame(EncodedFrame* aFrame);
// Marks the audio track as ended. Once all tracks for which we have metadata
// have ended, GetData() will drain and the muxer will be marked as finished.
void AudioEndOfStream();
// Marks the video track as ended. Once all tracks for which we have metadata
// have ended, GetData() will drain and the muxer will be marked as finished.
void VideoEndOfStream();
// Gets the data that has been muxed and written into the container so far.
nsresult GetData(nsTArray<nsTArray<uint8_t>>* aOutputBuffers);
private:
// Writes data in MediaQueues to the ContainerWriter.
nsresult Mux();
// Audio frames that have been encoded and are pending write to the muxer.
MediaQueue<EncodedFrame> mEncodedAudioFrames;
// Video frames that have been encoded and are pending write to the muxer.
MediaQueue<EncodedFrame> mEncodedVideoFrames;
// The writer for the specific container we're recording into.
UniquePtr<ContainerWriter> mWriter;
// How much each audio time stamp should be delayed in microseconds. Used to
// adjust for opus codec delay.
uint64_t mAudioCodecDelay = 0;
// True once metadata has been set in the muxer.
bool mMetadataSet = false;
// True once metadata has been written to file.
bool mMetadataEncoded = false;
// True if metadata is set and contains an audio track.
bool mHasAudio = false;
// True if metadata is set and contains a video track.
bool mHasVideo = false;
};
} // namespace mozilla
#endif