| OLD | NEW |
| 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 |
| 11 #include "webrtc/base/checks.h" | 13 #include "webrtc/base/checks.h" |
| 12 #include "webrtc/base/logging.h" | 14 #include "webrtc/base/logging.h" |
| 13 #include "webrtc/base/timeutils.h" | 15 #include "webrtc/base/timeutils.h" |
| 14 #include "webrtc/base/trace_event.h" | 16 #include "webrtc/base/trace_event.h" |
| 15 #include "webrtc/modules/video_coding/include/video_coding.h" | 17 #include "webrtc/modules/video_coding/include/video_coding.h" |
| 16 #include "webrtc/modules/video_coding/generic_decoder.h" | |
| 17 #include "webrtc/modules/video_coding/internal_defines.h" | 18 #include "webrtc/modules/video_coding/internal_defines.h" |
| 18 #include "webrtc/system_wrappers/include/clock.h" | 19 #include "webrtc/system_wrappers/include/clock.h" |
| 19 | 20 |
| 20 namespace webrtc { | 21 namespace webrtc { |
| 21 | 22 |
| 22 VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing, | 23 VCMDecodedFrameCallback::VCMDecodedFrameCallback(VCMTiming* timing, |
| 23 Clock* clock) | 24 Clock* clock) |
| 24 : _clock(clock), | 25 : _clock(clock), |
| 25 _timing(timing), | 26 _timing(timing), |
| 26 _timestampMap(kDecoderFrameMemoryLength), | 27 _timestampMap(kDecoderFrameMemoryLength), |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 149 if (_timestampMap.Pop(timestamp) == NULL) { | 150 if (_timestampMap.Pop(timestamp) == NULL) { |
| 150 return VCM_GENERAL_ERROR; | 151 return VCM_GENERAL_ERROR; |
| 151 } | 152 } |
| 152 return VCM_OK; | 153 return VCM_OK; |
| 153 } | 154 } |
| 154 | 155 |
| 155 VCMGenericDecoder::VCMGenericDecoder(VideoDecoder* decoder, bool isExternal) | 156 VCMGenericDecoder::VCMGenericDecoder(VideoDecoder* decoder, bool isExternal) |
| 156 : _callback(NULL), | 157 : _callback(NULL), |
| 157 _frameInfos(), | 158 _frameInfos(), |
| 158 _nextFrameInfoIdx(0), | 159 _nextFrameInfoIdx(0), |
| 159 _decoder(decoder), | 160 decoder_(decoder), |
| 160 _codecType(kVideoCodecUnknown), | 161 _codecType(kVideoCodecUnknown), |
| 161 _isExternal(isExternal), | 162 _isExternal(isExternal), |
| 162 _keyFrameDecoded(false), | 163 _last_keyframe_content_type(VideoContentType::UNSPECIFIED) { |
| 163 _last_keyframe_content_type(VideoContentType::UNSPECIFIED) {} | 164 RTC_DCHECK(decoder_); |
| 165 } |
| 164 | 166 |
| 165 VCMGenericDecoder::~VCMGenericDecoder() {} | 167 VCMGenericDecoder::~VCMGenericDecoder() { |
| 168 decoder_->Release(); |
| 169 if (_isExternal) |
| 170 decoder_.release(); |
| 171 RTC_DCHECK(_isExternal || !decoder_); |
| 172 } |
| 166 | 173 |
| 167 int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings, | 174 int32_t VCMGenericDecoder::InitDecode(const VideoCodec* settings, |
| 168 int32_t numberOfCores) { | 175 int32_t numberOfCores) { |
| 169 TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode"); | 176 TRACE_EVENT0("webrtc", "VCMGenericDecoder::InitDecode"); |
| 170 _codecType = settings->codecType; | 177 _codecType = settings->codecType; |
| 171 | 178 |
| 172 return _decoder->InitDecode(settings, numberOfCores); | 179 return decoder_->InitDecode(settings, numberOfCores); |
| 173 } | 180 } |
| 174 | 181 |
| 175 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) { | 182 int32_t VCMGenericDecoder::Decode(const VCMEncodedFrame& frame, int64_t nowMs) { |
| 176 TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp", | 183 TRACE_EVENT1("webrtc", "VCMGenericDecoder::Decode", "timestamp", |
| 177 frame.EncodedImage()._timeStamp); | 184 frame.EncodedImage()._timeStamp); |
| 178 _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs; | 185 _frameInfos[_nextFrameInfoIdx].decodeStartTimeMs = nowMs; |
| 179 _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs(); | 186 _frameInfos[_nextFrameInfoIdx].renderTimeMs = frame.RenderTimeMs(); |
| 180 _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation(); | 187 _frameInfos[_nextFrameInfoIdx].rotation = frame.rotation(); |
| 181 _frameInfos[_nextFrameInfoIdx].timing = frame.video_timing(); | 188 _frameInfos[_nextFrameInfoIdx].timing = frame.video_timing(); |
| 182 // Set correctly only for key frames. Thus, use latest key frame | 189 // Set correctly only for key frames. Thus, use latest key frame |
| 183 // content type. If the corresponding key frame was lost, decode will fail | 190 // content type. If the corresponding key frame was lost, decode will fail |
| 184 // and content type will be ignored. | 191 // and content type will be ignored. |
| 185 if (frame.FrameType() == kVideoFrameKey) { | 192 if (frame.FrameType() == kVideoFrameKey) { |
| 186 _frameInfos[_nextFrameInfoIdx].content_type = frame.contentType(); | 193 _frameInfos[_nextFrameInfoIdx].content_type = frame.contentType(); |
| 187 _last_keyframe_content_type = frame.contentType(); | 194 _last_keyframe_content_type = frame.contentType(); |
| 188 } else { | 195 } else { |
| 189 _frameInfos[_nextFrameInfoIdx].content_type = _last_keyframe_content_type; | 196 _frameInfos[_nextFrameInfoIdx].content_type = _last_keyframe_content_type; |
| 190 } | 197 } |
| 191 _callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]); | 198 _callback->Map(frame.TimeStamp(), &_frameInfos[_nextFrameInfoIdx]); |
| 192 | 199 |
| 193 _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength; | 200 _nextFrameInfoIdx = (_nextFrameInfoIdx + 1) % kDecoderFrameMemoryLength; |
| 194 const RTPFragmentationHeader dummy_header; | 201 const RTPFragmentationHeader dummy_header; |
| 195 int32_t ret = _decoder->Decode(frame.EncodedImage(), frame.MissingFrame(), | 202 int32_t ret = decoder_->Decode(frame.EncodedImage(), frame.MissingFrame(), |
| 196 &dummy_header, | 203 &dummy_header, |
| 197 frame.CodecSpecific(), frame.RenderTimeMs()); | 204 frame.CodecSpecific(), frame.RenderTimeMs()); |
| 198 | 205 |
| 199 _callback->OnDecoderImplementationName(_decoder->ImplementationName()); | 206 _callback->OnDecoderImplementationName(decoder_->ImplementationName()); |
| 200 if (ret < WEBRTC_VIDEO_CODEC_OK) { | 207 if (ret < WEBRTC_VIDEO_CODEC_OK) { |
| 201 LOG(LS_WARNING) << "Failed to decode frame with timestamp " | 208 LOG(LS_WARNING) << "Failed to decode frame with timestamp " |
| 202 << frame.TimeStamp() << ", error code: " << ret; | 209 << frame.TimeStamp() << ", error code: " << ret; |
| 203 _callback->Pop(frame.TimeStamp()); | 210 _callback->Pop(frame.TimeStamp()); |
| 204 return ret; | 211 return ret; |
| 205 } else if (ret == WEBRTC_VIDEO_CODEC_NO_OUTPUT || | 212 } else if (ret == WEBRTC_VIDEO_CODEC_NO_OUTPUT || |
| 206 ret == WEBRTC_VIDEO_CODEC_REQUEST_SLI) { | 213 ret == WEBRTC_VIDEO_CODEC_REQUEST_SLI) { |
| 207 // No output | 214 // No output |
| 208 _callback->Pop(frame.TimeStamp()); | 215 _callback->Pop(frame.TimeStamp()); |
| 209 } | 216 } |
| 210 return ret; | 217 return ret; |
| 211 } | 218 } |
| 212 | 219 |
| 213 int32_t VCMGenericDecoder::Release() { | |
| 214 return _decoder->Release(); | |
| 215 } | |
| 216 | |
| 217 int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback( | 220 int32_t VCMGenericDecoder::RegisterDecodeCompleteCallback( |
| 218 VCMDecodedFrameCallback* callback) { | 221 VCMDecodedFrameCallback* callback) { |
| 219 _callback = callback; | 222 _callback = callback; |
| 220 return _decoder->RegisterDecodeCompleteCallback(callback); | 223 return decoder_->RegisterDecodeCompleteCallback(callback); |
| 221 } | |
| 222 | |
| 223 bool VCMGenericDecoder::External() const { | |
| 224 return _isExternal; | |
| 225 } | 224 } |
| 226 | 225 |
| 227 bool VCMGenericDecoder::PrefersLateDecoding() const { | 226 bool VCMGenericDecoder::PrefersLateDecoding() const { |
| 228 return _decoder->PrefersLateDecoding(); | 227 return decoder_->PrefersLateDecoding(); |
| 229 } | 228 } |
| 230 | 229 |
| 231 } // namespace webrtc | 230 } // namespace webrtc |
| OLD | NEW |