1b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org/*
2b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *
4b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  Use of this source code is governed by a BSD-style license
5b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  that can be found in the LICENSE file in the root of the source
6b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  tree. An additional intellectual property rights grant can be found
7b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  in the file PATENTS.  All contributing project authors may
8b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org *  be found in the AUTHORS file in the root of the source tree.
9b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org */
10b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
113f45c2e0ac4cb280f941efa3a3476895795e3dd6pbos@webrtc.org#include <assert.h>
12b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
131bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/modules/video_coding/main/test/receiver_tests.h"
144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/modules/video_coding/main/test/vcm_payload_sink_factory.h"
152637d61b86b68c7082ae21b4cc9bc88cc36d1c13stefan@webrtc.org#include "webrtc/system_wrappers/interface/event_wrapper.h"
161bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/thread_wrapper.h"
171bb2146351979b6610107419b2a9c86cca2692a3stefan@webrtc.org#include "webrtc/system_wrappers/interface/trace.h"
184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org#include "webrtc/test/testsupport/fileutils.h"
194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgusing webrtc::rtpplayer::RtpPlayerInterface;
214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgusing webrtc::rtpplayer::VcmPayloadSinkFactory;
224d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
234d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgnamespace {
244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst bool kConfigProtectionEnabled = true;
264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst webrtc::VCMVideoProtection kConfigProtectionMethod =
274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::kProtectionDualDecoder;
284d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst float kConfigLossRate = 0.05f;
294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst uint32_t kConfigRttMs = 50;
304d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst bool kConfigReordering = false;
314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst uint32_t kConfigRenderDelayMs = 0;
324d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst uint32_t kConfigMinPlayoutDelayMs = 0;
334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgconst int64_t kConfigMaxRuntimeMs = 10000;
344d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
353b89e10f31160da35b408fd00cb8f89d2b08862dpbos@webrtc.org}  // namespace
364d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgbool PlayerThread(void* obj) {
384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  assert(obj);
394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  RtpPlayerInterface* rtp_player = static_cast<RtpPlayerInterface*>(obj);
404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::scoped_ptr<webrtc::EventWrapper> wait_event(
424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      webrtc::EventWrapper::Create());
434d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (wait_event.get() == NULL) {
444d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    return false;
454d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
464d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
474d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
484d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (rtp_player->NextPacket(clock->TimeInMilliseconds()) < 0) {
494d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    return false;
504d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
514d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  wait_event->Wait(rtp_player->TimeUntilNextPacket());
524d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
534d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return true;
54b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
55b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
564d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgbool ProcessingThread(void* obj) {
574d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  assert(obj);
584d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return static_cast<VcmPayloadSinkFactory*>(obj)->ProcessAll();
59b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
60b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
614d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgbool DecodeThread(void* obj) {
624d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  assert(obj);
634d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return static_cast<VcmPayloadSinkFactory*>(obj)->DecodeAll();
64b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
65b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
664d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.orgint RtpPlayMT(const CmdArgs& args) {
674d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string trace_file = webrtc::test::OutputPath() + "receiverTestTrace.txt";
684d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::Trace::CreateTrace();
694d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::Trace::SetTraceFile(trace_file.c_str());
7006eaa5465d57f416c14bb3a587ba4146290d6a58andrew@webrtc.org  webrtc::Trace::set_level_filter(webrtc::kTraceAll);
71b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
724d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::rtpplayer::PayloadTypes payload_types;
734d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  payload_types.push_back(webrtc::rtpplayer::PayloadCodecTuple(
744d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      VCM_VP8_PAYLOAD_TYPE, "VP8", webrtc::kVideoCodecVP8));
75b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
764d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  std::string output_file = args.outputFile;
774d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (output_file == "") {
784d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    output_file = webrtc::test::OutputPath() + "RtpPlayMT_decoded.yuv";
794d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
80b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
814d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::Clock* clock = webrtc::Clock::GetRealTimeClock();
824d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  VcmPayloadSinkFactory factory(output_file, clock, kConfigProtectionEnabled,
834d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      kConfigProtectionMethod, kConfigRttMs, kConfigRenderDelayMs,
8431a8ce783a62afe0c014bc23f0be8c2a779dbd74mikhal@webrtc.org      kConfigMinPlayoutDelayMs);
854d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::scoped_ptr<RtpPlayerInterface> rtp_player(webrtc::rtpplayer::Create(
864d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      args.inputFile, &factory, clock, payload_types, kConfigLossRate,
874d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      kConfigRttMs, kConfigReordering));
884d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  if (rtp_player.get() == NULL) {
894d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    return -1;
904d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
91b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
924d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  {
934d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::scoped_ptr<webrtc::ThreadWrapper> player_thread(
944d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org        webrtc::ThreadWrapper::CreateThread(PlayerThread, rtp_player.get(),
954d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org            webrtc::kNormalPriority, "PlayerThread"));
964d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (player_thread.get() == NULL) {
974d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      printf("Unable to start RTP reader thread\n");
984d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
99b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
100b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1014d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::scoped_ptr<webrtc::ThreadWrapper> processing_thread(
1024d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org        webrtc::ThreadWrapper::CreateThread(ProcessingThread, &factory,
1034d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org            webrtc::kNormalPriority, "ProcessingThread"));
1044d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (processing_thread.get() == NULL) {
1054d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      printf("Unable to start processing thread\n");
1064d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
107b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
108b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1094d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::scoped_ptr<webrtc::ThreadWrapper> decode_thread(
1104d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org        webrtc::ThreadWrapper::CreateThread(DecodeThread, &factory,
1114d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org            webrtc::kNormalPriority, "DecodeThread"));
1124d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (decode_thread.get() == NULL) {
1134d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      printf("Unable to start decode thread\n");
1144d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
115b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
116b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1174d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    webrtc::scoped_ptr<webrtc::EventWrapper> wait_event(
1184d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org        webrtc::EventWrapper::Create());
1194d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    if (wait_event.get() == NULL) {
1204d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      printf("Unable to create wait event\n");
1214d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org      return -1;
122b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
123b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1244d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    unsigned int dummy_thread_id;
1254d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    player_thread->Start(dummy_thread_id);
1264d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    processing_thread->Start(dummy_thread_id);
1274d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    decode_thread->Start(dummy_thread_id);
128b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1294d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    wait_event->Wait(kConfigMaxRuntimeMs);
130b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org
1314d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    while (!player_thread->Stop()) {
132b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1334d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    while (!processing_thread->Stop()) {
134b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1354d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org    while (!decode_thread->Stop()) {
136b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org    }
1374d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  }
1384d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
1394d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  rtp_player->Print();
1404d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org
1414d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  webrtc::Trace::ReturnTrace();
1424d2a2eccaef42c24ada13e98fe2917439d882033solenberg@webrtc.org  return 0;
143b015cbede88899f67a53fbbe581b02ce8e32794andrew@webrtc.org}
144