blob: b9e43e0bf8cb0a995bc9b6160fd5680795f94826 [file] [log] [blame]
// 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