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

Side by Side Diff: media/capture/webm_muxer.cc

Issue 1313603004: MediaRecorderHandler (video part) and unittests (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase, gyp and MediaRecorderHandlerTest Created 5 years, 3 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 unified diff | Download patch
OLDNEW
1 // Copyright 2015 The Chromium Authors. All rights reserved. 1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "media/capture/webm_muxer.h" 5 #include "media/capture/webm_muxer.h"
6 6
7 #include <limits> 7 #include <limits>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "media/base/video_frame.h" 10 #include "media/base/video_frame.h"
11 11
12 namespace media { 12 namespace media {
13 13
14 static double GetFrameRate(const scoped_refptr<VideoFrame>& video_frame) { 14 static double GetFrameRate(const scoped_refptr<VideoFrame>& video_frame) {
15 double frame_rate = 0.0f; 15 double frame_rate = 0.0f;
16 base::IgnoreResult(video_frame->metadata()->GetDouble( 16 base::IgnoreResult(video_frame->metadata()->GetDouble(
17 VideoFrameMetadata::FRAME_RATE, &frame_rate)); 17 VideoFrameMetadata::FRAME_RATE, &frame_rate));
18 return frame_rate; 18 return frame_rate;
19 } 19 }
20 20
21 WebmMuxer::WebmMuxer(const WriteDataCB& write_data_callback) 21 WebmMuxer::WebmMuxer(const WriteDataCB& write_data_callback)
22 : track_index_(0), 22 : track_index_(0),
23 write_data_callback_(write_data_callback), 23 write_data_callback_(write_data_callback),
24 position_(0) { 24 position_(0) {
25 DCHECK(thread_checker_.CalledOnValidThread());
26 DCHECK(!write_data_callback_.is_null()); 25 DCHECK(!write_data_callback_.is_null());
27 segment_.Init(this); 26 // Creation is done on a different thread than main activities.
28 segment_.set_mode(mkvmuxer::Segment::kLive); 27 io_thread_checker_.DetachFromThread();
29 segment_.OutputCues(false);
30
31 mkvmuxer::SegmentInfo* const info = segment_.GetSegmentInfo();
32 info->set_writing_app("Chrome");
33 info->set_muxing_app("Chrome");
34 } 28 }
35 29
36 WebmMuxer::~WebmMuxer() { 30 WebmMuxer::~WebmMuxer() {
37 DCHECK(thread_checker_.CalledOnValidThread()); 31 // No need to segment_.Finalize() since is not Seekable(), i.e. a live stream.
miu 2015/09/02 21:28:13 What if this class is used to write a complete Web
mcasas 2015/09/04 02:16:30 The mode (kLive/kFile) does not relate to File/Str
miu 2015/09/04 21:48:52 Would it break anything to include the call to Fin
mcasas 2015/09/05 02:43:01 Done. Left the comment though.
38 segment_.Finalize();
39 } 32 }
40 33
41 void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame, 34 void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame,
42 const base::StringPiece& encoded_data, 35 const base::StringPiece& encoded_data,
43 base::TimeTicks timestamp, 36 base::TimeTicks timestamp,
44 bool is_key_frame) { 37 bool is_key_frame) {
45 DCHECK(thread_checker_.CalledOnValidThread()); 38 DVLOG(1) << __FUNCTION__ << " - " << encoded_data.size() << "B";
39 DCHECK(io_thread_checker_.CalledOnValidThread());
46 if (!track_index_) { 40 if (!track_index_) {
47 // |track_index_|, cannot be zero (!), initialize WebmMuxer in that case. 41 // |track_index_|, cannot be zero (!), initialize WebmMuxer in that case.
48 // http://www.matroska.org/technical/specs/index.html#Tracks 42 // http://www.matroska.org/technical/specs/index.html#Tracks
49 AddVideoTrack(video_frame->visible_rect().size(), 43 AddVideoTrack(video_frame->visible_rect().size(),
50 GetFrameRate(video_frame)); 44 GetFrameRate(video_frame));
51 first_frame_timestamp_ = timestamp; 45 first_frame_timestamp_ = timestamp;
52 } 46 }
53 segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data.data()), 47 segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data.data()),
54 encoded_data.size(), 48 encoded_data.size(),
55 track_index_, 49 track_index_,
56 (timestamp - first_frame_timestamp_).InMilliseconds(), 50 (timestamp - first_frame_timestamp_).InMilliseconds(),
57 is_key_frame); 51 is_key_frame);
58 } 52 }
59 53
60 void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) { 54 void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) {
61 DCHECK(thread_checker_.CalledOnValidThread()); 55 DCHECK(io_thread_checker_.CalledOnValidThread());
56
57 segment_.Init(this);
58 segment_.set_mode(mkvmuxer::Segment::kLive);
59 segment_.OutputCues(false);
60
61 mkvmuxer::SegmentInfo* const info = segment_.GetSegmentInfo();
62 info->set_writing_app("Chrome");
63 info->set_muxing_app("Chrome");
64
62 DCHECK_EQ(track_index_, 0u); 65 DCHECK_EQ(track_index_, 0u);
63 track_index_ = 66 track_index_ =
64 segment_.AddVideoTrack(frame_size.width(), frame_size.height(), 0); 67 segment_.AddVideoTrack(frame_size.width(), frame_size.height(), 0);
65 DCHECK_GT(track_index_, 0u); 68 DCHECK_GT(track_index_, 0u);
66 69
67 mkvmuxer::VideoTrack* const video_track = 70 mkvmuxer::VideoTrack* const video_track =
68 reinterpret_cast<mkvmuxer::VideoTrack*>( 71 reinterpret_cast<mkvmuxer::VideoTrack*>(
69 segment_.GetTrackByNumber(track_index_)); 72 segment_.GetTrackByNumber(track_index_));
70 DCHECK(video_track); 73 DCHECK(video_track);
71 video_track->set_codec_id(mkvmuxer::Tracks::kVp8CodecId); 74 video_track->set_codec_id(mkvmuxer::Tracks::kVp8CodecId);
72 DCHECK_EQ(video_track->crop_right(), 0ull); 75 DCHECK_EQ(video_track->crop_right(), 0ull);
73 DCHECK_EQ(video_track->crop_left(), 0ull); 76 DCHECK_EQ(video_track->crop_left(), 0ull);
74 DCHECK_EQ(video_track->crop_top(), 0ull); 77 DCHECK_EQ(video_track->crop_top(), 0ull);
75 DCHECK_EQ(video_track->crop_bottom(), 0ull); 78 DCHECK_EQ(video_track->crop_bottom(), 0ull);
76 79
77 video_track->set_frame_rate(frame_rate); 80 video_track->set_frame_rate(frame_rate);
78 video_track->set_default_duration(base::Time::kMicrosecondsPerSecond / 81 video_track->set_default_duration(base::Time::kMicrosecondsPerSecond /
79 frame_rate); 82 frame_rate);
80 // Segment's timestamps should be in milliseconds, DCHECK it. See 83 // Segment's timestamps should be in milliseconds, DCHECK it. See
81 // http://www.webmproject.org/docs/container/#muxer-guidelines 84 // http://www.webmproject.org/docs/container/#muxer-guidelines
82 DCHECK_EQ(segment_.GetSegmentInfo()->timecode_scale(), 1000000ull); 85 DCHECK_EQ(segment_.GetSegmentInfo()->timecode_scale(), 1000000ull);
83 } 86 }
84 87
85 mkvmuxer::int32 WebmMuxer::Write(const void* buf, mkvmuxer::uint32 len) { 88 mkvmuxer::int32 WebmMuxer::Write(const void* buf, mkvmuxer::uint32 len) {
86 DCHECK(thread_checker_.CalledOnValidThread()); 89 DCHECK(io_thread_checker_.CalledOnValidThread());
87 DCHECK(buf); 90 DCHECK(buf);
88 write_data_callback_.Run(base::StringPiece(reinterpret_cast<const char*>(buf), 91 write_data_callback_.Run(base::StringPiece(reinterpret_cast<const char*>(buf),
89 len)); 92 len));
90 position_ += len; 93 position_ += len;
91 return 0; 94 return 0;
92 } 95 }
93 96
94 mkvmuxer::int64 WebmMuxer::Position() const { 97 mkvmuxer::int64 WebmMuxer::Position() const {
95 return position_.ValueOrDie(); 98 return position_.ValueOrDie();
96 } 99 }
97 100
98 mkvmuxer::int32 WebmMuxer::Position(mkvmuxer::int64 position) { 101 mkvmuxer::int32 WebmMuxer::Position(mkvmuxer::int64 position) {
99 // The stream is not Seekable() so indicate we cannot set the position. 102 // The stream is not Seekable() so indicate we cannot set the position.
100 return -1; 103 return -1;
101 } 104 }
102 105
103 bool WebmMuxer::Seekable() const { 106 bool WebmMuxer::Seekable() const {
104 return false; 107 return false;
105 } 108 }
106 109
107 void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id, 110 void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id,
108 mkvmuxer::int64 position) { 111 mkvmuxer::int64 position) {
109 // This method gets pinged before items are sent to |write_data_callback_|. 112 // This method gets pinged before items are sent to |write_data_callback_|.
110 DCHECK_GE(position, position_.ValueOrDefault(0)) 113 DCHECK_GE(position, position_.ValueOrDefault(0))
111 << "Can't go back in a live WebM stream."; 114 << "Can't go back in a live WebM stream.";
112 } 115 }
113 116
114 } // namespace media 117 } // namespace media
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698