1 /* 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3 * 4 * Use of this source code is governed by a BSD-style license 5 * that can be found in the LICENSE file in the root of the source 6 * tree. An additional intellectual property rights grant can be found 7 * in the file PATENTS. All contributing project authors may 8 * be found in the AUTHORS file in the root of the source tree. 9 */ 10 11 #include <assert.h> 12 #include <stdio.h> 13 #include <vector> 14 15 #include "google/gflags.h" 16 #include "webrtc/modules/audio_coding/neteq/tools/packet.h" 17 #include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" 18 #include "webrtc/system_wrappers/interface/scoped_ptr.h" 19 20 // Flag validator. 21 static bool ValidatePayloadType(const char* flagname, int32_t value) { 22 if (value >= 0 && value <= 127) // Value is ok. 23 return true; 24 printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value)); 25 return false; 26 } 27 static bool ValidateExtensionId(const char* flagname, int32_t value) { 28 if (value > 0 && value <= 255) // Value is ok. 29 return true; 30 printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value)); 31 return false; 32 } 33 34 // Define command line flags. 35 DEFINE_int32(red, 117, "RTP payload type for RED"); 36 static const bool red_dummy = 37 google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType); 38 DEFINE_int32(audio_level, 1, "Extension ID for audio level (RFC 6464)"); 39 static const bool audio_level_dummy = 40 google::RegisterFlagValidator(&FLAGS_audio_level, &ValidateExtensionId); 41 42 int main(int argc, char* argv[]) { 43 std::string program_name = argv[0]; 44 std::string usage = 45 "Tool for parsing an RTP dump file to text output.\n" 46 "Run " + 47 program_name + 48 " --helpshort for usage.\n" 49 "Example usage:\n" + 50 program_name + " input.rtp output.txt\n\n" + 51 "Output is sent to stdout if no output file is given." + 52 "Note that this tool can read files with our without payloads."; 53 google::SetUsageMessage(usage); 54 google::ParseCommandLineFlags(&argc, &argv, true); 55 56 if (argc != 2 && argc != 3) { 57 // Print usage information. 58 printf("%s", google::ProgramUsage()); 59 return 0; 60 } 61 62 FILE* in_file = fopen(argv[1], "rb"); 63 if (!in_file) { 64 printf("Cannot open input file %s\n", argv[1]); 65 return -1; 66 } 67 printf("Input file: %s\n", argv[1]); 68 webrtc::scoped_ptr<webrtc::test::RtpFileSource> file_source( 69 webrtc::test::RtpFileSource::Create(argv[1])); 70 assert(file_source.get()); 71 // Set RTP extension ID. 72 bool print_audio_level = false; 73 if (!google::GetCommandLineFlagInfoOrDie("audio_level").is_default) { 74 print_audio_level = true; 75 file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel, 76 FLAGS_audio_level); 77 } 78 79 FILE* out_file; 80 if (argc == 3) { 81 out_file = fopen(argv[2], "wt"); 82 if (!out_file) { 83 printf("Cannot open output file %s\n", argv[2]); 84 return -1; 85 } 86 printf("Output file: %s\n\n", argv[2]); 87 } else { 88 out_file = stdout; 89 } 90 91 // Print file header. 92 fprintf(out_file, "SeqNo TimeStamp SendTime Size PT M SSRC"); 93 if (print_audio_level) { 94 fprintf(out_file, " AuLvl (V)"); 95 } 96 fprintf(out_file, "\n"); 97 98 webrtc::scoped_ptr<webrtc::test::Packet> packet; 99 while (!file_source->EndOfFile()) { 100 packet.reset(file_source->NextPacket()); 101 if (!packet.get()) { 102 // This is probably an RTCP packet. Move on to the next one. 103 continue; 104 } 105 assert(packet.get()); 106 // Write packet data to file. 107 fprintf(out_file, 108 "%5u %10u %10u %5i %5i %2i %#08X", 109 packet->header().sequenceNumber, 110 packet->header().timestamp, 111 static_cast<unsigned int>(packet->time_ms()), 112 static_cast<int>(packet->packet_length_bytes()), 113 packet->header().payloadType, 114 packet->header().markerBit, 115 packet->header().ssrc); 116 if (print_audio_level && packet->header().extension.hasAudioLevel) { 117 // |audioLevel| consists of one bit for "V" and then 7 bits level. 118 fprintf(out_file, 119 " %5u (%1i)", 120 packet->header().extension.audioLevel & 0x7F, 121 (packet->header().extension.audioLevel & 0x80) == 0 ? 0 : 1); 122 } 123 fprintf(out_file, "\n"); 124 125 if (packet->header().payloadType == FLAGS_red) { 126 std::list<webrtc::RTPHeader*> red_headers; 127 packet->ExtractRedHeaders(&red_headers); 128 while (!red_headers.empty()) { 129 webrtc::RTPHeader* red = red_headers.front(); 130 assert(red); 131 fprintf(out_file, 132 "* %5u %10u %10u %5i\n", 133 red->sequenceNumber, 134 red->timestamp, 135 static_cast<unsigned int>(packet->time_ms()), 136 red->payloadType); 137 red_headers.pop_front(); 138 delete red; 139 } 140 } 141 } 142 143 fclose(in_file); 144 fclose(out_file); 145 146 return 0; 147 } 148