Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(632)

Unified Diff: talk/media/devices/filevideocapturer.cc

Issue 1587193006: Move talk/media to webrtc/media (Closed) Base URL: https://chromium.googlesource.com/external/webrtc.git@master
Patch Set: Rebased to b647aca12a884a13c1728118586245399b55fa3d (#11493) Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « talk/media/devices/filevideocapturer.h ('k') | talk/media/devices/filevideocapturer_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: talk/media/devices/filevideocapturer.cc
diff --git a/talk/media/devices/filevideocapturer.cc b/talk/media/devices/filevideocapturer.cc
deleted file mode 100644
index 8849a09b258f1d6f417deafee0439187bf26c945..0000000000000000000000000000000000000000
--- a/talk/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 "talk/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<char*>(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<VideoFormat> 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<uint32_t>* 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<uint32_t*>(&frame->width));
- buffer.ReadUInt32(reinterpret_cast<uint32_t*>(&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<uint64_t*>(&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<int64_t>(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<char*>(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<int>(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
« no previous file with comments | « talk/media/devices/filevideocapturer.h ('k') | talk/media/devices/filevideocapturer_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698