mirror of
https://github.com/mollyim/webrtc.git
synced 2025-05-14 06:10:40 +01:00

This is a reland of 5ccdc1331f
Original change's description:
> Prefix flag macros with WEBRTC_.
>
> Macros defined in rtc_base/flags.h are intended to be used to define
> flags in WebRTC's binaries (e.g. tests).
>
> They are currently not prefixed and this could cause problems with
> downstream clients since these names are quite common.
>
> This CL adds the 'WEBRTC_' prefix to them.
>
> Generated with:
>
> for x in DECLARE DEFINE; do
> for y in bool int float string FLAG; do
> git grep -l "\b$x\_$y\b" | \
> xargs sed -i "s/\b$x\_$y\b/WEBRTC_$x\_$y/g"
> done
> done
> git cl format
>
> Bug: webrtc:9884
> Change-Id: I7b524762b6a3e5aa5b2fc2395edd3e1a0fe72591
> Reviewed-on: https://webrtc-review.googlesource.com/c/106682
> Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
> Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
> Cr-Commit-Position: refs/heads/master@{#25270}
TBR=kwiberg@webrtc.org
Bug: webrtc:9884
Change-Id: I5ba5368a231a334d135ed5e6fd7a279629ced8a3
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://webrtc-review.googlesource.com/c/107161
Commit-Queue: Mirko Bonadei <mbonadei@webrtc.org>
Reviewed-by: Mirko Bonadei <mbonadei@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#25277}
151 lines
4.8 KiB
C++
151 lines
4.8 KiB
C++
/*
|
|
* Copyright (c) 2017 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 <stdio.h>
|
|
#include <algorithm>
|
|
#include <fstream>
|
|
#include <iostream>
|
|
#include <vector>
|
|
|
|
#include "api/array_view.h"
|
|
#include "modules/rtp_rtcp/source/byte_io.h"
|
|
#include "rtc_base/buffer.h"
|
|
#include "rtc_base/flags.h"
|
|
|
|
namespace webrtc {
|
|
namespace test {
|
|
namespace {
|
|
|
|
WEBRTC_DEFINE_bool(help, false, "Print help message");
|
|
|
|
constexpr size_t kRtpDumpHeaderLength = 8;
|
|
|
|
// Returns the next packet or an empty buffer if end of file was encountered.
|
|
rtc::Buffer ReadNextPacket(FILE* file) {
|
|
// Read the rtpdump header for the next packet.
|
|
rtc::Buffer buffer;
|
|
buffer.SetData(kRtpDumpHeaderLength, [&](rtc::ArrayView<uint8_t> x) {
|
|
return fread(x.data(), 1, x.size(), file);
|
|
});
|
|
if (buffer.size() != kRtpDumpHeaderLength) {
|
|
return rtc::Buffer();
|
|
}
|
|
|
|
// Get length field. This is the total length for this packet written to file,
|
|
// including the kRtpDumpHeaderLength bytes already read.
|
|
const uint16_t len = ByteReader<uint16_t>::ReadBigEndian(buffer.data());
|
|
RTC_CHECK_GE(len, kRtpDumpHeaderLength);
|
|
|
|
// Read remaining data from file directly into buffer.
|
|
buffer.AppendData(len - kRtpDumpHeaderLength, [&](rtc::ArrayView<uint8_t> x) {
|
|
return fread(x.data(), 1, x.size(), file);
|
|
});
|
|
if (buffer.size() != len) {
|
|
buffer.Clear();
|
|
}
|
|
return buffer;
|
|
}
|
|
|
|
struct PacketAndTime {
|
|
rtc::Buffer packet;
|
|
int time;
|
|
};
|
|
|
|
void WritePacket(const PacketAndTime& packet, FILE* file) {
|
|
// Write the first 4 bytes from the original packet.
|
|
const auto* payload_ptr = packet.packet.data();
|
|
RTC_CHECK_EQ(fwrite(payload_ptr, 4, 1, file), 1);
|
|
payload_ptr += 4;
|
|
|
|
// Convert the new time offset to network endian, and write to file.
|
|
uint8_t time[sizeof(uint32_t)];
|
|
ByteWriter<uint32_t, sizeof(uint32_t)>::WriteBigEndian(time, packet.time);
|
|
RTC_CHECK_EQ(fwrite(time, sizeof(uint32_t), 1, file), 1);
|
|
payload_ptr += 4; // Skip the old time in the original payload.
|
|
|
|
// Write the remaining part of the payload.
|
|
RTC_DCHECK_EQ(payload_ptr - packet.packet.data(), kRtpDumpHeaderLength);
|
|
RTC_CHECK_EQ(
|
|
fwrite(payload_ptr, packet.packet.size() - kRtpDumpHeaderLength, 1, file),
|
|
1);
|
|
}
|
|
|
|
int RunRtpJitter(int argc, char* argv[]) {
|
|
const std::string program_name = argv[0];
|
|
const std::string usage =
|
|
"Tool for alternating the arrival times in an RTP dump file.\n"
|
|
"Example usage:\n" +
|
|
program_name + " input.rtp arrival_times_ms.txt output.rtp\n\n";
|
|
if (rtc::FlagList::SetFlagsFromCommandLine(&argc, argv, true) || FLAG_help ||
|
|
argc != 4) {
|
|
printf("%s", usage.c_str());
|
|
return FLAG_help ? 0 : 1;
|
|
}
|
|
|
|
printf("Input RTP file: %s\n", argv[1]);
|
|
FILE* in_file = fopen(argv[1], "rb");
|
|
RTC_CHECK(in_file) << "Could not open file " << argv[1] << " for reading";
|
|
printf("Timing file: %s\n", argv[2]);
|
|
std::ifstream timing_file(argv[2]);
|
|
printf("Output file: %s\n", argv[3]);
|
|
FILE* out_file = fopen(argv[3], "wb");
|
|
RTC_CHECK(out_file) << "Could not open file " << argv[2] << " for writing";
|
|
|
|
// Copy the RTP file header to the output file.
|
|
char header_string[30];
|
|
RTC_CHECK(fgets(header_string, 30, in_file));
|
|
fprintf(out_file, "%s", header_string);
|
|
uint8_t file_header[16];
|
|
RTC_CHECK_EQ(fread(file_header, sizeof(file_header), 1, in_file), 1);
|
|
RTC_CHECK_EQ(fwrite(file_header, sizeof(file_header), 1, out_file), 1);
|
|
|
|
// Read all time values from the timing file. Store in a vector.
|
|
std::vector<int> new_arrival_times;
|
|
int new_time;
|
|
while (timing_file >> new_time) {
|
|
new_arrival_times.push_back(new_time);
|
|
}
|
|
|
|
// Read all packets from the input RTP file, but no more than the number of
|
|
// new time values. Store RTP packets together with new time values.
|
|
auto time_it = new_arrival_times.begin();
|
|
std::vector<PacketAndTime> packets;
|
|
while (1) {
|
|
auto packet = ReadNextPacket(in_file);
|
|
if (packet.empty() || time_it == new_arrival_times.end()) {
|
|
break;
|
|
}
|
|
packets.push_back({std::move(packet), *time_it});
|
|
++time_it;
|
|
}
|
|
|
|
// Sort on new time values.
|
|
std::sort(packets.begin(), packets.end(),
|
|
[](const PacketAndTime& a, const PacketAndTime& b) {
|
|
return a.time < b.time;
|
|
});
|
|
|
|
// Write packets to output file.
|
|
for (const auto& p : packets) {
|
|
WritePacket(p, out_file);
|
|
}
|
|
|
|
fclose(in_file);
|
|
fclose(out_file);
|
|
return 0;
|
|
}
|
|
|
|
} // namespace
|
|
} // namespace test
|
|
} // namespace webrtc
|
|
|
|
int main(int argc, char* argv[]) {
|
|
return webrtc::test::RunRtpJitter(argc, argv);
|
|
}
|