void Java_cn_nickwar_MainActivity_nativeWorker(JNIEnv* env, jobject obj) { uint16_t portbase=8000,destport=9000; std::string ipstr="192.168.1.102"; uint32_t destip=inet_addr(ipstr.c_str()); int status,i,num; RTPSession session; RTPSessionParams sessionparams; RTPUDPv4TransmissionParams transparams; RTPIPv4Address addr; if (destip == INADDR_NONE) { __android_log_print(ANDROID_LOG_DEBUG, "pspm.native", "Bad IP address specified"); } destip = ntohl(destip); num = 40; sessionparams.SetOwnTimestampUnit(1.0/10.0); sessionparams.SetAcceptOwnPackets(true); transparams.SetPortbase(portbase); addr.SetIP(destip); addr.SetPort(destport); status = session.Create(sessionparams,&transparams); if (status<0) { std::string tmp = "Create:"; __android_log_print(ANDROID_LOG_DEBUG, "pspm.native", (tmp+RTPGetErrorString(status)).c_str()); } status = session.AddDestination(addr); if (status<0) { std::string tmp = "AddDestination:"; __android_log_print(ANDROID_LOG_DEBUG, "pspm.native", (tmp+RTPGetErrorString(status)).c_str()); } while(!m_bExitApp) { session.BeginDataAccess(); unsigned char *buff = NULL; if (session.GotoFirstSourceWithData()) { do { RTPPacket *pack; while((pack = session.GetNextPacket()) !=NULL) { __android_log_print(ANDROID_LOG_DEBUG, "pspm.native", "got packet!\n"); char message[26]; sprintf(message, "got packet"); jstring messageString = env->NewStringUTF(message); env->CallVoidMethod(obj, rtpresultFromJNI, messageString); if (NULL != env->ExceptionOccurred()) { // break; continue; } if (pack->GetPayloadLength()>0) { buff = pack->GetPayloadData(); __android_log_print(ANDROID_LOG_DEBUG, "pspm.native", "packt data:%s",buff); } session.DeletePacket(pack); } } while(session.GotoNextSourceWithData()); } session.EndDataAccess(); // #ifndef RTP_SUPPORT_THREAD status = sess.Poll(); if (status<0) { session.Destroy(); return; } #endif RTPTime::Wait(RTPTime(0,5000)); } session.Destroy(); return; }
// Thread function for RTP session. static void* rtpSessionThread(void *arg) { VideoStream* video = reinterpret_cast<VideoStream*>(arg); u_int8_t bigBuffer[MAX_FRAME_SIZE]; unsigned int lastPacketTimestamp = 0; unsigned int currentIndex = 0; double last_time = 0; RTPSession session = createRtpSession(video->getMulticastIP(), video->getPort()); while (1) { session.Poll(); // Distribute data from the session to connected clients if we've // got anything session.BeginDataAccess(); if (session.GotoFirstSourceWithData()) { do { RTPPacket *packet = NULL; while ((packet = session.GetNextPacket()) != NULL) { if ((packet->GetPayloadLength() > sizeof(bigBuffer)) || (packet->GetPayloadLength() == 0)) { // Free the packet, we're not going to use it. session.DeletePacket(packet); continue; // Exit this level of the loop and drop it } // Check timestamps for new data. A new timestamp means // this is from a different time. if (packet->GetTimestamp() != lastPacketTimestamp) { video->decode((uint8_t*)&bigBuffer[0], currentIndex); currentIndex = 0; memset(&bigBuffer[0], 0, sizeof(bigBuffer)); } // End new timestamp optimization. // Copy data into buffer if (currentIndex + packet->GetPayloadLength() > sizeof(bigBuffer)) { throw std::runtime_error("Frame buffer overflow"); } memcpy(&bigBuffer[currentIndex], packet->GetPayloadData(), packet->GetPayloadLength()); currentIndex += packet->GetPayloadLength(); // Mark our last timestamp lastPacketTimestamp = packet->GetTimestamp(); // Free the packet. session.DeletePacket(packet); } } while (session.GotoNextSourceWithData()); } session.EndDataAccess(); RTPTime delay(0, 100); // 100usec // Update More Data bool moreData; session.WaitForIncomingData(delay, &moreData); } // Leave the session while sending BYE. RTPTime timeout(0.75f); // Wait briefly. const char* reason = "Session Destroyed."; unsigned int reasonlen = strlen(reason); if (session.IsActive()) session.BYEDestroy(timeout, reason, reasonlen); }
int main(void) { RTPSession sess; int portbase; unsigned long destip; int destport; char ipstr[256]; int status; char dummybuffer[1024]; struct timeval rttprev = {0,0},rtt,tv; int sock1,sock2; bool done; fd_set fdset; /* First, we'll ask for the necessary information */ printf("Enter the local portbase\n"); scanf("%d",&portbase); printf("\n"); printf("Enter the destination IP address\n"); scanf("%s",ipstr); destip = inet_addr(ipstr); if (destip == INADDR_NONE) { printf("Bad IP address specified\n"); return -1; } // The inet_addr function returns a value in network byte order, but // we need the IP address in host byte order, so we use a call to // ntohl destip = ntohl(destip); printf("Enter the destination port\n"); scanf("%d",&destport); /* Now, we'll create a RTP session, set the destination, send some packets and poll for incoming data. */ status = sess.Create(portbase); checkerror(status); /* Get the sockets, so we can use them in a 'select' call */ sess.GetRTPSocket(&sock1); sess.GetRTCPSocket(&sock2); status = sess.AddDestination(destip,destport); checkerror(status); printf("Press return to quit...\n"); done = false; while (!done) { /* Just send something */ status = sess.SendPacket("1234567890",10,0,false,10); checkerror(status); /* Wait for incoming data, or wait just one second */ tv.tv_sec = 1; tv.tv_usec = 0; FD_ZERO(&fdset); FD_SET(sock1,&fdset); FD_SET(sock2,&fdset); FD_SET(0,&fdset); // check for keypress select(FD_SETSIZE,&fdset,NULL,NULL,&tv); if (FD_ISSET(0,&fdset)) done = true; /* poll for incoming data */ status = sess.PollData(); /* check incoming packets */ if (sess.GotoFirstSourceWithData()) { do { RTPSourceData *srcdat; srcdat = sess.GetCurrentSourceInfo(); srcdat->FlushPackets(); // we don't need the actual data rtt = srcdat->INF_GetRoundTripTime(); if (rtt.tv_sec != 0 || rtt.tv_usec != 0) { if ((rtt.tv_sec != rttprev.tv_sec) || (rtt.tv_usec != rttprev.tv_usec)) { double t; t = (double)rtt.tv_sec; t += ((double)rtt.tv_usec)/1000000.0; t *= 1000.0; // we want milliseconds; printf("rtt: %f ms\n",(float)t); rttprev = rtt; } } } while (sess.GotoNextSourceWithData()); } } return 0; }