Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RTCP packets and hooking #22

Closed
wowaser opened this issue Jun 2, 2021 · 4 comments
Closed

RTCP packets and hooking #22

wowaser opened this issue Jun 2, 2021 · 4 comments
Labels
bug Something isn't working

Comments

@wowaser
Copy link
Contributor

wowaser commented Jun 2, 2021

Hello,

I am testing the RTCP functionality based on the example (https://github.com/ultravideo/uvgRTP/blob/master/docs/examples/rtcp_hook.cc). I modified it slightly so that it only sends 5 frames. Also, I added the deallocation of the session object, as instructed here:
image.

My issue is that the RTCP packets are terribly out of sync, and even when we go out of scope and start doing something else, the RTCP receiver reports keep on coming. Because we sent 5 frames, I expect 5 reports, but if we let it play out we receive much more than that:
image

Moreover, after we stop sending stuff, we just receive RTCP report of the last frame over and over. Inevitably, as we destroy the session, we get an error, because RTCP packets keep on coming:
image

void receiver_hook(uvgrtp::frame::rtcp_receiver_report* frame)
{
	LOG_INFO("Received an RTCP Receiver Report");

	for (auto& block : frame->report_blocks) {
		fprintf(stderr, "ssrc:      %x\n", block.ssrc);
		fprintf(stderr, "fraction:  %u\n", block.fraction);
		fprintf(stderr, "lost:      %d\n", block.lost);
		fprintf(stderr, "last_seq:  %u\n", block.last_seq);
		fprintf(stderr, "jitter:    %u\n", block.jitter);
		fprintf(stderr, "lsr:       %u\n", block.lsr);
		//fprintf(stderr, "dlsr (ms): %u\n", uvgrtp::clock::jiffies_to_ms(block.dlsr));
	}

	/* RTCP frames can be deallocated using delete */
	delete frame;
}

void appHook(uvgrtp::frame::rtcp_app_packet* packet) {
	LOG_INFO("Received an APP packet!!");
	fprintf(stderr, "Message: '%s'", packet->payload);
        delete packet;
}

int main() {

	uvgrtp::context ctx;
	uvgrtp::session* sess = ctx.create_session("127.0.0.1");
	uvgrtp::media_stream* sender = sess->create_stream(7777, 8888, RTP_FORMAT_GENERIC, RCE_RTCP);
	uvgrtp::media_stream* receiver = sess->create_stream(8888, 7777, RTP_FORMAT_GENERIC, RCE_RTCP);

	char* message = (char*)"Hello, world!";
	size_t len = strlen(message) + 1;
	auto data = (uint8_t*)message;
	
	char* name = (char*)"name";
	char* packet_txt = (char*)"pack";
	size_t pack_len = strlen(packet_txt) + 1;
	auto pack_data = (uint8_t*)packet_txt;
	
	
	//sender->get_rtcp()->install_app_hook(appHook);

	sender->get_rtcp()->install_receiver_hook(receiver_hook);

	uvgrtp::frame::rtp_frame* frame;
	for (int i = 0; i < 5; ++i) {
		sender->push_frame(data, len, 0);
		std::this_thread::sleep_for(std::chrono::milliseconds(2000));

		frame = receiver->pull_frame();
		fprintf(stderr, "RECEIVED Message: '%s'\n", frame->payload);
		

		//receiver->get_rtcp()->send_app_packet(name, 0, pack_len, pack_data);

		uvgrtp::frame::dealloc_frame(frame);

	}
	// uncomment to recreate repetitive RTCP packets
	/*
	for (int i = 0; i < 10000; ++i) {
		std::this_thread::sleep_for(std::chrono::milliseconds(20));
	}
	*/
	
	ctx.destroy_session(sess);
	return 0;
}

rtcp_app hook and manual APP packet sending will demonstrate how synchronous packet exchange could be.

Thank you

@altonen
Copy link
Collaborator

altonen commented Jun 2, 2021

Hi,

as Marko already mentioned/implied, the RTCP code was hacked together fast and is quite untested so there be dragons but unfortunately I'm not sure what kind of pressure there is to fix these bugs right now at least.

As for these issues, I'm not sure what you mean by RTCP being horribly out of sync. I believe we set, for simplicity's sake, the RTCP interval to maximum which I believe is around 5 seconds. So every 5 seconds you should receive an RTCP report. RTCP reports are not tied to any single RTP packet but to an interval of time where multiple RTP packets may arrive.

The fix to stop the RTCP reports from coming after sender has stopped streaming is quite simple. The RTCP runner could keep track of when the last packet from the participant was received and if it was more than some interval, it could convert the participant back to receiver (i.e., it wouldn't send RTCP packets to that participant anymore). Somebody should check what the specification has to say about this though.

The crash is probably quite easy to fix. When the session is destroyed, the RTCP destructor must block until the RTCP runner has stopped. This could be done with a condition variable/simple boolean to signal the RTCP runner that is must stop.

@jrsnen
Copy link
Member

jrsnen commented Jun 2, 2021

Just to clarify on the previous response, we (Ultra Video Group) will fix all reasonable issues users encounter, but we have somewhat limited resources to dedicate to this task (after @altonen graduated). If no one else has time, I will look at this bug when I have the time. Unfortunately, I'm not very familiar with the library.

As far as I understand, RTCP reports are supposed to be sent at constant intervals regardless of how many frames the user sends.

@wowaser
Copy link
Contributor Author

wowaser commented Jun 2, 2021

@polusto That is fine, I will submit a pull request to the previous issue (about APP packets) tomorrow. This one is not as critical

@jrsnen
Copy link
Member

jrsnen commented Jul 29, 2021

I'm closing this issue since there doesn't seem to any direct bugs. There will probably be a slight improvement to the timing accuracy of the reports coming in near future. We may continue the discussion of RTCP reports in issue #59

@jrsnen jrsnen closed this as completed Jul 29, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

No branches or pull requests

3 participants