| // Copyright 2019 The libgav1 Authors | |
| // | |
| // 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 "src/gav1/decoder.h" | |
| #include <memory> | |
| #include <new> | |
| #include "src/decoder_impl.h" | |
| extern "C" { | |
| Libgav1StatusCode Libgav1DecoderCreate(const Libgav1DecoderSettings* settings, | |
| Libgav1Decoder** decoder_out) { | |
| std::unique_ptr<libgav1::Decoder> cxx_decoder(new (std::nothrow) | |
| libgav1::Decoder()); | |
| if (cxx_decoder == nullptr) return kLibgav1StatusOutOfMemory; | |
| libgav1::DecoderSettings cxx_settings; | |
| cxx_settings.threads = settings->threads; | |
| cxx_settings.frame_parallel = settings->frame_parallel != 0; | |
| cxx_settings.blocking_dequeue = settings->blocking_dequeue != 0; | |
| cxx_settings.on_frame_buffer_size_changed = | |
| settings->on_frame_buffer_size_changed; | |
| cxx_settings.get_frame_buffer = settings->get_frame_buffer; | |
| cxx_settings.release_frame_buffer = settings->release_frame_buffer; | |
| cxx_settings.release_input_buffer = settings->release_input_buffer; | |
| cxx_settings.callback_private_data = settings->callback_private_data; | |
| cxx_settings.output_all_layers = settings->output_all_layers != 0; | |
| cxx_settings.operating_point = settings->operating_point; | |
| cxx_settings.post_filter_mask = settings->post_filter_mask; | |
| const Libgav1StatusCode status = cxx_decoder->Init(&cxx_settings); | |
| if (status == kLibgav1StatusOk) { | |
| *decoder_out = reinterpret_cast<Libgav1Decoder*>(cxx_decoder.release()); | |
| } | |
| return status; | |
| } | |
| void Libgav1DecoderDestroy(Libgav1Decoder* decoder) { | |
| auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder); | |
| delete cxx_decoder; | |
| } | |
| Libgav1StatusCode Libgav1DecoderEnqueueFrame(Libgav1Decoder* decoder, | |
| const uint8_t* data, size_t size, | |
| int64_t user_private_data, | |
| void* buffer_private_data) { | |
| auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder); | |
| return cxx_decoder->EnqueueFrame(data, size, user_private_data, | |
| buffer_private_data); | |
| } | |
| Libgav1StatusCode Libgav1DecoderDequeueFrame( | |
| Libgav1Decoder* decoder, const Libgav1DecoderBuffer** out_ptr) { | |
| auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder); | |
| return cxx_decoder->DequeueFrame(out_ptr); | |
| } | |
| Libgav1StatusCode Libgav1DecoderSignalEOS(Libgav1Decoder* decoder) { | |
| auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder); | |
| return cxx_decoder->SignalEOS(); | |
| } | |
| int Libgav1DecoderGetMaxBitdepth() { | |
| return libgav1::Decoder::GetMaxBitdepth(); | |
| } | |
| } // extern "C" | |
| namespace libgav1 { | |
| Decoder::Decoder() = default; | |
| Decoder::~Decoder() = default; | |
| StatusCode Decoder::Init(const DecoderSettings* const settings) { | |
| if (impl_ != nullptr) return kStatusAlready; | |
| if (settings != nullptr) settings_ = *settings; | |
| return DecoderImpl::Create(&settings_, &impl_); | |
| } | |
| StatusCode Decoder::EnqueueFrame(const uint8_t* data, const size_t size, | |
| int64_t user_private_data, | |
| void* buffer_private_data) { | |
| if (impl_ == nullptr) return kStatusNotInitialized; | |
| return impl_->EnqueueFrame(data, size, user_private_data, | |
| buffer_private_data); | |
| } | |
| StatusCode Decoder::DequeueFrame(const DecoderBuffer** out_ptr) { | |
| if (impl_ == nullptr) return kStatusNotInitialized; | |
| return impl_->DequeueFrame(out_ptr); | |
| } | |
| StatusCode Decoder::SignalEOS() { | |
| if (impl_ == nullptr) return kStatusNotInitialized; | |
| // In non-frame-parallel mode, we have to release all the references. This | |
| // simply means replacing the |impl_| with a new instance so that all the | |
| // existing references are released and the state is cleared. | |
| impl_ = nullptr; | |
| return DecoderImpl::Create(&settings_, &impl_); | |
| } | |
| // static. | |
| int Decoder::GetMaxBitdepth() { return DecoderImpl::GetMaxBitdepth(); } | |
| } // namespace libgav1 |