mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1161276: part 2 - pass bitrates to track encoders for MediaRecorder r=roc
This commit is contained in:
parent
0b5c28b0ff
commit
a7d86cae5e
@ -595,9 +595,17 @@ private:
|
|||||||
|
|
||||||
// Make sure the application has permission to assign AUDIO_3GPP
|
// Make sure the application has permission to assign AUDIO_3GPP
|
||||||
if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP) && Check3gppPermission()) {
|
if (mRecorder->mMimeType.EqualsLiteral(AUDIO_3GPP) && Check3gppPermission()) {
|
||||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP), aTrackTypes);
|
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(AUDIO_3GPP),
|
||||||
|
mRecorder->GetAudioBitrate(),
|
||||||
|
mRecorder->GetVideoBitrate(),
|
||||||
|
mRecorder->GetBitrate(),
|
||||||
|
aTrackTypes);
|
||||||
} else {
|
} else {
|
||||||
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""), aTrackTypes);
|
mEncoder = MediaEncoder::CreateEncoder(NS_LITERAL_STRING(""),
|
||||||
|
mRecorder->GetAudioBitrate(),
|
||||||
|
mRecorder->GetVideoBitrate(),
|
||||||
|
mRecorder->GetBitrate(),
|
||||||
|
aTrackTypes);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!mEncoder) {
|
if (!mEncoder) {
|
||||||
@ -1015,6 +1023,17 @@ MediaRecorder::SetOptions(const MediaRecorderOptions& aInitDict)
|
|||||||
aInitDict.mVideoBitsPerSecond.Value() : 0;
|
aInitDict.mVideoBitsPerSecond.Value() : 0;
|
||||||
mBitsPerSecond = aInitDict.mBitsPerSecond.WasPassed() ?
|
mBitsPerSecond = aInitDict.mBitsPerSecond.WasPassed() ?
|
||||||
aInitDict.mBitsPerSecond.Value() : 0;
|
aInitDict.mBitsPerSecond.Value() : 0;
|
||||||
|
// We're not handling dynamic changes yet. Eventually we'll handle
|
||||||
|
// setting audio, video and/or total -- and anything that isn't set,
|
||||||
|
// we'll derive. Calculated versions require querying bitrates after
|
||||||
|
// the encoder is Init()ed. This happens only after data is
|
||||||
|
// available and thus requires dynamic changes.
|
||||||
|
//
|
||||||
|
// Until dynamic changes are supported, I prefer to be safe and err
|
||||||
|
// slightly high
|
||||||
|
if (aInitDict.mBitsPerSecond.WasPassed() && !aInitDict.mVideoBitsPerSecond.WasPassed()) {
|
||||||
|
mVideoBitsPerSecond = mBitsPerSecond;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
|
@ -104,6 +104,9 @@ public:
|
|||||||
|
|
||||||
NS_DECL_NSIDOCUMENTACTIVITY
|
NS_DECL_NSIDOCUMENTACTIVITY
|
||||||
|
|
||||||
|
uint32_t GetAudioBitrate() { return mAudioBitsPerSecond; }
|
||||||
|
uint32_t GetVideoBitrate() { return mVideoBitsPerSecond; }
|
||||||
|
uint32_t GetBitrate() { return mBitsPerSecond; }
|
||||||
protected:
|
protected:
|
||||||
virtual ~MediaRecorder();
|
virtual ~MediaRecorder();
|
||||||
|
|
||||||
|
@ -73,7 +73,9 @@ MediaEncoder::NotifyEvent(MediaStreamGraph* aGraph,
|
|||||||
|
|
||||||
/* static */
|
/* static */
|
||||||
already_AddRefed<MediaEncoder>
|
already_AddRefed<MediaEncoder>
|
||||||
MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint8_t aTrackTypes)
|
MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint32_t aAudioBitrate,
|
||||||
|
uint32_t aVideoBitrate, uint32_t aBitrate,
|
||||||
|
uint8_t aTrackTypes)
|
||||||
{
|
{
|
||||||
if (!gMediaEncoderLog) {
|
if (!gMediaEncoderLog) {
|
||||||
gMediaEncoderLog = PR_NewLogModule("MediaEncoder");
|
gMediaEncoderLog = PR_NewLogModule("MediaEncoder");
|
||||||
@ -144,8 +146,15 @@ MediaEncoder::CreateEncoder(const nsAString& aMIMEType, uint8_t aTrackTypes)
|
|||||||
LOG(LogLevel::Debug, ("Create encoder result:a[%d] v[%d] w[%d] mimeType = %s.",
|
LOG(LogLevel::Debug, ("Create encoder result:a[%d] v[%d] w[%d] mimeType = %s.",
|
||||||
audioEncoder != nullptr, videoEncoder != nullptr,
|
audioEncoder != nullptr, videoEncoder != nullptr,
|
||||||
writer != nullptr, mimeType.get()));
|
writer != nullptr, mimeType.get()));
|
||||||
|
if (videoEncoder && aVideoBitrate != 0) {
|
||||||
|
videoEncoder->SetBitrate(aVideoBitrate);
|
||||||
|
}
|
||||||
|
if (audioEncoder && aAudioBitrate != 0) {
|
||||||
|
audioEncoder->SetBitrate(aAudioBitrate);
|
||||||
|
}
|
||||||
encoder = new MediaEncoder(writer.forget(), audioEncoder.forget(),
|
encoder = new MediaEncoder(writer.forget(), audioEncoder.forget(),
|
||||||
videoEncoder.forget(), mimeType);
|
videoEncoder.forget(), mimeType, aAudioBitrate,
|
||||||
|
aVideoBitrate, aBitrate);
|
||||||
return encoder.forget();
|
return encoder.forget();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -62,7 +62,10 @@ public :
|
|||||||
MediaEncoder(ContainerWriter* aWriter,
|
MediaEncoder(ContainerWriter* aWriter,
|
||||||
AudioTrackEncoder* aAudioEncoder,
|
AudioTrackEncoder* aAudioEncoder,
|
||||||
VideoTrackEncoder* aVideoEncoder,
|
VideoTrackEncoder* aVideoEncoder,
|
||||||
const nsAString& aMIMEType)
|
const nsAString& aMIMEType,
|
||||||
|
uint32_t aAudioBitrate,
|
||||||
|
uint32_t aVideoBitrate,
|
||||||
|
uint32_t aBitrate)
|
||||||
: mWriter(aWriter)
|
: mWriter(aWriter)
|
||||||
, mAudioEncoder(aAudioEncoder)
|
, mAudioEncoder(aAudioEncoder)
|
||||||
, mVideoEncoder(aVideoEncoder)
|
, mVideoEncoder(aVideoEncoder)
|
||||||
@ -96,6 +99,8 @@ public :
|
|||||||
* Ogg+Opus if it is empty.
|
* Ogg+Opus if it is empty.
|
||||||
*/
|
*/
|
||||||
static already_AddRefed<MediaEncoder> CreateEncoder(const nsAString& aMIMEType,
|
static already_AddRefed<MediaEncoder> CreateEncoder(const nsAString& aMIMEType,
|
||||||
|
uint32_t aAudioBitrate, uint32_t aVideoBitrate,
|
||||||
|
uint32_t aBitrate,
|
||||||
uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK);
|
uint8_t aTrackTypes = ContainerWriter::CREATE_AUDIO_TRACK);
|
||||||
/**
|
/**
|
||||||
* Encodes the raw track data and returns the final container data. Assuming
|
* Encodes the raw track data and returns the final container data. Assuming
|
||||||
|
@ -187,8 +187,13 @@ OpusTrackEncoder::Init(int aChannels, int aSamplingRate)
|
|||||||
mEncoder = opus_encoder_create(GetOutputSampleRate(), mChannels,
|
mEncoder = opus_encoder_create(GetOutputSampleRate(), mChannels,
|
||||||
OPUS_APPLICATION_AUDIO, &error);
|
OPUS_APPLICATION_AUDIO, &error);
|
||||||
|
|
||||||
|
|
||||||
mInitialized = (error == OPUS_OK);
|
mInitialized = (error == OPUS_OK);
|
||||||
|
|
||||||
|
if (mAudioBitrate) {
|
||||||
|
opus_encoder_ctl(mEncoder, OPUS_SET_BITRATE(static_cast<int>(mAudioBitrate)));
|
||||||
|
}
|
||||||
|
|
||||||
mReentrantMonitor.NotifyAll();
|
mReentrantMonitor.NotifyAll();
|
||||||
|
|
||||||
return error == OPUS_OK ? NS_OK : NS_ERROR_FAILURE;
|
return error == OPUS_OK ? NS_OK : NS_ERROR_FAILURE;
|
||||||
|
@ -84,6 +84,8 @@ public:
|
|||||||
mReentrantMonitor.NotifyAll();
|
mReentrantMonitor.NotifyAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual void SetBitrate(const uint32_t aBitrate) {}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Notifies track encoder that we have reached the end of source stream, and
|
* Notifies track encoder that we have reached the end of source stream, and
|
||||||
@ -141,6 +143,7 @@ public:
|
|||||||
: TrackEncoder()
|
: TrackEncoder()
|
||||||
, mChannels(0)
|
, mChannels(0)
|
||||||
, mSamplingRate(0)
|
, mSamplingRate(0)
|
||||||
|
, mAudioBitrate(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
|
virtual void NotifyQueuedTrackChanges(MediaStreamGraph* aGraph, TrackID aID,
|
||||||
@ -191,6 +194,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||||
|
|
||||||
|
virtual void SetBitrate(const uint32_t aBitrate) override
|
||||||
|
{
|
||||||
|
mAudioBitrate = aBitrate;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Number of samples per channel in a pcm buffer. This is also the value of
|
* Number of samples per channel in a pcm buffer. This is also the value of
|
||||||
@ -239,6 +246,8 @@ protected:
|
|||||||
* A segment queue of audio track data, protected by mReentrantMonitor.
|
* A segment queue of audio track data, protected by mReentrantMonitor.
|
||||||
*/
|
*/
|
||||||
AudioSegment mRawSegment;
|
AudioSegment mRawSegment;
|
||||||
|
|
||||||
|
uint32_t mAudioBitrate;
|
||||||
};
|
};
|
||||||
|
|
||||||
class VideoTrackEncoder : public TrackEncoder
|
class VideoTrackEncoder : public TrackEncoder
|
||||||
@ -252,6 +261,7 @@ public:
|
|||||||
, mDisplayHeight(0)
|
, mDisplayHeight(0)
|
||||||
, mTrackRate(0)
|
, mTrackRate(0)
|
||||||
, mTotalFrameDuration(0)
|
, mTotalFrameDuration(0)
|
||||||
|
, mVideoBitrate(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -267,6 +277,10 @@ public:
|
|||||||
*/
|
*/
|
||||||
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
size_t SizeOfExcludingThis(mozilla::MallocSizeOf aMallocSizeOf) const;
|
||||||
|
|
||||||
|
virtual void SetBitrate(const uint32_t aBitrate) override
|
||||||
|
{
|
||||||
|
mVideoBitrate = aBitrate;
|
||||||
|
}
|
||||||
protected:
|
protected:
|
||||||
/**
|
/**
|
||||||
* Initialized the video encoder. In order to collect the value of width and
|
* Initialized the video encoder. In order to collect the value of width and
|
||||||
@ -332,6 +346,8 @@ protected:
|
|||||||
* A segment queue of audio track data, protected by mReentrantMonitor.
|
* A segment queue of audio track data, protected by mReentrantMonitor.
|
||||||
*/
|
*/
|
||||||
VideoSegment mRawSegment;
|
VideoSegment mRawSegment;
|
||||||
|
|
||||||
|
uint32_t mVideoBitrate;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace mozilla
|
} // namespace mozilla
|
||||||
|
@ -20,7 +20,7 @@ PRLogModuleInfo* gVP8TrackEncoderLog;
|
|||||||
(msg, ##__VA_ARGS__))
|
(msg, ##__VA_ARGS__))
|
||||||
// Debug logging macro with object pointer and class name.
|
// Debug logging macro with object pointer and class name.
|
||||||
|
|
||||||
#define DEFAULT_BITRATE 2500 // in kbit/s
|
#define DEFAULT_BITRATE_BPS 2500000
|
||||||
#define DEFAULT_ENCODE_FRAMERATE 30
|
#define DEFAULT_ENCODE_FRAMERATE 30
|
||||||
|
|
||||||
using namespace mozilla::layers;
|
using namespace mozilla::layers;
|
||||||
@ -87,7 +87,9 @@ VP8TrackEncoder::Init(int32_t aWidth, int32_t aHeight, int32_t aDisplayWidth,
|
|||||||
config.g_h = mFrameHeight;
|
config.g_h = mFrameHeight;
|
||||||
// TODO: Maybe we should have various aFrameRate bitrate pair for each devices?
|
// TODO: Maybe we should have various aFrameRate bitrate pair for each devices?
|
||||||
// or for different platform
|
// or for different platform
|
||||||
config.rc_target_bitrate = DEFAULT_BITRATE; // in kbit/s
|
|
||||||
|
// rc_target_bitrate needs kbit/s
|
||||||
|
config.rc_target_bitrate = (mVideoBitrate != 0 ? mVideoBitrate : DEFAULT_BITRATE_BPS)/1000;
|
||||||
|
|
||||||
// Setting the time base of the codec
|
// Setting the time base of the codec
|
||||||
config.g_timebase.num = 1;
|
config.g_timebase.num = 1;
|
||||||
|
@ -56,9 +56,12 @@ VorbisTrackEncoder::Init(int aChannels, int aSamplingRate)
|
|||||||
|
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
vorbis_info_init(&mVorbisInfo);
|
vorbis_info_init(&mVorbisInfo);
|
||||||
|
double quality = mAudioBitrate ? (double)mAudioBitrate/aSamplingRate :
|
||||||
|
BASE_QUALITY;
|
||||||
|
|
||||||
|
printf("quality %f \n", quality);
|
||||||
ret = vorbis_encode_init_vbr(&mVorbisInfo, mChannels, mSamplingRate,
|
ret = vorbis_encode_init_vbr(&mVorbisInfo, mChannels, mSamplingRate,
|
||||||
BASE_QUALITY);
|
quality);
|
||||||
|
|
||||||
mInitialized = (ret == 0);
|
mInitialized = (ret == 0);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user