• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  Copyright (c) 2013 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/modules/video_coding/main/test/rtp_file_reader.h"
12 
13 #ifdef WIN32
14 #include <windows.h>
15 #include <Winsock2.h>
16 #else
17 #include <arpa/inet.h>
18 #endif
19 #include <assert.h>
20 #include <stdio.h>
21 
22 #include "webrtc/modules/video_coding/main/test/rtp_player.h"
23 #include "webrtc/system_wrappers/interface/scoped_ptr.h"
24 
25 namespace webrtc {
26 namespace rtpplayer {
27 
28 enum {
29   kResultFail = -1,
30   kResultSuccess = 0,
31 
32   kFirstLineLength = 40,    // More than needed to read the ID line.
33   kPacketHeaderSize = 8     // Rtpplay packet header size in bytes.
34 };
35 
36 #if 1
37 # define DEBUG_LOG(text)
38 # define DEBUG_LOG1(text, arg)
39 #else
40 # define DEBUG_LOG(text) (printf(text "\n"))
41 # define DEBUG_LOG1(text, arg) (printf(text "\n", arg))
42 #endif
43 
44 #define TRY(expr)                                      \
45   do {                                                 \
46     if ((expr) < 0) {                                  \
47       DEBUG_LOG1("FAIL at " __FILE__ ":%d", __LINE__);       \
48       return kResultFail;                                       \
49     }                                                  \
50   } while (0)
51 
52 // Read RTP packets from file in rtpdump format, as documented at:
53 // http://www.cs.columbia.edu/irt/software/rtptools/
54 class RtpFileReaderImpl : public RtpPacketSourceInterface {
55  public:
RtpFileReaderImpl()56   RtpFileReaderImpl() : file_(NULL) {}
~RtpFileReaderImpl()57   virtual ~RtpFileReaderImpl() {
58     if (file_ != NULL) {
59       fclose(file_);
60       file_ = NULL;
61     }
62   }
63 
Initialize(const std::string & filename)64   int Initialize(const std::string& filename) {
65     file_ = fopen(filename.c_str(), "rb");
66     if (file_ == NULL) {
67       printf("ERROR: Can't open file: %s\n", filename.c_str());
68       return kResultFail;
69     }
70 
71     char firstline[kFirstLineLength + 1] = {0};
72     if (fgets(firstline, kFirstLineLength, file_) == NULL) {
73       DEBUG_LOG("ERROR: Can't read from file\n");
74       return kResultFail;
75     }
76     if (strncmp(firstline, "#!rtpplay", 9) == 0) {
77       if (strncmp(firstline, "#!rtpplay1.0", 12) != 0) {
78         DEBUG_LOG("ERROR: wrong rtpplay version, must be 1.0\n");
79         return kResultFail;
80       }
81     } else if (strncmp(firstline, "#!RTPencode", 11) == 0) {
82       if (strncmp(firstline, "#!RTPencode1.0", 14) != 0) {
83         DEBUG_LOG("ERROR: wrong RTPencode version, must be 1.0\n");
84         return kResultFail;
85       }
86     } else {
87       DEBUG_LOG("ERROR: wrong file format of input file\n");
88       return kResultFail;
89     }
90 
91     uint32_t start_sec;
92     uint32_t start_usec;
93     uint32_t source;
94     uint16_t port;
95     uint16_t padding;
96     TRY(Read(&start_sec));
97     TRY(Read(&start_usec));
98     TRY(Read(&source));
99     TRY(Read(&port));
100     TRY(Read(&padding));
101 
102     return kResultSuccess;
103   }
104 
NextPacket(uint8_t * rtp_data,uint32_t * length,uint32_t * time_ms)105   virtual int NextPacket(uint8_t* rtp_data, uint32_t* length,
106                          uint32_t* time_ms) {
107     assert(rtp_data);
108     assert(length);
109     assert(time_ms);
110 
111     uint16_t len;
112     uint16_t plen;
113     uint32_t offset;
114     TRY(Read(&len));
115     TRY(Read(&plen));
116     TRY(Read(&offset));
117 
118     // Use 'len' here because a 'plen' of 0 specifies rtcp.
119     len -= kPacketHeaderSize;
120     if (*length < len) {
121       return kResultFail;
122     }
123     if (fread(rtp_data, 1, len, file_) != len) {
124       return kResultFail;
125     }
126 
127     *length = len;
128     *time_ms = offset;
129     return kResultSuccess;
130   }
131 
132  private:
Read(uint32_t * out)133   int Read(uint32_t* out) {
134     assert(out);
135     uint32_t tmp = 0;
136     if (fread(&tmp, 1, sizeof(uint32_t), file_) != sizeof(uint32_t)) {
137       return kResultFail;
138     }
139     *out = ntohl(tmp);
140     return kResultSuccess;
141   }
142 
Read(uint16_t * out)143   int Read(uint16_t* out) {
144     assert(out);
145     uint16_t tmp = 0;
146     if (fread(&tmp, 1, sizeof(uint16_t), file_) != sizeof(uint16_t)) {
147       return kResultFail;
148     }
149     *out = ntohs(tmp);
150     return kResultSuccess;
151   }
152 
153   FILE* file_;
154 
155   DISALLOW_COPY_AND_ASSIGN(RtpFileReaderImpl);
156 };
157 
CreateRtpFileReader(const std::string & filename)158 RtpPacketSourceInterface* CreateRtpFileReader(const std::string& filename) {
159   scoped_ptr<RtpFileReaderImpl> impl(new RtpFileReaderImpl());
160   if (impl->Initialize(filename) != 0) {
161     return NULL;
162   }
163   return impl.release();
164 }
165 }  // namespace rtpplayer
166 }  // namespace webrtc
167