| /* |
| * Copyright (c) 2011 The WebRTC project authors. All Rights Reserved. |
| * |
| * Use of this source code is governed by a BSD-style license |
| * that can be found in the LICENSE file in the root of the source |
| * tree. An additional intellectual property rights grant can be found |
| * in the file PATENTS. All contributing project authors may |
| * be found in the AUTHORS file in the root of the source tree. |
| */ |
| |
| #include <algorithm> |
| #include <stdio.h> |
| #include <vector> |
| |
| #include "NETEQTEST_RTPpacket.h" |
| #include "gtest/gtest.h" |
| |
| /*********************/ |
| /* Misc. definitions */ |
| /*********************/ |
| |
| #define FIRSTLINELEN 40 |
| |
| bool pktCmp (NETEQTEST_RTPpacket *a, NETEQTEST_RTPpacket *b) |
| { |
| return (a->time() < b->time()); |
| } |
| |
| |
| int main(int argc, char* argv[]) |
| { |
| FILE *inFile=fopen(argv[1],"rb"); |
| if (!inFile) |
| { |
| printf("Cannot open input file %s\n", argv[1]); |
| return(-1); |
| } |
| printf("Input RTP file: %s\n",argv[1]); |
| |
| FILE *statFile=fopen(argv[2],"rt"); |
| if (!statFile) |
| { |
| printf("Cannot open timing file %s\n", argv[2]); |
| return(-1); |
| } |
| printf("Timing file: %s\n",argv[2]); |
| |
| FILE *outFile=fopen(argv[3],"wb"); |
| if (!outFile) |
| { |
| printf("Cannot open output file %s\n", argv[3]); |
| return(-1); |
| } |
| printf("Output RTP file: %s\n\n",argv[3]); |
| |
| // read all statistics and insert into map |
| // read first line |
| char tempStr[100]; |
| if (fgets(tempStr, 100, statFile) == NULL) |
| { |
| printf("Failed to read timing file %s\n", argv[2]); |
| return (-1); |
| } |
| // define map |
| std::map<std::pair<WebRtc_UWord16, WebRtc_UWord32>, WebRtc_UWord32> |
| packetStats; |
| WebRtc_UWord16 seqNo; |
| WebRtc_UWord32 ts; |
| WebRtc_UWord32 sendTime; |
| |
| while(fscanf(statFile, "%hu %u %u %*i %*i\n", &seqNo, &ts, &sendTime) == 3) |
| { |
| std::pair<WebRtc_UWord16, WebRtc_UWord32> tempPair = |
| std::pair<WebRtc_UWord16, WebRtc_UWord32>(seqNo, ts); |
| |
| packetStats[tempPair] = sendTime; |
| } |
| |
| fclose(statFile); |
| |
| // read file header and write directly to output file |
| char firstline[FIRSTLINELEN]; |
| if (fgets(firstline, FIRSTLINELEN, inFile) == NULL) |
| { |
| printf("Failed to read first line of input file %s\n", argv[1]); |
| return (-1); |
| } |
| fputs(firstline, outFile); |
| // start_sec + start_usec + source + port + padding |
| const unsigned int kRtpDumpHeaderSize = 4 + 4 + 4 + 2 + 2; |
| if (fread(firstline, 1, kRtpDumpHeaderSize, inFile) != kRtpDumpHeaderSize) |
| { |
| printf("Failed to read RTP dump header from input file %s\n", argv[1]); |
| return (-1); |
| } |
| if (fwrite(firstline, 1, kRtpDumpHeaderSize, outFile) != kRtpDumpHeaderSize) |
| { |
| printf("Failed to write RTP dump header to output file %s\n", argv[3]); |
| return (-1); |
| } |
| |
| std::vector<NETEQTEST_RTPpacket *> packetVec; |
| |
| while (1) |
| { |
| // insert in vector |
| NETEQTEST_RTPpacket *newPacket = new NETEQTEST_RTPpacket(); |
| if (newPacket->readFromFile(inFile) < 0) |
| { |
| // end of file |
| break; |
| } |
| |
| // look for new send time in statistics vector |
| std::pair<WebRtc_UWord16, WebRtc_UWord32> tempPair = |
| std::pair<WebRtc_UWord16, WebRtc_UWord32>(newPacket->sequenceNumber(), newPacket->timeStamp()); |
| |
| WebRtc_UWord32 newSendTime = packetStats[tempPair]; |
| if (newSendTime >= 0) |
| { |
| newPacket->setTime(newSendTime); // set new send time |
| packetVec.push_back(newPacket); // insert in vector |
| } |
| else |
| { |
| // negative value represents lost packet |
| // don't insert, but delete packet object |
| delete newPacket; |
| } |
| |
| } |
| |
| // sort the vector according to send times |
| std::sort(packetVec.begin(), packetVec.end(), pktCmp); |
| |
| std::vector<NETEQTEST_RTPpacket *>::iterator it; |
| for (it = packetVec.begin(); it != packetVec.end(); it++) |
| { |
| // write to out file |
| if ((*it)->writeToFile(outFile) < 0) |
| { |
| printf("Error writing to file\n"); |
| return(-1); |
| } |
| |
| // delete packet |
| delete *it; |
| } |
| |
| fclose(inFile); |
| fclose(outFile); |
| |
| return 0; |
| } |