// 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); }
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; }