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

Side by Side Diff: modules/video_coding/codecs/stereo/stereo_encoder_adapter.cc

Issue 2951033003: [EXPERIMENTAL] Generic stereo codec with index header sending single frames
Patch Set: Rebase and add external codec support. Created 3 years, 2 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 /*
2 * Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
3 *
4 * Use of this source code is governed by a BSD-style license
5 * that can be found in the LICENSE file in the root of the source
6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree.
9 */
10
11 #include "modules/video_coding/codecs/stereo/include/stereo_encoder_adapter.h"
12
13 #include "common_video/include/video_frame.h"
14 #include "common_video/include/video_frame_buffer.h"
15 #include "common_video/libyuv/include/webrtc_libyuv.h"
16 #include "media/engine/scopedvideoencoder.h"
17 #include "modules/include/module_common_types.h"
18 #include "rtc_base/keep_ref_until_done.h"
19 #include "rtc_base/logging.h"
20
21 namespace webrtc {
22
23 class StereoEncoderAdapter::AdapterEncodedImageCallback
24 : public webrtc::EncodedImageCallback {
25 public:
26 AdapterEncodedImageCallback(webrtc::StereoEncoderAdapter* adapter,
27 StereoCodecStream stream_idx)
28 : adapter_(adapter), stream_idx_(stream_idx) {}
29
30 EncodedImageCallback::Result OnEncodedImage(
31 const EncodedImage& encoded_image,
32 const CodecSpecificInfo* codec_specific_info,
33 const RTPFragmentationHeader* fragmentation) override {
34 if (!adapter_)
35 return Result(Result::OK);
36 return adapter_->OnEncodedImage(stream_idx_, encoded_image,
37 codec_specific_info, fragmentation);
38 }
39
40 private:
41 StereoEncoderAdapter* adapter_;
42 const StereoCodecStream stream_idx_;
43 };
44
45 struct StereoEncoderAdapter::EncodedImageData {
46 explicit EncodedImageData(StereoCodecStream stream_idx)
47 : stream_idx_(stream_idx) {
48 RTC_DCHECK_EQ(kAXXStream, stream_idx);
49 encodedImage_._length = 0;
50 }
51 EncodedImageData(StereoCodecStream stream_idx,
52 const EncodedImage& encodedImage,
53 const CodecSpecificInfo* codecSpecificInfo,
54 const RTPFragmentationHeader* fragmentation)
55 : stream_idx_(stream_idx),
56 encodedImage_(encodedImage),
57 codecSpecificInfo_(*codecSpecificInfo) {
58 fragmentation_.CopyFrom(*fragmentation);
59 }
60 const StereoCodecStream stream_idx_;
61 EncodedImage encodedImage_;
62 const CodecSpecificInfo codecSpecificInfo_;
63 RTPFragmentationHeader fragmentation_;
64
65 private:
66 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(EncodedImageData);
67 };
68
69 StereoEncoderAdapter::StereoEncoderAdapter(
70 cricket::WebRtcVideoEncoderFactory* factory)
71 : factory_(factory), encoded_complete_callback_(nullptr) {}
72
73 StereoEncoderAdapter::~StereoEncoderAdapter() {
74 Release();
75 }
76
77 int StereoEncoderAdapter::InitEncode(const VideoCodec* inst,
78 int number_of_cores,
79 size_t max_payload_size) {
80 const size_t buffer_size =
81 CalcBufferSize(VideoType::kI420, inst->width, inst->height);
82 stereo_dummy_planes_.resize(buffer_size);
83 // It is more expensive to encode 0x00, so use 0x80 instead.
84 std::fill(stereo_dummy_planes_.begin(), stereo_dummy_planes_.end(), 0x80);
85
86 for (size_t i = 0; i < kStereoCodecStreams; ++i) {
87 std::unique_ptr<VideoEncoder> encoder =
88 CreateScopedVideoEncoder(factory_, cricket::VideoCodec("VP9"));
89 const int rv = encoder->InitEncode(inst, number_of_cores, max_payload_size);
90 if (rv)
91 return rv;
92 adapter_callbacks_.emplace_back(new AdapterEncodedImageCallback(
93 this, static_cast<StereoCodecStream>(i)));
94 encoder->RegisterEncodeCompleteCallback(adapter_callbacks_.back().get());
95 encoders_.emplace_back(std::move(encoder));
96 }
97 return WEBRTC_VIDEO_CODEC_OK;
98 }
99
100 int StereoEncoderAdapter::Encode(const VideoFrame& input_image,
101 const CodecSpecificInfo* codec_specific_info,
102 const std::vector<FrameType>* frame_types) {
103 if (!encoded_complete_callback_) {
104 return WEBRTC_VIDEO_CODEC_UNINITIALIZED;
105 }
106
107 // Encode AXX
108 rtc::scoped_refptr<I420BufferInterface> yuva_buffer =
109 input_image.video_frame_buffer()->ToI420();
110 if (yuva_buffer->HasAlpha()) {
111 rtc::scoped_refptr<WrappedI420Buffer> alpha_buffer(
112 new rtc::RefCountedObject<webrtc::WrappedI420Buffer>(
113 input_image.width(), input_image.height(), yuva_buffer->DataA(),
114 yuva_buffer->StrideA(), stereo_dummy_planes_.data(),
115 yuva_buffer->StrideU(), stereo_dummy_planes_.data(),
116 yuva_buffer->StrideV(),
117 rtc::KeepRefUntilDone(input_image.video_frame_buffer())));
118 VideoFrame alpha_image(alpha_buffer, input_image.timestamp(),
119 input_image.render_time_ms(),
120 input_image.rotation());
121 encoders_[kAXXStream]->Encode(alpha_image, codec_specific_info,
122 frame_types);
123 frame_count_.emplace(input_image.timestamp(), 2);
124 } else {
125 RTC_DCHECK(frame_count_.find(input_image.timestamp()) ==
126 frame_count_.end());
127 frame_count_.emplace(input_image.timestamp(), 1);
128 }
129
130 // Encode YUV
131 int rv = encoders_[kYUVStream]->Encode(input_image, codec_specific_info,
132 frame_types);
133 return rv;
134 }
135
136 int StereoEncoderAdapter::RegisterEncodeCompleteCallback(
137 EncodedImageCallback* callback) {
138 encoded_complete_callback_ = callback;
139 return WEBRTC_VIDEO_CODEC_OK;
140 }
141
142 int StereoEncoderAdapter::SetChannelParameters(uint32_t packet_loss,
143 int64_t rtt) {
144 for (auto& encoder : encoders_) {
145 const int rv = encoder->SetChannelParameters(packet_loss, rtt);
146 if (rv)
147 return rv;
148 }
149 return WEBRTC_VIDEO_CODEC_OK;
150 }
151
152 int StereoEncoderAdapter::SetRateAllocation(const BitrateAllocation& bitrate,
153 uint32_t new_framerate) {
154 for (auto& encoder : encoders_) {
155 const int rv = encoder->SetRateAllocation(bitrate, new_framerate);
156 if (rv)
157 return rv;
158 }
159 return WEBRTC_VIDEO_CODEC_OK;
160 }
161
162 int StereoEncoderAdapter::Release() {
163 for (auto& encoder : encoders_) {
164 const int rv = encoder->Release();
165 if (rv)
166 return rv;
167 // factory_->DestroyVideoEncoder(encoder.get());
168 }
169 encoders_.clear();
170 adapter_callbacks_.clear();
171 return WEBRTC_VIDEO_CODEC_OK;
172 }
173
174 EncodedImageCallback::Result StereoEncoderAdapter::OnEncodedImage(
175 StereoCodecStream stream_idx,
176 const EncodedImage& encodedImage,
177 const CodecSpecificInfo* codecSpecificInfo,
178 const RTPFragmentationHeader* fragmentation) {
179 const auto& frame_count_object = frame_count_.find(encodedImage._timeStamp);
180
181 // If the timestamp has already be deleted, this means the frame
182 // arrives later than its future frame, but we still send it out
183 // not to break the frame dependence chain on the receiver side.
184 int frame_count = frame_count_object != frame_count_.end()
185 ? frame_count_object->second
186 : kStereoCodecStreams;
187
188 frame_count_.erase(frame_count_.begin(), frame_count_object);
189
190 CodecSpecificInfo* yuv_codec =
191 const_cast<CodecSpecificInfo*>(codecSpecificInfo);
192 yuv_codec->codecType = kVideoCodecStereo;
193 yuv_codec->codec_name = "stereo-vp9";
194 yuv_codec->stereoInfo.stereoCodecType = kVideoCodecVP9;
195 yuv_codec->stereoInfo.frameIndex = stream_idx;
196 yuv_codec->stereoInfo.frameCount = frame_count;
197 yuv_codec->stereoInfo.pictureIndex = ++picture_index_;
198 encoded_complete_callback_->OnEncodedImage(encodedImage, yuv_codec,
199 fragmentation);
200 return EncodedImageCallback::Result(EncodedImageCallback::Result::OK);
201 }
202
203 } // namespace webrtc
OLDNEW
« no previous file with comments | « modules/video_coding/codecs/stereo/stereo_decoder_adapter.cc ('k') | modules/video_coding/encoded_frame.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698