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 |
(...skipping 1127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1138 if (vpx_codec_decode(decoder_, buffer, input_image._length, 0, | 1138 if (vpx_codec_decode(decoder_, buffer, input_image._length, 0, |
1139 VPX_DL_REALTIME)) { | 1139 VPX_DL_REALTIME)) { |
1140 // Reset to avoid requesting key frames too often. | 1140 // Reset to avoid requesting key frames too often. |
1141 if (propagation_cnt_ > 0) { | 1141 if (propagation_cnt_ > 0) { |
1142 propagation_cnt_ = 0; | 1142 propagation_cnt_ = 0; |
1143 } | 1143 } |
1144 return WEBRTC_VIDEO_CODEC_ERROR; | 1144 return WEBRTC_VIDEO_CODEC_ERROR; |
1145 } | 1145 } |
1146 | 1146 |
1147 img = vpx_codec_get_frame(decoder_, &iter); | 1147 img = vpx_codec_get_frame(decoder_, &iter); |
1148 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_); | 1148 int qp; |
1149 vpx_codec_control(decoder_, VPXD_GET_LAST_QUANTIZER, &qp); | |
sakal
2017/02/16 12:44:49
This method can return failure in theory. However,
| |
1150 ret = ReturnFrame(img, input_image._timeStamp, input_image.ntp_time_ms_, qp); | |
1149 if (ret != 0) { | 1151 if (ret != 0) { |
1150 // Reset to avoid requesting key frames too often. | 1152 // Reset to avoid requesting key frames too often. |
1151 if (ret < 0 && propagation_cnt_ > 0) | 1153 if (ret < 0 && propagation_cnt_ > 0) |
1152 propagation_cnt_ = 0; | 1154 propagation_cnt_ = 0; |
1153 return ret; | 1155 return ret; |
1154 } | 1156 } |
1155 if (feedback_mode_) { | 1157 if (feedback_mode_) { |
1156 // Whenever we receive an incomplete key frame all reference buffers will | 1158 // Whenever we receive an incomplete key frame all reference buffers will |
1157 // be corrupt. If that happens we must request new key frames until we | 1159 // be corrupt. If that happens we must request new key frames until we |
1158 // decode a complete key frame. | 1160 // decode a complete key frame. |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1198 if (propagation_cnt_ > kVp8ErrorPropagationTh) { | 1200 if (propagation_cnt_ > kVp8ErrorPropagationTh) { |
1199 // Reset to avoid requesting key frames too often. | 1201 // Reset to avoid requesting key frames too often. |
1200 propagation_cnt_ = 0; | 1202 propagation_cnt_ = 0; |
1201 return WEBRTC_VIDEO_CODEC_ERROR; | 1203 return WEBRTC_VIDEO_CODEC_ERROR; |
1202 } | 1204 } |
1203 return WEBRTC_VIDEO_CODEC_OK; | 1205 return WEBRTC_VIDEO_CODEC_OK; |
1204 } | 1206 } |
1205 | 1207 |
1206 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, | 1208 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, |
1207 uint32_t timestamp, | 1209 uint32_t timestamp, |
1208 int64_t ntp_time_ms) { | 1210 int64_t ntp_time_ms, |
1211 int qp) { | |
1209 if (img == NULL) { | 1212 if (img == NULL) { |
1210 // Decoder OK and NULL image => No show frame | 1213 // Decoder OK and NULL image => No show frame |
1211 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1214 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
1212 } | 1215 } |
1213 last_frame_width_ = img->d_w; | 1216 last_frame_width_ = img->d_w; |
1214 last_frame_height_ = img->d_h; | 1217 last_frame_height_ = img->d_h; |
1215 // Allocate memory for decoded image. | 1218 // Allocate memory for decoded image. |
1216 rtc::scoped_refptr<I420Buffer> buffer = | 1219 rtc::scoped_refptr<I420Buffer> buffer = |
1217 buffer_pool_.CreateBuffer(img->d_w, img->d_h); | 1220 buffer_pool_.CreateBuffer(img->d_w, img->d_h); |
1218 if (!buffer.get()) { | 1221 if (!buffer.get()) { |
1219 // Pool has too many pending frames. | 1222 // Pool has too many pending frames. |
1220 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", | 1223 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", |
1221 1); | 1224 1); |
1222 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1225 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
1223 } | 1226 } |
1224 | 1227 |
1225 libyuv::I420Copy(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], | 1228 libyuv::I420Copy(img->planes[VPX_PLANE_Y], img->stride[VPX_PLANE_Y], |
1226 img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], | 1229 img->planes[VPX_PLANE_U], img->stride[VPX_PLANE_U], |
1227 img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], | 1230 img->planes[VPX_PLANE_V], img->stride[VPX_PLANE_V], |
1228 buffer->MutableDataY(), buffer->StrideY(), | 1231 buffer->MutableDataY(), buffer->StrideY(), |
1229 buffer->MutableDataU(), buffer->StrideU(), | 1232 buffer->MutableDataU(), buffer->StrideU(), |
1230 buffer->MutableDataV(), buffer->StrideV(), | 1233 buffer->MutableDataV(), buffer->StrideV(), |
1231 img->d_w, img->d_h); | 1234 img->d_w, img->d_h); |
1232 | 1235 |
1233 VideoFrame decoded_image(buffer, timestamp, 0, kVideoRotation_0); | 1236 VideoFrame decoded_image(buffer, timestamp, 0, kVideoRotation_0); |
1234 decoded_image.set_ntp_time_ms(ntp_time_ms); | 1237 decoded_image.set_ntp_time_ms(ntp_time_ms); |
1235 int ret = decode_complete_callback_->Decoded(decoded_image); | 1238 decode_complete_callback_->Decoded(decoded_image, rtc::Optional<int32_t>(), |
1236 if (ret != 0) | 1239 rtc::Optional<uint8_t>(qp)); |
1237 return ret; | |
1238 | 1240 |
1239 // Remember image format for later | 1241 // Remember image format for later |
1240 image_format_ = img->fmt; | 1242 image_format_ = img->fmt; |
1241 return WEBRTC_VIDEO_CODEC_OK; | 1243 return WEBRTC_VIDEO_CODEC_OK; |
1242 } | 1244 } |
1243 | 1245 |
1244 int VP8DecoderImpl::RegisterDecodeCompleteCallback( | 1246 int VP8DecoderImpl::RegisterDecodeCompleteCallback( |
1245 DecodedImageCallback* callback) { | 1247 DecodedImageCallback* callback) { |
1246 decode_complete_callback_ = callback; | 1248 decode_complete_callback_ = callback; |
1247 return WEBRTC_VIDEO_CODEC_OK; | 1249 return WEBRTC_VIDEO_CODEC_OK; |
(...skipping 29 matching lines...) Expand all Loading... | |
1277 return -1; | 1279 return -1; |
1278 } | 1280 } |
1279 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != | 1281 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != |
1280 VPX_CODEC_OK) { | 1282 VPX_CODEC_OK) { |
1281 return -1; | 1283 return -1; |
1282 } | 1284 } |
1283 return 0; | 1285 return 0; |
1284 } | 1286 } |
1285 | 1287 |
1286 } // namespace webrtc | 1288 } // namespace webrtc |
OLD | NEW |