1 // Copyright 2019 The libgav1 Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 #include "src/gav1/decoder.h"
16
17 #include <memory>
18 #include <new>
19 #include <vector>
20
21 #include "src/decoder_impl.h"
22
23 extern "C" {
24
Libgav1DecoderCreate(const Libgav1DecoderSettings * settings,Libgav1Decoder ** decoder_out)25 Libgav1StatusCode Libgav1DecoderCreate(const Libgav1DecoderSettings* settings,
26 Libgav1Decoder** decoder_out) {
27 std::unique_ptr<libgav1::Decoder> cxx_decoder(new (std::nothrow)
28 libgav1::Decoder());
29 if (cxx_decoder == nullptr) return kLibgav1StatusOutOfMemory;
30
31 libgav1::DecoderSettings cxx_settings;
32 cxx_settings.threads = settings->threads;
33 cxx_settings.frame_parallel = settings->frame_parallel != 0;
34 cxx_settings.blocking_dequeue = settings->blocking_dequeue != 0;
35 cxx_settings.on_frame_buffer_size_changed =
36 settings->on_frame_buffer_size_changed;
37 cxx_settings.get_frame_buffer = settings->get_frame_buffer;
38 cxx_settings.release_frame_buffer = settings->release_frame_buffer;
39 cxx_settings.release_input_buffer = settings->release_input_buffer;
40 cxx_settings.callback_private_data = settings->callback_private_data;
41 cxx_settings.output_all_layers = settings->output_all_layers != 0;
42 cxx_settings.operating_point = settings->operating_point;
43 cxx_settings.post_filter_mask = settings->post_filter_mask;
44 cxx_settings.parse_only = settings->parse_only != 0;
45
46 const Libgav1StatusCode status = cxx_decoder->Init(&cxx_settings);
47 if (status == kLibgav1StatusOk) {
48 *decoder_out = reinterpret_cast<Libgav1Decoder*>(cxx_decoder.release());
49 }
50 return status;
51 }
52
Libgav1DecoderDestroy(Libgav1Decoder * decoder)53 void Libgav1DecoderDestroy(Libgav1Decoder* decoder) {
54 auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder);
55 delete cxx_decoder;
56 }
57
Libgav1DecoderEnqueueFrame(Libgav1Decoder * decoder,const uint8_t * data,size_t size,int64_t user_private_data,void * buffer_private_data)58 Libgav1StatusCode Libgav1DecoderEnqueueFrame(Libgav1Decoder* decoder,
59 const uint8_t* data, size_t size,
60 int64_t user_private_data,
61 void* buffer_private_data) {
62 auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder);
63 return cxx_decoder->EnqueueFrame(data, size, user_private_data,
64 buffer_private_data);
65 }
66
Libgav1DecoderDequeueFrame(Libgav1Decoder * decoder,const Libgav1DecoderBuffer ** out_ptr)67 Libgav1StatusCode Libgav1DecoderDequeueFrame(
68 Libgav1Decoder* decoder, const Libgav1DecoderBuffer** out_ptr) {
69 auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder);
70 return cxx_decoder->DequeueFrame(out_ptr);
71 }
72
Libgav1DecoderSignalEOS(Libgav1Decoder * decoder)73 Libgav1StatusCode Libgav1DecoderSignalEOS(Libgav1Decoder* decoder) {
74 auto* cxx_decoder = reinterpret_cast<libgav1::Decoder*>(decoder);
75 return cxx_decoder->SignalEOS();
76 }
77
Libgav1DecoderGetMaxBitdepth()78 int Libgav1DecoderGetMaxBitdepth() {
79 return libgav1::Decoder::GetMaxBitdepth();
80 }
81
82 } // extern "C"
83
84 namespace libgav1 {
85
86 Decoder::Decoder() = default;
87
88 Decoder::~Decoder() = default;
89
Init(const DecoderSettings * const settings)90 StatusCode Decoder::Init(const DecoderSettings* const settings) {
91 if (impl_ != nullptr) return kStatusAlready;
92 if (settings != nullptr) settings_ = *settings;
93 return DecoderImpl::Create(&settings_, &impl_);
94 }
95
EnqueueFrame(const uint8_t * data,const size_t size,int64_t user_private_data,void * buffer_private_data)96 StatusCode Decoder::EnqueueFrame(const uint8_t* data, const size_t size,
97 int64_t user_private_data,
98 void* buffer_private_data) {
99 if (impl_ == nullptr) return kStatusNotInitialized;
100 return impl_->EnqueueFrame(data, size, user_private_data,
101 buffer_private_data);
102 }
103
DequeueFrame(const DecoderBuffer ** out_ptr)104 StatusCode Decoder::DequeueFrame(const DecoderBuffer** out_ptr) {
105 if (impl_ == nullptr) return kStatusNotInitialized;
106 StatusCode status = impl_->DequeueFrame(out_ptr);
107 if (settings_.parse_only) {
108 frame_mean_qps_ = impl_->GetFrameQps();
109 }
110 return status;
111 }
112
SignalEOS()113 StatusCode Decoder::SignalEOS() {
114 if (impl_ == nullptr) return kStatusNotInitialized;
115 // In non-frame-parallel mode, we have to release all the references. This
116 // simply means replacing the |impl_| with a new instance so that all the
117 // existing references are released and the state is cleared.
118 impl_ = nullptr;
119 return DecoderImpl::Create(&settings_, &impl_);
120 }
121
122 // static.
GetMaxBitdepth()123 int Decoder::GetMaxBitdepth() { return DecoderImpl::GetMaxBitdepth(); }
124
GetFramesMeanQpInTemporalUnit()125 std::vector<int> Decoder::GetFramesMeanQpInTemporalUnit() {
126 return frame_mean_qps_;
127 }
128
129 } // namespace libgav1
130