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

Side by Side Diff: webrtc/modules/video_coding/generic_decoder.cc

Issue 2792033003: Revert of Deliver video frames on Android, on the decode thread. (Closed)
Patch Set: Created 3 years, 8 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 /* 1 /*
2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved. 2 * Copyright (c) 2012 The WebRTC project authors. All Rights Reserved.
3 * 3 *
4 * Use of this source code is governed by a BSD-style license 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 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 6 * tree. An additional intellectual property rights grant can be found
7 * in the file PATENTS. All contributing project authors may 7 * in the file PATENTS. All contributing project authors may
8 * be found in the AUTHORS file in the root of the source tree. 8 * be found in the AUTHORS file in the root of the source tree.
9 */ 9 */
10 10
11 #include "webrtc/modules/video_coding/generic_decoder.h"
12
13 #include "webrtc/base/checks.h" 11 #include "webrtc/base/checks.h"
14 #include "webrtc/base/logging.h" 12 #include "webrtc/base/logging.h"
15 #include "webrtc/base/trace_event.h" 13 #include "webrtc/base/trace_event.h"
16 #include "webrtc/modules/video_coding/include/video_coding.h" 14 #include "webrtc/modules/video_coding/include/video_coding.h"
15 #include "webrtc/modules/video_coding/generic_decoder.h"
17 #include "webrtc/modules/video_coding/internal_defines.h" 16 #include "webrtc/modules/video_coding/internal_defines.h"
18 #include "webrtc/system_wrappers/include/clock.h" 17 #include "webrtc/system_wrappers/include/clock.h"
19 18
20 namespace webrtc { 19 namespace webrtc {
21 20
22 VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing, 21 VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing,
23 Clock* clock) 22 Clock* clock)
24 : _clock(clock), 23 : _clock(clock),
25 _timing(timing), 24 _timing(timing),
26 _timestampMap(kDecoderFrameMemoryLength), 25 _timestampMap(kDecoderFrameMemoryLength),
27 _lastReceivedPictureID(0) { 26 _lastReceivedPictureID(0) {}
28 decoder_thread_.DetachFromThread();
29 }
30 27
31 VCMDecodedFrameCallback::~VCMDecodedFrameCallback() { 28 VCMDecodedFrameCallback::~VCMDecodedFrameCallback() {
32 RTC_DCHECK(construction_thread_.CalledOnValidThread());
33 } 29 }
34 30
35 void VCMDecodedFrameCallback::SetUserReceiveCallback( 31 void VCMDecodedFrameCallback::SetUserReceiveCallback(
36 VCMReceiveCallback* receiveCallback) { 32 VCMReceiveCallback* receiveCallback) {
37 RTC_DCHECK(construction_thread_.CalledOnValidThread()); 33 RTC_DCHECK(construction_thread_.CalledOnValidThread());
38 RTC_DCHECK((!_receiveCallback && receiveCallback) || 34 RTC_DCHECK((!_receiveCallback && receiveCallback) ||
39 (_receiveCallback && !receiveCallback)); 35 (_receiveCallback && !receiveCallback));
40 _receiveCallback = receiveCallback; 36 _receiveCallback = receiveCallback;
41 } 37 }
42 38
43 VCMReceiveCallback* VCMDecodedFrameCallback::UserReceiveCallback() { 39 VCMReceiveCallback* VCMDecodedFrameCallback::UserReceiveCallback() {
44 RTC_DCHECK_RUN_ON(&decoder_thread_);
45 // Called on the decode thread via VCMCodecDataBase::GetDecoder. 40 // Called on the decode thread via VCMCodecDataBase::GetDecoder.
46 // The callback must always have been set before this happens. 41 // The callback must always have been set before this happens.
47 RTC_DCHECK(_receiveCallback); 42 RTC_DCHECK(_receiveCallback);
48 return _receiveCallback; 43 return _receiveCallback;
49 } 44 }
50 45
51 int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage) { 46 int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage) {
52 return Decoded(decodedImage, -1); 47 return Decoded(decodedImage, -1);
53 } 48 }
54 49
55 int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, 50 int32_t VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
56 int64_t decode_time_ms) { 51 int64_t decode_time_ms) {
57 Decoded(decodedImage, 52 Decoded(decodedImage,
58 decode_time_ms >= 0 ? rtc::Optional<int32_t>(decode_time_ms) 53 decode_time_ms >= 0 ? rtc::Optional<int32_t>(decode_time_ms)
59 : rtc::Optional<int32_t>(), 54 : rtc::Optional<int32_t>(),
60 rtc::Optional<uint8_t>()); 55 rtc::Optional<uint8_t>());
61 return WEBRTC_VIDEO_CODEC_OK; 56 return WEBRTC_VIDEO_CODEC_OK;
62 } 57 }
63 58
64 void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage, 59 void VCMDecodedFrameCallback::Decoded(VideoFrame& decodedImage,
65 rtc::Optional<int32_t> decode_time_ms, 60 rtc::Optional<int32_t> decode_time_ms,
66 rtc::Optional<uint8_t> qp) { 61 rtc::Optional<uint8_t> qp) {
67 RTC_DCHECK_RUN_ON(&decoder_thread_);
68 RTC_DCHECK(_receiveCallback) << "Callback must not be null at this point"; 62 RTC_DCHECK(_receiveCallback) << "Callback must not be null at this point";
69
70 TRACE_EVENT_INSTANT1("webrtc", "VCMDecodedFrameCallback::Decoded", 63 TRACE_EVENT_INSTANT1("webrtc", "VCMDecodedFrameCallback::Decoded",
71 "timestamp", decodedImage.timestamp()); 64 "timestamp", decodedImage.timestamp());
72 // TODO(holmer): We should improve this so that we can handle multiple 65 // TODO(holmer): We should improve this so that we can handle multiple
73 // callbacks from one call to Decode(). 66 // callbacks from one call to Decode().
74 VCMFrameInformation* frameInfo = _timestampMap.Pop(decodedImage.timestamp()); 67 VCMFrameInformation* frameInfo;
68 {
69 rtc::CritScope cs(&lock_);
70 frameInfo = _timestampMap.Pop(decodedImage.timestamp());
71 }
75 72
76 if (frameInfo == NULL) { 73 if (frameInfo == NULL) {
77 LOG(LS_WARNING) << "Too many frames backed up in the decoder, dropping " 74 LOG(LS_WARNING) << "Too many frames backed up in the decoder, dropping "
78 "this one."; 75 "this one.";
79 return; 76 return;
80 } 77 }
81 78
82 const int64_t now_ms = _clock->TimeInMilliseconds(); 79 const int64_t now_ms = _clock->TimeInMilliseconds();
83 if (!decode_time_ms) { 80 if (!decode_time_ms) {
84 decode_time_ms = 81 decode_time_ms =
85 rtc::Optional<int32_t>(now_ms - frameInfo->decodeStartTimeMs); 82 rtc::Optional<int32_t>(now_ms - frameInfo->decodeStartTimeMs);
86 } 83 }
87 _timing->StopDecodeTimer(decodedImage.timestamp(), *decode_time_ms, now_ms, 84 _timing->StopDecodeTimer(decodedImage.timestamp(), *decode_time_ms, now_ms,
88 frameInfo->renderTimeMs); 85 frameInfo->renderTimeMs);
89 86
90 decodedImage.set_timestamp_us( 87 decodedImage.set_timestamp_us(
91 frameInfo->renderTimeMs * rtc::kNumMicrosecsPerMillisec); 88 frameInfo->renderTimeMs * rtc::kNumMicrosecsPerMillisec);
92 decodedImage.set_rotation(frameInfo->rotation); 89 decodedImage.set_rotation(frameInfo->rotation);
93 _receiveCallback->FrameToRender(decodedImage, qp); 90 _receiveCallback->FrameToRender(decodedImage, qp);
94 } 91 }
95 92
96 int32_t VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame( 93 int32_t VCMDecodedFrameCallback::ReceivedDecodedReferenceFrame(
97 const uint64_t pictureId) { 94 const uint64_t pictureId) {
98 RTC_DCHECK_RUN_ON(&decoder_thread_);
99 return _receiveCallback->ReceivedDecodedReferenceFrame(pictureId); 95 return _receiveCallback->ReceivedDecodedReferenceFrame(pictureId);
100 } 96 }
101 97
102 int32_t VCMDecodedFrameCallback::ReceivedDecodedFrame( 98 int32_t VCMDecodedFrameCallback::ReceivedDecodedFrame(
103 const uint64_t pictureId) { 99 const uint64_t pictureId) {
104 RTC_DCHECK_RUN_ON(&decoder_thread_);
105 _lastReceivedPictureID = pictureId; 100 _lastReceivedPictureID = pictureId;
106 return 0; 101 return 0;
107 } 102 }
108 103
109 uint64_t VCMDecodedFrameCallback::LastReceivedPictureID() const { 104 uint64_t VCMDecodedFrameCallback::LastReceivedPictureID() const {
110 RTC_DCHECK_RUN_ON(&decoder_thread_);
111 return _lastReceivedPictureID; 105 return _lastReceivedPictureID;
112 } 106 }
113 107
114 void VCMDecodedFrameCallback::OnDecoderImplementationName( 108 void VCMDecodedFrameCallback::OnDecoderImplementationName(
115 const char* implementation_name) { 109 const char* implementation_name) {
116 RTC_DCHECK_RUN_ON(&decoder_thread_);
117 _receiveCallback->OnDecoderImplementationName(implementation_name); 110 _receiveCallback->OnDecoderImplementationName(implementation_name);
118 } 111 }
119 112
120 void VCMDecodedFrameCallback::Map(uint32_t timestamp, 113 void VCMDecodedFrameCallback::Map(uint32_t timestamp,
121 VCMFrameInformation* frameInfo) { 114 VCMFrameInformation* frameInfo) {
122 RTC_DCHECK_RUN_ON(&decoder_thread_); 115 rtc::CritScope cs(&lock_);
123 _timestampMap.Add(timestamp, frameInfo); 116 _timestampMap.Add(timestamp, frameInfo);
124 } 117 }
125 118
126 int32_t VCMDecodedFrameCallback::Pop(uint32_t timestamp) { 119 int32_t VCMDecodedFrameCallback::Pop(uint32_t timestamp) {
127 RTC_DCHECK_RUN_ON(&decoder_thread_); 120 rtc::CritScope cs(&lock_);
128 return _timestampMap.Pop(timestamp) == nullptr ? VCM_GENERAL_ERROR : VCM_OK; 121 if (_timestampMap.Pop(timestamp) == NULL) {
122 return VCM_GENERAL_ERROR;
123 }
124 return VCM_OK;
129 } 125 }
130 126
131 VCMGenericDecoder::VCMGenericDecoder(VideoDecoder* decoder, bool isExternal) 127 VCMGenericDecoder::VCMGenericDecoder(VideoDecoder* decoder, bool isExternal)
132 : _callback(NULL), 128 : _callback(NULL),
133 _frameInfos(), 129 _frameInfos(),
134 _nextFrameInfoIdx(0), 130 _nextFrameInfoIdx(0),
135 decoder_(decoder), 131 _decoder(decoder),
136 _codecType(kVideoCodecUnknown), 132 _codecType(kVideoCodecUnknown),
137 _isExternal(isExternal) {} 133 _isExternal(isExternal),
134 _keyFrameDecoded(false) {}
138 135
139 VCMGenericDecoder::~VCMGenericDecoder() { 136 VCMGenericDecoder::~VCMGenericDecoder() {}
140 decoder_->Release();
141 if (_isExternal)
142 decoder_.release();
143
144 RTC_DCHECK(_isExternal || !decoder_);
145 }
146 137
147 int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings, 138 int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings,
148 int32_t numberOfCores) { 139 int32_t numberOfCores) {
149 RTC_DCHECK_RUN_ON(&decoder_thread_);
150 TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode"); 140 TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode");
151 _codecType = settings->codecType; 141 _codecType = settings->codecType;
152 142
153 return decoder_->InitDecode(settings, numberOfCores); 143 return _decoder->InitDecode(settings, numberOfCores);
154 } 144 }
155 145
156 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) { 146 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) {
157 RTC_DCHECK_RUN_ON(&decoder_thread_); 147 TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp",
158 TRACE_EVENT2("webrtc", "VCMGenericDecoder::Decode", "timestamp", 148 frame.EncodedImage()._timeStamp);
159 frame.EncodedImage()._timeStamp, "decoder", 149 _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs;
160 decoder_->ImplementationName()); 150 _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs();
161 _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs; 151 _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation();
162 _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs(); 152 _callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);
163 _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation();
164 _callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]);
165 153
166 _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength; 154 _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength;
167 const RTPFragmentationHeader dummy_header; 155 const RTPFragmentationHeader dummy_header;
168 int32_t ret = decoder_->Decode(frame.EncodedImage(), frame.MissingFrame(), 156 int32_t ret = _decoder->Decode(frame.EncodedImage(), frame.MissingFrame(),
169 &dummy_header, frame.CodecSpecific(), 157 &dummy_header,
170 frame.RenderTimeMs()); 158 frame.CodecSpecific(), frame.RenderTimeMs());
171 159
172 // TODO(tommi): Necessary every time? 160 _callback->OnDecoderImplementationName(_decoder->ImplementationName());
173 // Maybe this should be the first thing the function does, and only the first 161 if (ret < WEBRTC_VIDEO_CODEC_OK) {
174 // time around? 162 LOG(LS_WARNING) << "Failed to decode frame with timestamp "
175 _callback->OnDecoderImplementationName(decoder_->ImplementationName()); 163 << frame.TimeStamp() << ", error code: " << ret;
164 _callback->Pop(frame.TimeStamp());
165 return ret;
166 } else if (ret == WEBRTC_VIDEO_CODEC_NO_OUTPUT ||
167 ret == WEBRTC_VIDEO_CODEC_REQUEST_SLI) {
168 // No output
169 _callback->Pop(frame.TimeStamp());
170 }
171 return ret;
172 }
176 173
177 if (ret != WEBRTC_VIDEO_CODEC_OK) { 174 int32_t VCMGenericDecoder::Release() {
178 if (ret < WEBRTC_VIDEO_CODEC_OK) { 175 return _decoder->Release();
179 LOG(LS_WARNING) << "Failed to decode frame with timestamp "
180 << frame.TimeStamp() << ", error code: " << ret;
181 }
182 // We pop the frame for all non-'OK', failure or success codes such as
183 // WEBRTC_VIDEO_CODEC_NO_OUTPUT and WEBRTC_VIDEO_CODEC_REQUEST_SLI.
184 _callback->Pop(frame.TimeStamp());
185 }
186
187 return ret;
188 } 176 }
189 177
190 int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback( 178 int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback(
191 VCMDecodedFrameCallback* callback) { 179 VCMDecodedFrameCallback* callback) {
192 RTC_DCHECK_RUN_ON(&decoder_thread_);
193 _callback = callback; 180 _callback = callback;
194 return decoder_->RegisterDecodeCompleteCallback(callback); 181 return _decoder->RegisterDecodeCompleteCallback(callback);
182 }
183
184 bool VCMGenericDecoder::External() const {
185 return _isExternal;
195 } 186 }
196 187
197 bool VCMGenericDecoder::PrefersLateDecoding() const { 188 bool VCMGenericDecoder::PrefersLateDecoding() const {
198 RTC_DCHECK_RUN_ON(&decoder_thread_); 189 return _decoder->PrefersLateDecoding();
199 return decoder_->PrefersLateDecoding();
200 } 190 }
201 191
202 #if defined(WEBRTC_ANDROID)
203 void VCMGenericDecoder::PollDecodedFrames() {
204 RTC_DCHECK_RUN_ON(&decoder_thread_);
205 decoder_->PollDecodedFrames();
206 }
207 #endif
208
209 } // namespace webrtc 192 } // namespace webrtc
OLDNEW
« no previous file with comments | « webrtc/modules/video_coding/generic_decoder.h ('k') | webrtc/modules/video_coding/video_coding_impl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698