1 /*
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
13 #include "webrtc/modules/video_coding/main/test/receiver_tests.h"
14 #include "webrtc/modules/video_coding/main/test/vcm_payload_sink_factory.h"
15 #include "webrtc/system_wrappers/interface/event_wrapper.h"
16 #include "webrtc/system_wrappers/interface/thread_wrapper.h"
17 #include "webrtc/system_wrappers/interface/trace.h"
18 #include "webrtc/test/testsupport/fileutils.h"
19
20 using webrtc::rtpplayer::RtpPlayerInterface;
21 using webrtc::rtpplayer::VcmPayloadSinkFactory;
22
23 namespace {
24
25 const bool kConfigProtectionEnabled = true;
26 const webrtc::VCMVideoProtection kConfigProtectionMethod =
27 webrtc::kProtectionDualDecoder;
28 const float kConfigLossRate = 0.05f;
29 const uint32_t kConfigRttMs = 50;
30 const bool kConfigReordering = false;
31 const uint32_t kConfigRenderDelayMs = 0;
32 const uint32_t kConfigMinPlayoutDelayMs = 0;
33 const int64_t kConfigMaxRuntimeMs = 10000;
34
35 } // namespace
36
PlayerThread(void * obj)37 bool PlayerThread(void* obj) {
38 assert(obj);
39 RtpPlayerInterface* rtp_player = static_cast<RtpPlayerInterface*>(obj);
40
41 webrtc::scoped_ptr<webrtc::EventWrapper> wait_event(
42 webrtc::EventWrapper::Create());
43 if (wait_event.get() == NULL) {
44 return false;
45 }
46
47 webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
48 if (rtp_player->NextPacket(clock->TimeInMilliseconds()) < 0) {
49 return false;
50 }
51 wait_event->Wait(rtp_player->TimeUntilNextPacket());
52
53 return true;
54 }
55
ProcessingThread(void * obj)56 bool ProcessingThread(void* obj) {
57 assert(obj);
58 return static_cast<VcmPayloadSinkFactory*>(obj)->ProcessAll();
59 }
60
DecodeThread(void * obj)61 bool DecodeThread(void* obj) {
62 assert(obj);
63 return static_cast<VcmPayloadSinkFactory*>(obj)->DecodeAll();
64 }
65
RtpPlayMT(const CmdArgs & args)66 int RtpPlayMT(const CmdArgs& args) {
67 std::string trace_file = webrtc::test::OutputPath() + "receiverTestTrace.txt";
68 webrtc::Trace::CreateTrace();
69 webrtc::Trace::SetTraceFile(trace_file.c_str());
70 webrtc::Trace::set_level_filter(webrtc::kTraceAll);
71
72 webrtc::rtpplayer::PayloadTypes payload_types;
73 payload_types.push_back(webrtc::rtpplayer::PayloadCodecTuple(
74 VCM_VP8_PAYLOAD_TYPE, "VP8", webrtc::kVideoCodecVP8));
75
76 std::string output_file = args.outputFile;
77 if (output_file == "") {
78 output_file = webrtc::test::OutputPath() + "RtpPlayMT_decoded.yuv";
79 }
80
81 webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
82 VcmPayloadSinkFactory factory(output_file, clock, kConfigProtectionEnabled,
83 kConfigProtectionMethod, kConfigRttMs, kConfigRenderDelayMs,
84 kConfigMinPlayoutDelayMs);
85 webrtc::scoped_ptr<RtpPlayerInterface> rtp_player(webrtc::rtpplayer::Create(
86 args.inputFile, &factory, clock, payload_types, kConfigLossRate,
87 kConfigRttMs, kConfigReordering));
88 if (rtp_player.get() == NULL) {
89 return -1;
90 }
91
92 {
93 webrtc::scoped_ptr<webrtc::ThreadWrapper> player_thread(
94 webrtc::ThreadWrapper::CreateThread(PlayerThread, rtp_player.get(),
95 webrtc::kNormalPriority, "PlayerThread"));
96 if (player_thread.get() == NULL) {
97 printf("Unable to start RTP reader thread\n");
98 return -1;
99 }
100
101 webrtc::scoped_ptr<webrtc::ThreadWrapper> processing_thread(
102 webrtc::ThreadWrapper::CreateThread(ProcessingThread, &factory,
103 webrtc::kNormalPriority, "ProcessingThread"));
104 if (processing_thread.get() == NULL) {
105 printf("Unable to start processing thread\n");
106 return -1;
107 }
108
109 webrtc::scoped_ptr<webrtc::ThreadWrapper> decode_thread(
110 webrtc::ThreadWrapper::CreateThread(DecodeThread, &factory,
111 webrtc::kNormalPriority, "DecodeThread"));
112 if (decode_thread.get() == NULL) {
113 printf("Unable to start decode thread\n");
114 return -1;
115 }
116
117 webrtc::scoped_ptr<webrtc::EventWrapper> wait_event(
118 webrtc::EventWrapper::Create());
119 if (wait_event.get() == NULL) {
120 printf("Unable to create wait event\n");
121 return -1;
122 }
123
124 unsigned int dummy_thread_id;
125 player_thread->Start(dummy_thread_id);
126 processing_thread->Start(dummy_thread_id);
127 decode_thread->Start(dummy_thread_id);
128
129 wait_event->Wait(kConfigMaxRuntimeMs);
130
131 while (!player_thread->Stop()) {
132 }
133 while (!processing_thread->Stop()) {
134 }
135 while (!decode_thread->Stop()) {
136 }
137 }
138
139 rtp_player->Print();
140
141 webrtc::Trace::ReturnTrace();
142 return 0;
143 }
144