blob: f9390381cd38d0d12ec113a313565eadf70484fe [file] [log] [blame]
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +00001/*
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>
kwiberg2d0c3322016-02-14 09:28:33 -080013
14#include <memory>
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000015#include <vector>
16
Mirko Bonadei92ea95e2017-09-15 06:47:31 +020017#include "modules/audio_coding/neteq/tools/packet.h"
18#include "modules/audio_coding/neteq/tools/rtp_file_source.h"
19#include "rtc_base/flags.h"
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000020
21// Define command line flags.
Mirko Bonadeic538fc72018-10-19 15:04:07 +000022DEFINE_int(red, 117, "RTP payload type for RED");
23DEFINE_int(audio_level,
24 -1,
25 "Extension ID for audio level (RFC 6464); "
26 "-1 not to print audio level");
27DEFINE_int(abs_send_time,
28 -1,
29 "Extension ID for absolute sender time; "
30 "-1 not to print absolute send time");
31DEFINE_bool(help, false, "Print this message");
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000032
33int main(int argc, char* argv[]) {
34 std::string program_name = argv[0];
35 std::string usage =
36 "Tool for parsing an RTP dump file to text output.\n"
37 "Run " +
38 program_name +
oprypin6e09d872017-08-31 03:21:39 -070039 " --help for usage.\n"
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000040 "Example usage:\n" +
41 program_name + " input.rtp output.txt\n\n" +
oprypin6e09d872017-08-31 03:21:39 -070042 "Output is sent to stdout if no output file is given. " +
43 "Note that this tool can read files with or without payloads.\n";
Yves Gerey665174f2018-06-19 15:03:05 +020044 if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || FLAG_help ||
45 (argc != 2 && argc != 3)) {
oprypin6e09d872017-08-31 03:21:39 -070046 printf("%s", usage.c_str());
47 if (FLAG_help) {
48 rtc::FlagList::Print(nullptr, false);
49 return 0;
50 }
51 return 1;
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000052 }
53
Yves Gerey665174f2018-06-19 15:03:05 +020054 RTC_CHECK(FLAG_red >= 0 && FLAG_red <= 127); // Payload type
55 RTC_CHECK(FLAG_audio_level == -1 || // Default
56 (FLAG_audio_level > 0 && FLAG_audio_level <= 255)); // Extension ID
57 RTC_CHECK(
58 FLAG_abs_send_time == -1 || // Default
oprypin6e09d872017-08-31 03:21:39 -070059 (FLAG_abs_send_time > 0 && FLAG_abs_send_time <= 255)); // Extension ID
60
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000061 printf("Input file: %s\n", argv[1]);
kwiberg2d0c3322016-02-14 09:28:33 -080062 std::unique_ptr<webrtc::test::RtpFileSource> file_source(
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000063 webrtc::test::RtpFileSource::Create(argv[1]));
64 assert(file_source.get());
Henrik Lundinb0b54252015-04-17 11:47:07 +020065 // Set RTP extension IDs.
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000066 bool print_audio_level = false;
oprypin6e09d872017-08-31 03:21:39 -070067 if (FLAG_audio_level != -1) {
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000068 print_audio_level = true;
69 file_source->RegisterRtpHeaderExtension(webrtc::kRtpExtensionAudioLevel,
oprypin6e09d872017-08-31 03:21:39 -070070 FLAG_audio_level);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000071 }
Henrik Lundinb0b54252015-04-17 11:47:07 +020072 bool print_abs_send_time = false;
oprypin6e09d872017-08-31 03:21:39 -070073 if (FLAG_abs_send_time != -1) {
Henrik Lundinb0b54252015-04-17 11:47:07 +020074 print_abs_send_time = true;
75 file_source->RegisterRtpHeaderExtension(
oprypin6e09d872017-08-31 03:21:39 -070076 webrtc::kRtpExtensionAbsoluteSendTime, FLAG_abs_send_time);
Henrik Lundinb0b54252015-04-17 11:47:07 +020077 }
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +000078
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.
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000092 fprintf(out_file, "SeqNo TimeStamp SendTime Size PT M SSRC");
93 if (print_audio_level) {
94 fprintf(out_file, " AuLvl (V)");
95 }
Henrik Lundinb0b54252015-04-17 11:47:07 +020096 if (print_abs_send_time) {
97 fprintf(out_file, " AbsSendTime");
98 }
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +000099 fprintf(out_file, "\n");
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +0000100
Henrik Lundinb0b54252015-04-17 11:47:07 +0200101 uint32_t max_abs_send_time = 0;
102 int cycles = -1;
kwiberg2d0c3322016-02-14 09:28:33 -0800103 std::unique_ptr<webrtc::test::Packet> packet;
henrik.lundin@webrtc.org4b133da2014-10-02 08:19:38 +0000104 while (true) {
henrik.lundin46ba49c2016-05-24 22:50:47 -0700105 packet = file_source->NextPacket();
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000106 if (!packet.get()) {
henrik.lundin@webrtc.org4b133da2014-10-02 08:19:38 +0000107 // End of file reached.
108 break;
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000109 }
Henrik Lundinb0b54252015-04-17 11:47:07 +0200110 // Write packet data to file. Use virtual_packet_length_bytes so that the
111 // correct packet sizes are printed also for RTP header-only dumps.
Yves Gerey665174f2018-06-19 15:03:05 +0200112 fprintf(out_file, "%5u %10u %10u %5i %5i %2i %#08X",
113 packet->header().sequenceNumber, packet->header().timestamp,
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000114 static_cast<unsigned int>(packet->time_ms()),
Henrik Lundinb0b54252015-04-17 11:47:07 +0200115 static_cast<int>(packet->virtual_packet_length_bytes()),
Yves Gerey665174f2018-06-19 15:03:05 +0200116 packet->header().payloadType, packet->header().markerBit,
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000117 packet->header().ssrc);
118 if (print_audio_level && packet->header().extension.hasAudioLevel) {
Yves Gerey665174f2018-06-19 15:03:05 +0200119 fprintf(out_file, " %5u (%1i)", packet->header().extension.audioLevel,
Minyue4cee4192015-08-10 15:08:36 +0200120 packet->header().extension.voiceActivity);
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000121 }
Henrik Lundinb0b54252015-04-17 11:47:07 +0200122 if (print_abs_send_time && packet->header().extension.hasAbsoluteSendTime) {
123 if (cycles == -1) {
124 // Initialize.
125 max_abs_send_time = packet->header().extension.absoluteSendTime;
126 cycles = 0;
127 }
128 // Abs sender time is 24 bit 6.18 fixed point. Shift by 8 to normalize to
129 // 32 bits (unsigned). Calculate the difference between this packet's
130 // send time and the maximum observed. Cast to signed 32-bit to get the
131 // desired wrap-around behavior.
132 if (static_cast<int32_t>(
133 (packet->header().extension.absoluteSendTime << 8) -
134 (max_abs_send_time << 8)) >= 0) {
135 // The difference is non-negative, meaning that this packet is newer
136 // than the previously observed maximum absolute send time.
137 if (packet->header().extension.absoluteSendTime < max_abs_send_time) {
138 // Wrap detected.
139 cycles++;
140 }
141 max_abs_send_time = packet->header().extension.absoluteSendTime;
142 }
143 // Abs sender time is 24 bit 6.18 fixed point. Divide by 2^18 to convert
144 // to floating point representation.
145 double send_time_seconds =
146 static_cast<double>(packet->header().extension.absoluteSendTime) /
147 262144 +
148 64.0 * cycles;
149 fprintf(out_file, " %11f", send_time_seconds);
150 }
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000151 fprintf(out_file, "\n");
152
oprypin6e09d872017-08-31 03:21:39 -0700153 if (packet->header().payloadType == FLAG_red) {
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000154 std::list<webrtc::RTPHeader*> red_headers;
155 packet->ExtractRedHeaders(&red_headers);
156 while (!red_headers.empty()) {
157 webrtc::RTPHeader* red = red_headers.front();
158 assert(red);
Yves Gerey665174f2018-06-19 15:03:05 +0200159 fprintf(out_file, "* %5u %10u %10u %5i\n", red->sequenceNumber,
160 red->timestamp, static_cast<unsigned int>(packet->time_ms()),
henrik.lundin@webrtc.org810acbc2014-04-14 18:42:23 +0000161 red->payloadType);
162 red_headers.pop_front();
163 delete red;
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +0000164 }
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +0000165 }
166 }
167
henrik.lundin@webrtc.org184b9132014-04-02 20:56:17 +0000168 fclose(out_file);
169
170 return 0;
171}