Roll src/third_party/WebKit d9c6159:8139f33 (svn 201974:201975)
[chromium-blink-merge.git] / media / capture / webm_muxer.cc
blobb3f8e749546b9ef0776474727459407d15ebdf93
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
3 // found in the LICENSE file.
5 #include "media/capture/webm_muxer.h"
7 #include "base/bind.h"
8 #include "media/base/limits.h"
9 #include "media/base/video_frame.h"
11 namespace media {
13 static double GetFrameRate(const scoped_refptr<VideoFrame>& video_frame) {
14 const double kZeroFrameRate = 0.0;
15 const double kDefaultFrameRate = 30.0;
17 double frame_rate = kDefaultFrameRate;
18 if (!video_frame->metadata()->GetDouble(
19 VideoFrameMetadata::FRAME_RATE, &frame_rate) ||
20 frame_rate <= kZeroFrameRate ||
21 frame_rate > media::limits::kMaxFramesPerSecond) {
22 frame_rate = kDefaultFrameRate;
24 return frame_rate;
27 WebmMuxer::WebmMuxer(const WriteDataCB& write_data_callback)
28 : track_index_(0),
29 write_data_callback_(write_data_callback),
30 position_(0) {
31 DCHECK(thread_checker_.CalledOnValidThread());
32 DCHECK(!write_data_callback_.is_null());
33 segment_.Init(this);
34 segment_.set_mode(mkvmuxer::Segment::kLive);
35 segment_.OutputCues(false);
37 mkvmuxer::SegmentInfo* const info = segment_.GetSegmentInfo();
38 info->set_writing_app("Chrome");
39 info->set_muxing_app("Chrome");
42 WebmMuxer::~WebmMuxer() {
43 DCHECK(thread_checker_.CalledOnValidThread());
44 segment_.Finalize();
47 void WebmMuxer::OnEncodedVideo(const scoped_refptr<VideoFrame>& video_frame,
48 const base::StringPiece& encoded_data,
49 base::TimeTicks timestamp,
50 bool is_key_frame) {
51 DCHECK(thread_checker_.CalledOnValidThread());
52 if (!track_index_) {
53 // |track_index_|, cannot be zero (!), initialize WebmMuxer in that case.
54 // http://www.matroska.org/technical/specs/index.html#Tracks
55 AddVideoTrack(video_frame->visible_rect().size(),
56 GetFrameRate(video_frame));
57 first_frame_timestamp_ = timestamp;
59 segment_.AddFrame(reinterpret_cast<const uint8_t*>(encoded_data.data()),
60 encoded_data.size(),
61 track_index_,
62 (timestamp - first_frame_timestamp_).InMicroseconds() *
63 base::Time::kNanosecondsPerMicrosecond,
64 is_key_frame);
67 void WebmMuxer::AddVideoTrack(const gfx::Size& frame_size, double frame_rate) {
68 DCHECK(thread_checker_.CalledOnValidThread());
69 DCHECK_EQ(track_index_, 0u);
70 track_index_ =
71 segment_.AddVideoTrack(frame_size.width(), frame_size.height(), 0);
72 DCHECK_GT(track_index_, 0u);
74 mkvmuxer::VideoTrack* const video_track =
75 reinterpret_cast<mkvmuxer::VideoTrack*>(
76 segment_.GetTrackByNumber(track_index_));
77 DCHECK(video_track);
78 video_track->set_codec_id(mkvmuxer::Tracks::kVp8CodecId);
79 DCHECK_EQ(video_track->crop_right(), 0ull);
80 DCHECK_EQ(video_track->crop_left(), 0ull);
81 DCHECK_EQ(video_track->crop_top(), 0ull);
82 DCHECK_EQ(video_track->crop_bottom(), 0ull);
84 video_track->set_frame_rate(frame_rate);
85 video_track->set_default_duration(base::Time::kNanosecondsPerSecond /
86 frame_rate);
87 // Segment's timestamps should be in milliseconds, DCHECK it. See
88 // http://www.webmproject.org/docs/container/#muxer-guidelines
89 DCHECK_EQ(segment_.GetSegmentInfo()->timecode_scale(), 1000000ull);
92 mkvmuxer::int32 WebmMuxer::Write(const void* buf, mkvmuxer::uint32 len) {
93 DCHECK(thread_checker_.CalledOnValidThread());
94 DCHECK(buf);
95 write_data_callback_.Run(base::StringPiece(reinterpret_cast<const char*>(buf),
96 len));
97 position_ += len;
98 return 0;
101 mkvmuxer::int64 WebmMuxer::Position() const {
102 return position_.ValueOrDie();
105 mkvmuxer::int32 WebmMuxer::Position(mkvmuxer::int64 position) {
106 // The stream is not Seekable() so indicate we cannot set the position.
107 return -1;
110 bool WebmMuxer::Seekable() const {
111 return false;
114 void WebmMuxer::ElementStartNotify(mkvmuxer::uint64 element_id,
115 mkvmuxer::int64 position) {
116 // This method gets pinged before items are sent to |write_data_callback_|.
117 DCHECK_GE(position, position_.ValueOrDefault(0))
118 << "Can't go back in a live WebM stream.";
121 } // namespace media