1 /* 2 * Copyright (c) 2014 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 "webrtc/test/rtp_file_writer.h" 12 13 #include <stdio.h> 14 15 #include <string> 16 17 #include "webrtc/base/checks.h" 18 #include "webrtc/base/constructormagic.h" 19 20 namespace webrtc { 21 namespace test { 22 23 static const uint16_t kPacketHeaderSize = 8; 24 static const char kFirstLine[] = "#!rtpplay1.0 0.0.0.0/0\n"; 25 26 // Write RTP packets to file in rtpdump format, as documented at: 27 // http://www.cs.columbia.edu/irt/software/rtptools/ 28 class RtpDumpWriter : public RtpFileWriter { 29 public: 30 explicit RtpDumpWriter(FILE* file) : file_(file) { 31 RTC_CHECK(file_ != NULL); 32 Init(); 33 } 34 virtual ~RtpDumpWriter() { 35 if (file_ != NULL) { 36 fclose(file_); 37 file_ = NULL; 38 } 39 } 40 41 bool WritePacket(const RtpPacket* packet) override { 42 uint16_t len = static_cast<uint16_t>(packet->length + kPacketHeaderSize); 43 uint16_t plen = static_cast<uint16_t>(packet->original_length); 44 uint32_t offset = packet->time_ms; 45 RTC_CHECK(WriteUint16(len)); 46 RTC_CHECK(WriteUint16(plen)); 47 RTC_CHECK(WriteUint32(offset)); 48 return fwrite(packet->data, sizeof(uint8_t), packet->length, file_) == 49 packet->length; 50 } 51 52 private: 53 bool Init() { 54 fprintf(file_, "%s", kFirstLine); 55 56 RTC_CHECK(WriteUint32(0)); 57 RTC_CHECK(WriteUint32(0)); 58 RTC_CHECK(WriteUint32(0)); 59 RTC_CHECK(WriteUint16(0)); 60 RTC_CHECK(WriteUint16(0)); 61 62 return true; 63 } 64 65 bool WriteUint32(uint32_t in) { 66 // Loop through shifts = {24, 16, 8, 0}. 67 for (int shifts = 24; shifts >= 0; shifts -= 8) { 68 uint8_t tmp = static_cast<uint8_t>((in >> shifts) & 0xFF); 69 if (fwrite(&tmp, sizeof(uint8_t), 1, file_) != 1) 70 return false; 71 } 72 return true; 73 } 74 75 bool WriteUint16(uint16_t in) { 76 // Write 8 MSBs. 77 uint8_t tmp = static_cast<uint8_t>((in >> 8) & 0xFF); 78 if (fwrite(&tmp, sizeof(uint8_t), 1, file_) != 1) 79 return false; 80 // Write 8 LSBs. 81 tmp = static_cast<uint8_t>(in & 0xFF); 82 if (fwrite(&tmp, sizeof(uint8_t), 1, file_) != 1) 83 return false; 84 return true; 85 } 86 87 FILE* file_; 88 89 RTC_DISALLOW_COPY_AND_ASSIGN(RtpDumpWriter); 90 }; 91 92 RtpFileWriter* RtpFileWriter::Create(FileFormat format, 93 const std::string& filename) { 94 FILE* file = fopen(filename.c_str(), "wb"); 95 if (file == NULL) { 96 printf("ERROR: Can't open file: %s\n", filename.c_str()); 97 return NULL; 98 } 99 switch (format) { 100 case kRtpDump: 101 return new RtpDumpWriter(file); 102 } 103 fclose(file); 104 return NULL; 105 } 106 107 } // namespace test 108 } // namespace webrtc 109