/*
 *  Copyright (c) 2014 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 <cstdint>
#include <cstring>
#include <fstream>
#include <map>
#include <memory>
#include <sstream>  // no-presubmit-check TODO(webrtc:8982)
#include <string>
#include <string_view>
#include <utility>
#include <vector>

#include "absl/flags/flag.h"
#include "absl/flags/parse.h"
#include "absl/strings/str_format.h"
#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "api/environment/environment.h"
#include "api/environment/environment_factory.h"
#include "api/field_trials.h"
#include "api/field_trials_view.h"
#include "api/media_types.h"
#include "api/rtp_parameters.h"
#include "api/task_queue/task_queue_base.h"
#include "api/task_queue/task_queue_factory.h"
#include "api/test/video/function_video_decoder_factory.h"
#include "api/units/time_delta.h"
#include "api/units/timestamp.h"
#include "api/video/encoded_image.h"
#include "api/video/video_codec_type.h"
#include "api/video/video_sink_interface.h"
#include "api/video_codecs/video_decoder_factory.h"
#include "call/call.h"
#include "call/call_config.h"
#include "call/flexfec_receive_stream.h"
#include "call/video_receive_stream.h"
#include "media/engine/internal_decoder_factory.h"
#include "modules/rtp_rtcp/include/rtp_header_extension_map.h"
#include "modules/rtp_rtcp/source/rtp_packet.h"
#include "modules/rtp_rtcp/source/rtp_packet_received.h"
#include "modules/rtp_rtcp/source/rtp_util.h"
#include "modules/video_coding/include/video_error_codes.h"
#include "modules/video_coding/utility/ivf_file_writer.h"
#include "rtc_base/checks.h"
#include "rtc_base/copy_on_write_buffer.h"
#include "rtc_base/event.h"
#include "rtc_base/logging.h"
#include "rtc_base/strings/json.h"
#include "rtc_base/system/file_wrapper.h"
#include "rtc_base/thread.h"
#include "system_wrappers/include/clock.h"
#include "test/call_config_utils.h"
#include "test/encoder_settings.h"
#include "test/fake_decoder.h"
#include "test/gtest.h"
#include "test/null_transport.h"
#include "test/rtp_file_reader.h"
#include "test/run_test.h"
#include "test/testsupport/frame_writer.h"
#include "test/time_controller/simulated_time_controller.h"
#include "test/video_renderer.h"
#include "test/video_test_constants.h"

// Flag for payload type.
ABSL_FLAG(int,
          media_payload_type,
          webrtc::test::VideoTestConstants::kPayloadTypeVP8,
          "Media payload type");

// Flag for RED payload type.
ABSL_FLAG(int,
          red_payload_type,
          webrtc::test::VideoTestConstants::kRedPayloadType,
          "RED payload type");

// Flag for ULPFEC payload type.
ABSL_FLAG(int,
          ulpfec_payload_type,
          webrtc::test::VideoTestConstants::kUlpfecPayloadType,
          "ULPFEC payload type");

// Flag for FLEXFEC payload type.
ABSL_FLAG(int,
          flexfec_payload_type,
          webrtc::test::VideoTestConstants::kFlexfecPayloadType,
          "FLEXFEC payload type");

ABSL_FLAG(int,
          media_payload_type_rtx,
          webrtc::test::VideoTestConstants::kSendRtxPayloadType,
          "Media over RTX payload type");

ABSL_FLAG(int,
          red_payload_type_rtx,
          webrtc::test::VideoTestConstants::kRtxRedPayloadType,
          "RED over RTX payload type");

// Flag for SSRC and RTX SSRC.
ABSL_FLAG(uint32_t,
          ssrc,
          webrtc::test::VideoTestConstants::kVideoSendSsrcs[0],
          "Incoming SSRC");
ABSL_FLAG(uint32_t,
          ssrc_rtx,
          webrtc::test::VideoTestConstants::kSendRtxSsrcs[0],
          "Incoming RTX SSRC");

ABSL_FLAG(uint32_t,
          ssrc_flexfec,
          webrtc::test::VideoTestConstants::kFlexfecSendSsrc,
          "Incoming FLEXFEC SSRC");

ABSL_FLAG(std::vector<std::string>,
          ext_map,
          {},
          "RTP extension to ID map in the format of EXT1:ID,EXT2:ID,EXT3:ID"
          " Known extensions are:\n"
          "TOFF    - kTimestampOffsetUri\n"
          "ABSSEND - kAbsSendTimeUri\n"
          "ABSCAPT - kAbsoluteCaptureTimeUri\n"
          "ROT     - kVideoRotationUri\n"
          "CONT    - kVideoContentTypeUri\n"
          "DD      - kDependencyDescriptorUri\n"
          "LALOC   - kVideoLayersAllocationUri\n"
          "TWCC    - kTransportSequenceNumberUri\n"
          "TWCC2   - kTransportSequenceNumberV2Uri\n"
          "DELAY   - kPlayoutDelayUri\n"
          "COLOR   - kColorSpaceUri\n");

// Flag for rtpdump input file.
ABSL_FLAG(std::string, input_file, "", "input file");

ABSL_FLAG(std::string, config_file, "", "config file");

// Flag for raw output files.
ABSL_FLAG(std::string,
          out_base,
          "",
          "Basename (excluding .jpg) for raw output");

ABSL_FLAG(std::string,
          decoder_bitstream_filename,
          "",
          "Decoder bitstream output file");

ABSL_FLAG(std::string, decoder_ivf_filename, "", "Decoder ivf output file");

// Flag for video codec.
ABSL_FLAG(std::string, codec, "VP8", "Video codec");

// Flags for rtp start and stop timestamp.
ABSL_FLAG(uint32_t,
          start_timestamp,
          0,
          "RTP start timestamp, packets with smaller timestamp will be ignored "
          "(no wraparound)");
ABSL_FLAG(uint32_t,
          stop_timestamp,
          4294967295,
          "RTP stop timestamp, packets with larger timestamp will be ignored "
          "(no wraparound)");

// Flags for render window width and height
ABSL_FLAG(uint32_t, render_width, 640, "Width of render window");
ABSL_FLAG(uint32_t, render_height, 480, "Height of render window");

ABSL_FLAG(
    std::string,
    force_fieldtrials,
    "",
    "Field trials control experimental feature code which can be forced. "
    "E.g. running with --force_fieldtrials=WebRTC-FooFeature/Enabled/"
    " will assign the group Enable to field trial WebRTC-FooFeature. Multiple "
    "trials are separated by \"/\"");

ABSL_FLAG(bool, simulated_time, false, "Run in simulated time");

ABSL_FLAG(bool, disable_preview, false, "Disable decoded video preview.");

ABSL_FLAG(bool, disable_decoding, false, "Disable video decoding.");

ABSL_FLAG(int,
          extend_run_time_duration,
          0,
          "Extends the run time of the receiving client after the last RTP "
          "packet has been delivered. Typically useful to let the last few "
          "frames be decoded and rendered. Duration given in seconds.");

namespace {
bool ValidatePayloadType(int32_t payload_type) {
  return payload_type > 0 && payload_type <= 127;
}

bool ValidateOptionalPayloadType(int32_t payload_type) {
  return payload_type == -1 || ValidatePayloadType(payload_type);
}

bool ValidateInputFilenameNotEmpty(const std::string& string) {
  return !string.empty();
}
}  // namespace

namespace webrtc {
namespace {

const uint32_t kReceiverLocalSsrc = 0x123456;

class NullRenderer : public VideoSinkInterface<VideoFrame> {
 public:
  void OnFrame(const VideoFrame& frame) override {}
};

class FileRenderPassthrough : public VideoSinkInterface<VideoFrame> {
 public:
  FileRenderPassthrough(const std::string& basename,
                        VideoSinkInterface<VideoFrame>* renderer)
      : basename_(basename), renderer_(renderer), file_(nullptr), count_(0) {}

  ~FileRenderPassthrough() override {
    if (file_)
      fclose(file_);
  }

 private:
  void OnFrame(const VideoFrame& video_frame) override {
    if (renderer_)
      renderer_->OnFrame(video_frame);

    if (basename_.empty())
      return;

    std::string filename;
    absl::Format(&filename, "%s%zu_%u.jpg", basename_, count_++,
                 video_frame.rtp_timestamp());

    test::JpegFrameWriter frame_writer(filename);
    RTC_CHECK(frame_writer.WriteFrame(video_frame, 100));
  }

  const std::string basename_;
  VideoSinkInterface<VideoFrame>* const renderer_;
  FILE* file_;
  size_t count_;
};

class DecoderBitstreamFileWriter : public test::FakeDecoder {
 public:
  explicit DecoderBitstreamFileWriter(const char* filename)
      : file_(fopen(filename, "wb")) {
    RTC_DCHECK(file_);
  }
  ~DecoderBitstreamFileWriter() override { fclose(file_); }

  int32_t Decode(const EncodedImage& encoded_frame,
                 int64_t /* render_time_ms */) override {
    if (fwrite(encoded_frame.data(), 1, encoded_frame.size(), file_) <
        encoded_frame.size()) {
      RTC_LOG_ERR(LS_ERROR) << "fwrite of encoded frame failed.";
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    return WEBRTC_VIDEO_CODEC_OK;
  }

 private:
  FILE* file_;
};

class DecoderIvfFileWriter : public test::FakeDecoder {
 public:
  explicit DecoderIvfFileWriter(const char* filename, const std::string& codec)
      : file_writer_(
            IvfFileWriter::Wrap(FileWrapper::OpenWriteOnly(filename), 0)) {
    RTC_DCHECK(file_writer_.get());
    if (codec == "VP8") {
      video_codec_type_ = VideoCodecType::kVideoCodecVP8;
    } else if (codec == "VP9") {
      video_codec_type_ = VideoCodecType::kVideoCodecVP9;
    } else if (codec == "H264") {
      video_codec_type_ = VideoCodecType::kVideoCodecH264;
    } else if (codec == "AV1") {
      video_codec_type_ = VideoCodecType::kVideoCodecAV1;
    } else if (codec == "H265") {
      video_codec_type_ = VideoCodecType::kVideoCodecH265;
    } else {
      RTC_LOG(LS_ERROR) << "Unsupported video codec " << codec;
      RTC_DCHECK_NOTREACHED();
    }
  }
  ~DecoderIvfFileWriter() override { file_writer_->Close(); }

  int32_t Decode(const EncodedImage& encoded_frame,
                 int64_t render_time_ms) override {
    if (!file_writer_->WriteFrame(encoded_frame, video_codec_type_)) {
      return WEBRTC_VIDEO_CODEC_ERROR;
    }
    return WEBRTC_VIDEO_CODEC_OK;
  }

 private:
  std::unique_ptr<IvfFileWriter> file_writer_;
  VideoCodecType video_codec_type_;
};

// Holds all the shared memory structures required for a receive stream. This
// structure is used to prevent members being deallocated before the replay
// has been finished.
struct StreamState {
  test::NullTransport transport;
  std::vector<std::unique_ptr<VideoSinkInterface<VideoFrame>>> sinks;
  std::vector<VideoReceiveStreamInterface*> receive_streams;
  std::vector<FlexfecReceiveStream*> flexfec_streams;
  std::unique_ptr<VideoDecoderFactory> decoder_factory;
};

// Loads multiple configurations from the provided configuration file.
std::unique_ptr<StreamState> ConfigureFromFile(const std::string& config_path,
                                               Call* call) {
  auto stream_state = std::make_unique<StreamState>();
  // Parse the configuration file.
  std::ifstream config_file(config_path);
  std::stringstream raw_json_buffer;
  raw_json_buffer << config_file.rdbuf();
  std::string raw_json = raw_json_buffer.str();
  Json::CharReaderBuilder builder;
  Json::Value json_configs;
  std::string error_message;
  std::unique_ptr<Json::CharReader> json_reader(builder.newCharReader());
  if (!json_reader->parse(raw_json.data(), raw_json.data() + raw_json.size(),
                          &json_configs, &error_message)) {
    fprintf(stderr, "Error parsing JSON config\n");
    fprintf(stderr, "%s\n", error_message.c_str());
    return nullptr;
  }

  if (absl::GetFlag(FLAGS_disable_decoding)) {
    stream_state->decoder_factory =
        std::make_unique<test::FunctionVideoDecoderFactory>(
            []() { return std::make_unique<test::FakeDecoder>(); });
  } else {
    stream_state->decoder_factory = std::make_unique<InternalDecoderFactory>();
  }
  size_t config_count = 0;
  for (const auto& json : json_configs) {
    // Create the configuration and parse the JSON into the config.
    auto receive_config =
        ParseVideoReceiveStreamJsonConfig(&(stream_state->transport), json);
    // Instantiate the underlying decoder.
    for (auto& decoder : receive_config.decoders) {
      decoder = test::CreateMatchingDecoder(decoder.payload_type,
                                            decoder.video_format.name);
    }
    if (absl::GetFlag(FLAGS_disable_preview)) {
      stream_state->sinks.emplace_back(std::make_unique<NullRenderer>());
    } else {
      // Create a window for this config.
      std::string window_title;
      absl::Format(&window_title, "Playback Video (%zu)", config_count++);
      stream_state->sinks.emplace_back(test::VideoRenderer::Create(
          window_title.c_str(), absl::GetFlag(FLAGS_render_width),
          absl::GetFlag(FLAGS_render_height)));
    }
    // Create a receive stream for this config.
    receive_config.renderer = stream_state->sinks.back().get();
    receive_config.decoder_factory = stream_state->decoder_factory.get();
    stream_state->receive_streams.emplace_back(
        call->CreateVideoReceiveStream(std::move(receive_config)));
  }
  return stream_state;
}

// Loads the base configuration from flags passed in on the commandline.
std::unique_ptr<StreamState> ConfigureFromFlags(
    const std::string& rtp_dump_path,
    Call* call) {
  auto stream_state = std::make_unique<StreamState>();
  // Create the video renderers. We must add both to the stream state to keep
  // them from deallocating.
  std::unique_ptr<VideoSinkInterface<VideoFrame>> playback_video;
  if (absl::GetFlag(FLAGS_disable_preview)) {
    playback_video = std::make_unique<NullRenderer>();
  } else {
    std::string window_title;
    absl::Format(&window_title, "Playback Video (%s)", rtp_dump_path);
    playback_video.reset(test::VideoRenderer::Create(
        window_title.c_str(), absl::GetFlag(FLAGS_render_width),
        absl::GetFlag(FLAGS_render_height)));
  }
  auto file_passthrough = std::make_unique<FileRenderPassthrough>(
      absl::GetFlag(FLAGS_out_base), playback_video.get());
  stream_state->sinks.push_back(std::move(playback_video));
  stream_state->sinks.push_back(std::move(file_passthrough));
  // Setup the configuration from the flags.
  VideoReceiveStreamInterface::Config receive_config(
      &(stream_state->transport));
  receive_config.rtp.remote_ssrc = absl::GetFlag(FLAGS_ssrc);
  receive_config.rtp.local_ssrc = kReceiverLocalSsrc;
  receive_config.rtp.rtx_ssrc = absl::GetFlag(FLAGS_ssrc_rtx);
  receive_config.rtp.rtx_associated_payload_types[absl::GetFlag(
      FLAGS_media_payload_type_rtx)] = absl::GetFlag(FLAGS_media_payload_type);
  receive_config.rtp
      .rtx_associated_payload_types[absl::GetFlag(FLAGS_red_payload_type_rtx)] =
      absl::GetFlag(FLAGS_red_payload_type);
  receive_config.rtp.ulpfec_payload_type =
      absl::GetFlag(FLAGS_ulpfec_payload_type);
  receive_config.rtp.red_payload_type = absl::GetFlag(FLAGS_red_payload_type);
  receive_config.rtp.nack.rtp_history_ms = 1000;

  if (absl::GetFlag(FLAGS_flexfec_payload_type) != -1) {
    receive_config.rtp.protected_by_flexfec = true;
    FlexfecReceiveStream::Config flexfec_config(&(stream_state->transport));
    flexfec_config.payload_type = absl::GetFlag(FLAGS_flexfec_payload_type);
    flexfec_config.protected_media_ssrcs.push_back(absl::GetFlag(FLAGS_ssrc));
    flexfec_config.rtp.remote_ssrc = absl::GetFlag(FLAGS_ssrc_flexfec);
    FlexfecReceiveStream* flexfec_stream =
        call->CreateFlexfecReceiveStream(flexfec_config);
    receive_config.rtp.packet_sink_ = flexfec_stream;
    stream_state->flexfec_streams.push_back(flexfec_stream);
  }

  receive_config.renderer = stream_state->sinks.back().get();

  // Setup the receiving stream
  VideoReceiveStreamInterface::Decoder decoder;
  decoder = test::CreateMatchingDecoder(absl::GetFlag(FLAGS_media_payload_type),
                                        absl::GetFlag(FLAGS_codec));
  if (!absl::GetFlag(FLAGS_decoder_bitstream_filename).empty()) {
    // Replace decoder with file writer if we're writing the bitstream to a
    // file instead.
    stream_state->decoder_factory =
        std::make_unique<test::FunctionVideoDecoderFactory>([]() {
          return std::make_unique<DecoderBitstreamFileWriter>(
              absl::GetFlag(FLAGS_decoder_bitstream_filename).c_str());
        });
  } else if (!absl::GetFlag(FLAGS_decoder_ivf_filename).empty()) {
    // Replace decoder with file writer if we're writing the ivf to a
    // file instead.
    stream_state->decoder_factory =
        std::make_unique<test::FunctionVideoDecoderFactory>([]() {
          return std::make_unique<DecoderIvfFileWriter>(
              absl::GetFlag(FLAGS_decoder_ivf_filename).c_str(),
              absl::GetFlag(FLAGS_codec));
        });
  } else if (absl::GetFlag(FLAGS_disable_decoding)) {
    stream_state->decoder_factory =
        std::make_unique<test::FunctionVideoDecoderFactory>(
            []() { return std::make_unique<test::FakeDecoder>(); });
  } else {
    stream_state->decoder_factory = std::make_unique<InternalDecoderFactory>();
  }
  receive_config.decoder_factory = stream_state->decoder_factory.get();
  receive_config.decoders.push_back(decoder);

  stream_state->receive_streams.emplace_back(
      call->CreateVideoReceiveStream(std::move(receive_config)));
  return stream_state;
}

