/**************************************** * RecText * Obtiene los packetes y los muestra *****************************************/ int MediaBridgeSession::RecText() { DWORD timeStamp=0; DWORD lastSeq = RTPPacket::MaxExtSeqNum; Log(">RecText\n"); //Mientras tengamos que capturar while(receivingText) { //Get packet RTPPacket *packet = rtpText.GetPacket(); //Check packet if (!packet) continue; //Get data BYTE* data = packet->GetMediaData(); //And length DWORD size = packet->GetMediaLength(); //Get extended sequence number DWORD seq = packet->GetExtSeqNum(); //Lost packets since last one DWORD lost = 0; //If not first if (lastSeq!=RTPPacket::MaxExtSeqNum) //Calculate losts lost = seq-lastSeq-1; //Update last sequence number lastSeq = seq; //Get type TextCodec::Type type = (TextCodec::Type)packet->GetCodec(); //Check the type of data if (type==TextCodec::T140RED) { //Get redundant packet RTPRedundantPacket* red = (RTPRedundantPacket*)packet; //Check lost packets count if (lost == 0) { //Create text frame TextFrame frame(timeStamp ,red->GetPrimaryPayloadData(),red->GetPrimaryPayloadSize()); //Create new timestamp associated to latest media time RTMPMetaData meta(getDifTime(&first)/1000); //Add text name meta.AddParam(new AMFString(L"onText")); //Set data meta.AddParam(new AMFString(frame.GetWChar())); //Send data SendMetaData(&meta); } else { //Timestamp of first packet (either receovered or not) DWORD ts = timeStamp; //Check if we have any red pacekt if (red->GetRedundantCount()>0) //Get the timestamp of first redundant packet ts = red->GetRedundantTimestamp(0); //If we have lost too many if (lost>red->GetRedundantCount()) //Get what we have available only lost = red->GetRedundantCount(); //For each lonot recoveredt packet send a mark for (int i=red->GetRedundantCount();i<lost;i++) { //Create frame of lost replacement TextFrame frame(ts,LOSTREPLACEMENT,sizeof(LOSTREPLACEMENT)); //Create new timestamp associated to latest media time RTMPMetaData meta(getDifTime(&first)/1000); //Add text name meta.AddParam(new AMFString(L"onText")); //Set data meta.AddParam(new AMFString(frame.GetWChar())); //Send data SendMetaData(&meta); } //Fore each recovered packet for (int i=red->GetRedundantCount()-lost;i<red->GetRedundantCount();i++) { //Create frame from recovered data TextFrame frame(red->GetRedundantTimestamp(i),red->GetRedundantPayloadData(i),red->GetRedundantPayloadSize(i)); //Create new timestamp associated to latest media time RTMPMetaData meta(getDifTime(&first)/1000); //Add text name meta.AddParam(new AMFString(L"onText")); //Set data meta.AddParam(new AMFString(frame.GetWChar())); //Send data SendMetaData(&meta); } } } else { //Create frame TextFrame frame(timeStamp,data,size); //Create new timestamp associated to latest media time RTMPMetaData meta(getDifTime(&first)/1000); //Add text name meta.AddParam(new AMFString(L"onText")); //Set data meta.AddParam(new AMFString(frame.GetWChar())); //Send data SendMetaData(&meta); } } Log("<RecText\n"); }
bool FECDecoder::AddPacket(RTPPacket* packet) { //Check if it is a redundant packet if (packet->GetCodec()==VideoCodec::RED) { //Get the redundant packet RTPRedundantPacket *red = (RTPRedundantPacket *)packet; //Check primary redundant type if (red->GetPrimaryCodec()==VideoCodec::ULPFEC) { //Create new FEC data FECData *fec = new FECData(red->GetPrimaryPayloadData(),red->GetPrimaryPayloadSize()); //Log Debug("-fec primary red data at %d\n",fec->GetBaseExtSeq()); //Append it codes.insert(std::pair<DWORD,FECData*>(fec->GetBaseExtSeq(),fec)); //Packet contained no media return false; } //Ensure we don't have it already if (medias.find(packet->GetExtSeqNum())==medias.end()) //Add media packet medias[packet->GetExtSeqNum()] = red->CreatePrimaryPacket(); //For each redundant data for (int i=0;i<red->GetRedundantCount();++i) { //Check if it is a FEC pacekt if (red->GetRedundantCodec(i)==VideoCodec::ULPFEC) { //Create new FEC data FECData *fec = new FECData(red->GetRedundantPayloadData(i),red->GetRedundantPayloadSize(i)); //Log Debug("-fec red data at %d\n",fec->GetBaseExtSeq()); //Append it codes.insert(std::pair<DWORD,FECData*>(fec->GetBaseExtSeq(),fec)); } } } else if (packet->GetCodec()==VideoCodec::ULPFEC ) { //Create new FEC data FECData *fec = new FECData(packet->GetMediaData(),packet->GetMediaLength()); //Log Debug("-fec data at %d\n",fec->GetBaseExtSeq()); //Append it codes.insert(std::pair<DWORD,FECData*>(fec->GetBaseExtSeq(),fec)); //Packet contained no media return false; } else if (packet->GetCodec()==VideoCodec::FLEXFEC) { //TODO return false; } else { //Check if we have it already if (medias.find(packet->GetExtSeqNum())!=medias.end()) //Do nothing return false; //Add media packet medias[packet->GetExtSeqNum()] = packet->Clone(); } //Get last seq number DWORD seq = medias.rbegin()->first; //Remove unused packets RTPOrderedPackets::iterator it = medias.begin(); //Delete everything until seq-63 while (it->first<seq-63 && it!=medias.end()) { //Delete rtp packet delete (it->second); //Erase it medias.erase(it++); } //Now clean recovery codes FECOrderedData::iterator it2 = codes.begin(); //Check base sequence while (it2->first<seq-63 && it2!=codes.end()) { //Delete object delete(it2->second); //Erase and move to next codes.erase(it2++); } //Packet had media return true; }