Skip to content

Instantly share code, notes, and snippets.

@roxlu
Created July 23, 2011 16:14
Show Gist options
  • Select an option

  • Save roxlu/1101594 to your computer and use it in GitHub Desktop.

Select an option

Save roxlu/1101594 to your computer and use it in GitHub Desktop.
Testing RTP video stream
#include "ofxRTPSession.h"
#include "ofMain.h" // tmp debug
ofxRTPSession::ofxRTPSession() {
must_send = false;
}
ofxRTPSession& ofxRTPSession::start() {
session_params.SetAcceptOwnPackets(true);
//session_params.SetMaximumPacketSize((1024*60));
cout << "Session timestamp unit: " << session_params.GetOwnTimestampUnit() << endl;
cout << "Session accept own packets: " << session_params.AcceptOwnPackets() << endl;
cout << "Tranmission portbase: " << transmission_params.GetPortbase() << endl;
cout << "Destination address: " << dest_ip << endl;
cout << "Destination port: " << dest_port << endl;
// create session
int status = rtp_session.Create(session_params, &transmission_params);
if(status < 0) {
std::cerr << RTPGetErrorString(status) << std::endl;
exit(-1);
}
// now tell to which address we want to send data.
uint8_t dest_ip_array[4] = {0,0,0,0};
stringToIPArray(dest_ip, dest_ip_array);
RTPIPv4Address dest_addr(dest_ip_array, dest_port);
status = rtp_session.AddDestination(dest_addr);
if(status < 0) {
std::cerr << jrtplib::RTPGetErrorString(status);
exit(-1);
}
// start our thread.
thread.start(*this);
return *this;
}
void ofxRTPSession::sendImage(unsigned char* pix, int w, int h) {
Mutex::ScopedLock sl(mutex);
int s = w * h * 3;
size_t num_bytes = s * sizeof(unsigned char);
unsigned char* copied_data = new unsigned char[s];
// copy image data.
memcpy(copied_data, pix, num_bytes);
// create a new frame and add it to our send queue.
ofxRTPVideoFrame* video_frame = new ofxRTPVideoFrame(copied_data, num_bytes);
images.push_back(video_frame);
}
// testing.
void ofxRTPSession::testSend() {
must_send = true;
}
void ofxRTPSession::run() {
// for now we copied this from the documetation.
// http://research.edm.uhasselt.be/jori/jrtplib/documentation/index.html
RTPTime delay(0.120);
RTPTime start_time = RTPTime::CurrentTime();
bool done = false;
int status = 0;
ofxRTPVideoFrame* frame = NULL;
while(!done) {
// Lock our image queue and get a new frame when necessary.
must_send = false;
{
Mutex::ScopedLock sl(mutex);
if(images.size() > 0) {
must_send = true;
frame = images.front();
images.pop_front();
}
}
if(must_send && frame != NULL) {
// frame contains the pixel data we want to
// send to our participants. It contains the pixel array
// of a size: image.width * image.height * 3 (rgb colors).
unsigned char* data_buf = frame->pixels;
// In this loop we send all image data using multiple packets
// Question: Is this how it's supposed to work? How does the
// receiving part build up the image again?
int start_byte = 0;
int buff_size = 1024;
int bytes_to_send = frame->num_bytes;
while(bytes_to_send > 0) {
status = rtp_session.SendPacket(
(void*)(frame->pixels+start_byte)
,buff_size
,0
,false
,10 // for now just some value...
);
if(status < 0) {
std::cerr << RTPGetErrorString(status) << std::endl;
exit(-1);
}
start_byte += buff_size;
bytes_to_send -= buff_size;
}
delete frame;
frame = NULL;
}
// check if participants have waiting data.
rtp_session.BeginDataAccess(); // multi threaded sync.
if(rtp_session.GotoFirstSourceWithData()) {
do {
RTPPacket* packet;
while((packet = rtp_session.GetNextPacket()) != NULL) {
// TODO: do something with packet.
cout << "Got packet with extended sequence number: "
<< packet->GetExtendedSequenceNumber()
<< " from SSRC: " << packet->GetSSRC()
<< " length:" << packet->GetPayloadLength()
<< std::endl;
// cleanup
rtp_session.DeletePacket(packet);
}
} while(rtp_session.GotoNextSourceWithData());
}
rtp_session.EndDataAccess();
status = rtp_session.Poll();
if(status < 0) {
std::cerr << RTPGetErrorString(status) << endl;
}
}
}
void ofxRTPSession::stringToIPArray(std::string ip, uint8_t* array) {
std::string ip_piece;
std::istringstream is(ip);
int c = 0;
while(std::getline(is, ip_piece, '.')) {
istringstream ostr(ip_piece);
int num;
ostr >> num;
array[c] = num;
c++;
}
}
void ofxRTPSession::update() {
}
// ========================================================================
// ========================================================================
// ========================================================================
// Main application (just for reference)
// ========================================================================
// ========================================================================
// ========================================================================
// testApp.cpp
#include "testApp.h"
//--------------------------------------------------------------
void testApp::setup(){
ofBackground(33);
ofSetWindowPosition(10,300);
server = rtp.createSession();
server->setLocalPort(9000)
.setDestinationIP("127.0.0.1")
.setDestinationPort(8000)
.setTimestampUnit(1.0/10.0)
.start();
video_player.loadMovie("fingers.mov");
video_player.play();
}
//--------------------------------------------------------------
void testApp::update(){
video_player.update();
if(video_player.isFrameNew()) {
server->sendImage(video_player.getPixels(), video_player.getWidth(), video_player.getHeight());
}
ofSetWindowTitle(ofToString(ofGetFrameRate()) + " - server " );
}
//--------------------------------------------------------------
void testApp::draw(){
ofDrawBitmapString("server",10,20);
video_player.draw(10,30,120,80);
}
// ========================================================================
// ========================================================================
// testApp.h
// ========================================================================
// ========================================================================
#pragma once
#include "ofMain.h"
#include "ofxRTP.h"
class testApp : public ofBaseApp{
public:
void setup();
void update();
void draw();
void keyPressed (int key);
void keyReleased(int key);
void mouseMoved(int x, int y );
void mouseDragged(int x, int y, int button);
void mousePressed(int x, int y, int button);
void mouseReleased(int x, int y, int button);
void windowResized(int w, int h);
void dragEvent(ofDragInfo dragInfo);
void gotMessage(ofMessage msg);
ofxRTP rtp;
ofxRTPSession* server;
ofVideoPlayer video_player;
};
@djougue
Copy link

djougue commented Feb 10, 2016

hi, please i am interesting by the part of your program used to send image throught rtpLib:

                        unsigned char* data_buf = frame->pixels;

            // In this loop we send all image data using multiple packets 
            // Question: Is this how it's supposed to work? How does the
            // receiving part build up the image again?
            int start_byte = 0;
            int buff_size = 1024;
            int bytes_to_send = frame->num_bytes;

            while(bytes_to_send > 0) {
                status = rtp_session.SendPacket(
                    (void*)(frame->pixels+start_byte)
                    ,buff_size
                    ,0
                    ,false
                    ,10     // for now just some value... 
                );

                if(status < 0) {
                    std::cerr << RTPGetErrorString(status) << std::endl;
                    exit(-1);
                }

                start_byte += buff_size;
                bytes_to_send -= buff_size;
            }

```I believe that you send image by packet because the maximum size of packet allow by jrtpLib isn't enough (up to 1024). But i didn't seen any on the server side were you reconstitute the image in order to obtain the initial image(given that you have segmented the initial packet into sub packet)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment