/* * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. * * Use of this source code is governed by a BSD-style license * that can be found in the LICENSE file in the root of the source * tree. An additional intellectual property rights grant can be found * in the file PATENTS. All contributing project authors may * be found in the AUTHORS file in the root of the source tree. */ #include #include #include "vpx/vpx_encoder.h" #include "vpx/vp8cx.h" namespace Swift { ReferencePictureSelection::ReferencePictureSelection() : update_golden_next_(true), established_golden_(false), received_ack_(false), last_sent_ref_picture_id_(0), established_ref_picture_id_(0), send_refresh(false) { } void ReferencePictureSelection::ReceivedRPSI(int rpsi_picture_id) { // Assume RPSI is signaled with 7 bits. SWIFT_LOG(debug) << "ReceivedRPSI: " << rpsi_picture_id << ", " << last_sent_ref_picture_id_ << std::endl; if ((rpsi_picture_id & 127) == (last_sent_ref_picture_id_ & 127)) { // Remote peer has received our last reference frame, switch frame type. received_ack_ = true; established_golden_ = update_golden_next_; update_golden_next_ = !update_golden_next_; established_ref_picture_id_ = last_sent_ref_picture_id_; SWIFT_LOG(debug) << "Ref established: " << established_ref_picture_id_ << std::endl; } } void ReferencePictureSelection::ReceivedSLI() { send_refresh = true; } int ReferencePictureSelection::EncodeFlags(int picture_id) { int flags = 0; // We can't refresh the decoder until we have established the key frame. if (send_refresh/* && received_ack_*/) { flags = VPX_EFLAG_FORCE_KF; // flags |= VPX_EFLAG_FORCE_KF; /* flags |= VP8_EFLAG_NO_REF_LAST; // Don't reference the last frame if (established_golden_) flags |= VP8_EFLAG_NO_REF_ARF; // Don't reference the alt-ref frame. else flags |= VP8_EFLAG_NO_REF_GF; // Don't reference the golden frame */ /*SWIFT_LOG(debug) << "Send refresh" << std::endl; if (established_golden_) { flags |= VP8_EFLAG_FORCE_ARF; flags |= VP8_EFLAG_NO_UPD_GF; flags |= VP8_EFLAG_NO_REF_ARF; } else { flags |= VP8_EFLAG_FORCE_GF; flags |= VP8_EFLAG_NO_UPD_ARF; flags |= VP8_EFLAG_NO_REF_GF; }*/ } send_refresh = false; // Don't send reference frame updates until we have an established reference. if (received_ack_ && picture_id % 8 == 0 && false) { flags |= VP8_EFLAG_NO_REF_LAST; // Don't reference the last frame. SWIFT_LOG(debug) << "Send reference : " << std::boolalpha << update_golden_next_ << std::endl; if (update_golden_next_) { flags |= VP8_EFLAG_FORCE_GF; // Update the golden reference. flags |= VP8_EFLAG_NO_UPD_ARF; // Don't update alt-ref. flags |= VP8_EFLAG_NO_REF_GF; // Don't reference the golden frame. } else { flags |= VP8_EFLAG_FORCE_ARF; // Update the alt-ref reference. flags |= VP8_EFLAG_NO_UPD_GF; // Don't update the golden frame. flags |= VP8_EFLAG_NO_REF_ARF; // Don't reference the alt-ref frame. } } else { // No update of golden or alt-ref. We can therefore freely reference the // established reference frame and the last frame. if (established_golden_) flags |= VP8_EFLAG_NO_REF_ARF; // Don't reference the alt-ref frame. else flags |= VP8_EFLAG_NO_REF_GF; // Don't reference the golden frame. flags |= VP8_EFLAG_NO_UPD_GF; // Don't update the golden frame. flags |= VP8_EFLAG_NO_UPD_ARF; // Don't update the alt-ref frame. } return flags; } void ReferencePictureSelection::refFrameSent(int picture_id) { last_sent_ref_picture_id_ = picture_id; received_ack_ = false; } }