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

Side by Side Diff: content/renderer/media/video_track_recorder.cc

Issue 1211973012: [Experimental] MediaStreamRecorder playground (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Removed FFmpegMuxer, using instead libwebm::IMkvMuxer, which is partially added Created 5 years, 5 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
(Empty)
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.
4
5 #include "content/renderer/media/video_track_recorder.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "base/trace_event/trace_event.h"
10 #include "media/base/bind_to_current_loop.h"
11 #include "media/base/video_capture_types.h"
12 #include "media/base/video_frame.h"
13
14 #define VPX_CODEC_DISABLE_COMPAT 1
15 #include "third_party/libvpx/source/libvpx/vpx/vp8cx.h"
16 #include "third_party/libvpx/source/libvpx/vpx/vpx_encoder.h"
17 #define interface (vpx_codec_vp8_cx())
18
19 namespace content {
20
21 const uint32 kVideoFrequency = 90000;
22
23 class VideoTrackRecorder::Encoder : public base::RefCountedThreadSafe<Encoder> {
24 public:
25 Encoder(const VideoEncoderCB& callback);
26
27 void EncodeOnIo(const scoped_refptr<media::VideoFrame>& frame,
28 const base::TimeTicks& estimated_capture_time);
29
30 void CancelEncoding();
31
32 private:
33 friend class base::RefCountedThreadSafe<Encoder>;
34 virtual ~Encoder();
35
36 // Used to DCHECK that we are called on the correct thread.
37 base::ThreadChecker thread_checker_;
38
39 VideoEncoderCB callback_;
40 bool first_frame_;
41
42 // VP8 internal objects. TODO(mcasas): make scoped_ptr<>?
43 vpx_codec_ctx_t codec_;
44 vpx_codec_enc_cfg_t cfg_;
45 vpx_image_t* raw_image_;
46 int frame_cnt_;
47
48 base::TimeTicks timestamp_base_;
49 };
50
51 VideoTrackRecorder::Encoder::Encoder(const VideoEncoderCB& callback)
52 : callback_(callback),
53 first_frame_(false),
54 raw_image_(nullptr),
55 frame_cnt_(0) {
56 DVLOG(3) << __FUNCTION__;
57 }
58
59 VideoTrackRecorder::Encoder::~Encoder() {
60 DVLOG(3) << __FUNCTION__;
61 DCHECK(thread_checker_.CalledOnValidThread());
62 if (first_frame_)
63 vpx_codec_destroy(&codec_);
64 vpx_img_free(raw_image_);
65 }
66
67 void VideoTrackRecorder::Encoder::EncodeOnIo(
68 const scoped_refptr<media::VideoFrame>& frame,
69 const base::TimeTicks& estimated_capture_time) {
70 DVLOG(3) << __FUNCTION__;
71 DCHECK(thread_checker_.CalledOnValidThread());
72 TRACE_EVENT0("video", "VideoTrackRecorder::Encoder::EncodeOnIo");
73 if (callback_.is_null())
74 return;
75
76 const base::TimeTicks encode_start_time = base::TimeTicks::Now();
77 if(!first_frame_) {
78 vpx_codec_enc_config_default(interface, &cfg_, 0);
79
80 /* Update the default configuration with our settings */
81 cfg_.rc_target_bitrate =
82 frame->natural_size().width() * frame->natural_size().height() *
83 cfg_.rc_target_bitrate / cfg_.g_w / cfg_.g_h;
84 cfg_.g_w = frame->natural_size().width();
85 cfg_.g_h = frame->natural_size().height();
86
87 // Setting the codec time base.
88 cfg_.g_timebase.num = 1;
89 cfg_.g_timebase.den = kVideoFrequency;
90 cfg_.g_lag_in_frames = 0;
91 // cfg_.kf_mode = VPX_KF_DISABLED;
92 cfg_.kf_mode = VPX_KF_AUTO;
93 cfg_.kf_min_dist = 300;
94 cfg_.kf_max_dist = 300;
95
96 vpx_codec_err_t ret = vpx_codec_enc_init(&codec_, interface, &cfg_, 0);
97 DCHECK(ret == VPX_CODEC_OK);
98
99 // Creating a wrapper to the image - setting image data to NULL. Actual
100 // pointer will be set during encode. Setting align to 1, as it is
101 // meaningless (actual memory is not allocated).
102 raw_image_ =
103 vpx_img_wrap(nullptr, VPX_IMG_FMT_I420, frame->natural_size().width(),
104 frame->natural_size().height(), 1, nullptr);
105
106 first_frame_ = false;
107 timestamp_base_ = encode_start_time;
108 }
109
110 // TODO(mcasas): get this from |frame|.
111 const float frame_rate = 30.0f;
112 const int timestamp = (encode_start_time - timestamp_base_).InMilliseconds();
113 const int duration = kVideoFrequency / frame_rate;
114 // Image in vpx_image_t format.
115 // Input image is const. VP8's raw image is not defined as const.
116 raw_image_->planes[VPX_PLANE_Y] =
117 const_cast<uint8*>(frame->data(media::VideoFrame::kYPlane));
118 raw_image_->planes[VPX_PLANE_U] =
119 const_cast<uint8*>(frame->data(media::VideoFrame::kUPlane));
120 raw_image_->planes[VPX_PLANE_V] =
121 const_cast<uint8*>(frame->data(media::VideoFrame::kVPlane));
122
123 raw_image_->stride[VPX_PLANE_Y] = frame->stride(media::VideoFrame::kYPlane);
124 raw_image_->stride[VPX_PLANE_U] = frame->stride(media::VideoFrame::kUPlane);
125 raw_image_->stride[VPX_PLANE_V] = frame->stride(media::VideoFrame::kVPlane);
126
127
128 int flags = 0;
129 vpx_codec_err_t ret = vpx_codec_encode(&codec_, raw_image_, timestamp,
130 duration, flags, VPX_DL_REALTIME);
131
132 DCHECK_EQ(ret, VPX_CODEC_OK)
133 << "Encoding error: " << vpx_codec_err_to_string(ret) << "\n"
134 << "Details: " << vpx_codec_error(&codec_) << "\n"
135 << vpx_codec_error_detail(&codec_);
136
137 std::string data;
138 bool keyframe = false;
139 const vpx_codec_cx_pkt_t *pkt;
140 vpx_codec_iter_t iter = nullptr;
141 while( (pkt = vpx_codec_get_cx_data(&codec_, &iter)) ) {
142 if (pkt->kind != VPX_CODEC_CX_FRAME_PKT)
143 continue;
144
145 data.append(static_cast<const char*>(pkt->data.frame.buf),
146 pkt->data.frame.sz);
147 keyframe = !!(pkt->data.frame.flags & VPX_FRAME_IS_KEY);
148 LOG(ERROR) << "keyframe" << keyframe;
149 break;
150 }
151 callback_.Run(data,
152 estimated_capture_time,
153 keyframe,
154 frame->natural_size(),
155 frame_rate);
156 }
157
158 void VideoTrackRecorder::Encoder::CancelEncoding() {
159 callback_.Reset();
160 }
161
162 VideoTrackRecorder::VideoTrackRecorder(const blink::WebMediaStreamTrack& track,
163 const VideoEncoderCB& callback)
164 : web_track_(track),
165 encoder_(new VideoTrackRecorder::Encoder(callback)) {
166 DVLOG(3) << __FUNCTION__;
167 AddToVideoTrack(
168 this,
169 media::BindToCurrentLoop(
170 base::Bind(&VideoTrackRecorder::Encoder::EncodeOnIo, encoder_)),
171 web_track_);
172
173 }
174
175 VideoTrackRecorder::~VideoTrackRecorder() {
176 DVLOG(3) << __FUNCTION__;
177 RemoveFromVideoTrack(this, web_track_);
178 encoder_->CancelEncoding();
179 }
180
181 } // namespace content
OLDNEW
« no previous file with comments | « content/renderer/media/video_track_recorder.h ('k') | content/renderer/renderer_blink_platform_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698