std::unique_ptr<test::RtpFileReader> CreateRtpReader(
    const std::string& rtp_dump_path) {
  std::unique_ptr<test::RtpFileReader> rtp_reader(test::RtpFileReader::Create(
      test::RtpFileReader::kRtpDump, rtp_dump_path));
  if (!rtp_reader) {
    rtp_reader.reset(
        test::RtpFileReader::Create(test::RtpFileReader::kPcap, rtp_dump_path));
    if (!rtp_reader) {
      fprintf(stderr,
              "Couldn't open input file as either a rtpdump or .pcap. Note "
              "that .pcapng is not supported.\nTrying to interpret the file as "
              "length/packet interleaved.\n");
      rtp_reader.reset(test::RtpFileReader::Create(
          test::RtpFileReader::kLengthPacketInterleaved, rtp_dump_path));
      if (!rtp_reader) {
        fprintf(stderr,
                "Unable to open input file with any supported format\n");
        return nullptr;
      }
    }
  }
  return rtp_reader;
}

// The RtpReplayer is responsible for parsing the configuration provided by
// the user, setting up the windows, receive streams and decoders and then
// replaying the provided RTP dump.
class RtpReplayer final {
 public:
  RtpReplayer(absl::string_view replay_config_path,
              absl::string_view rtp_dump_path,
              std::unique_ptr<FieldTrialsView> field_trials,
              bool simulated_time)
      : replay_config_path_(replay_config_path),
        rtp_dump_path_(rtp_dump_path),
        time_sim_(simulated_time
                      ? std::make_unique<GlobalSimulatedTimeController>(
                            Timestamp::Millis(1 << 30))
                      : nullptr),
        env_(CreateEnvironment(
            std::move(field_trials),
            time_sim_ ? time_sim_->GetTaskQueueFactory() : nullptr,
            time_sim_ ? time_sim_->GetClock() : nullptr)),
        rtp_reader_(CreateRtpReader(rtp_dump_path_)) {
    worker_thread_ = env_.task_queue_factory().CreateTaskQueue(
        "worker_thread", TaskQueueFactory::Priority::NORMAL);
    Event event;
    worker_thread_->PostTask([&]() {
      call_ = Call::Create(CallConfig(env_));

      // Creation of the streams must happen inside a task queue because it is
      // resued as a worker thread.
      if (replay_config_path_.empty()) {
        stream_state_ = ConfigureFromFlags(rtp_dump_path_, call_.get());
      } else {
        stream_state_ = ConfigureFromFile(replay_config_path_, call_.get());
      }
      event.Set();
    });
    event.Wait(/*give_up_after=*/TimeDelta::Seconds(10));

    RTC_CHECK(stream_state_);
    RTC_CHECK(rtp_reader_);
  }

  ~RtpReplayer() {
    // Destruction of streams and the call must happen on the same thread as
    // their creation.
    Event event;
    worker_thread_->PostTask([&]() {
      for (const auto& receive_stream : stream_state_->receive_streams) {
        call_->DestroyVideoReceiveStream(receive_stream);
      }
      for (const auto& flexfec_stream : stream_state_->flexfec_streams) {
        call_->DestroyFlexfecReceiveStream(flexfec_stream);
      }
      call_.reset();
      event.Set();
    });
    event.Wait(/*give_up_after=*/TimeDelta::Seconds(10));
  }

  void Run() {
    Event event;
    worker_thread_->PostTask([&]() {
      // Start replaying the provided stream now that it has been configured.
      // VideoReceiveStreams must be started on the same thread as they were
      // created on.
      for (const auto& receive_stream : stream_state_->receive_streams) {
        receive_stream->Start();
      }
      event.Set();
    });
    event.Wait(/*give_up_after=*/TimeDelta::Seconds(10));

    ReplayPackets();
  }

 private:
  RtpHeaderExtensionMap GetExtensionMapFromFlags() {
    const std::map<std::string_view, absl::string_view> kKnownExtensions = {
        {"TOFF", RtpExtension::kTimestampOffsetUri},
        {"ABSSEND", RtpExtension::kAbsSendTimeUri},
        {"ABSCAPT", RtpExtension::kAbsoluteCaptureTimeUri},
        {"ROT", RtpExtension::kVideoRotationUri},
        {"CONT", RtpExtension::kVideoContentTypeUri},
        {"DD", RtpExtension::kDependencyDescriptorUri},
        {"LALOC", RtpExtension::kVideoLayersAllocationUri},
        {"TWCC", RtpExtension::kTransportSequenceNumberUri},
        {"TWCC2", RtpExtension::kTransportSequenceNumberV2Uri},
        {"DELAY", RtpExtension::kPlayoutDelayUri},
        {"COLOR", RtpExtension::kColorSpaceUri},
    };

    RtpHeaderExtensionMap res;
    for (const std::string& extension : absl::GetFlag(FLAGS_ext_map)) {
      std::pair<std::string, std::string> ext = absl::StrSplit(extension, ':');
      if (auto it = kKnownExtensions.find(ext.first);
          it != kKnownExtensions.end()) {
        res.RegisterByUri(std::stoi(ext.second), it->second);
      } else {
        RTC_DCHECK_NOTREACHED() << "Unknown extension \"" << ext.first << "\"";
      }
    }

    return res;
  }

  void ReplayPackets() {
    enum class Result { kOk, kUnknownSsrc, kParsingFailed };
    int64_t replay_start_ms = -1;
    int num_packets = 0;
    std::map<uint32_t, int> unknown_packets;
    Event event(/*manual_reset=*/false, /*initially_signalled=*/false);
    uint32_t start_timestamp = absl::GetFlag(FLAGS_start_timestamp);
    uint32_t stop_timestamp = absl::GetFlag(FLAGS_stop_timestamp);

    RtpHeaderExtensionMap extensions = GetExtensionMapFromFlags();

    while (true) {
      int64_t now_ms = CurrentTimeMs();
      test::RtpPacket packet;
      if (!rtp_reader_->NextPacket(&packet)) {
        break;
      }
      CopyOnWriteBuffer packet_buffer(
          packet.original_length > 0 ? packet.original_length : packet.length);
      memcpy(packet_buffer.MutableData(), packet.data, packet.length);
      if (packet.length < packet.original_length) {
        // Only the RTP header was recorded in the RTP dump, payload is not
        // known and and padding length is not known, zero the payload and
        // clear the padding bit.
        memset(packet_buffer.MutableData() + packet.length, 0,
               packet.original_length - packet.length);
        packet_buffer.MutableData()[0] &= ~0x20;
      }
      // Check that the packet is a RTP packet and is valid.
      if (!IsRtpPacket({packet.data, packet.length})) {
        continue;
      }
      RtpPacket header;
      if (!header.Parse(packet_buffer) ||
          header.Timestamp() < start_timestamp ||
          header.Timestamp() > stop_timestamp) {
        continue;
      }
      if (replay_start_ms == -1) {
        replay_start_ms = now_ms - packet.time_ms;
      }

      int64_t deliver_in_ms = replay_start_ms + packet.time_ms - now_ms;
      SleepOrAdvanceTime(deliver_in_ms);

      ++num_packets;

      Result result = Result::kOk;
      worker_thread_->PostTask([&]() {
        if (IsRtcpPacket(packet_buffer)) {
          call_->Receiver()->DeliverRtcpPacket(std::move(packet_buffer));
        }
        RtpPacketReceived received_packet(&extensions,
                                          Timestamp::Millis(CurrentTimeMs()));
        if (!received_packet.Parse(std::move(packet_buffer))) {
          result = Result::kParsingFailed;
        } else {
          call_->Receiver()->DeliverRtpPacket(
              MediaType::VIDEO, received_packet,
              [&result](const RtpPacketReceived& parsed_packet) -> bool {
                result = Result::kUnknownSsrc;
                // No point in trying to demux again.
                return false;
              });
        }
        event.Set();
      });
      event.Wait(/*give_up_after=*/TimeDelta::Seconds(10));

      switch (result) {
        case Result::kOk:
          break;
        case Result::kUnknownSsrc: {
          if (unknown_packets[header.Ssrc()] == 0)
            fprintf(stderr, "Unknown SSRC: %u!\n", header.Ssrc());
          ++unknown_packets[header.Ssrc()];
          break;
        }
        case Result::kParsingFailed: {
          fprintf(stderr,
                  "Packet error, corrupt packets or incorrect setup?\n");
          fprintf(stderr, "Packet len=%zu pt=%u seq=%u ts=%u ssrc=0x%8x\n",
                  packet.length, header.PayloadType(), header.SequenceNumber(),
                  header.Timestamp(), header.Ssrc());
          break;
        }
      }
    }
    // Note that even when `extend_run_time_duration` is zero
    // `SleepOrAdvanceTime` should still be called in order to process the last
    // delivered packet when running in simulated time.
    SleepOrAdvanceTime(absl::GetFlag(FLAGS_extend_run_time_duration) * 1000);

    fprintf(stderr, "num_packets: %d\n", num_packets);

    for (std::map<uint32_t, int>::const_iterator it = unknown_packets.begin();
         it != unknown_packets.end(); ++it) {
      fprintf(stderr, "Packets for unknown ssrc '%u': %d\n", it->first,
              it->second);
    }
  }

