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; |
} |