Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -139,14 +139,21 @@ namespace jni
return WEBRTC_VIDEO_CODEC_ERR_SIMULCAST_PARAMETERS_NOT_SUPPORTED;
}
// NV12 has chroma at half the resolution in both directions, and the
// frame is cropped in units of two pixels.
if (settings->width % 2 != 0 || settings->height % 2 != 0) {
// frame is cropped in units of two pixels. The first frame of a source
// can be odd, since WebRTC asks the source for
// requested_resolution_alignment only once the encoder has been set up.
// Refusing it would leave the whole session to the software encoder, so
// the encoder takes the even size below it and drops the last row and
// column of such frames.
if (settings->width < 2 || settings->height < 2) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}

Release();

codecSettings = *settings;
codecSettings.width &= ~1;
codecSettings.height &= ~1;
widthInMbs = (codecSettings.width + 15) / 16;
heightInMbs = (codecSettings.height + 15) / 16;
bitrateBps = std::max(1u, codecSettings.startBitrate) * 1000;
Expand Down Expand Up @@ -339,8 +346,12 @@ namespace jni
const int height = static_cast<int>(codecSettings.height);

// WebRTC initializes the encoder again when the frame size changes,
// so a frame of another size is one that raced with that.
if (i420->width() != width || i420->height() != height) {
// so a frame of another size is one that raced with that. An odd frame
// is cropped to the even size the encoder took, which needs no copy.
const bool cropped = i420->width() - width >= 0 && i420->width() - width <= 1
&& i420->height() - height >= 0 && i420->height() - height <= 1;

if (!cropped) {
webrtc::scoped_refptr<webrtc::I420Buffer> scaled = webrtc::I420Buffer::Create(width, height);
scaled->ScaleFrom(*i420);
i420 = scaled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,14 +70,21 @@ namespace jni
if (settings->GetScalabilityMode().value_or(webrtc::ScalabilityMode::kL1T1) != webrtc::ScalabilityMode::kL1T1) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
// NV12 has chroma at half the resolution in both directions.
if (settings->width % 2 != 0 || settings->height % 2 != 0) {
// NV12 has chroma at half the resolution in both directions. The first
// frame of a source can be odd, since WebRTC asks the source for
// requested_resolution_alignment only once the encoder has been set up.
// Refusing it would leave the whole session to the software encoder, so
// the encoder takes the even size below it and drops the last row and
// column of such frames.
if (settings->width < 2 || settings->height < 2) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}

Release();

codecSettings = *settings;
codecSettings.width &= ~1;
codecSettings.height &= ~1;
bitrateBps = std::max(1u, codecSettings.startBitrate) * 1000;
framerate = std::max(1u, codecSettings.maxFramerate);
frameCount = 0;
Expand Down Expand Up @@ -390,8 +397,12 @@ namespace jni
const int height = static_cast<int>(codecSettings.height);

// WebRTC initializes the encoder again when the frame size changes,
// so a frame of another size is one that raced with that.
if (i420->width() != width || i420->height() != height) {
// so a frame of another size is one that raced with that. An odd frame
// is cropped to the even size the encoder took, which needs no copy.
const bool cropped = i420->width() - width >= 0 && i420->width() - width <= 1
&& i420->height() - height >= 0 && i420->height() - height <= 1;

if (!cropped) {
webrtc::scoped_refptr<webrtc::I420Buffer> scaled = webrtc::I420Buffer::Create(width, height);
scaled->ScaleFrom(*i420);
i420 = scaled;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,8 +138,13 @@ namespace jni
if (settings->GetScalabilityMode().value_or(webrtc::ScalabilityMode::kL1T1) != webrtc::ScalabilityMode::kL1T1) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}
// NV12 has chroma at half the resolution in both directions.
if (settings->width % 2 != 0 || settings->height % 2 != 0) {
// NV12 has chroma at half the resolution in both directions. The first
// frame of a source can be odd, since WebRTC asks the source for
// requested_resolution_alignment only once the encoder has been set up.
// Refusing it would leave the whole session to the software encoder, so
// the encoder takes the even size below it and drops the last row and
// column of such frames.
if (settings->width < 2 || settings->height < 2) {
return WEBRTC_VIDEO_CODEC_ERR_PARAMETER;
}

Expand All @@ -157,6 +162,8 @@ namespace jni
}

codecSettings = *settings;
codecSettings.width &= ~1;
codecSettings.height &= ~1;
bitrateBps = std::max(1u, codecSettings.startBitrate) * 1000;
framerate = std::max(1u, codecSettings.maxFramerate);

Expand Down Expand Up @@ -493,8 +500,12 @@ namespace jni
const int height = static_cast<int>(codecSettings.height);

// WebRTC initializes the encoder again when the frame size changes,
// so a frame of another size is one that raced with that.
if (i420->width() != width || i420->height() != height) {
// so a frame of another size is one that raced with that. An odd frame
// is cropped to the even size the encoder took, which needs no copy.
const bool cropped = i420->width() - width >= 0 && i420->width() - width <= 1
&& i420->height() - height >= 0 && i420->height() - height <= 1;

if (!cropped) {
webrtc::scoped_refptr<webrtc::I420Buffer> scaled = webrtc::I420Buffer::Create(width, height);
scaled->ScaleFrom(*i420);
i420 = scaled;
Expand Down
Loading
Loading