mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1063883: use multiples of macroblocks for qm_select downscaling r=pkerr
This commit is contained in:
parent
76d7f5c6fa
commit
af3712e640
@ -597,6 +597,15 @@ WebrtcVideoConduit::ConfigureSendMediaCodec(const VideoCodecConfig* codecConfig)
|
||||
// width/height will be overridden on the first frame
|
||||
video_codec.width = 320;
|
||||
video_codec.height = 240;
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
if (codecConfig->mType == webrtc::kVideoCodecH264) {
|
||||
video_codec.resolution_divisor = 16;
|
||||
} else {
|
||||
video_codec.resolution_divisor = 1; // We could try using it to handle odd resolutions
|
||||
}
|
||||
#else
|
||||
video_codec.resolution_divisor = 1; // We could try using it to handle odd resolutions
|
||||
#endif
|
||||
video_codec.qpMax = 56;
|
||||
video_codec.numberOfSimulcastStreams = 1;
|
||||
video_codec.mode = webrtc::kRealtimeVideo;
|
||||
@ -1303,6 +1312,9 @@ WebrtcVideoConduit::CodecConfigToWebRTCCodec(const VideoCodecConfig* codecInfo,
|
||||
|
||||
if (cinst.codecType == webrtc::kVideoCodecH264)
|
||||
{
|
||||
#ifdef MOZ_WEBRTC_OMX
|
||||
cinst.resolution_divisor = 16;
|
||||
#endif
|
||||
cinst.codecSpecific.H264.profile = codecInfo->mProfile;
|
||||
cinst.codecSpecific.H264.constraints = codecInfo->mConstraints;
|
||||
cinst.codecSpecific.H264.level = codecInfo->mLevel;
|
||||
|
@ -671,6 +671,8 @@ struct VideoCodec
|
||||
|
||||
unsigned short width;
|
||||
unsigned short height;
|
||||
// width & height modulo resolution_divisor must be 0
|
||||
unsigned char resolution_divisor;
|
||||
|
||||
unsigned int startBitrate; // kilobits/sec.
|
||||
unsigned int maxBitrate; // kilobits/sec.
|
||||
|
@ -92,6 +92,8 @@ bool VCMCodecDataBase::Codec(int list_id,
|
||||
settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
|
||||
settings->width = VCM_DEFAULT_CODEC_WIDTH;
|
||||
settings->height = VCM_DEFAULT_CODEC_HEIGHT;
|
||||
// consider using 2 to avoid deal with 'odd' downscales
|
||||
settings->resolution_divisor = 1; // may not actually be needed
|
||||
settings->numberOfSimulcastStreams = 0;
|
||||
settings->qpMax = 56;
|
||||
settings->codecSpecific.VP8.resilience = kResilientStream;
|
||||
@ -118,6 +120,7 @@ bool VCMCodecDataBase::Codec(int list_id,
|
||||
settings->maxFramerate = VCM_DEFAULT_FRAME_RATE;
|
||||
settings->width = VCM_DEFAULT_CODEC_WIDTH;
|
||||
settings->height = VCM_DEFAULT_CODEC_HEIGHT;
|
||||
settings->resolution_divisor = 1;
|
||||
settings->minBitrate = VCM_MIN_BITRATE;
|
||||
settings->numberOfSimulcastStreams = 0;
|
||||
return true;
|
||||
@ -318,6 +321,7 @@ bool VCMCodecDataBase::RequiresEncoderReset(const VideoCodec& new_send_codec) {
|
||||
new_send_codec.plType != send_codec_.plType ||
|
||||
new_send_codec.width != send_codec_.width ||
|
||||
new_send_codec.height != send_codec_.height ||
|
||||
new_send_codec.resolution_divisor != send_codec_.resolution_divisor ||
|
||||
new_send_codec.maxBitrate != send_codec_.maxBitrate ||
|
||||
new_send_codec.minBitrate != send_codec_.minBitrate ||
|
||||
new_send_codec.qpMax != send_codec_.qpMax ||
|
||||
|
@ -114,7 +114,7 @@ MediaOptimization::~MediaOptimization(void) {
|
||||
}
|
||||
|
||||
void MediaOptimization::Reset() {
|
||||
SetEncodingData(kVideoCodecUnknown, 0, 0, 0, 0, 0, 0, max_payload_size_);
|
||||
SetEncodingData(kVideoCodecUnknown, 0, 0, 0, 0, 0, 1, 0, max_payload_size_);
|
||||
memset(incoming_frame_times_, -1, sizeof(incoming_frame_times_));
|
||||
incoming_frame_rate_ = 0.0;
|
||||
frame_dropper_->Reset();
|
||||
@ -128,6 +128,8 @@ void MediaOptimization::Reset() {
|
||||
target_bit_rate_ = 0;
|
||||
codec_width_ = 0;
|
||||
codec_height_ = 0;
|
||||
min_width_ = 0;
|
||||
min_height_ = 0;
|
||||
user_frame_rate_ = 0;
|
||||
key_frame_cnt_ = 0;
|
||||
delta_frame_cnt_ = 0;
|
||||
@ -138,12 +140,24 @@ void MediaOptimization::Reset() {
|
||||
num_layers_ = 1;
|
||||
}
|
||||
|
||||
// Euclid's algorithm
|
||||
// on arm, binary may be faster, but we do this rarely
|
||||
static int GreatestCommonDenominator(int a, int b) {
|
||||
while (b != 0) {
|
||||
int t = b;
|
||||
b = a % b;
|
||||
a = t;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
|
||||
void MediaOptimization::SetEncodingData(VideoCodecType send_codec_type,
|
||||
int32_t max_bit_rate,
|
||||
uint32_t frame_rate,
|
||||
uint32_t target_bitrate,
|
||||
uint16_t width,
|
||||
uint16_t height,
|
||||
uint8_t divisor,
|
||||
int num_layers,
|
||||
int32_t mtu) {
|
||||
// Everything codec specific should be reset here since this means the codec
|
||||
@ -167,6 +181,9 @@ void MediaOptimization::SetEncodingData(VideoCodecType send_codec_type,
|
||||
user_frame_rate_ = static_cast<float>(frame_rate);
|
||||
codec_width_ = width;
|
||||
codec_height_ = height;
|
||||
int gcd = GreatestCommonDenominator(codec_width_, codec_height_);
|
||||
min_width_ = gcd ? (codec_width_/gcd * divisor) : 0;
|
||||
min_height_ = gcd ? (codec_height_/gcd * divisor) : 0;
|
||||
num_layers_ = (num_layers <= 1) ? 1 : num_layers; // Can also be zero.
|
||||
max_payload_size_ = mtu;
|
||||
qm_resolution_->Initialize(target_bitrate_kbps,
|
||||
@ -555,13 +572,26 @@ bool MediaOptimization::QMUpdate(
|
||||
codec_width_ = qm->codec_width;
|
||||
codec_height_ = qm->codec_height;
|
||||
}
|
||||
// handle codec limitations on input resolutions
|
||||
if (codec_width_ % min_width_ != 0 || codec_height_ % min_height_ != 0) {
|
||||
// XXX find a better algorithm for selecting sizes
|
||||
// This uses the GCD to find options that meet alignment requirements
|
||||
// (divisor) and at the same time retain the aspect ratio exactly.
|
||||
codec_width_ = ((codec_width_ + min_width_-1)/min_width_)*min_width_;
|
||||
codec_height_ = ((codec_height_ + min_height_-1)/min_height_)*min_height_;
|
||||
|
||||
// to avoid confusion later
|
||||
qm->codec_width = codec_width_;
|
||||
qm->codec_height = codec_height_;
|
||||
}
|
||||
|
||||
|
||||
WEBRTC_TRACE(webrtc::kTraceDebug,
|
||||
webrtc::kTraceVideoCoding,
|
||||
id_,
|
||||
"Resolution change from QM select: W = %d, H = %d, FR = %f",
|
||||
qm->codec_width,
|
||||
qm->codec_height,
|
||||
"Resolution change from QM select: W = %d (%d), H = %d (%d), FR = %f",
|
||||
qm->codec_width, codec_width_,
|
||||
qm->codec_height, codec_height_,
|
||||
qm->frame_rate);
|
||||
|
||||
// Update VPM with new target frame rate and frame size.
|
||||
|
@ -46,6 +46,7 @@ class MediaOptimization {
|
||||
uint32_t bit_rate,
|
||||
uint16_t width,
|
||||
uint16_t height,
|
||||
uint8_t divisor,
|
||||
int num_temporal_layers,
|
||||
int32_t mtu);
|
||||
|
||||
@ -133,6 +134,8 @@ class MediaOptimization {
|
||||
VideoCodecType send_codec_type_;
|
||||
uint16_t codec_width_;
|
||||
uint16_t codec_height_;
|
||||
uint16_t min_width_;
|
||||
uint16_t min_height_;
|
||||
float user_frame_rate_;
|
||||
scoped_ptr<FrameDropper> frame_dropper_;
|
||||
scoped_ptr<VCMLossProtectionLogic> loss_prot_logic_;
|
||||
|
@ -328,6 +328,8 @@ void VCMQmResolution::UpdateRates(float target_bitrate,
|
||||
// Initialize() state are kept in |down_action_history_|.
|
||||
// 4) The total amount of down-sampling (spatial and/or temporal) from the
|
||||
// Initialize() state (native resolution) is limited by various factors.
|
||||
// 5) If the codec can't handle arbitrary input resolutions, limit to %16==0
|
||||
// i.e. for h.264
|
||||
int VCMQmResolution::SelectResolution(VCMResolutionScale** qm) {
|
||||
if (!init_) {
|
||||
return VCM_UNINITIALIZED;
|
||||
|
@ -42,6 +42,11 @@ struct VCMResolutionScale {
|
||||
bool change_resolution_temporal;
|
||||
};
|
||||
|
||||
// Other possibilities:
|
||||
// aspect 1.333*
|
||||
// kQQVGA = 160x120
|
||||
// k??? 192x144
|
||||
// k??? 256x192 (good step between 320x240 and 160x120)
|
||||
enum ImageType {
|
||||
kQCIF = 0, // 176x144
|
||||
kHCIF, // 264x216 = half(~3/4x3/4) CIF.
|
||||
|
@ -161,6 +161,7 @@ int32_t VideoSender::RegisterSendCodec(const VideoCodec* sendCodec,
|
||||
sendCodec->startBitrate * 1000,
|
||||
sendCodec->width,
|
||||
sendCodec->height,
|
||||
sendCodec->resolution_divisor,
|
||||
numLayers,
|
||||
maxPayloadSize);
|
||||
return VCM_OK;
|
||||
|
Loading…
Reference in New Issue
Block a user