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 |