1324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver/* 2324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 3324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * 4324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * Use of this source code is governed by a BSD-style license 5324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * that can be found in the LICENSE file in the root of the source 6324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * tree. An additional intellectual property rights grant can be found 7324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * in the file PATENTS. All contributing project authors may 8324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver * be found in the AUTHORS file in the root of the source tree. 9324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver */ 10324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 11324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <assert.h> 12324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <stdio.h> 13324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include <vector> 14324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 15324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "google/gflags.h" 16324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "webrtc/modules/audio_coding/neteq/tools/packet.h" 17324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "webrtc/modules/audio_coding/neteq/tools/rtp_file_source.h" 18324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver#include "webrtc/system_wrappers/interface/scoped_ptr.h" 19324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 20324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Flag validator. 21324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic bool ValidatePayloadType(const char* flagname, int32_t value) { 22324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (value >= 0 && value <= 127) // Value is ok. 23324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 24324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value)); 25324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 26324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 27324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic bool ValidateExtensionId(const char* flagname, int32_t value) { 28324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (value > 0 && value <= 255) // Value is ok. 29324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return true; 30324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("Invalid value for --%s: %d\n", flagname, static_cast<int>(value)); 31324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return false; 32324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver} 33324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 34324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver// Define command line flags. 35324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDEFINE_int32(red, 117, "RTP payload type for RED"); 36324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic const bool red_dummy = 37324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver google::RegisterFlagValidator(&FLAGS_red, &ValidatePayloadType); 38324c4644fee44b9898524c09511bd33c3f12e2dfBen GruverDEFINE_int32(audio_level, 1, "Extension ID for audio level (RFC 6464)"); 39324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverstatic const bool audio_level_dummy = 40324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver google::RegisterFlagValidator(&FLAGS_audio_level, &ValidateExtensionId); 41324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 42324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruverint main(int argc, char* argv[]) { 43324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver std::string program_name = argv[0]; 44324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver std::string usage = 45324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Tool for parsing an RTP dump file to text output.\n" 46324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Run " + 47324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver program_name + 48324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver " --helpshort for usage.\n" 49324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Example usage:\n" + 50324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver program_name + " input.rtp output.txt\n\n" + 51324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Output is sent to stdout if no output file is given." + 52324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver "Note that this tool can read files with our without payloads."; 53324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver google::SetUsageMessage(usage); 54324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver google::ParseCommandLineFlags(&argc, &argv, true); 55324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 56324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (argc != 2 && argc != 3) { 57324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Print usage information. 58324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("%s", google::ProgramUsage()); 59324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return 0; 60324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 61324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 62324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("Input file: %s\n", argv[1]); 63324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver webrtc::scoped_ptr<webrtc::test::RtpFileSource> file_source( 64324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver webrtc::test::RtpFileSource::Create(argv[1])); 65324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver assert(file_source.get()); 66324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver // Set RTP extension ID. 67324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver bool print_audio_level = false; 68324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!google::GetCommandLineFlagInfoOrDie("audio_level").is_default) { 69324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver print_audio_level = true; 70324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel, 71324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver FLAGS_audio_level); 72324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 73324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver 74324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver FILE* out_file; 75324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (argc == 3) { 76324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver out_file = fopen(argv[2], "wt"); 77324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver if (!out_file) { 78324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("Cannot open output file %s\n", argv[2]); 79324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver return -1; 80324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 81324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver printf("Output file: %s\n\n", argv[2]); 82324c4644fee44b9898524c09511bd33c3f12e2dfBen Gruver } 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