// 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 #include #include "src/decoder_impl.h" extern "C" { Libgav1StatusCode Libgav1DecoderCreate(const Libgav1DecoderSettings* settings, Libgav1Decoder** decoder_out) { std::unique_ptr 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(cxx_decoder.release()); } return status; } void Libgav1DecoderDestroy(Libgav1Decoder* decoder) { auto* cxx_decoder = reinterpret_cast(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(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(decoder); return cxx_decoder->DequeueFrame(out_ptr); } Libgav1StatusCode Libgav1DecoderSignalEOS(Libgav1Decoder* decoder) { auto* cxx_decoder = reinterpret_cast(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