  int64_t CurrentTimeMs() { return env_.clock().CurrentTime().ms(); }

  void SleepOrAdvanceTime(int64_t duration_ms) {
    if (time_sim_) {
      time_sim_->AdvanceTime(TimeDelta::Millis(duration_ms));
    } else if (duration_ms > 0) {
      Thread::SleepMs(duration_ms);
    }
  }

  const std::string replay_config_path_;
  const std::string rtp_dump_path_;
  std::unique_ptr<GlobalSimulatedTimeController> time_sim_;
  Environment env_;
  std::unique_ptr<TaskQueueBase, TaskQueueDeleter> worker_thread_;
  std::unique_ptr<Call> call_;
  std::unique_ptr<test::RtpFileReader> rtp_reader_;
  std::unique_ptr<StreamState> stream_state_;
};

void RtpReplay() {
  RtpReplayer replayer(
      absl::GetFlag(FLAGS_config_file), absl::GetFlag(FLAGS_input_file),
      std::make_unique<FieldTrials>(absl::GetFlag(FLAGS_force_fieldtrials)),
      absl::GetFlag(FLAGS_simulated_time));
  replayer.Run();
}

}  // namespace
}  // namespace webrtc

int main(int argc, char* argv[]) {
  ::testing::InitGoogleTest(&argc, argv);
  absl::ParseCommandLine(argc, argv);

  RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_media_payload_type)));
  RTC_CHECK(ValidatePayloadType(absl::GetFlag(FLAGS_media_payload_type_rtx)));
  RTC_CHECK(ValidateOptionalPayloadType(absl::GetFlag(FLAGS_red_payload_type)));
  RTC_CHECK(
      ValidateOptionalPayloadType(absl::GetFlag(FLAGS_red_payload_type_rtx)));
  RTC_CHECK(
      ValidateOptionalPayloadType(absl::GetFlag(FLAGS_ulpfec_payload_type)));
  RTC_CHECK(
      ValidateOptionalPayloadType(absl::GetFlag(FLAGS_flexfec_payload_type)));
  RTC_CHECK(ValidateInputFilenameNotEmpty(absl::GetFlag(FLAGS_input_file)));
  RTC_CHECK_GE(absl::GetFlag(FLAGS_extend_run_time_duration), 0);

  webrtc::ThreadManager::Instance()->WrapCurrentThread();
  webrtc::test::RunTest(webrtc::RtpReplay);
  return 0;
}
