summaryrefslogtreecommitdiffstats
blob: dc2a81eda71dea3daa8094e204b4fe2d6081ade2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
/*
 *  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 <Swiften/ScreenSharing/ReferencePictureSelection.h>
#include <Swiften/Base/Log.h>

#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;
}

}