| Index: media/capture/webm_muxer.cc
|
| diff --git a/media/capture/webm_muxer.cc b/media/capture/webm_muxer.cc
|
| index b913fa7501416818c31a857084d225fa66e740d1..30f14df130685e023f4170bdb067a68d6f19392d 100644
|
| --- a/media/capture/webm_muxer.cc
|
| +++ b/media/capture/webm_muxer.cc
|
| @@ -5,6 +5,7 @@
|
| #include "media/capture/webm_muxer.h"
|
|
|
| #include "base/bind.h"
|
| +#include "base/strings/stringprintf.h"
|
| #include "media/base/limits.h"
|
| #include "media/base/video_frame.h"
|
|
|
| @@ -24,21 +25,20 @@ static double GetFrameRate(const scoped_refptr<VideoFrame>& video_frame) {
|
| return frame_rate;
|
| }
|
|
|
| -WebmMuxer::WebmMuxer(const WriteDataCB& write_data_callback)
|
| - : track_index_(0),
|
| +WebmMuxer::WebmMuxer(
|
| + const scoped_refptr<base::SingleThreadTaskRunner> main_task_runner,
|
| + const WriteDataCB& write_data_callback)
|
| + : main_task_runner_(main_task_runner),
|
| + track_index_(0),
|
| write_data_callback_(write_data_callback),
|
| - position_(0) {
|
| + position_(0),
|
| + segment_(new mkvmuxer::Segment()) {
|
| + DCHECK(main_task_runner_);
|
| DCHECK(!write_data_callback_.is_null());
|
| // Creation is done on a different thread than main activities.
|
| thread_checker_.DetachFromThread();
|
| }
|
|
|
| -WebmMuxer::~WebmMuxer() {
|
| - // No need to segment_.Finalize() since is not Seekable(), i.e. a live stream,
|
| - // but is good practice.
|
| - segment_.Finalize();
|
| -}
|
| -
|
| void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame,
|
| const base::StringPiece& encoded_data,
|
| base::TimeTicks timestamp,
|
| @@ -52,33 +52,46 @@ void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame,
|
| GetFrameRate(video_frame));
|
| first_frame_timestamp_ = timestamp;
|
| }
|
| - segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data.data()),
|
| - encoded_data.size(),
|
| - track_index_,
|
| - (timestamp - first_frame_timestamp_).InMicroseconds() *
|
| - base::Time::kNanosecondsPerMicrosecond,
|
| - is_key_frame);
|
| + segment_->AddFrame(reinterpret_cast<const uint8_t*>(encoded_data.data()),
|
| + encoded_data.size(),
|
| + track_index_,
|
| + (timestamp - first_frame_timestamp_).InMicroseconds() *
|
| + base::Time::kNanosecondsPerMicrosecond,
|
| + is_key_frame);
|
| +}
|
| +
|
| +//static
|
| +void WebmMuxer::FinalizeSegment(scoped_ptr<mkvmuxer::Segment> segment) {
|
| + // No need to segment_->Finalize() since is not Seekable(), i.e. a live
|
| + // stream, but is a good practice.
|
| + segment->Finalize();
|
| +}
|
| +
|
| +WebmMuxer::~WebmMuxer() {
|
| + // Guarantee destruction of |segment_| in the appropriate thread.
|
| + main_task_runner_->PostTask(FROM_HERE,
|
| + base::Bind(&WebmMuxer::FinalizeSegment, base::Passed(&segment_)));
|
| }
|
|
|
| void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK_EQ(track_index_, 0u) << "WebmMuxer can only be initialised once.";
|
|
|
| - segment_.Init(this);
|
| - segment_.set_mode(mkvmuxer::Segment::kLive);
|
| - segment_.OutputCues(false);
|
| + segment_->Init(this);
|
| + segment_->set_mode(mkvmuxer::Segment::kLive);
|
| + segment_->OutputCues(false);
|
|
|
| - mkvmuxer::SegmentInfo* const info = segment_.GetSegmentInfo();
|
| + mkvmuxer::SegmentInfo* const info = segment_->GetSegmentInfo();
|
| info->set_writing_app("Chrome");
|
| info->set_muxing_app("Chrome");
|
|
|
| track_index_ =
|
| - segment_.AddVideoTrack(frame_size.width(), frame_size.height(), 0);
|
| + segment_->AddVideoTrack(frame_size.width(), frame_size.height(), 0);
|
| DCHECK_GT(track_index_, 0u);
|
|
|
| mkvmuxer::VideoTrack* const video_track =
|
| reinterpret_cast<mkvmuxer::VideoTrack*>(
|
| - segment_.GetTrackByNumber(track_index_));
|
| + segment_->GetTrackByNumber(track_index_));
|
| DCHECK(video_track);
|
| video_track->set_codec_id(mkvmuxer::Tracks::kVp8CodecId);
|
| DCHECK_EQ(video_track->crop_right(), 0ull);
|
| @@ -91,14 +104,14 @@ void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) {
|
| frame_rate);
|
| // Segment's timestamps should be in milliseconds, DCHECK it. See
|
| // http://www.webmproject.org/docs/container/#muxer-guidelines
|
| - DCHECK_EQ(segment_.GetSegmentInfo()->timecode_scale(), 1000000ull);
|
| + DCHECK_EQ(segment_->GetSegmentInfo()->timecode_scale(), 1000000ull);
|
| }
|
|
|
| mkvmuxer::int32 WebmMuxer::Write(const void* buf, mkvmuxer::uint32 len) {
|
| DCHECK(thread_checker_.CalledOnValidThread());
|
| DCHECK(buf);
|
| - write_data_callback_.Run(base::StringPiece(reinterpret_cast<const char*>(buf),
|
| - len));
|
| + write_data_callback_.Run(scoped_ptr<std::string>(
|
| + new std::string(reinterpret_cast<const char*>(buf), len)));
|
| position_ += len;
|
| return 0;
|
| }
|
|
|