diff --git a/webrtc/build/sanitizers/tsan_suppressions_webrtc.cc b/webrtc/build/sanitizers/tsan_suppressions_webrtc.cc index ac27c49c27..2bc1b277f0 100644 --- a/webrtc/build/sanitizers/tsan_suppressions_webrtc.cc +++ b/webrtc/build/sanitizers/tsan_suppressions_webrtc.cc @@ -25,7 +25,6 @@ char kTSanDefaultSuppressions[] = // Split up suppressions covered previously by thread.cc and messagequeue.cc. "race:rtc::MessageQueue::Quit\n" -"race:FileVideoCapturerTest::VideoCapturerListener::OnFrameCaptured\n" "race:vp8cx_remove_encoder_threads\n" "race:third_party/libvpx_new/source/libvpx/vp9/common/vp9_scan.h\n" diff --git a/webrtc/media/devices/devicemanager.cc b/webrtc/media/devices/devicemanager.cc index a3f34fd02f..cbae2b2e64 100644 --- a/webrtc/media/devices/devicemanager.cc +++ b/webrtc/media/devices/devicemanager.cc @@ -35,10 +35,9 @@ #include "webrtc/base/windowpicker.h" #include "webrtc/base/windowpickerfactory.h" #include "webrtc/media/base/mediacommon.h" +#include "webrtc/media/base/videocapturer.h" #include "webrtc/media/base/videocapturerfactory.h" #include "webrtc/media/devices/deviceinfo.h" -#include "webrtc/media/devices/filevideocapturer.h" -#include "webrtc/media/devices/yuvframescapturer.h" #ifdef HAVE_WEBRTC_VIDEO #include "webrtc/media/webrtc/webrtcvideocapturerfactory.h" @@ -154,27 +153,6 @@ bool DeviceManager::GetVideoCaptureDevice(const std::string& name, } } - // If |name| is a valid name for a file or yuvframedevice, - // return a fake video capturer device. - if (GetFakeVideoCaptureDevice(name, out)) { - return true; - } - - return false; -} - -bool DeviceManager::GetFakeVideoCaptureDevice(const std::string& name, - Device* out) const { - if (rtc::Filesystem::IsFile(name)) { - *out = FileVideoCapturer::CreateFileVideoCapturerDevice(name); - return true; - } - - if (name == YuvFramesCapturer::kYuvFrameDeviceName) { - *out = YuvFramesCapturer::CreateYuvFramesCapturerDevice(); - return true; - } - return false; } @@ -190,16 +168,12 @@ void DeviceManager::ClearVideoCaptureDeviceMaxFormat( } VideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const { - VideoCapturer* capturer = MaybeConstructFakeVideoCapturer(device); - if (capturer) { - return capturer; - } - if (!video_device_capturer_factory_) { LOG(LS_ERROR) << "No video capturer factory for devices."; return NULL; } - capturer = video_device_capturer_factory_->Create(device); + cricket::VideoCapturer* capturer = + video_device_capturer_factory_->Create(device); if (!capturer) { return NULL; } @@ -213,29 +187,6 @@ VideoCapturer* DeviceManager::CreateVideoCapturer(const Device& device) const { return capturer; } -VideoCapturer* DeviceManager::MaybeConstructFakeVideoCapturer( - const Device& device) const { - // TODO(hellner): Throw out the creation of a file video capturer once the - // refactoring is completed. - if (FileVideoCapturer::IsFileVideoCapturerDevice(device)) { - FileVideoCapturer* capturer = new FileVideoCapturer; - if (!capturer->Init(device)) { - delete capturer; - return NULL; - } - LOG(LS_INFO) << "Created file video capturer " << device.name; - capturer->set_repeat(FileVideoCapturer::kForever); - return capturer; - } - - if (YuvFramesCapturer::IsYuvFramesCapturerDevice(device)) { - YuvFramesCapturer* capturer = new YuvFramesCapturer(); - capturer->Init(); - return capturer; - } - return NULL; -} - bool DeviceManager::GetWindows( std::vector* descriptions) { if (!window_picker_) { diff --git a/webrtc/media/devices/devicemanager.h b/webrtc/media/devices/devicemanager.h index 932fc5b8f7..86780e55ac 100644 --- a/webrtc/media/devices/devicemanager.h +++ b/webrtc/media/devices/devicemanager.h @@ -193,8 +193,6 @@ class DeviceManager : public DeviceManagerInterface { // The exclusion_list MUST be a NULL terminated list. static bool ShouldDeviceBeIgnored(const std::string& device_name, const char* const exclusion_list[]); - bool GetFakeVideoCaptureDevice(const std::string& name, Device* out) const; - VideoCapturer* MaybeConstructFakeVideoCapturer(const Device& device) const; bool initialized_; rtc::scoped_ptr< diff --git a/webrtc/media/devices/devicemanager_unittest.cc b/webrtc/media/devices/devicemanager_unittest.cc index 1fded4bab1..f49e6d5751 100644 --- a/webrtc/media/devices/devicemanager_unittest.cc +++ b/webrtc/media/devices/devicemanager_unittest.cc @@ -45,7 +45,6 @@ #include "webrtc/media/base/screencastid.h" #include "webrtc/media/base/testutils.h" #include "webrtc/media/base/videocapturerfactory.h" -#include "webrtc/media/devices/filevideocapturer.h" #include "webrtc/media/devices/v4llookup.h" #ifdef WEBRTC_LINUX @@ -202,16 +201,6 @@ TEST(DeviceManagerTest, GetVideoDeviceIds) { } } -TEST(DeviceManagerTest, GetVideoDeviceIds_File) { - scoped_ptr dm(DeviceManagerFactory::Create()); - EXPECT_TRUE(dm->Init()); - Device device; - const std::string test_file = - cricket::GetTestFilePath("captured-320x240-2s-48.frames"); - EXPECT_TRUE(dm->GetVideoCaptureDevice(test_file, &device)); - EXPECT_TRUE(cricket::FileVideoCapturer::IsFileVideoCapturerDevice(device)); -} - TEST(DeviceManagerTest, VerifyDevicesListsAreCleared) { const std::string imaginary("_NOT A REAL DEVICE_"); scoped_ptr dm(DeviceManagerFactory::Create()); diff --git a/webrtc/media/devices/filevideocapturer.cc b/webrtc/media/devices/filevideocapturer.cc deleted file mode 100644 index 466170afd6..0000000000 --- a/webrtc/media/devices/filevideocapturer.cc +++ /dev/null @@ -1,385 +0,0 @@ -/* - * libjingle - * Copyright 2004 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// Implementation of VideoRecorder and FileVideoCapturer. - -#include "webrtc/media/devices/filevideocapturer.h" - -#include "webrtc/base/bytebuffer.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" - -namespace cricket { - -///////////////////////////////////////////////////////////////////// -// Implementation of class VideoRecorder -///////////////////////////////////////////////////////////////////// -bool VideoRecorder::Start(const std::string& filename, bool write_header) { - Stop(); - write_header_ = write_header; - int err; - if (!video_file_.Open(filename, "wb", &err)) { - LOG(LS_ERROR) << "Unable to open file " << filename << " err=" << err; - return false; - } - return true; -} - -void VideoRecorder::Stop() { - video_file_.Close(); -} - -bool VideoRecorder::RecordFrame(const CapturedFrame& frame) { - if (rtc::SS_CLOSED == video_file_.GetState()) { - LOG(LS_ERROR) << "File not opened yet"; - return false; - } - - uint32_t size = 0; - if (!frame.GetDataSize(&size)) { - LOG(LS_ERROR) << "Unable to calculate the data size of the frame"; - return false; - } - - if (write_header_) { - // Convert the frame header to bytebuffer. - rtc::ByteBuffer buffer; - buffer.WriteUInt32(frame.width); - buffer.WriteUInt32(frame.height); - buffer.WriteUInt32(frame.fourcc); - buffer.WriteUInt32(frame.pixel_width); - buffer.WriteUInt32(frame.pixel_height); - // Elapsed time is deprecated. - const uint64_t dummy_elapsed_time = 0; - buffer.WriteUInt64(dummy_elapsed_time); - buffer.WriteUInt64(frame.time_stamp); - buffer.WriteUInt32(size); - - // Write the bytebuffer to file. - if (rtc::SR_SUCCESS != video_file_.Write(buffer.Data(), - buffer.Length(), - NULL, - NULL)) { - LOG(LS_ERROR) << "Failed to write frame header"; - return false; - } - } - // Write the frame data to file. - if (rtc::SR_SUCCESS != video_file_.Write(frame.data, - size, - NULL, - NULL)) { - LOG(LS_ERROR) << "Failed to write frame data"; - return false; - } - - return true; -} - -/////////////////////////////////////////////////////////////////////// -// Definition of private class FileReadThread that periodically reads -// frames from a file. -/////////////////////////////////////////////////////////////////////// -class FileVideoCapturer::FileReadThread - : public rtc::Thread, public rtc::MessageHandler { - public: - explicit FileReadThread(FileVideoCapturer* capturer) - : capturer_(capturer), - finished_(false) { - } - - virtual ~FileReadThread() { - Stop(); - } - - // Override virtual method of parent Thread. Context: Worker Thread. - virtual void Run() { - // Read the first frame and start the message pump. The pump runs until - // Stop() is called externally or Quit() is called by OnMessage(). - int waiting_time_ms = 0; - if (capturer_ && capturer_->ReadFrame(true, &waiting_time_ms)) { - PostDelayed(waiting_time_ms, this); - Thread::Run(); - } - - rtc::CritScope cs(&crit_); - finished_ = true; - } - - // Override virtual method of parent MessageHandler. Context: Worker Thread. - virtual void OnMessage(rtc::Message* /*pmsg*/) { - int waiting_time_ms = 0; - if (capturer_ && capturer_->ReadFrame(false, &waiting_time_ms)) { - PostDelayed(waiting_time_ms, this); - } else { - Quit(); - } - } - - // Check if Run() is finished. - bool Finished() const { - rtc::CritScope cs(&crit_); - return finished_; - } - - private: - FileVideoCapturer* capturer_; - rtc::CriticalSection crit_; - bool finished_; - - RTC_DISALLOW_COPY_AND_ASSIGN(FileReadThread); -}; - -///////////////////////////////////////////////////////////////////// -// Implementation of class FileVideoCapturer -///////////////////////////////////////////////////////////////////// -static const int64_t kNumNanoSecsPerMilliSec = 1000000; -const char* FileVideoCapturer::kVideoFileDevicePrefix = "video-file:"; - -FileVideoCapturer::FileVideoCapturer() - : frame_buffer_size_(0), - file_read_thread_(NULL), - repeat_(0), - last_frame_timestamp_ns_(0), - ignore_framerate_(false) { -} - -FileVideoCapturer::~FileVideoCapturer() { - Stop(); - delete[] static_cast(captured_frame_.data); -} - -bool FileVideoCapturer::Init(const Device& device) { - if (!FileVideoCapturer::IsFileVideoCapturerDevice(device)) { - return false; - } - std::string filename(device.name); - if (IsRunning()) { - LOG(LS_ERROR) << "The file video capturer is already running"; - return false; - } - // Open the file. - int err; - if (!video_file_.Open(filename, "rb", &err)) { - LOG(LS_ERROR) << "Unable to open the file " << filename << " err=" << err; - return false; - } - // Read the first frame's header to determine the supported format. - CapturedFrame frame; - if (rtc::SR_SUCCESS != ReadFrameHeader(&frame)) { - LOG(LS_ERROR) << "Failed to read the first frame header"; - video_file_.Close(); - return false; - } - // Seek back to the start of the file. - if (!video_file_.SetPosition(0)) { - LOG(LS_ERROR) << "Failed to seek back to beginning of the file"; - video_file_.Close(); - return false; - } - - // Enumerate the supported formats. We have only one supported format. We set - // the frame interval to kMinimumInterval here. In Start(), if the capture - // format's interval is greater than kMinimumInterval, we use the interval; - // otherwise, we use the timestamp in the file to control the interval. - VideoFormat format(frame.width, frame.height, VideoFormat::kMinimumInterval, - frame.fourcc); - std::vector supported; - supported.push_back(format); - - // TODO(thorcarpenter): Report the actual file video format as the supported - // format. Do not use kMinimumInterval as it conflicts with video adaptation. - SetId(device.id); - SetSupportedFormats(supported); - - // TODO(wuwang): Design an E2E integration test for video adaptation, - // then remove the below call to disable the video adapter. - set_enable_video_adapter(false); - return true; -} - -bool FileVideoCapturer::Init(const std::string& filename) { - return Init(FileVideoCapturer::CreateFileVideoCapturerDevice(filename)); -} - -CaptureState FileVideoCapturer::Start(const VideoFormat& capture_format) { - if (IsRunning()) { - LOG(LS_ERROR) << "The file video capturer is already running"; - return CS_FAILED; - } - - if (rtc::SS_CLOSED == video_file_.GetState()) { - LOG(LS_ERROR) << "File not opened yet"; - return CS_NO_DEVICE; - } else if (!video_file_.SetPosition(0)) { - LOG(LS_ERROR) << "Failed to seek back to beginning of the file"; - return CS_FAILED; - } - - SetCaptureFormat(&capture_format); - // Create a thread to read the file. - file_read_thread_ = new FileReadThread(this); - bool ret = file_read_thread_->Start(); - if (ret) { - LOG(LS_INFO) << "File video capturer '" << GetId() << "' started"; - return CS_RUNNING; - } else { - LOG(LS_ERROR) << "File video capturer '" << GetId() << "' failed to start"; - return CS_FAILED; - } -} - -bool FileVideoCapturer::IsRunning() { - return file_read_thread_ && !file_read_thread_->Finished(); -} - -void FileVideoCapturer::Stop() { - if (file_read_thread_) { - file_read_thread_->Stop(); - file_read_thread_ = NULL; - LOG(LS_INFO) << "File video capturer '" << GetId() << "' stopped"; - } - SetCaptureFormat(NULL); -} - -bool FileVideoCapturer::GetPreferredFourccs(std::vector* fourccs) { - if (!fourccs) { - return false; - } - - fourccs->push_back(GetSupportedFormats()->at(0).fourcc); - return true; -} - -rtc::StreamResult FileVideoCapturer::ReadFrameHeader( - CapturedFrame* frame) { - // We first read kFrameHeaderSize bytes from the file stream to a memory - // buffer, then construct a bytebuffer from the memory buffer, and finally - // read the frame header from the bytebuffer. - char header[CapturedFrame::kFrameHeaderSize]; - rtc::StreamResult sr; - size_t bytes_read; - int error; - sr = video_file_.Read(header, - CapturedFrame::kFrameHeaderSize, - &bytes_read, - &error); - LOG(LS_VERBOSE) << "Read frame header: stream_result = " << sr - << ", bytes read = " << bytes_read << ", error = " << error; - if (rtc::SR_SUCCESS == sr) { - if (CapturedFrame::kFrameHeaderSize != bytes_read) { - return rtc::SR_EOS; - } - rtc::ByteBuffer buffer(header, CapturedFrame::kFrameHeaderSize); - buffer.ReadUInt32(reinterpret_cast(&frame->width)); - buffer.ReadUInt32(reinterpret_cast(&frame->height)); - buffer.ReadUInt32(&frame->fourcc); - buffer.ReadUInt32(&frame->pixel_width); - buffer.ReadUInt32(&frame->pixel_height); - // Elapsed time is deprecated. - uint64_t dummy_elapsed_time; - buffer.ReadUInt64(&dummy_elapsed_time); - buffer.ReadUInt64(reinterpret_cast(&frame->time_stamp)); - buffer.ReadUInt32(&frame->data_size); - } - - return sr; -} - -// Executed in the context of FileReadThread. -bool FileVideoCapturer::ReadFrame(bool first_frame, int* wait_time_ms) { - uint32_t start_read_time_ms = rtc::Time(); - - // 1. Signal the previously read frame to downstream. - if (!first_frame) { - captured_frame_.time_stamp = - kNumNanoSecsPerMilliSec * static_cast(start_read_time_ms); - SignalFrameCaptured(this, &captured_frame_); - } - - // 2. Read the next frame. - if (rtc::SS_CLOSED == video_file_.GetState()) { - LOG(LS_ERROR) << "File not opened yet"; - return false; - } - // 2.1 Read the frame header. - rtc::StreamResult result = ReadFrameHeader(&captured_frame_); - if (rtc::SR_EOS == result) { // Loop back if repeat. - if (repeat_ != kForever) { - if (repeat_ > 0) { - --repeat_; - } else { - return false; - } - } - - if (video_file_.SetPosition(0)) { - result = ReadFrameHeader(&captured_frame_); - } - } - if (rtc::SR_SUCCESS != result) { - LOG(LS_ERROR) << "Failed to read the frame header"; - return false; - } - // 2.2 Reallocate memory for the frame data if necessary. - if (frame_buffer_size_ < captured_frame_.data_size) { - frame_buffer_size_ = captured_frame_.data_size; - delete[] static_cast(captured_frame_.data); - captured_frame_.data = new char[frame_buffer_size_]; - } - // 2.3 Read the frame adata. - if (rtc::SR_SUCCESS != video_file_.Read(captured_frame_.data, - captured_frame_.data_size, - NULL, NULL)) { - LOG(LS_ERROR) << "Failed to read frame data"; - return false; - } - - // 3. Decide how long to wait for the next frame. - *wait_time_ms = 0; - - // If the capture format's interval is not kMinimumInterval, we use it to - // control the rate; otherwise, we use the timestamp in the file to control - // the rate. - if (!first_frame && !ignore_framerate_) { - int64_t interval_ns = - GetCaptureFormat()->interval > VideoFormat::kMinimumInterval - ? GetCaptureFormat()->interval - : captured_frame_.time_stamp - last_frame_timestamp_ns_; - int interval_ms = static_cast(interval_ns / kNumNanoSecsPerMilliSec); - interval_ms -= rtc::Time() - start_read_time_ms; - if (interval_ms > 0) { - *wait_time_ms = interval_ms; - } - } - // Keep the original timestamp read from the file. - last_frame_timestamp_ns_ = captured_frame_.time_stamp; - return true; -} - -} // namespace cricket diff --git a/webrtc/media/devices/filevideocapturer.h b/webrtc/media/devices/filevideocapturer.h deleted file mode 100644 index 4631b93bc9..0000000000 --- a/webrtc/media/devices/filevideocapturer.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * libjingle - * Copyright 2004 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -// -// This file contains two classes, VideoRecorder and FileVideoCapturer. -// VideoRecorder records the captured frames into a file. The file stores a -// sequence of captured frames; each frame has a header defined in struct -// CapturedFrame, followed by the frame data. -// -// FileVideoCapturer, a subclass of VideoCapturer, is a simulated video capturer -// that periodically reads images from a previously recorded file. - -#ifndef WEBRTC_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_ -#define WEBRTC_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_ - -#include -#include - -#include "webrtc/base/stream.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/media/base/videocapturer.h" - -namespace rtc { -class FileStream; -} - -namespace cricket { - -// Utility class to record the frames captured by a video capturer into a file. -class VideoRecorder { - public: - VideoRecorder() {} - ~VideoRecorder() { Stop(); } - - // Start the recorder by opening the specified file. Return true if the file - // is opened successfully. write_header should normally be true; false means - // write raw frame pixel data to file without any headers. - bool Start(const std::string& filename, bool write_header); - // Stop the recorder by closing the file. - void Stop(); - // Record a video frame to the file. Return true if the frame is written to - // the file successfully. This method needs to be called after Start() and - // before Stop(). - bool RecordFrame(const CapturedFrame& frame); - - private: - rtc::FileStream video_file_; - bool write_header_; - - RTC_DISALLOW_COPY_AND_ASSIGN(VideoRecorder); -}; - -// Simulated video capturer that periodically reads frames from a file. -class FileVideoCapturer : public VideoCapturer { - public: - static const int kForever = -1; - - FileVideoCapturer(); - virtual ~FileVideoCapturer(); - - // Determines if the given device is actually a video file, to be captured - // with a FileVideoCapturer. - static bool IsFileVideoCapturerDevice(const Device& device) { - return rtc::starts_with(device.id.c_str(), kVideoFileDevicePrefix); - } - - // Creates a fake device for the given filename. - static Device CreateFileVideoCapturerDevice(const std::string& filename) { - std::stringstream id; - id << kVideoFileDevicePrefix << filename; - return Device(filename, id.str()); - } - - // Set how many times to repeat reading the file. Repeat forever if the - // parameter is kForever; no repeat if the parameter is 0 or - // less than -1. - void set_repeat(int repeat) { repeat_ = repeat; } - - // If ignore_framerate is true, file is read as quickly as possible. If - // false, read rate is controlled by the timestamps in the video file - // (thus simulating camera capture). Default value set to false. - void set_ignore_framerate(bool ignore_framerate) { - ignore_framerate_ = ignore_framerate; - } - - // Initializes the capturer with the given file. - bool Init(const std::string& filename); - - // Initializes the capturer with the given device. This should only be used - // if IsFileVideoCapturerDevice returned true for the given device. - bool Init(const Device& device); - - // Override virtual methods of parent class VideoCapturer. - virtual CaptureState Start(const VideoFormat& capture_format); - virtual void Stop(); - virtual bool IsRunning(); - virtual bool IsScreencast() const { return false; } - - protected: - // Override virtual methods of parent class VideoCapturer. - virtual bool GetPreferredFourccs(std::vector* fourccs); - - // Read the frame header from the file stream, video_file_. - rtc::StreamResult ReadFrameHeader(CapturedFrame* frame); - - // Read a frame and determine how long to wait for the next frame. If the - // frame is read successfully, Set the output parameter, wait_time_ms and - // return true. Otherwise, do not change wait_time_ms and return false. - bool ReadFrame(bool first_frame, int* wait_time_ms); - - // Return the CapturedFrame - useful for extracting contents after reading - // a frame. Should be used only while still reading a file (i.e. only while - // the CapturedFrame object still exists). - const CapturedFrame* frame() const { - return &captured_frame_; - } - - private: - class FileReadThread; // Forward declaration, defined in .cc. - - static const char* kVideoFileDevicePrefix; - rtc::FileStream video_file_; - CapturedFrame captured_frame_; - // The number of bytes allocated buffer for captured_frame_.data. - uint32_t frame_buffer_size_; - FileReadThread* file_read_thread_; - int repeat_; // How many times to repeat the file. - int64_t last_frame_timestamp_ns_; // Timestamp of last read frame. - bool ignore_framerate_; - - RTC_DISALLOW_COPY_AND_ASSIGN(FileVideoCapturer); -}; - -} // namespace cricket - -#endif // WEBRTC_MEDIA_DEVICES_FILEVIDEOCAPTURER_H_ diff --git a/webrtc/media/devices/filevideocapturer_unittest.cc b/webrtc/media/devices/filevideocapturer_unittest.cc deleted file mode 100644 index b34b69ff69..0000000000 --- a/webrtc/media/devices/filevideocapturer_unittest.cc +++ /dev/null @@ -1,204 +0,0 @@ -/* - * libjingle - * Copyright 2004 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -#include -#include - -#include "webrtc/base/gunit.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" -#include "webrtc/media/base/testutils.h" -#include "webrtc/media/devices/filevideocapturer.h" - -namespace { - -class FileVideoCapturerTest : public testing::Test { - public: - virtual void SetUp() { - capturer_.reset(new cricket::FileVideoCapturer); - } - - bool OpenFile(const std::string& filename) { - return capturer_->Init(cricket::GetTestFilePath(filename)); - } - - protected: - class VideoCapturerListener : public sigslot::has_slots<> { - public: - VideoCapturerListener() - : frame_count_(0), - frame_width_(0), - frame_height_(0), - resolution_changed_(false) { - } - - void OnFrameCaptured(cricket::VideoCapturer* capturer, - const cricket::CapturedFrame* frame) { - ++frame_count_; - if (1 == frame_count_) { - frame_width_ = frame->width; - frame_height_ = frame->height; - } else if (frame_width_ != frame->width || - frame_height_ != frame->height) { - resolution_changed_ = true; - } - } - - int frame_count() const { return frame_count_; } - int frame_width() const { return frame_width_; } - int frame_height() const { return frame_height_; } - bool resolution_changed() const { return resolution_changed_; } - - private: - int frame_count_; - int frame_width_; - int frame_height_; - bool resolution_changed_; - }; - - rtc::scoped_ptr capturer_; - cricket::VideoFormat capture_format_; -}; - -TEST_F(FileVideoCapturerTest, TestNotOpened) { - EXPECT_EQ("", capturer_->GetId()); - EXPECT_TRUE(capturer_->GetSupportedFormats()->empty()); - EXPECT_EQ(NULL, capturer_->GetCaptureFormat()); - EXPECT_FALSE(capturer_->IsRunning()); -} - -TEST_F(FileVideoCapturerTest, TestInvalidOpen) { - EXPECT_FALSE(OpenFile("NotmeNotme")); -} - -TEST_F(FileVideoCapturerTest, TestOpen) { - EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames")); - EXPECT_NE("", capturer_->GetId()); - EXPECT_TRUE(NULL != capturer_->GetSupportedFormats()); - EXPECT_EQ(1U, capturer_->GetSupportedFormats()->size()); - EXPECT_EQ(NULL, capturer_->GetCaptureFormat()); // not started yet - EXPECT_FALSE(capturer_->IsRunning()); -} - -TEST_F(FileVideoCapturerTest, TestLargeSmallDesiredFormat) { - EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames")); - // desired format with large resolution. - cricket::VideoFormat desired( - 3200, 2400, cricket::VideoFormat::FpsToInterval(30), cricket::FOURCC_ANY); - EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_)); - EXPECT_EQ(320, capture_format_.width); - EXPECT_EQ(240, capture_format_.height); - - // Desired format with small resolution. - desired.width = 0; - desired.height = 0; - EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_)); - EXPECT_EQ(320, capture_format_.width); - EXPECT_EQ(240, capture_format_.height); -} - -TEST_F(FileVideoCapturerTest, TestSupportedAsDesiredFormat) { - EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames")); - // desired format same as the capture format supported by the file - cricket::VideoFormat desired = capturer_->GetSupportedFormats()->at(0); - EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_)); - EXPECT_TRUE(desired == capture_format_); - - // desired format same as the supported capture format except the fourcc - desired.fourcc = cricket::FOURCC_ANY; - EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_)); - EXPECT_NE(capture_format_.fourcc, desired.fourcc); - - // desired format with minimum interval - desired.interval = cricket::VideoFormat::kMinimumInterval; - EXPECT_TRUE(capturer_->GetBestCaptureFormat(desired, &capture_format_)); -} - -TEST_F(FileVideoCapturerTest, TestNoRepeat) { - EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames")); - VideoCapturerListener listener; - capturer_->SignalFrameCaptured.connect( - &listener, &VideoCapturerListener::OnFrameCaptured); - capturer_->set_repeat(0); - capture_format_ = capturer_->GetSupportedFormats()->at(0); - EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning(), 20000); - EXPECT_EQ(48, listener.frame_count()); -} - -TEST_F(FileVideoCapturerTest, TestRepeatForever) { - // Start the capturer_ with 50 fps and read no less than 150 frames. - EXPECT_TRUE(OpenFile("captured-320x240-2s-48.frames")); - VideoCapturerListener listener; - capturer_->SignalFrameCaptured.connect( - &listener, &VideoCapturerListener::OnFrameCaptured); - capturer_->set_repeat(cricket::FileVideoCapturer::kForever); - capture_format_ = capturer_->GetSupportedFormats()->at(0); - capture_format_.interval = cricket::VideoFormat::FpsToInterval(50); - EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE(NULL != capturer_->GetCaptureFormat()); - EXPECT_TRUE(capture_format_ == *capturer_->GetCaptureFormat()); - EXPECT_TRUE_WAIT(!capturer_->IsRunning() || - listener.frame_count() >= 150, 20000); - capturer_->Stop(); - EXPECT_FALSE(capturer_->IsRunning()); - EXPECT_GE(listener.frame_count(), 150); - EXPECT_FALSE(listener.resolution_changed()); - EXPECT_EQ(listener.frame_width(), capture_format_.width); - EXPECT_EQ(listener.frame_height(), capture_format_.height); -} - -// See: https://code.google.com/p/webrtc/issues/detail?id=2409 -TEST_F(FileVideoCapturerTest, DISABLED_TestPartialFrameHeader) { - EXPECT_TRUE(OpenFile("1.frame_plus_1.byte")); - VideoCapturerListener listener; - capturer_->SignalFrameCaptured.connect( - &listener, &VideoCapturerListener::OnFrameCaptured); - capturer_->set_repeat(0); - capture_format_ = capturer_->GetSupportedFormats()->at(0); - EXPECT_EQ(cricket::CS_RUNNING, capturer_->Start(capture_format_)); - EXPECT_TRUE_WAIT(!capturer_->IsRunning(), 1000); - EXPECT_EQ(1, listener.frame_count()); -} - -TEST_F(FileVideoCapturerTest, TestFileDevices) { - cricket::Device not_a_file("I'm a camera", "with an id"); - EXPECT_FALSE( - cricket::FileVideoCapturer::IsFileVideoCapturerDevice(not_a_file)); - const std::string test_file = - cricket::GetTestFilePath("captured-320x240-2s-48.frames"); - cricket::Device file_device = - cricket::FileVideoCapturer::CreateFileVideoCapturerDevice(test_file); - EXPECT_TRUE( - cricket::FileVideoCapturer::IsFileVideoCapturerDevice(file_device)); - EXPECT_TRUE(capturer_->Init(file_device)); - EXPECT_EQ(file_device.id, capturer_->GetId()); -} - -} // unnamed namespace diff --git a/webrtc/media/devices/yuvframescapturer.cc b/webrtc/media/devices/yuvframescapturer.cc deleted file mode 100644 index c36de9b44c..0000000000 --- a/webrtc/media/devices/yuvframescapturer.cc +++ /dev/null @@ -1,199 +0,0 @@ -/* - * libjingle - * Copyright 2004 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#include "webrtc/media/devices/yuvframescapturer.h" - -#include "webrtc/base/bytebuffer.h" -#include "webrtc/base/criticalsection.h" -#include "webrtc/base/logging.h" -#include "webrtc/base/thread.h" - -#include "webrtc/system_wrappers/include/clock.h" - -namespace cricket { -/////////////////////////////////////////////////////////////////////// -// Definition of private class YuvFramesThread that periodically generates -// frames. -/////////////////////////////////////////////////////////////////////// -class YuvFramesCapturer::YuvFramesThread - : public rtc::Thread, public rtc::MessageHandler { - public: - explicit YuvFramesThread(YuvFramesCapturer* capturer) - : capturer_(capturer), - finished_(false) { - } - - virtual ~YuvFramesThread() { - Stop(); - } - - // Override virtual method of parent Thread. Context: Worker Thread. - virtual void Run() { - // Read the first frame and start the message pump. The pump runs until - // Stop() is called externally or Quit() is called by OnMessage(). - int waiting_time_ms = 0; - if (capturer_) { - capturer_->ReadFrame(true); - PostDelayed(waiting_time_ms, this); - Thread::Run(); - } - - rtc::CritScope cs(&crit_); - finished_ = true; - } - - // Override virtual method of parent MessageHandler. Context: Worker Thread. - virtual void OnMessage(rtc::Message* /*pmsg*/) { - int waiting_time_ms = 0; - if (capturer_) { - capturer_->ReadFrame(false); - PostDelayed(waiting_time_ms, this); - } else { - Quit(); - } - } - - // Check if Run() is finished. - bool Finished() const { - rtc::CritScope cs(&crit_); - return finished_; - } - - private: - YuvFramesCapturer* capturer_; - rtc::CriticalSection crit_; - bool finished_; - - RTC_DISALLOW_COPY_AND_ASSIGN(YuvFramesThread); -}; - -///////////////////////////////////////////////////////////////////// -// Implementation of class YuvFramesCapturer. -///////////////////////////////////////////////////////////////////// - -const char* YuvFramesCapturer::kYuvFrameDeviceName = "YuvFramesGenerator"; - -// TODO(shaowei): allow width_ and height_ to be configurable. -YuvFramesCapturer::YuvFramesCapturer() - : frames_generator_thread(NULL), - width_(640), - height_(480), - frame_index_(0), - barcode_interval_(1) { -} - -YuvFramesCapturer::~YuvFramesCapturer() { - Stop(); - delete[] static_cast(captured_frame_.data); -} - -void YuvFramesCapturer::Init() { - int size = width_ * height_; - int qsize = size / 4; - frame_generator_ = new YuvFrameGenerator(width_, height_, true); - frame_data_size_ = size + 2 * qsize; - captured_frame_.data = new char[frame_data_size_]; - captured_frame_.fourcc = FOURCC_IYUV; - captured_frame_.pixel_height = 1; - captured_frame_.pixel_width = 1; - captured_frame_.width = width_; - captured_frame_.height = height_; - captured_frame_.data_size = frame_data_size_; - - // Enumerate the supported formats. We have only one supported format. - VideoFormat format(width_, height_, VideoFormat::kMinimumInterval, - FOURCC_IYUV); - std::vector supported; - supported.push_back(format); - SetSupportedFormats(supported); -} - -CaptureState YuvFramesCapturer::Start(const VideoFormat& capture_format) { - if (IsRunning()) { - LOG(LS_ERROR) << "Yuv Frame Generator is already running"; - return CS_FAILED; - } - SetCaptureFormat(&capture_format); - - barcode_reference_timestamp_millis_ = - static_cast(rtc::Time()) * 1000; - // Create a thread to generate frames. - frames_generator_thread = new YuvFramesThread(this); - bool ret = frames_generator_thread->Start(); - if (ret) { - LOG(LS_INFO) << "Yuv Frame Generator started"; - return CS_RUNNING; - } else { - LOG(LS_ERROR) << "Yuv Frame Generator failed to start"; - return CS_FAILED; - } -} - -bool YuvFramesCapturer::IsRunning() { - return frames_generator_thread && !frames_generator_thread->Finished(); -} - -void YuvFramesCapturer::Stop() { - if (frames_generator_thread) { - frames_generator_thread->Stop(); - frames_generator_thread = NULL; - LOG(LS_INFO) << "Yuv Frame Generator stopped"; - } - SetCaptureFormat(NULL); -} - -bool YuvFramesCapturer::GetPreferredFourccs(std::vector* fourccs) { - if (!fourccs) { - return false; - } - fourccs->push_back(GetSupportedFormats()->at(0).fourcc); - return true; -} - -// Executed in the context of YuvFramesThread. -void YuvFramesCapturer::ReadFrame(bool first_frame) { - // 1. Signal the previously read frame to downstream. - if (!first_frame) { - SignalFrameCaptured(this, &captured_frame_); - } - uint8_t* buffer = new uint8_t[frame_data_size_]; - frame_generator_->GenerateNextFrame(buffer, GetBarcodeValue()); - frame_index_++; - memmove(captured_frame_.data, buffer, frame_data_size_); - delete[] buffer; -} - -int32_t YuvFramesCapturer::GetBarcodeValue() { - if (barcode_reference_timestamp_millis_ == -1 || - frame_index_ % barcode_interval_ != 0) { - return -1; - } - int64_t now_millis = static_cast(rtc::Time()) * 1000; - return static_cast(now_millis - barcode_reference_timestamp_millis_); -} - -} // namespace cricket diff --git a/webrtc/media/devices/yuvframescapturer.h b/webrtc/media/devices/yuvframescapturer.h deleted file mode 100644 index 2dd0857326..0000000000 --- a/webrtc/media/devices/yuvframescapturer.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * libjingle - * Copyright 2010 Google Inc. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO - * EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, - * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; - * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, - * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR - * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF - * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef WEBRTC_MEDIA_DEVICES_YUVFRAMESCAPTURER_H_ -#define WEBRTC_MEDIA_DEVICES_YUVFRAMESCAPTURER_H_ - -#include -#include - -#include "webrtc/base/stream.h" -#include "webrtc/base/stringutils.h" -#include "webrtc/media/base/videocapturer.h" -#include "webrtc/media/base/yuvframegenerator.h" - - -namespace rtc { -class FileStream; -} - -namespace cricket { - - -// Simulated video capturer that periodically reads frames from a file. -class YuvFramesCapturer : public VideoCapturer { - public: - YuvFramesCapturer(); - YuvFramesCapturer(int width, int height); - virtual ~YuvFramesCapturer(); - - static const char* kYuvFrameDeviceName; - static Device CreateYuvFramesCapturerDevice() { - std::stringstream id; - id << kYuvFrameDeviceName; - return Device(id.str(), id.str()); - } - static bool IsYuvFramesCapturerDevice(const Device& device) { - return rtc::starts_with(device.id.c_str(), kYuvFrameDeviceName); - } - - void Init(); - // Override virtual methods of parent class VideoCapturer. - virtual CaptureState Start(const VideoFormat& capture_format); - virtual void Stop(); - virtual bool IsRunning(); - virtual bool IsScreencast() const { return false; } - - protected: - // Override virtual methods of parent class VideoCapturer. - virtual bool GetPreferredFourccs(std::vector* fourccs); - - // Read a frame and determine how long to wait for the next frame. - void ReadFrame(bool first_frame); - - private: - class YuvFramesThread; // Forward declaration, defined in .cc. - - YuvFrameGenerator* frame_generator_; - CapturedFrame captured_frame_; - YuvFramesThread* frames_generator_thread; - int width_; - int height_; - uint32_t frame_data_size_; - uint32_t frame_index_; - - int64_t barcode_reference_timestamp_millis_; - int32_t barcode_interval_; - int32_t GetBarcodeValue(); - - RTC_DISALLOW_COPY_AND_ASSIGN(YuvFramesCapturer); -}; - -} // namespace cricket - -#endif // WEBRTC_MEDIA_DEVICES_YUVFRAMESCAPTURER_H_ diff --git a/webrtc/media/media.gyp b/webrtc/media/media.gyp index 107918efcf..7a2ab1c892 100644 --- a/webrtc/media/media.gyp +++ b/webrtc/media/media.gyp @@ -13,7 +13,7 @@ 'target_name': 'rtc_media', 'type': 'static_library', 'dependencies': [ - '<(webrtc_root)/base/base.gyp:rtc_base', + '<(webrtc_root)/base/base.gyp:rtc_base_approved', '<(webrtc_root)/common.gyp:webrtc_common', '<(webrtc_root)/modules/modules.gyp:video_render_module', '<(webrtc_root)/webrtc.gyp:webrtc', @@ -80,11 +80,7 @@ 'devices/devicemanager.cc', 'devices/devicemanager.h', 'devices/dummydevicemanager.h', - 'devices/filevideocapturer.cc', - 'devices/filevideocapturer.h', 'devices/videorendererfactory.h', - 'devices/yuvframescapturer.cc', - 'devices/yuvframescapturer.h', 'sctp/sctpdataengine.cc', 'sctp/sctpdataengine.h', 'webrtc/nullwebrtcvideoengine.h', diff --git a/webrtc/media/media_tests.gypi b/webrtc/media/media_tests.gypi index fce1e003b8..4d03068fa2 100644 --- a/webrtc/media/media_tests.gypi +++ b/webrtc/media/media_tests.gypi @@ -90,7 +90,6 @@ 'base/videoengine_unittest.h', 'base/videoframe_unittest.h', 'devices/dummydevicemanager_unittest.cc', - 'devices/filevideocapturer_unittest.cc', 'sctp/sctpdataengine_unittest.cc', 'webrtc/nullwebrtcvideoengine_unittest.cc', 'webrtc/simulcast_unittest.cc',