| 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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 282 int layers = std::max(static_cast<uint8_t>(1), | 282 int layers = std::max(static_cast<uint8_t>(1), |
| 283 codec.simulcastStream[i].numberOfTemporalLayers); | 283 codec.simulcastStream[i].numberOfTemporalLayers); |
| 284 temporal_layers_.push_back(tl_factory->Create(i, layers, rand())); | 284 temporal_layers_.push_back(tl_factory->Create(i, layers, rand())); |
| 285 } | 285 } |
| 286 } | 286 } |
| 287 } | 287 } |
| 288 | 288 |
| 289 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, | 289 int VP8EncoderImpl::InitEncode(const VideoCodec* inst, |
| 290 int number_of_cores, | 290 int number_of_cores, |
| 291 size_t /*maxPayloadSize */) { | 291 size_t /*maxPayloadSize */) { |
| 292 if (inst == NULL) { | 292 if (inst == nullptr) { |
| 293 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 293 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 294 } | 294 } |
| 295 if (inst->maxFramerate < 1) { | 295 if (inst->maxFramerate < 1) { |
| 296 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 296 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 297 } | 297 } |
| 298 // allow zero to represent an unspecified maxBitRate | 298 // allow zero to represent an unspecified maxBitRate |
| 299 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { | 299 if (inst->maxBitrate > 0 && inst->startBitrate > inst->maxBitrate) { |
| 300 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 300 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 301 } | 301 } |
| 302 if (inst->width <= 1 || inst->height <= 1) { | 302 if (inst->width <= 1 || inst->height <= 1) { |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 366 if (number_of_streams > 1) { | 366 if (number_of_streams > 1) { |
| 367 send_stream_[number_of_streams - 1] = false; | 367 send_stream_[number_of_streams - 1] = false; |
| 368 downsampling_factors_[number_of_streams - 1].num = 1; | 368 downsampling_factors_[number_of_streams - 1].num = 1; |
| 369 downsampling_factors_[number_of_streams - 1].den = 1; | 369 downsampling_factors_[number_of_streams - 1].den = 1; |
| 370 } | 370 } |
| 371 for (int i = 0; i < number_of_streams; ++i) { | 371 for (int i = 0; i < number_of_streams; ++i) { |
| 372 // Random start, 16 bits is enough. | 372 // Random start, 16 bits is enough. |
| 373 picture_id_[i] = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT | 373 picture_id_[i] = static_cast<uint16_t>(rand()) & 0x7FFF; // NOLINT |
| 374 last_key_frame_picture_id_[i] = -1; | 374 last_key_frame_picture_id_[i] = -1; |
| 375 // allocate memory for encoded image | 375 // allocate memory for encoded image |
| 376 if (encoded_images_[i]._buffer != NULL) { | 376 if (encoded_images_[i]._buffer != nullptr) { |
| 377 delete[] encoded_images_[i]._buffer; | 377 delete[] encoded_images_[i]._buffer; |
| 378 } | 378 } |
| 379 encoded_images_[i]._size = | 379 encoded_images_[i]._size = |
| 380 CalcBufferSize(kI420, codec_.width, codec_.height); | 380 CalcBufferSize(kI420, codec_.width, codec_.height); |
| 381 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; | 381 encoded_images_[i]._buffer = new uint8_t[encoded_images_[i]._size]; |
| 382 encoded_images_[i]._completeFrame = true; | 382 encoded_images_[i]._completeFrame = true; |
| 383 } | 383 } |
| 384 // populate encoder configuration with default values | 384 // populate encoder configuration with default values |
| 385 if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &configurations_[0], | 385 if (vpx_codec_enc_config_default(vpx_codec_vp8_cx(), &configurations_[0], |
| 386 0)) { | 386 0)) { |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 inst->simulcastStream[number_of_streams - 1 - i].height); | 469 inst->simulcastStream[number_of_streams - 1 - i].height); |
| 470 } | 470 } |
| 471 configurations_[0].g_w = inst->width; | 471 configurations_[0].g_w = inst->width; |
| 472 configurations_[0].g_h = inst->height; | 472 configurations_[0].g_h = inst->height; |
| 473 | 473 |
| 474 // Determine number of threads based on the image size and #cores. | 474 // Determine number of threads based on the image size and #cores. |
| 475 // TODO(fbarchard): Consider number of Simulcast layers. | 475 // TODO(fbarchard): Consider number of Simulcast layers. |
| 476 configurations_[0].g_threads = NumberOfThreads( | 476 configurations_[0].g_threads = NumberOfThreads( |
| 477 configurations_[0].g_w, configurations_[0].g_h, number_of_cores); | 477 configurations_[0].g_w, configurations_[0].g_h, number_of_cores); |
| 478 | 478 |
| 479 // Creating a wrapper to the image - setting image data to NULL. | 479 // Creating a wrapper to the image - setting image data to null. |
| 480 // Actual pointer will be set in encode. Setting align to 1, as it | 480 // Actual pointer will be set in encode. Setting align to 1, as it |
| 481 // is meaningless (no memory allocation is done here). | 481 // is meaningless (no memory allocation is done here). |
| 482 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1, | 482 vpx_img_wrap(&raw_images_[0], VPX_IMG_FMT_I420, inst->width, inst->height, 1, |
| 483 NULL); | 483 nullptr); |
| 484 | 484 |
| 485 // Note the order we use is different from webm, we have lowest resolution | 485 // Note the order we use is different from webm, we have lowest resolution |
| 486 // at position 0 and they have highest resolution at position 0. | 486 // at position 0 and they have highest resolution at position 0. |
| 487 int stream_idx = encoders_.size() - 1; | 487 int stream_idx = encoders_.size() - 1; |
| 488 SimulcastRateAllocator init_allocator(codec_, nullptr); | 488 SimulcastRateAllocator init_allocator(codec_, nullptr); |
| 489 BitrateAllocation allocation = init_allocator.GetAllocation( | 489 BitrateAllocation allocation = init_allocator.GetAllocation( |
| 490 inst->startBitrate * 1000, inst->maxFramerate); | 490 inst->startBitrate * 1000, inst->maxFramerate); |
| 491 std::vector<uint32_t> stream_bitrates; | 491 std::vector<uint32_t> stream_bitrates; |
| 492 for (int i = 0; i == 0 || i < inst->numberOfSimulcastStreams; ++i) { | 492 for (int i = 0; i == 0 || i < inst->numberOfSimulcastStreams; ++i) { |
| 493 uint32_t bitrate = allocation.GetSpatialLayerSum(i) / 1000; | 493 uint32_t bitrate = allocation.GetSpatialLayerSum(i) / 1000; |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 653 } | 653 } |
| 654 | 654 |
| 655 int VP8EncoderImpl::Encode(const VideoFrame& frame, | 655 int VP8EncoderImpl::Encode(const VideoFrame& frame, |
| 656 const CodecSpecificInfo* codec_specific_info, | 656 const CodecSpecificInfo* codec_specific_info, |
| 657 const std::vector<FrameType>* frame_types) { | 657 const std::vector<FrameType>* frame_types) { |
| 658 RTC_DCHECK_EQ(frame.width(), codec_.width); | 658 RTC_DCHECK_EQ(frame.width(), codec_.width); |
| 659 RTC_DCHECK_EQ(frame.height(), codec_.height); | 659 RTC_DCHECK_EQ(frame.height(), codec_.height); |
| 660 | 660 |
| 661 if (!inited_) | 661 if (!inited_) |
| 662 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 662 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 663 if (encoded_complete_callback_ == NULL) | 663 if (encoded_complete_callback_ == nullptr) |
| 664 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 664 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 665 | 665 |
| 666 rtc::scoped_refptr<VideoFrameBuffer> input_image = frame.video_frame_buffer(); | 666 rtc::scoped_refptr<VideoFrameBuffer> input_image = frame.video_frame_buffer(); |
| 667 // Since we are extracting raw pointers from |input_image| to | 667 // Since we are extracting raw pointers from |input_image| to |
| 668 // |raw_images_[0]|, the resolution of these frames must match. Note that | 668 // |raw_images_[0]|, the resolution of these frames must match. Note that |
| 669 // |input_image| might be scaled from |frame|. In that case, the resolution of | 669 // |input_image| might be scaled from |frame|. In that case, the resolution of |
| 670 // |raw_images_[0]| should have been updated in UpdateCodecFrameSize. | 670 // |raw_images_[0]| should have been updated in UpdateCodecFrameSize. |
| 671 RTC_DCHECK_EQ(input_image->width(), raw_images_[0].d_w); | 671 RTC_DCHECK_EQ(input_image->width(), raw_images_[0].d_w); |
| 672 RTC_DCHECK_EQ(input_image->height(), raw_images_[0].d_h); | 672 RTC_DCHECK_EQ(input_image->height(), raw_images_[0].d_h); |
| 673 | 673 |
| (...skipping 182 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 } | 856 } |
| 857 return WEBRTC_VIDEO_CODEC_OK; | 857 return WEBRTC_VIDEO_CODEC_OK; |
| 858 } | 858 } |
| 859 | 859 |
| 860 void VP8EncoderImpl::PopulateCodecSpecific( | 860 void VP8EncoderImpl::PopulateCodecSpecific( |
| 861 CodecSpecificInfo* codec_specific, | 861 CodecSpecificInfo* codec_specific, |
| 862 const vpx_codec_cx_pkt_t& pkt, | 862 const vpx_codec_cx_pkt_t& pkt, |
| 863 int stream_idx, | 863 int stream_idx, |
| 864 uint32_t timestamp, | 864 uint32_t timestamp, |
| 865 bool only_predicting_from_key_frame) { | 865 bool only_predicting_from_key_frame) { |
| 866 assert(codec_specific != NULL); | 866 assert(codec_specific != nullptr); |
| 867 codec_specific->codecType = kVideoCodecVP8; | 867 codec_specific->codecType = kVideoCodecVP8; |
| 868 codec_specific->codec_name = ImplementationName(); | 868 codec_specific->codec_name = ImplementationName(); |
| 869 CodecSpecificInfoVP8* vp8Info = &(codec_specific->codecSpecific.VP8); | 869 CodecSpecificInfoVP8* vp8Info = &(codec_specific->codecSpecific.VP8); |
| 870 vp8Info->pictureId = picture_id_[stream_idx]; | 870 vp8Info->pictureId = picture_id_[stream_idx]; |
| 871 if (pkt.data.frame.flags & VPX_FRAME_IS_KEY) { | 871 if (pkt.data.frame.flags & VPX_FRAME_IS_KEY) { |
| 872 last_key_frame_picture_id_[stream_idx] = picture_id_[stream_idx]; | 872 last_key_frame_picture_id_[stream_idx] = picture_id_[stream_idx]; |
| 873 } | 873 } |
| 874 vp8Info->simulcastIdx = stream_idx; | 874 vp8Info->simulcastIdx = stream_idx; |
| 875 vp8Info->keyIdx = kNoKeyIdx; // TODO(hlundin) populate this | 875 vp8Info->keyIdx = kNoKeyIdx; // TODO(hlundin) populate this |
| 876 vp8Info->nonReference = | 876 vp8Info->nonReference = |
| 877 (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) ? true : false; | 877 (pkt.data.frame.flags & VPX_FRAME_IS_DROPPABLE) ? true : false; |
| 878 bool base_layer_sync_point = (pkt.data.frame.flags & VPX_FRAME_IS_KEY) || | 878 bool base_layer_sync_point = (pkt.data.frame.flags & VPX_FRAME_IS_KEY) || |
| 879 only_predicting_from_key_frame; | 879 only_predicting_from_key_frame; |
| 880 temporal_layers_[stream_idx]->PopulateCodecSpecific(base_layer_sync_point, | 880 temporal_layers_[stream_idx]->PopulateCodecSpecific(base_layer_sync_point, |
| 881 vp8Info, timestamp); | 881 vp8Info, timestamp); |
| 882 // Prepare next. | 882 // Prepare next. |
| 883 picture_id_[stream_idx] = (picture_id_[stream_idx] + 1) & 0x7FFF; | 883 picture_id_[stream_idx] = (picture_id_[stream_idx] + 1) & 0x7FFF; |
| 884 } | 884 } |
| 885 | 885 |
| 886 int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image, | 886 int VP8EncoderImpl::GetEncodedPartitions(const VideoFrame& input_image, |
| 887 bool only_predicting_from_key_frame) { | 887 bool only_predicting_from_key_frame) { |
| 888 int bw_resolutions_disabled = | 888 int bw_resolutions_disabled = |
| 889 (encoders_.size() > 1) ? NumStreamsDisabled(send_stream_) : -1; | 889 (encoders_.size() > 1) ? NumStreamsDisabled(send_stream_) : -1; |
| 890 | 890 |
| 891 int stream_idx = static_cast<int>(encoders_.size()) - 1; | 891 int stream_idx = static_cast<int>(encoders_.size()) - 1; |
| 892 int result = WEBRTC_VIDEO_CODEC_OK; | 892 int result = WEBRTC_VIDEO_CODEC_OK; |
| 893 for (size_t encoder_idx = 0; encoder_idx < encoders_.size(); | 893 for (size_t encoder_idx = 0; encoder_idx < encoders_.size(); |
| 894 ++encoder_idx, --stream_idx) { | 894 ++encoder_idx, --stream_idx) { |
| 895 vpx_codec_iter_t iter = NULL; | 895 vpx_codec_iter_t iter = nullptr; |
| 896 int part_idx = 0; | 896 int part_idx = 0; |
| 897 encoded_images_[encoder_idx]._length = 0; | 897 encoded_images_[encoder_idx]._length = 0; |
| 898 encoded_images_[encoder_idx]._frameType = kVideoFrameDelta; | 898 encoded_images_[encoder_idx]._frameType = kVideoFrameDelta; |
| 899 RTPFragmentationHeader frag_info; | 899 RTPFragmentationHeader frag_info; |
| 900 // token_partitions_ is number of bits used. | 900 // token_partitions_ is number of bits used. |
| 901 frag_info.VerifyAndAllocateFragmentationHeader((1 << token_partitions_) + | 901 frag_info.VerifyAndAllocateFragmentationHeader((1 << token_partitions_) + |
| 902 1); | 902 1); |
| 903 CodecSpecificInfo codec_specific; | 903 CodecSpecificInfo codec_specific; |
| 904 const vpx_codec_cx_pkt_t* pkt = NULL; | 904 const vpx_codec_cx_pkt_t* pkt = nullptr; |
| 905 while ((pkt = vpx_codec_get_cx_data(&encoders_[encoder_idx], &iter)) != | 905 while ((pkt = vpx_codec_get_cx_data(&encoders_[encoder_idx], &iter)) != |
| 906 NULL) { | 906 nullptr) { |
| 907 switch (pkt->kind) { | 907 switch (pkt->kind) { |
| 908 case VPX_CODEC_CX_FRAME_PKT: { | 908 case VPX_CODEC_CX_FRAME_PKT: { |
| 909 size_t length = encoded_images_[encoder_idx]._length; | 909 size_t length = encoded_images_[encoder_idx]._length; |
| 910 if (pkt->data.frame.sz + length > | 910 if (pkt->data.frame.sz + length > |
| 911 encoded_images_[encoder_idx]._size) { | 911 encoded_images_[encoder_idx]._size) { |
| 912 uint8_t* buffer = new uint8_t[pkt->data.frame.sz + length]; | 912 uint8_t* buffer = new uint8_t[pkt->data.frame.sz + length]; |
| 913 memcpy(buffer, encoded_images_[encoder_idx]._buffer, length); | 913 memcpy(buffer, encoded_images_[encoder_idx]._buffer, length); |
| 914 delete[] encoded_images_[encoder_idx]._buffer; | 914 delete[] encoded_images_[encoder_idx]._buffer; |
| 915 encoded_images_[encoder_idx]._buffer = buffer; | 915 encoded_images_[encoder_idx]._buffer = buffer; |
| 916 encoded_images_[encoder_idx]._size = pkt->data.frame.sz + length; | 916 encoded_images_[encoder_idx]._size = pkt->data.frame.sz + length; |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 990 } | 990 } |
| 991 | 991 |
| 992 int VP8EncoderImpl::RegisterEncodeCompleteCallback( | 992 int VP8EncoderImpl::RegisterEncodeCompleteCallback( |
| 993 EncodedImageCallback* callback) { | 993 EncodedImageCallback* callback) { |
| 994 encoded_complete_callback_ = callback; | 994 encoded_complete_callback_ = callback; |
| 995 return WEBRTC_VIDEO_CODEC_OK; | 995 return WEBRTC_VIDEO_CODEC_OK; |
| 996 } | 996 } |
| 997 | 997 |
| 998 VP8DecoderImpl::VP8DecoderImpl() | 998 VP8DecoderImpl::VP8DecoderImpl() |
| 999 : buffer_pool_(false, 300 /* max_number_of_buffers*/), | 999 : buffer_pool_(false, 300 /* max_number_of_buffers*/), |
| 1000 decode_complete_callback_(NULL), | 1000 decode_complete_callback_(nullptr), |
| 1001 inited_(false), | 1001 inited_(false), |
| 1002 feedback_mode_(false), | 1002 feedback_mode_(false), |
| 1003 decoder_(NULL), | 1003 decoder_(nullptr), |
| 1004 image_format_(VPX_IMG_FMT_NONE), | 1004 image_format_(VPX_IMG_FMT_NONE), |
| 1005 ref_frame_(NULL), | 1005 ref_frame_(nullptr), |
| 1006 propagation_cnt_(-1), | 1006 propagation_cnt_(-1), |
| 1007 last_frame_width_(0), | 1007 last_frame_width_(0), |
| 1008 last_frame_height_(0), | 1008 last_frame_height_(0), |
| 1009 key_frame_required_(true) {} | 1009 key_frame_required_(true) {} |
| 1010 | 1010 |
| 1011 VP8DecoderImpl::~VP8DecoderImpl() { | 1011 VP8DecoderImpl::~VP8DecoderImpl() { |
| 1012 inited_ = true; // in order to do the actual release | 1012 inited_ = true; // in order to do the actual release |
| 1013 Release(); | 1013 Release(); |
| 1014 } | 1014 } |
| 1015 | 1015 |
| 1016 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { | 1016 int VP8DecoderImpl::InitDecode(const VideoCodec* inst, int number_of_cores) { |
| 1017 int ret_val = Release(); | 1017 int ret_val = Release(); |
| 1018 if (ret_val < 0) { | 1018 if (ret_val < 0) { |
| 1019 return ret_val; | 1019 return ret_val; |
| 1020 } | 1020 } |
| 1021 if (decoder_ == NULL) { | 1021 if (decoder_ == nullptr) { |
| 1022 decoder_ = new vpx_codec_ctx_t; | 1022 decoder_ = new vpx_codec_ctx_t; |
| 1023 memset(decoder_, 0, sizeof(*decoder_)); | 1023 memset(decoder_, 0, sizeof(*decoder_)); |
| 1024 } | 1024 } |
| 1025 if (inst && inst->codecType == kVideoCodecVP8) { | 1025 if (inst && inst->codecType == kVideoCodecVP8) { |
| 1026 feedback_mode_ = inst->VP8().feedbackModeOn; | 1026 feedback_mode_ = inst->VP8().feedbackModeOn; |
| 1027 } | 1027 } |
| 1028 vpx_codec_dec_cfg_t cfg; | 1028 vpx_codec_dec_cfg_t cfg; |
| 1029 // Setting number of threads to a constant value (1) | 1029 // Setting number of threads to a constant value (1) |
| 1030 cfg.threads = 1; | 1030 cfg.threads = 1; |
| 1031 cfg.h = cfg.w = 0; // set after decode | 1031 cfg.h = cfg.w = 0; // set after decode |
| (...skipping 23 matching lines...) Expand all Loading... |
| 1055 } | 1055 } |
| 1056 | 1056 |
| 1057 int VP8DecoderImpl::Decode(const EncodedImage& input_image, | 1057 int VP8DecoderImpl::Decode(const EncodedImage& input_image, |
| 1058 bool missing_frames, | 1058 bool missing_frames, |
| 1059 const RTPFragmentationHeader* fragmentation, | 1059 const RTPFragmentationHeader* fragmentation, |
| 1060 const CodecSpecificInfo* codec_specific_info, | 1060 const CodecSpecificInfo* codec_specific_info, |
| 1061 int64_t /*render_time_ms*/) { | 1061 int64_t /*render_time_ms*/) { |
| 1062 if (!inited_) { | 1062 if (!inited_) { |
| 1063 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 1063 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 1064 } | 1064 } |
| 1065 if (decode_complete_callback_ == NULL) { | 1065 if (decode_complete_callback_ == nullptr) { |
| 1066 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; | 1066 return WEBRTC_VIDEO_CODEC_UNINITIALIZED; |
| 1067 } | 1067 } |
| 1068 if (input_image._buffer == NULL && input_image._length > 0) { | 1068 if (input_image._buffer == nullptr && input_image._length > 0) { |
| 1069 // Reset to avoid requesting key frames too often. | 1069 // Reset to avoid requesting key frames too often. |
| 1070 if (propagation_cnt_ > 0) | 1070 if (propagation_cnt_ > 0) |
| 1071 propagation_cnt_ = 0; | 1071 propagation_cnt_ = 0; |
| 1072 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; | 1072 return WEBRTC_VIDEO_CODEC_ERR_PARAMETER; |
| 1073 } | 1073 } |
| 1074 | 1074 |
| 1075 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ | 1075 #if !defined(WEBRTC_ARCH_ARM) && !defined(WEBRTC_ARCH_ARM64) && \ |
| 1076 !defined(ANDROID) | 1076 !defined(ANDROID) |
| 1077 vp8_postproc_cfg_t ppcfg; | 1077 vp8_postproc_cfg_t ppcfg; |
| 1078 // MFQE enabled to reduce key frame popping. | 1078 // MFQE enabled to reduce key frame popping. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1107 // Start count on first loss. | 1107 // Start count on first loss. |
| 1108 } else if ((!input_image._completeFrame || missing_frames) && | 1108 } else if ((!input_image._completeFrame || missing_frames) && |
| 1109 propagation_cnt_ == -1) { | 1109 propagation_cnt_ == -1) { |
| 1110 propagation_cnt_ = 0; | 1110 propagation_cnt_ = 0; |
| 1111 } | 1111 } |
| 1112 if (propagation_cnt_ >= 0) { | 1112 if (propagation_cnt_ >= 0) { |
| 1113 propagation_cnt_++; | 1113 propagation_cnt_++; |
| 1114 } | 1114 } |
| 1115 } | 1115 } |
| 1116 | 1116 |
| 1117 vpx_codec_iter_t iter = NULL; | 1117 vpx_codec_iter_t iter = nullptr; |
| 1118 vpx_image_t* img; | 1118 vpx_image_t* img; |
| 1119 int ret; | 1119 int ret; |
| 1120 | 1120 |
| 1121 // Check for missing frames. | 1121 // Check for missing frames. |
| 1122 if (missing_frames) { | 1122 if (missing_frames) { |
| 1123 // Call decoder with zero data length to signal missing frames. | 1123 // Call decoder with zero data length to signal missing frames. |
| 1124 if (vpx_codec_decode(decoder_, NULL, 0, 0, VPX_DL_REALTIME)) { | 1124 if (vpx_codec_decode(decoder_, nullptr, 0, 0, VPX_DL_REALTIME)) { |
| 1125 // Reset to avoid requesting key frames too often. | 1125 // Reset to avoid requesting key frames too often. |
| 1126 if (propagation_cnt_ > 0) | 1126 if (propagation_cnt_ > 0) |
| 1127 propagation_cnt_ = 0; | 1127 propagation_cnt_ = 0; |
| 1128 return WEBRTC_VIDEO_CODEC_ERROR; | 1128 return WEBRTC_VIDEO_CODEC_ERROR; |
| 1129 } | 1129 } |
| 1130 img = vpx_codec_get_frame(decoder_, &iter); | 1130 img = vpx_codec_get_frame(decoder_, &iter); |
| 1131 iter = NULL; | 1131 iter = nullptr; |
| 1132 } | 1132 } |
| 1133 | 1133 |
| 1134 uint8_t* buffer = input_image._buffer; | 1134 uint8_t* buffer = input_image._buffer; |
| 1135 if (input_image._length == 0) { | 1135 if (input_image._length == 0) { |
| 1136 buffer = NULL; // Triggers full frame concealment. | 1136 buffer = nullptr; // Triggers full frame concealment. |
| 1137 } | 1137 } |
| 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 |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1199 // Reset to avoid requesting key frames too often. | 1199 // Reset to avoid requesting key frames too often. |
| 1200 propagation_cnt_ = 0; | 1200 propagation_cnt_ = 0; |
| 1201 return WEBRTC_VIDEO_CODEC_ERROR; | 1201 return WEBRTC_VIDEO_CODEC_ERROR; |
| 1202 } | 1202 } |
| 1203 return WEBRTC_VIDEO_CODEC_OK; | 1203 return WEBRTC_VIDEO_CODEC_OK; |
| 1204 } | 1204 } |
| 1205 | 1205 |
| 1206 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, | 1206 int VP8DecoderImpl::ReturnFrame(const vpx_image_t* img, |
| 1207 uint32_t timestamp, | 1207 uint32_t timestamp, |
| 1208 int64_t ntp_time_ms) { | 1208 int64_t ntp_time_ms) { |
| 1209 if (img == NULL) { | 1209 if (img == nullptr) { |
| 1210 // Decoder OK and NULL image => No show frame | 1210 // Decoder OK and null image => No show frame |
| 1211 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; | 1211 return WEBRTC_VIDEO_CODEC_NO_OUTPUT; |
| 1212 } | 1212 } |
| 1213 last_frame_width_ = img->d_w; | 1213 last_frame_width_ = img->d_w; |
| 1214 last_frame_height_ = img->d_h; | 1214 last_frame_height_ = img->d_h; |
| 1215 // Allocate memory for decoded image. | 1215 // Allocate memory for decoded image. |
| 1216 rtc::scoped_refptr<I420Buffer> buffer = | 1216 rtc::scoped_refptr<I420Buffer> buffer = |
| 1217 buffer_pool_.CreateBuffer(img->d_w, img->d_h); | 1217 buffer_pool_.CreateBuffer(img->d_w, img->d_h); |
| 1218 if (!buffer.get()) { | 1218 if (!buffer.get()) { |
| 1219 // Pool has too many pending frames. | 1219 // Pool has too many pending frames. |
| 1220 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", | 1220 RTC_HISTOGRAM_BOOLEAN("WebRTC.Video.VP8DecoderImpl.TooManyPendingFrames", |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1241 return WEBRTC_VIDEO_CODEC_OK; | 1241 return WEBRTC_VIDEO_CODEC_OK; |
| 1242 } | 1242 } |
| 1243 | 1243 |
| 1244 int VP8DecoderImpl::RegisterDecodeCompleteCallback( | 1244 int VP8DecoderImpl::RegisterDecodeCompleteCallback( |
| 1245 DecodedImageCallback* callback) { | 1245 DecodedImageCallback* callback) { |
| 1246 decode_complete_callback_ = callback; | 1246 decode_complete_callback_ = callback; |
| 1247 return WEBRTC_VIDEO_CODEC_OK; | 1247 return WEBRTC_VIDEO_CODEC_OK; |
| 1248 } | 1248 } |
| 1249 | 1249 |
| 1250 int VP8DecoderImpl::Release() { | 1250 int VP8DecoderImpl::Release() { |
| 1251 if (decoder_ != NULL) { | 1251 if (decoder_ != nullptr) { |
| 1252 if (vpx_codec_destroy(decoder_)) { | 1252 if (vpx_codec_destroy(decoder_)) { |
| 1253 return WEBRTC_VIDEO_CODEC_MEMORY; | 1253 return WEBRTC_VIDEO_CODEC_MEMORY; |
| 1254 } | 1254 } |
| 1255 delete decoder_; | 1255 delete decoder_; |
| 1256 decoder_ = NULL; | 1256 decoder_ = nullptr; |
| 1257 } | 1257 } |
| 1258 if (ref_frame_ != NULL) { | 1258 if (ref_frame_ != nullptr) { |
| 1259 vpx_img_free(&ref_frame_->img); | 1259 vpx_img_free(&ref_frame_->img); |
| 1260 delete ref_frame_; | 1260 delete ref_frame_; |
| 1261 ref_frame_ = NULL; | 1261 ref_frame_ = nullptr; |
| 1262 } | 1262 } |
| 1263 buffer_pool_.Release(); | 1263 buffer_pool_.Release(); |
| 1264 inited_ = false; | 1264 inited_ = false; |
| 1265 return WEBRTC_VIDEO_CODEC_OK; | 1265 return WEBRTC_VIDEO_CODEC_OK; |
| 1266 } | 1266 } |
| 1267 | 1267 |
| 1268 const char* VP8DecoderImpl::ImplementationName() const { | 1268 const char* VP8DecoderImpl::ImplementationName() const { |
| 1269 return "libvpx"; | 1269 return "libvpx"; |
| 1270 } | 1270 } |
| 1271 | 1271 |
| 1272 int VP8DecoderImpl::CopyReference(VP8DecoderImpl* copy) { | 1272 int VP8DecoderImpl::CopyReference(VP8DecoderImpl* copy) { |
| 1273 // The type of frame to copy should be set in ref_frame_->frame_type | 1273 // The type of frame to copy should be set in ref_frame_->frame_type |
| 1274 // before the call to this function. | 1274 // before the call to this function. |
| 1275 if (vpx_codec_control(decoder_, VP8_COPY_REFERENCE, ref_frame_) != | 1275 if (vpx_codec_control(decoder_, VP8_COPY_REFERENCE, ref_frame_) != |
| 1276 VPX_CODEC_OK) { | 1276 VPX_CODEC_OK) { |
| 1277 return -1; | 1277 return -1; |
| 1278 } | 1278 } |
| 1279 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != | 1279 if (vpx_codec_control(copy->decoder_, VP8_SET_REFERENCE, ref_frame_) != |
| 1280 VPX_CODEC_OK) { | 1280 VPX_CODEC_OK) { |
| 1281 return -1; | 1281 return -1; |
| 1282 } | 1282 } |
| 1283 return 0; | 1283 return 0; |
| 1284 } | 1284 } |
| 1285 | 1285 |
| 1286 } // namespace webrtc | 1286 } // namespace webrtc |
| OLD | NEW |