Set first_frame_in_picture on first encoded frame of picture.
Set the flag based on coded length of buffered frame which is reset after picture is encoded and, thus, is equal to zero when encoder delivers first frame of next picture. Before this change first_frame_in_picture was set based on index of spatial layer of encoded frame. This is not right anymore since encoder can drop base layer but deliver upper layers. Bug: chromium:828350 Change-Id: I12c7534240de8bc4905f04ff368cc3704720a70b Reviewed-on: https://webrtc-review.googlesource.com/68561 Reviewed-by: Rasmus Brandt <brandtr@webrtc.org> Commit-Queue: Sergey Silkin <ssilkin@webrtc.org> Cr-Commit-Position: refs/heads/master@{#22805}
This commit is contained in:
committed by
Commit Bot
parent
bda78c9464
commit
07f80cc393
@ -585,11 +585,14 @@ int VP9EncoderImpl::Encode(const VideoFrame& input_image,
|
||||
|
||||
void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||
const vpx_codec_cx_pkt& pkt,
|
||||
uint32_t timestamp) {
|
||||
uint32_t timestamp,
|
||||
bool first_frame_in_picture) {
|
||||
RTC_CHECK(codec_specific != nullptr);
|
||||
codec_specific->codecType = kVideoCodecVP9;
|
||||
codec_specific->codec_name = ImplementationName();
|
||||
CodecSpecificInfoVP9* vp9_info = &(codec_specific->codecSpecific.VP9);
|
||||
|
||||
vp9_info->first_frame_in_picture = first_frame_in_picture;
|
||||
// TODO(asapersson): Set correct value.
|
||||
vp9_info->inter_pic_predicted =
|
||||
(pkt.data.frame.flags & VPX_FRAME_IS_KEY) ? false : true;
|
||||
@ -623,15 +626,7 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||
// TODO(asapersson): this info has to be obtained from the encoder.
|
||||
vp9_info->temporal_up_switch = false;
|
||||
|
||||
bool is_first_frame = false;
|
||||
if (is_flexible_mode_) {
|
||||
is_first_frame =
|
||||
layer_id.spatial_layer_id == spatial_layer_->GetStartLayer();
|
||||
} else {
|
||||
is_first_frame = layer_id.spatial_layer_id == 0;
|
||||
}
|
||||
|
||||
if (is_first_frame) {
|
||||
if (first_frame_in_picture) {
|
||||
// TODO(asapersson): this info has to be obtained from the encoder.
|
||||
vp9_info->inter_layer_predicted = false;
|
||||
++frames_since_kf_;
|
||||
@ -640,8 +635,6 @@ void VP9EncoderImpl::PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||
vp9_info->inter_layer_predicted = true;
|
||||
}
|
||||
|
||||
vp9_info->first_frame_in_picture = is_first_frame;
|
||||
|
||||
if (pkt.data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||
frames_since_kf_ = 0;
|
||||
}
|
||||
@ -687,6 +680,13 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
|
||||
return WEBRTC_VIDEO_CODEC_OK;
|
||||
}
|
||||
|
||||
vpx_svc_layer_id_t layer_id = {0};
|
||||
vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
|
||||
const bool first_frame_in_picture = encoded_image_._length == 0;
|
||||
// Ensure we don't buffer layers of previous picture (superframe).
|
||||
RTC_DCHECK(first_frame_in_picture || layer_id.spatial_layer_id > 0);
|
||||
|
||||
const bool end_of_superframe = false;
|
||||
DeliverBufferedFrame(end_of_superframe);
|
||||
|
||||
@ -698,14 +698,12 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
|
||||
memcpy(encoded_image_._buffer, pkt->data.frame.buf, pkt->data.frame.sz);
|
||||
encoded_image_._length = pkt->data.frame.sz;
|
||||
|
||||
vpx_svc_layer_id_t layer_id = {0};
|
||||
vpx_codec_control(encoder_, VP9E_GET_SVC_LAYER_ID, &layer_id);
|
||||
if (is_flexible_mode_ && codec_.mode == kScreensharing)
|
||||
if (is_flexible_mode_ && codec_.mode == kScreensharing) {
|
||||
spatial_layer_->LayerFrameEncoded(
|
||||
static_cast<unsigned int>(encoded_image_._length),
|
||||
layer_id.spatial_layer_id);
|
||||
}
|
||||
|
||||
// End of frame.
|
||||
// Check if encoded frame is a key frame.
|
||||
encoded_image_._frameType = kVideoFrameDelta;
|
||||
if (pkt->data.frame.flags & VPX_FRAME_IS_KEY) {
|
||||
@ -714,7 +712,8 @@ int VP9EncoderImpl::GetEncodedLayerFrame(const vpx_codec_cx_pkt* pkt) {
|
||||
RTC_DCHECK_LE(encoded_image_._length, encoded_image_._size);
|
||||
|
||||
memset(&codec_specific_, 0, sizeof(codec_specific_));
|
||||
PopulateCodecSpecific(&codec_specific_, *pkt, input_image_->timestamp());
|
||||
PopulateCodecSpecific(&codec_specific_, *pkt, input_image_->timestamp(),
|
||||
first_frame_in_picture);
|
||||
|
||||
TRACE_COUNTER1("webrtc", "EncodedFrameSize", encoded_image_._length);
|
||||
encoded_image_._timeStamp = input_image_->timestamp();
|
||||
|
||||
@ -74,7 +74,8 @@ class VP9EncoderImpl : public VP9Encoder {
|
||||
|
||||
void PopulateCodecSpecific(CodecSpecificInfo* codec_specific,
|
||||
const vpx_codec_cx_pkt& pkt,
|
||||
uint32_t timestamp);
|
||||
uint32_t timestamp,
|
||||
bool first_frame_in_picture);
|
||||
|
||||
bool ExplicitlyConfiguredSpatialLayers() const;
|
||||
bool SetSvcRates(const BitrateAllocation& bitrate_allocation);
|
||||
|
||||
Reference in New Issue
Block a user