| // Copyright 2016 Google Inc. All Rights Reserved. | |
| // | |
| // Licensed under the Apache License, Version 2.0 (the "License"); | |
| // you may not use this file except in compliance with the License. | |
| // You may obtain a copy of the License at | |
| // | |
| // http://www.apache.org/licenses/LICENSE-2.0 | |
| // | |
| // Unless required by applicable law or agreed to in writing, software | |
| // distributed under the License is distributed on an "AS IS" BASIS, | |
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| // See the License for the specific language governing permissions and | |
| // limitations under the License. | |
| #include "starboard/shared/starboard/player/input_buffer_internal.h" | |
| #include <vector> | |
| #include "starboard/atomic.h" | |
| #include "starboard/log.h" | |
| #include "starboard/memory.h" | |
| namespace starboard { | |
| namespace shared { | |
| namespace starboard { | |
| namespace player { | |
| class InputBuffer::ReferenceCountedBuffer { | |
| public: | |
| ReferenceCountedBuffer(SbPlayerDeallocateSampleFunc deallocate_sample_func, | |
| SbPlayer player, | |
| void* context, | |
| const void* sample_buffer, | |
| int sample_buffer_size, | |
| SbMediaTime sample_pts, | |
| const SbMediaVideoSampleInfo* video_sample_info, | |
| const SbDrmSampleInfo* sample_drm_info) | |
| : ref_count_(0), | |
| deallocate_sample_func_(deallocate_sample_func), | |
| player_(player), | |
| context_(context), | |
| data_(reinterpret_cast<const uint8_t*>(sample_buffer)), | |
| size_(sample_buffer_size), | |
| pts_(sample_pts), | |
| has_video_sample_info_(video_sample_info != NULL), | |
| has_drm_info_(sample_drm_info != NULL) { | |
| SB_DCHECK(deallocate_sample_func); | |
| if (has_video_sample_info_) { | |
| video_sample_info_ = *video_sample_info; | |
| } | |
| if (has_drm_info_) { | |
| SB_DCHECK(sample_drm_info->subsample_count > 0); | |
| subsamples_.assign(sample_drm_info->subsample_mapping, | |
| sample_drm_info->subsample_mapping + | |
| sample_drm_info->subsample_count); | |
| drm_info_ = *sample_drm_info; | |
| drm_info_.subsample_mapping = | |
| subsamples_.empty() ? NULL : &subsamples_[0]; | |
| } | |
| } | |
| void AddRef() const { SbAtomicBarrier_Increment(&ref_count_, 1); } | |
| void Release() const { | |
| if (SbAtomicBarrier_Increment(&ref_count_, -1) == 0) { | |
| delete this; | |
| } | |
| } | |
| const uint8_t* data() const { return data_; } | |
| int size() const { return size_; } | |
| SbMediaTime pts() const { return pts_; } | |
| const SbMediaVideoSampleInfo* video_sample_info() const { | |
| return has_video_sample_info_ ? &video_sample_info_ : NULL; | |
| } | |
| const SbDrmSampleInfo* drm_info() const { | |
| return has_drm_info_ ? &drm_info_ : NULL; | |
| } | |
| void SetDecryptedContent(const void* buffer, int size) { | |
| SB_DCHECK(size == size_); | |
| SB_DCHECK(deallocate_sample_func_); | |
| DeallocateSampleBuffer(); | |
| if (size > 0) { | |
| decrypted_data_.resize(size); | |
| SbMemoryCopy(&decrypted_data_[0], buffer, size); | |
| data_ = &decrypted_data_[0]; | |
| } else { | |
| data_ = NULL; | |
| } | |
| size_ = size; | |
| has_drm_info_ = false; | |
| } | |
| private: | |
| ~ReferenceCountedBuffer() { DeallocateSampleBuffer(); } | |
| void DeallocateSampleBuffer() { | |
| if (deallocate_sample_func_) { | |
| deallocate_sample_func_(player_, context_, const_cast<uint8_t*>(data_)); | |
| deallocate_sample_func_ = NULL; | |
| } | |
| } | |
| mutable SbAtomic32 ref_count_; | |
| SbPlayerDeallocateSampleFunc deallocate_sample_func_; | |
| SbPlayer player_; | |
| void* context_; | |
| const uint8_t* data_; | |
| int size_; | |
| SbMediaTime pts_; | |
| bool has_video_sample_info_; | |
| SbMediaVideoSampleInfo video_sample_info_; | |
| bool has_drm_info_; | |
| SbDrmSampleInfo drm_info_; | |
| std::vector<uint8_t> decrypted_data_; | |
| std::vector<SbDrmSubSampleMapping> subsamples_; | |
| SB_DISALLOW_COPY_AND_ASSIGN(ReferenceCountedBuffer); | |
| }; | |
| InputBuffer::InputBuffer() : buffer_(NULL) {} | |
| InputBuffer::InputBuffer(SbPlayerDeallocateSampleFunc deallocate_sample_func, | |
| SbPlayer player, | |
| void* context, | |
| const void* sample_buffer, | |
| int sample_buffer_size, | |
| SbMediaTime sample_pts, | |
| const SbMediaVideoSampleInfo* video_sample_info, | |
| const SbDrmSampleInfo* sample_drm_info) { | |
| buffer_ = new ReferenceCountedBuffer( | |
| deallocate_sample_func, player, context, sample_buffer, | |
| sample_buffer_size, sample_pts, video_sample_info, sample_drm_info); | |
| buffer_->AddRef(); | |
| } | |
| InputBuffer::InputBuffer(const InputBuffer& that) { | |
| buffer_ = that.buffer_; | |
| if (buffer_) { | |
| buffer_->AddRef(); | |
| } | |
| } | |
| InputBuffer::~InputBuffer() { | |
| if (buffer_) { | |
| buffer_->Release(); | |
| } | |
| } | |
| InputBuffer& InputBuffer::operator=(const InputBuffer& that) { | |
| if (that.buffer_) { | |
| that.buffer_->AddRef(); | |
| } | |
| if (buffer_) { | |
| buffer_->Release(); | |
| } | |
| buffer_ = that.buffer_; | |
| return *this; | |
| } | |
| const uint8_t* InputBuffer::data() const { | |
| SB_DCHECK(buffer_); | |
| return buffer_->data(); | |
| } | |
| int InputBuffer::size() const { | |
| SB_DCHECK(buffer_); | |
| return buffer_->size(); | |
| } | |
| SbMediaTime InputBuffer::pts() const { | |
| SB_DCHECK(buffer_); | |
| return buffer_->pts(); | |
| } | |
| const SbMediaVideoSampleInfo* InputBuffer::video_sample_info() const { | |
| SB_DCHECK(buffer_); | |
| return buffer_->video_sample_info(); | |
| } | |
| const SbDrmSampleInfo* InputBuffer::drm_info() const { | |
| SB_DCHECK(buffer_); | |
| return buffer_->drm_info(); | |
| } | |
| void InputBuffer::SetDecryptedContent(const void* buffer, int size) { | |
| SB_DCHECK(buffer_); | |
| buffer_->SetDecryptedContent(buffer, size); | |
| } | |
| } // namespace player | |
| } // namespace starboard | |
| } // namespace shared | |
| } // namespace starboard |