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. 21static 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} 27static 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. 35DEFINE_int32(red, 117, "RTP payload type for RED"); 36static const bool red_dummy = 37 google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType); 38DEFINE_int32(audio_level, 1, "Extension ID for audio level (RFC 6464)"); 39static const bool audio_level_dummy = 40 google::RegisterFlagValidator(&FLAGS_audio_level, &ValidateExtensionId); 41 42int 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 printf("Input file: %s\n", argv[1]); 63 webrtc::scoped_ptr<webrtc::test::RtpFileSource> file_source( 64 webrtc::test::RtpFileSource::Create(argv[1])); 65 assert(file_source.get()); 66 // Set RTP extension ID. 67 bool print_audio_level = false; 68 if (!google::GetCommandLineFlagInfoOrDie("audio_level").is_default) { 69 print_audio_level = true; 70 file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel, 71 FLAGS_audio_level); 72 } 73 74 FILE* out_file; 75 if (argc == 3) { 76 out_file = fopen(argv[2], "wt"); 77 if (!out_file) { 78 printf("Cannot open output file %s\n", argv[2]); 79 return -1; 80 } 81 printf("Output file: %s\n\n", argv[2]); 82 } else { 83 out_file = stdout; 84 } 85 86 // Print file header. 87 fprintf(out_file, "SeqNo TimeStamp SendTime Size PT M SSRC"); 88 if (print_audio_level) { 89 fprintf(out_file, " AuLvl (V)"); 90 } 91 fprintf(out_file, "\n"); 92 93 webrtc::scoped_ptr<webrtc::test::Packet> packet; 94 while (!file_source->EndOfFile()) { 95 packet.reset(file_source->NextPacket()); 96 if (!packet.get()) { 97 // This is probably an RTCP packet. Move on to the next one. 98 continue; 99 } 100 assert(packet.get()); 101 // Write packet data to file. 102 fprintf(out_file, 103 "%5u %10u %10u %5i %5i %2i %#08X", 104 packet->header().sequenceNumber, 105 packet->header().timestamp, 106 static_cast<unsigned int>(packet->time_ms()), 107 static_cast<int>(packet->packet_length_bytes()), 108 packet->header().payloadType, 109 packet->header().markerBit, 110 packet->header().ssrc); 111 if (print_audio_level && packet->header().extension.hasAudioLevel) { 112 // |audioLevel| consists of one bit for "V" and then 7 bits level. 113 fprintf(out_file, 114 " %5u (%1i)", 115 packet->header().extension.audioLevel & 0x7F, 116 (packet->header().extension.audioLevel & 0x80) == 0 ? 0 : 1); 117 } 118 fprintf(out_file, "\n"); 119 120 if (packet->header().payloadType == FLAGS_red) { 121 std::list<webrtc::RTPHeader*> red_headers; 122 packet->ExtractRedHeaders(&red_headers); 123 while (!red_headers.empty()) { 124 webrtc::RTPHeader* red = red_headers.front(); 125 assert(red); 126 fprintf(out_file, 127 "* %5u %10u %10u %5i\n", 128 red->sequenceNumber, 129 red->timestamp, 130 static_cast<unsigned int>(packet->time_ms()), 131 red->payloadType); 132 red_headers.pop_front(); 133 delete red; 134 } 135 } 136 } 137 138 fclose(out_file); 139 140 return 0; 141} 142