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

Side by Side Diff: modules/video_coding/codecs/stereo/stereo_decoder_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_decoder_adapter.h"
12
13 #include "api/video/i420_buffer.h"
14 #include "common_video/include/video_frame.h"
15 #include "common_video/include/video_frame_buffer.h"
16 #include "common_video/libyuv/include/webrtc_libyuv.h"
17 #include "media/engine/scopedvideodecoder.h"
18 #include "rtc_base/keep_ref_until_done.h"
19 #include "rtc_base/logging.h"
20
21 namespace webrtc {
22
23 class StereoDecoderAdapter::AdapterDecodedImageCallback
24 : public webrtc::DecodedImageCallback {
25 public:
26 AdapterDecodedImageCallback(webrtc::StereoDecoderAdapter* adapter,
27 StereoCodecStream stream_idx)
28 : adapter_(adapter), stream_idx_(stream_idx) {}
29
30 void Decoded(VideoFrame& decodedImage,
31 rtc::Optional<int32_t> decode_time_ms,
32 rtc::Optional<uint8_t> qp) override {
33 if (!adapter_)
34 return;
35 adapter_->Decoded(stream_idx_, decodedImage, decode_time_ms, qp);
36 }
37 int32_t Decoded(VideoFrame& decodedImage) override {
38 RTC_NOTREACHED();
39 return WEBRTC_VIDEO_CODEC_OK;
40 }
41 int32_t Decoded(VideoFrame& decodedImage, int64_t decode_time_ms) override {
42 RTC_NOTREACHED();
43 return WEBRTC_VIDEO_CODEC_OK;
44 }
45
46 private:
47 StereoDecoderAdapter* adapter_;
48 const StereoCodecStream stream_idx_;
49 };
50
51 struct StereoDecoderAdapter::DecodedImageData {
52 explicit DecodedImageData(StereoCodecStream stream_idx)
53 : stream_idx_(stream_idx),
54 decodedImage_(I420Buffer::Create(1 /* width */, 1 /* height */),
55 0,
56 0,
57 kVideoRotation_0) {
58 RTC_DCHECK_EQ(kAXXStream, stream_idx);
59 }
60 DecodedImageData(StereoCodecStream stream_idx,
61 const VideoFrame& decodedImage,
62 const rtc::Optional<int32_t>& decode_time_ms,
63 const rtc::Optional<uint8_t>& qp)
64 : stream_idx_(stream_idx),
65 decodedImage_(decodedImage),
66 decode_time_ms_(decode_time_ms),
67 qp_(qp) {}
68 const StereoCodecStream stream_idx_;
69 VideoFrame decodedImage_;
70 const rtc::Optional<int32_t> decode_time_ms_;
71 const rtc::Optional<uint8_t> qp_;
72
73 private:
74 RTC_DISALLOW_IMPLICIT_CONSTRUCTORS(DecodedImageData);
75 };
76
77 StereoDecoderAdapter::StereoDecoderAdapter(
78 cricket::WebRtcVideoDecoderFactory* factory)
79 : factory_(factory) {}
80
81 StereoDecoderAdapter::~StereoDecoderAdapter() {
82 Release();
83 }
84
85 int32_t StereoDecoderAdapter::InitDecode(const VideoCodec* codec_settings,
86 int32_t number_of_cores) {
87 VideoCodec settings = *codec_settings;
88 settings.codecType = kVideoCodecVP9;
89 for (size_t i = 0; i < kStereoCodecStreams; ++i) {
90 std::unique_ptr<VideoDecoder> decoder = CreateScopedVideoDecoder(
91 factory_, cricket::VideoCodec("VP9"), cricket::VideoDecoderParams());
92 const int32_t rv = decoder->InitDecode(&settings, number_of_cores);
93 if (rv)
94 return rv;
95 adapter_callbacks_.emplace_back(
96 new StereoDecoderAdapter::AdapterDecodedImageCallback(
97 this, static_cast<StereoCodecStream>(i)));
98 decoder->RegisterDecodeCompleteCallback(adapter_callbacks_.back().get());
99 decoders_.emplace_back(std::move(decoder));
100 }
101 return WEBRTC_VIDEO_CODEC_OK;
102 }
103
104 int32_t StereoDecoderAdapter::Decode(
105 const EncodedImage& input_image,
106 bool missing_frames,
107 const RTPFragmentationHeader* /*fragmentation*/,
108 const CodecSpecificInfo* codec_specific_info,
109 int64_t render_time_ms) {
110 LOG(LS_ERROR) << __func__;
111 LOG(LS_ERROR) << __func__
112 << static_cast<int>(codec_specific_info->stereoInfo.frameIndex);
113 LOG(LS_ERROR) << __func__
114 << static_cast<int>(codec_specific_info->stereoInfo.frameCount);
115 LOG(LS_ERROR) << __func__
116 << static_cast<int>(
117 codec_specific_info->stereoInfo.pictureIndex);
118 if (codec_specific_info->stereoInfo.frameCount == 1) {
119 RTC_DCHECK(decoded_data_.find(input_image._timeStamp) ==
120 decoded_data_.end());
121 decoded_data_.emplace(std::piecewise_construct,
122 std::forward_as_tuple(input_image._timeStamp),
123 std::forward_as_tuple(kAXXStream));
124 }
125
126 int32_t rv = decoders_[codec_specific_info->stereoInfo.frameIndex]->Decode(
127 input_image, missing_frames, nullptr, codec_specific_info,
128 render_time_ms);
129 return rv;
130 }
131
132 int32_t StereoDecoderAdapter::RegisterDecodeCompleteCallback(
133 DecodedImageCallback* callback) {
134 decoded_complete_callback_ = callback;
135 return WEBRTC_VIDEO_CODEC_OK;
136 }
137
138 int32_t StereoDecoderAdapter::Release() {
139 for (auto& decoder : decoders_) {
140 const int32_t rv = decoder->Release();
141 if (rv)
142 return rv;
143 // factory_->Destroy(decoder);
144 }
145 decoders_.clear();
146 adapter_callbacks_.clear();
147 return WEBRTC_VIDEO_CODEC_OK;
148 }
149
150 void StereoDecoderAdapter::Decoded(StereoCodecStream stream_idx,
151 VideoFrame& decoded_image,
152 rtc::Optional<int32_t> decode_time_ms,
153 rtc::Optional<uint8_t> qp) {
154 const auto& other_decoded_data_it =
155 decoded_data_.find(decoded_image.timestamp());
156 if (other_decoded_data_it != decoded_data_.end()) {
157 auto& other_image_data = other_decoded_data_it->second;
158 if (stream_idx == kYUVStream) {
159 RTC_DCHECK_EQ(kAXXStream, other_image_data.stream_idx_);
160 MergeDecodedImages(
161 decoded_image, decode_time_ms, qp, other_image_data.decodedImage_,
162 other_image_data.decode_time_ms_, other_image_data.qp_);
163 } else {
164 RTC_DCHECK_EQ(kYUVStream, other_image_data.stream_idx_);
165 RTC_DCHECK_EQ(kAXXStream, stream_idx);
166 MergeDecodedImages(other_image_data.decodedImage_,
167 other_image_data.decode_time_ms_, other_image_data.qp_,
168 decoded_image, decode_time_ms, qp);
169 }
170 decoded_data_.erase(decoded_data_.begin(), other_decoded_data_it);
171 return;
172 }
173 RTC_DCHECK(decoded_data_.find(decoded_image.timestamp()) ==
174 decoded_data_.end());
175 decoded_data_.emplace(
176 std::piecewise_construct,
177 std::forward_as_tuple(decoded_image.timestamp()),
178 std::forward_as_tuple(stream_idx, decoded_image, decode_time_ms, qp));
179 }
180
181 void StereoDecoderAdapter::MergeDecodedImages(
182 VideoFrame& decodedImage,
183 const rtc::Optional<int32_t>& decode_time_ms,
184 const rtc::Optional<uint8_t>& qp,
185 VideoFrame& alpha_decodedImage,
186 const rtc::Optional<int32_t>& stereo_decode_time_ms,
187 const rtc::Optional<uint8_t>& stereo_qp) {
188 if (!alpha_decodedImage.timestamp()) {
189 decoded_complete_callback_->Decoded(decodedImage, decode_time_ms, qp);
190 return;
191 }
192 rtc::scoped_refptr<webrtc::I420BufferInterface> alpha_buffer =
193 alpha_decodedImage.video_frame_buffer()->ToI420();
194 rtc::scoped_refptr<WrappedI420ABuffer> wrapped_buffer(
195 new rtc::RefCountedObject<webrtc::WrappedI420ABuffer>(
196 decodedImage.video_frame_buffer(), alpha_buffer->DataY(),
197 alpha_buffer->StrideY(),
198 rtc::KeepRefUntilDone(alpha_decodedImage.video_frame_buffer())));
199 VideoFrame wrapped_image(wrapped_buffer, decodedImage.timestamp(),
200 0 /* render_time_ms */, decodedImage.rotation());
201 decoded_complete_callback_->Decoded(wrapped_image, decode_time_ms, qp);
202 }
203
204 } // namespace webrtc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698