Image-Text-to-Text
Transformers
Safetensors
mage_vl
multimodal
vision-language-model
mage-vl
video-understanding
streaming
conversational
custom_code
Instructions to use Mage-Fans/Mage-VL with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use Mage-Fans/Mage-VL with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("image-text-to-text", model="Mage-Fans/Mage-VL", trust_remote_code=True) messages = [ { "role": "user", "content": [ {"type": "image", "url": "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/p-blog/candy.JPG"}, {"type": "text", "text": "What animal is on the candy?"} ] }, ] pipe(text=messages)# Load model directly from transformers import AutoModelForImageTextToText model = AutoModelForImageTextToText.from_pretrained("Mage-Fans/Mage-VL", trust_remote_code=True, device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use Mage-Fans/Mage-VL with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "Mage-Fans/Mage-VL" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Mage-Fans/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker
docker model run hf.co/Mage-Fans/Mage-VL
- SGLang
How to use Mage-Fans/Mage-VL with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "Mage-Fans/Mage-VL" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Mage-Fans/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "Mage-Fans/Mage-VL" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/chat/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "Mage-Fans/Mage-VL", "messages": [ { "role": "user", "content": [ { "type": "text", "text": "Describe this image in one sentence." }, { "type": "image_url", "image_url": { "url": "https://cdn.britannica.com/61/93061-050-99147DCE/Statue-of-Liberty-Island-New-York-Bay.jpg" } } ] } ] }' - Docker Model Runner
How to use Mage-Fans/Mage-VL with Docker Model Runner:
docker model run hf.co/Mage-Fans/Mage-VL
| /* Copyright 2020 InterDigital Communications, Inc. | |
| * | |
| * 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. | |
| */ | |
| /* Rans64 extensions from: | |
| * https://fgiesen.wordpress.com/2015/12/21/rans-in-practice/ | |
| * Unbounded range coding from: | |
| * https://github.com/tensorflow/compression/blob/master/tensorflow_compression/cc/kernels/unbounded_index_range_coding_kernels.cc | |
| **/ | |
| constexpr uint16_t bypass_precision = 2; /* number of bits in bypass mode */ | |
| constexpr uint16_t max_bypass_val = (1 << bypass_precision) - 1; | |
| inline void RansEncPutBits(RansState& r, uint8_t*& ptr, uint32_t val) | |
| { | |
| RansAssert(bypass_precision <= 8); | |
| RansAssert(val < (1u << bypass_precision)); | |
| constexpr uint32_t freq = 1 << (SCALE_BITS - bypass_precision); | |
| constexpr uint32_t x_max = freq << ENC_RENORM_SHIFT_BITS; | |
| while (r >= x_max) { | |
| *(--ptr) = static_cast<uint8_t>(r & 0xff); | |
| r >>= 8; | |
| } | |
| r = (r << bypass_precision) | val; | |
| } | |
| inline uint32_t RansDecGetBits(RansState& r, uint8_t*& ptr) | |
| { | |
| uint32_t val = r & ((1u << bypass_precision) - 1); | |
| /* Re-normalize */ | |
| r = r >> bypass_precision; | |
| if (r < RANS_BYTE_L) { | |
| r = (r << 8) | *ptr++; | |
| RansAssert(r >= RANS_BYTE_L); | |
| } | |
| return val; | |
| } | |
| RansEncoderLib::RansEncoderLib() | |
| { | |
| _stream = std::make_shared<std::vector<uint8_t>>(); | |
| } | |
| int RansEncoderLib::add_cdf(const std::shared_ptr<std::vector<std::vector<int32_t>>> cdfs, | |
| const std::shared_ptr<std::vector<int32_t>> cdfs_sizes, | |
| const std::shared_ptr<std::vector<int32_t>> offsets) | |
| { | |
| auto ransSymbols = std::make_shared<std::vector<std::vector<RansSymbol>>>(cdfs->size()); | |
| for (int i = 0; i < static_cast<int>(cdfs->size()); i++) { | |
| const int32_t* cdf = cdfs->at(i).data(); | |
| std::vector<RansSymbol> ransSym(cdfs->at(i).size()); | |
| const int ransSize = static_cast<int>(ransSym.size() - 1); | |
| for (int j = 0; j < ransSize; j++) { | |
| ransSym[j] = RansSymbol( | |
| { static_cast<uint16_t>(cdf[j]), static_cast<uint16_t>(cdf[j + 1] - cdf[j]) }); | |
| } | |
| ransSymbols->at(i) = ransSym; | |
| } | |
| _ransSymbols.push_back(ransSymbols); | |
| _cdfs_sizes.push_back(cdfs_sizes); | |
| _offsets.push_back(offsets); | |
| return static_cast<int>(_ransSymbols.size()) - 1; | |
| } | |
| void RansEncoderLib::empty_cdf_buffer() | |
| { | |
| _ransSymbols.clear(); | |
| _cdfs_sizes.clear(); | |
| _offsets.clear(); | |
| } | |
| FORCE_INLINE void RansEncoderLib::encode_one_symbol(uint8_t*& ptr, RansState& rans, const int32_t symbol, | |
| const int32_t cdf_size, const int32_t offset, | |
| const std::vector<RansSymbol>& ransSymbols) | |
| { | |
| const int32_t max_value = cdf_size - 2; | |
| int32_t value = symbol - offset; | |
| uint32_t raw_val = 0; | |
| if (value < 0) { | |
| raw_val = -2 * value - 1; | |
| value = max_value; | |
| } else if (value >= max_value) { | |
| raw_val = 2 * (value - max_value); | |
| value = max_value; | |
| } | |
| if (value == max_value) { | |
| std::vector<uint16_t> bypassBins; | |
| bypassBins.reserve(20); | |
| /* Determine the number of bypasses (in bypass_precision size) needed to | |
| * encode the raw value. */ | |
| int32_t n_bypass = 0; | |
| while ((raw_val >> (n_bypass * bypass_precision)) != 0) { | |
| ++n_bypass; | |
| } | |
| /* Encode number of bypasses */ | |
| int32_t val = n_bypass; | |
| while (val >= max_bypass_val) { | |
| bypassBins.push_back(max_bypass_val); | |
| val -= max_bypass_val; | |
| } | |
| bypassBins.push_back(static_cast<uint16_t>(val)); | |
| /* Encode raw value */ | |
| for (int32_t j = 0; j < n_bypass; ++j) { | |
| const int32_t val1 = (raw_val >> (j * bypass_precision)) & max_bypass_val; | |
| bypassBins.push_back(static_cast<uint16_t>(val1)); | |
| } | |
| for (auto it = bypassBins.rbegin(); it < bypassBins.rend(); it++) { | |
| RansEncPutBits(rans, ptr, *it); | |
| } | |
| } | |
| RansEncPut(rans, ptr, ransSymbols[value].start, ransSymbols[value].range); | |
| } | |
| void RansEncoderLib::encode_y(const std::shared_ptr<std::vector<int16_t>> symbols, | |
| const int cdf_group_index) | |
| { | |
| PendingTask p; | |
| p.workType = WorkType::EncodeDecodeY; | |
| p.symbols_y = symbols; | |
| p.cdf_group_index = cdf_group_index; | |
| m_pendingEncodingList.push_back(p); | |
| } | |
| void RansEncoderLib::encode_z(const std::shared_ptr<std::vector<int8_t>> symbols, | |
| const int cdf_group_index, const int start_offset, | |
| const int per_channel_size) | |
| { | |
| PendingTask p; | |
| p.workType = WorkType::EncodeDecodeZ; | |
| p.symbols_z = symbols; | |
| p.cdf_group_index = cdf_group_index; | |
| p.start_offset = start_offset; | |
| p.per_channel_size = per_channel_size; | |
| m_pendingEncodingList.push_back(p); | |
| } | |
| FORCE_INLINE void RansEncoderLib::encode_y_internal(uint8_t*& ptr, RansState& rans, | |
| const std::shared_ptr<std::vector<int16_t>> symbols, | |
| const int cdf_group_index) | |
| { | |
| // backward loop on symbols from the end; | |
| const int16_t* symbols_ptr = symbols->data(); | |
| const int32_t* cdfs_sizes_ptr = _cdfs_sizes[cdf_group_index]->data(); | |
| const int32_t* offsets_ptr = _offsets[cdf_group_index]->data(); | |
| const int symbol_size = static_cast<int>(symbols->size()); | |
| for (int i = symbol_size - 1; i >= 0; i--) { | |
| const int32_t combined_symbol = symbols_ptr[i]; | |
| const int32_t cdf_idx = combined_symbol & 0xff; | |
| const int32_t s = combined_symbol >> 8; | |
| encode_one_symbol(ptr, rans, s, cdfs_sizes_ptr[cdf_idx], offsets_ptr[cdf_idx], | |
| _ransSymbols[cdf_group_index]->at(cdf_idx)); | |
| } | |
| } | |
| FORCE_INLINE void RansEncoderLib::encode_z_internal(uint8_t*& ptr, RansState& rans, | |
| const std::shared_ptr<std::vector<int8_t>> symbols, | |
| const int cdf_group_index, const int start_offset, | |
| const int per_channel_size) | |
| { | |
| // backward loop on symbols from the end; | |
| const int8_t* symbols_ptr = symbols->data(); | |
| const int32_t* cdfs_sizes_ptr = _cdfs_sizes[cdf_group_index]->data(); | |
| const int32_t* offsets_ptr = _offsets[cdf_group_index]->data(); | |
| const int symbol_size = static_cast<int>(symbols->size()); | |
| for (int i = symbol_size - 1; i >= 0; i--) { | |
| const int32_t cdf_idx = i / per_channel_size + start_offset; | |
| encode_one_symbol(ptr, rans, symbols_ptr[i], cdfs_sizes_ptr[cdf_idx], offsets_ptr[cdf_idx], | |
| _ransSymbols[cdf_group_index]->at(cdf_idx)); | |
| } | |
| } | |
| void RansEncoderLib::flush() | |
| { | |
| RansState rans; | |
| RansEncInit(rans); | |
| int32_t total_symbol_size = 0; | |
| for (auto it = m_pendingEncodingList.begin(); it != m_pendingEncodingList.end(); it++) { | |
| if (it->workType == WorkType::EncodeDecodeY) { | |
| total_symbol_size += static_cast<int32_t>(it->symbols_y->size()); | |
| } else if (it->workType == WorkType::EncodeDecodeZ) { | |
| total_symbol_size += static_cast<int32_t>(it->symbols_z->size()); | |
| } | |
| } | |
| if (total_symbol_size == 0) { | |
| _stream->resize(0); | |
| return; | |
| } | |
| uint8_t* output = new uint8_t[total_symbol_size]; // too much space ? | |
| uint8_t* ptrEnd = output + total_symbol_size; | |
| uint8_t* ptr = ptrEnd; | |
| assert(ptr != nullptr); | |
| for (auto it = m_pendingEncodingList.rbegin(); it != m_pendingEncodingList.rend(); it++) { | |
| PendingTask p = *it; | |
| if (p.workType == WorkType::EncodeDecodeY) { | |
| encode_y_internal(ptr, rans, p.symbols_y, p.cdf_group_index); | |
| } else if (p.workType == WorkType::EncodeDecodeZ) { | |
| encode_z_internal(ptr, rans, p.symbols_z, p.cdf_group_index, p.start_offset, | |
| p.per_channel_size); | |
| } | |
| } | |
| RansEncFlush(rans, ptr); | |
| const int nbytes = static_cast<int>(std::distance(ptr, ptrEnd)); | |
| _stream->resize(nbytes); | |
| memcpy(_stream->data(), ptr, nbytes); | |
| delete[] output; | |
| } | |
| std::shared_ptr<std::vector<uint8_t>> RansEncoderLib::get_encoded_stream() | |
| { | |
| return _stream; | |
| } | |
| void RansEncoderLib::reset() | |
| { | |
| m_pendingEncodingList.clear(); | |
| _stream->clear(); | |
| } | |
| RansEncoderLibMultiThread::RansEncoderLibMultiThread() | |
| : RansEncoderLib() | |
| , m_finish(false) | |
| , m_result_ready(false) | |
| { | |
| m_thread = std::thread(&RansEncoderLibMultiThread::worker, this); | |
| } | |
| RansEncoderLibMultiThread::~RansEncoderLibMultiThread() | |
| { | |
| { | |
| std::lock_guard<std::mutex> lk(m_mutex_pending); | |
| std::lock_guard<std::mutex> lk1(m_mutex_result); | |
| m_finish = true; | |
| } | |
| m_cv_pending.notify_one(); | |
| m_cv_result.notify_one(); | |
| m_thread.join(); | |
| } | |
| void RansEncoderLibMultiThread::flush() | |
| { | |
| PendingTask p; | |
| p.workType = WorkType::Flush; | |
| { | |
| std::unique_lock<std::mutex> lk(m_mutex_pending); | |
| m_pending.push_back(p); | |
| } | |
| m_cv_pending.notify_one(); | |
| } | |
| std::shared_ptr<std::vector<uint8_t>> RansEncoderLibMultiThread::get_encoded_stream() | |
| { | |
| std::unique_lock<std::mutex> lk(m_mutex_result); | |
| m_cv_result.wait(lk, [this] { return m_result_ready || m_finish; }); | |
| return RansEncoderLib::get_encoded_stream(); | |
| } | |
| void RansEncoderLibMultiThread::reset() | |
| { | |
| RansEncoderLib::reset(); | |
| std::lock_guard<std::mutex> lk(m_mutex_result); | |
| m_result_ready = false; | |
| } | |
| void RansEncoderLibMultiThread::worker() | |
| { | |
| while (!m_finish) { | |
| std::unique_lock<std::mutex> lk(m_mutex_pending); | |
| m_cv_pending.wait(lk, [this] { return m_pending.size() > 0 || m_finish; }); | |
| if (m_finish) { | |
| lk.unlock(); | |
| break; | |
| } | |
| if (m_pending.size() == 0) { | |
| lk.unlock(); | |
| // std::cout << "contine in worker" << std::endl; | |
| continue; | |
| } | |
| while (m_pending.size() > 0) { | |
| auto p = m_pending.front(); | |
| m_pending.pop_front(); | |
| lk.unlock(); | |
| if (p.workType == WorkType::Flush) { | |
| RansEncoderLib::flush(); | |
| { | |
| std::lock_guard<std::mutex> lk_result(m_mutex_result); | |
| m_result_ready = true; | |
| } | |
| m_cv_result.notify_one(); | |
| } | |
| lk.lock(); | |
| } | |
| lk.unlock(); | |
| } | |
| } | |
| void RansDecoderLib::set_stream(const std::shared_ptr<std::vector<uint8_t>> encoded) | |
| { | |
| _stream = encoded; | |
| _ptr8 = (uint8_t*)(_stream->data()); | |
| RansDecInit(_rans, _ptr8); | |
| } | |
| int RansDecoderLib::add_cdf(const std::shared_ptr<std::vector<std::vector<int32_t>>> cdfs, | |
| const std::shared_ptr<std::vector<int32_t>> cdfs_sizes, | |
| const std::shared_ptr<std::vector<int32_t>> offsets) | |
| { | |
| _cdfs.push_back(cdfs); | |
| _cdfs_sizes.push_back(cdfs_sizes); | |
| _offsets.push_back(offsets); | |
| return static_cast<int>(_cdfs.size()) - 1; | |
| } | |
| void RansDecoderLib::empty_cdf_buffer() | |
| { | |
| _cdfs.clear(); | |
| _cdfs_sizes.clear(); | |
| _offsets.clear(); | |
| } | |
| FORCE_INLINE int8_t RansDecoderLib::decode_one_symbol(const int32_t* cdf, const int32_t cdf_size, | |
| const int32_t offset) | |
| { | |
| const int32_t max_value = cdf_size - 2; | |
| const int32_t cum_freq = static_cast<int32_t>(RansDecGet(_rans)); | |
| int s = 1; | |
| while (cdf[s++] <= cum_freq) { | |
| } | |
| s -= 2; | |
| RansDecAdvance(_rans, _ptr8, cdf[s], cdf[s + 1] - cdf[s]); | |
| int32_t value = static_cast<int32_t>(s); | |
| if (value == max_value) { | |
| /* Bypass decoding mode */ | |
| int32_t val = RansDecGetBits(_rans, _ptr8); | |
| int32_t n_bypass = val; | |
| while (val == max_bypass_val) { | |
| val = RansDecGetBits(_rans, _ptr8); | |
| n_bypass += val; | |
| } | |
| int32_t raw_val = 0; | |
| for (int j = 0; j < n_bypass; ++j) { | |
| val = RansDecGetBits(_rans, _ptr8); | |
| raw_val |= val << (j * bypass_precision); | |
| } | |
| value = raw_val >> 1; | |
| if (raw_val & 1) { | |
| value = -value - 1; | |
| } else { | |
| value += max_value; | |
| } | |
| } | |
| return static_cast<int8_t>(value + offset); | |
| } | |
| void RansDecoderLib::decode_y(const std::shared_ptr<std::vector<uint8_t>> indexes, | |
| const int cdf_group_index) | |
| { | |
| int index_size = static_cast<int>(indexes->size()); | |
| m_decoded = std::make_shared<std::vector<int8_t>>(index_size); | |
| int8_t* outout_ptr = m_decoded->data(); | |
| const uint8_t* indexes_ptr = indexes->data(); | |
| const int32_t* cdfs_sizes_ptr = _cdfs_sizes[cdf_group_index]->data(); | |
| const int32_t* offsets_ptr = _offsets[cdf_group_index]->data(); | |
| const auto& cdfs = _cdfs[cdf_group_index]; | |
| for (int i = 0; i < index_size; ++i) { | |
| const int32_t cdf_idx = indexes_ptr[i]; | |
| outout_ptr[i] = decode_one_symbol(cdfs->at(cdf_idx).data(), cdfs_sizes_ptr[cdf_idx], | |
| offsets_ptr[cdf_idx]); | |
| } | |
| } | |
| void RansDecoderLib::decode_z(const int total_size, const int cdf_group_index, | |
| const int start_offset, const int per_channel_size) | |
| { | |
| m_decoded = std::make_shared<std::vector<int8_t>>(total_size); | |
| int8_t* outout_ptr = m_decoded->data(); | |
| const int32_t* cdfs_sizes_ptr = _cdfs_sizes[cdf_group_index]->data(); | |
| const int32_t* offsets_ptr = _offsets[cdf_group_index]->data(); | |
| const auto& cdfs = _cdfs[cdf_group_index]; | |
| for (int i = 0; i < total_size; ++i) { | |
| const int32_t cdf_idx = i / per_channel_size + start_offset; | |
| outout_ptr[i] = decode_one_symbol(cdfs->at(cdf_idx).data(), cdfs_sizes_ptr[cdf_idx], | |
| offsets_ptr[cdf_idx]); | |
| } | |
| } | |
| std::shared_ptr<std::vector<int8_t>> RansDecoderLib::get_decoded_tensor() | |
| { | |
| return m_decoded; | |
| } | |
| RansDecoderLibMultiThread::RansDecoderLibMultiThread() | |
| : RansDecoderLib() | |
| , m_finish(false) | |
| , m_result_ready(false) | |
| { | |
| m_thread = std::thread(&RansDecoderLibMultiThread::worker, this); | |
| } | |
| RansDecoderLibMultiThread::~RansDecoderLibMultiThread() | |
| { | |
| { | |
| std::lock_guard<std::mutex> lk(m_mutex_pending); | |
| std::lock_guard<std::mutex> lk1(m_mutex_result); | |
| m_finish = true; | |
| } | |
| m_cv_pending.notify_one(); | |
| m_cv_result.notify_one(); | |
| m_thread.join(); | |
| } | |
| void RansDecoderLibMultiThread::decode_y(const std::shared_ptr<std::vector<uint8_t>> indexes, | |
| const int cdf_group_index) | |
| { | |
| { | |
| std::lock_guard<std::mutex> lk(m_mutex_result); | |
| m_result_ready = false; | |
| } | |
| PendingTask p; | |
| p.workType = WorkType::EncodeDecodeY; | |
| p.indexes = indexes; | |
| p.cdf_group_index = cdf_group_index; | |
| { | |
| std::unique_lock<std::mutex> lk(m_mutex_pending); | |
| m_pending.push_back(p); | |
| } | |
| m_cv_pending.notify_one(); | |
| } | |
| void RansDecoderLibMultiThread::decode_z(const int total_size, const int cdf_group_index, | |
| const int start_offset, const int per_channel_size) | |
| { | |
| { | |
| std::lock_guard<std::mutex> lk(m_mutex_result); | |
| m_result_ready = false; | |
| } | |
| PendingTask p; | |
| p.workType = WorkType::EncodeDecodeZ; | |
| p.total_size = total_size; | |
| p.cdf_group_index = cdf_group_index; | |
| p.start_offset = start_offset; | |
| p.per_channel_size = per_channel_size; | |
| { | |
| std::unique_lock<std::mutex> lk(m_mutex_pending); | |
| m_pending.push_back(p); | |
| } | |
| m_cv_pending.notify_one(); | |
| } | |
| std::shared_ptr<std::vector<int8_t>> RansDecoderLibMultiThread::get_decoded_tensor() | |
| { | |
| std::unique_lock<std::mutex> lk(m_mutex_result); | |
| m_cv_result.wait(lk, [this] { return m_result_ready || m_finish; }); | |
| return RansDecoderLib::get_decoded_tensor(); | |
| } | |
| void RansDecoderLibMultiThread::worker() | |
| { | |
| while (!m_finish) { | |
| std::unique_lock<std::mutex> lk(m_mutex_pending); | |
| m_cv_pending.wait(lk, [this] { return m_pending.size() > 0 || m_finish; }); | |
| if (m_finish) { | |
| lk.unlock(); | |
| break; | |
| } | |
| if (m_pending.size() == 0) { | |
| lk.unlock(); | |
| // std::cout << "contine in worker" << std::endl; | |
| continue; | |
| } | |
| while (m_pending.size() > 0) { | |
| auto p = m_pending.front(); | |
| m_pending.pop_front(); | |
| lk.unlock(); | |
| if (p.workType == WorkType::EncodeDecodeY) { | |
| RansDecoderLib::decode_y(p.indexes, p.cdf_group_index); | |
| } else if (p.workType == WorkType::EncodeDecodeZ) { | |
| RansDecoderLib::decode_z(p.total_size, p.cdf_group_index, p.start_offset, | |
| p.per_channel_size); | |
| } | |
| { | |
| std::lock_guard<std::mutex> lk_result(m_mutex_result); | |
| m_result_ready = true; | |
| } | |
| m_cv_result.notify_one(); | |
| lk.lock(); | |
| } | |
| lk.unlock(); | |
| } | |
| } | |