Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

wip: 16bit shader conversions #1581

Draft
wants to merge 50 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
a85012c
wip: basic format mapping
Julusian Dec 1, 2023
8cd4cfc
wip
Julusian Dec 1, 2023
bf12120
wip
Julusian Dec 1, 2023
8a2a85b
wip
Julusian Dec 1, 2023
73fab17
wip
Julusian Dec 1, 2023
c58ad0e
things are hooked up, but has no output
Julusian Dec 1, 2023
90a6ecd
nope
Julusian Dec 4, 2023
efd99f6
wip: something happens!
Julusian Dec 22, 2023
467062e
hack a mess
Julusian Dec 22, 2023
1f07c7f
Add 16bit support to ogl texture
niklaspandersson Dec 15, 2023
a940412
add 16bit support to ogl device
niklaspandersson Dec 15, 2023
1332a46
Add create_frame override to specify bit_depth in frame_factory inter…
niklaspandersson Dec 15, 2023
8f87171
add native_depth property to caspar::array
niklaspandersson Dec 15, 2023
723419d
add 16bits support to image_mixer
niklaspandersson Dec 15, 2023
b96d98e
wip: correct colour
Julusian Dec 22, 2023
79cde82
simplify
Julusian Dec 22, 2023
8e934cd
add 16bit yuv, untested
Julusian Dec 22, 2023
0c69bb8
wip: propogate frame_converter type to consumers
Julusian Dec 22, 2023
57a3624
wip
Julusian Dec 22, 2023
f6a30be
wip: boilerplate for frame conversion
Julusian Dec 27, 2023
111e8f7
wip: broke
Julusian Dec 29, 2023
95e30ec
fix: remove bit_depth property from `array`
Julusian Dec 29, 2023
6618c4b
wip: hackily expose composited texture inside const_frame
Julusian Dec 29, 2023
1e3b38a
fix
Julusian Dec 29, 2023
25fad45
wip: incorrect conversion, but something semi identifiable
Julusian Dec 29, 2023
e7fc480
fix colour and 8bit texture support
Julusian Dec 29, 2023
030308f
fix: rgba8 download was incorrectly 16bit packed
Julusian Dec 29, 2023
d6704df
fix: remove unused windows only gl code
Julusian Dec 29, 2023
54e42bc
wip: interleave shader and remove clamp
Julusian Dec 29, 2023
6155975
chore: remove some dead code
Julusian Dec 30, 2023
a60827e
chore: format
Julusian Dec 30, 2023
9cb0282
chore: add todos to ndi producer
Julusian Dec 30, 2023
98419f6
wip: tidy
Julusian Dec 30, 2023
4cf8a2a
wip: reimplement decklink key-only flag
Julusian Dec 30, 2023
4cc8a05
feat: minimise cpu image conversions for image producer
Julusian Nov 28, 2023
219ada3
wip: start of 16bit png writing
Julusian Dec 30, 2023
8cfc286
fix: image consumer 16bit generation
Julusian Dec 30, 2023
f22f6a2
fix: image consumer 16bit defined by amcp
Julusian Dec 30, 2023
7476448
Revert "fix: image consumer 16bit defined by amcp"
Julusian Dec 30, 2023
a99522e
fix: typo
Julusian Dec 30, 2023
c7984a4
feat: image producer can work in 64bit
Julusian Dec 30, 2023
544b516
fix: 64bit freeimage endianness
Julusian Dec 30, 2023
b9baeca
fix: propogate parameters from print command to image consumer
Julusian Dec 30, 2023
60fca06
wip: tidy
Julusian Dec 30, 2023
69c29f5
wip: tidying
Julusian Dec 30, 2023
4f58d1a
wip: tidying
Julusian Dec 30, 2023
e0047af
wip: generic key-only implementation
Julusian Dec 30, 2023
f07b281
wip: fixes
Julusian Jan 4, 2024
bfcedf4
fix: allow 16bit from ffmpeg
Julusian Jan 4, 2024
7adf098
wip: boilerplate for decklink 12bit, but nothing happens
Julusian Jan 4, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions src/accelerator/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ set(SOURCES
ogl/image/image_kernel.cpp
ogl/image/image_mixer.cpp
ogl/image/image_shader.cpp
ogl/image/frame_converter.cpp

ogl/util/buffer.cpp
ogl/util/compute_shader.cpp
ogl/util/device.cpp
ogl/util/shader.cpp
ogl/util/texture.cpp
Expand All @@ -17,21 +19,27 @@ set(HEADERS
ogl/image/image_kernel.h
ogl/image/image_mixer.h
ogl/image/image_shader.h
ogl/image/frame_converter.h

ogl/util/buffer.h
ogl/util/compute_shader.h
ogl/util/device.h
ogl/util/shader.h
ogl/util/texture.h

ogl_image_vertex.h
ogl_image_fragment.h
ogl_image_to_rgba.h
ogl_image_from_rgba.h

accelerator.h
StdAfx.h
)

bin2c("ogl/image/shader.vert" "ogl_image_vertex.h" "caspar::accelerator::ogl" "vertex_shader")
bin2c("ogl/image/shader.frag" "ogl_image_fragment.h" "caspar::accelerator::ogl" "fragment_shader")
bin2c("ogl/image/shader_to_rgba.comp" "ogl_image_to_rgba.h" "caspar::accelerator::ogl" "compute_to_rgba_shader")
bin2c("ogl/image/shader_from_rgba.comp" "ogl_image_from_rgba.h" "caspar::accelerator::ogl" "compute_from_rgba_shader")

casparcg_add_library(accelerator SOURCES ${SOURCES} ${HEADERS})
target_include_directories(accelerator PRIVATE
Expand Down
10 changes: 6 additions & 4 deletions src/accelerator/accelerator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@

#include <boost/property_tree/ptree.hpp>

#include <common/bit_depth.h>

#include <core/mixer/image/image_mixer.h>

#include <memory>
Expand All @@ -23,10 +25,10 @@ struct accelerator::impl
{
}

std::unique_ptr<core::image_mixer> create_image_mixer(const int channel_id)
std::unique_ptr<core::image_mixer> create_image_mixer(int channel_id, common::bit_depth depth)
{
return std::make_unique<ogl::image_mixer>(
spl::make_shared_ptr(get_device()), channel_id, format_repository_.get_max_video_format_size());
spl::make_shared_ptr(get_device()), channel_id, depth, format_repository_.get_max_video_format_size());
}

std::shared_ptr<ogl::device> get_device()
Expand All @@ -46,9 +48,9 @@ accelerator::accelerator(const core::video_format_repository format_repository)

accelerator::~accelerator() {}

std::unique_ptr<core::image_mixer> accelerator::create_image_mixer(const int channel_id)
std::unique_ptr<core::image_mixer> accelerator::create_image_mixer(const int channel_id, common::bit_depth depth)
{
return impl_->create_image_mixer(channel_id);
return impl_->create_image_mixer(channel_id, depth);
}

std::shared_ptr<accelerator_device> accelerator::get_device() const
Expand Down
4 changes: 3 additions & 1 deletion src/accelerator/accelerator.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#pragma once

#include <common/bit_depth.h>

#include <core/mixer/mixer.h>
#include <core/video_format.h>

Expand Down Expand Up @@ -27,7 +29,7 @@ class accelerator

accelerator& operator=(accelerator&) = delete;

std::unique_ptr<caspar::core::image_mixer> create_image_mixer(int channel_id);
std::unique_ptr<caspar::core::image_mixer> create_image_mixer(int channel_id, common::bit_depth depth);

std::shared_ptr<accelerator_device> get_device() const;

Expand Down
137 changes: 137 additions & 0 deletions src/accelerator/ogl/image/frame_converter.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
/*
* Copyright (c) 2011 Sveriges Television AB <[email protected]>
*
* This file is part of CasparCG (www.casparcg.com).
*
* CasparCG is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CasparCG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Julian Waller, [email protected]
*/
#include "frame_converter.h"
#include "../util/texture.h"

#include <core/frame/pixel_format.h>

#include <common/except.h>
#include <common/future.h>

namespace caspar::accelerator::ogl {

ogl_frame_converter::ogl_frame_converter(const spl::shared_ptr<device>& ogl)
: ogl_(ogl)
{
}

// core::mutable_frame ogl_frame_converter::create_frame(const void* tag, const core::pixel_format_desc& desc)
// {
// std::vector<array<std::uint8_t>> image_data;
// for (auto& plane : desc.planes) {
// image_data.push_back(ogl_->create_array(plane.size));
// }

// using future_texture = std::shared_future<std::shared_ptr<texture>>;

// std::weak_ptr<ogl_frame_converter> weak_self = shared_from_this();
// return core::mutable_frame(tag,
// std::move(image_data),
// array<int32_t>{},
// desc,
// [weak_self, desc](std::vector<array<const std::uint8_t>> image_data) -> boost::any {
// // TODO - replace this
// auto self = weak_self.lock();
// if (!self) {
// return boost::any{};
// }
// std::vector<future_texture> textures;
// for (int n = 0; n < static_cast<int>(desc.planes.size()); ++n) {
// textures.emplace_back(self->ogl_->copy_async(image_data[n],
// desc.planes[n].width,
// desc.planes[n].height,
// desc.planes[n].stride,
// desc.planes[n].depth));
// }
// return std::make_shared<decltype(textures)>(std::move(textures));
// });
// }

// core::draw_frame ogl_frame_converter::convert_to_rgba(const core::mutable_frame& frame)
// {
// // TODO
// return core::draw_frame{};
// }

std::shared_future<array<const std::uint8_t>>
ogl_frame_converter::convert_from_rgba(const core::const_frame& frame,
const core::encoded_frame_format format,
bool key_only,
bool straighten)
{
int buffer_size = 0;
unsigned int x_count = 0;
unsigned int y_count = 0;
int words_per_line = 0;

switch (format) {
case core::encoded_frame_format::rgba16:
case core::encoded_frame_format::bgra16:
x_count = frame.width();
y_count = frame.height();
buffer_size = frame.width() * frame.height() * 8;
words_per_line = frame.width() * 2;

break;
case core::encoded_frame_format::decklink_v210:
auto row_blocks = ((frame.width() + 47) / 48);
auto row_bytes = row_blocks * 128;

// TODO - result must be 128byte aligned. can that be guaranteed here?
buffer_size = row_bytes * frame.height();
x_count = row_blocks * 8;
y_count = frame.height();
words_per_line = row_blocks * 32;
break;
}

if (buffer_size == 0 || x_count == 0 || y_count == 0) {
CASPAR_THROW_EXCEPTION(not_supported() << msg_info("Unknown encoded frame format"));
}

auto texture_ptr = boost::any_cast<std::shared_ptr<texture>>(frame.opaque());
if (!texture_ptr) {
CASPAR_THROW_EXCEPTION(not_supported() << msg_info("No texture inside frame!"));
}

convert_from_texture_description description{};
description.target_format = format;
description.is_16_bit = texture_ptr->depth() == common::bit_depth::bit16;
description.width = frame.width();
description.height = frame.height();
description.words_per_line = words_per_line;
description.key_only = key_only;
description.straighten = straighten;

return ogl_->convert_from_texture(texture_ptr, buffer_size, description, x_count, y_count);
}

common::bit_depth ogl_frame_converter::get_frame_bitdepth(const core::const_frame& frame)
{
auto texture_ptr = boost::any_cast<std::shared_ptr<texture>>(frame.opaque());
if (!texture_ptr) {
CASPAR_THROW_EXCEPTION(not_supported() << msg_info("No texture inside frame!"));
}

return texture_ptr->depth();
}

} // namespace caspar::accelerator::ogl
59 changes: 59 additions & 0 deletions src/accelerator/ogl/image/frame_converter.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (c) 2011 Sveriges Television AB <[email protected]>
*
* This file is part of CasparCG (www.casparcg.com).
*
* CasparCG is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* CasparCG is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with CasparCG. If not, see <http://www.gnu.org/licenses/>.
*
* Author: Julian Waller, [email protected]
*/

#pragma once

#include <core/frame/draw_frame.h>
#include <core/frame/frame.h>
#include <core/frame/frame_factory.h>

#include "../util/device.h"

namespace caspar::accelerator::ogl {

class ogl_frame_converter
: public core::frame_converter
, public std::enable_shared_from_this<ogl_frame_converter>
{
public:
ogl_frame_converter(const spl::shared_ptr<device>& ogl);
ogl_frame_converter(const ogl_frame_converter&) = delete;

~ogl_frame_converter() override = default;

ogl_frame_converter& operator=(const ogl_frame_converter&) = delete;

// core::mutable_frame create_frame(const void* video_stream_tag, const core::pixel_format_desc& desc) override;

// core::draw_frame convert_to_rgba(const core::mutable_frame& frame) override;

std::shared_future<array<const std::uint8_t>> convert_from_rgba(const core::const_frame& frame,
core::encoded_frame_format format,
bool key_only,
bool straighten) override;

common::bit_depth get_frame_bitdepth(const core::const_frame& frame) override;

private:
const spl::shared_ptr<device> ogl_;
};

} // namespace caspar::accelerator::ogl
2 changes: 2 additions & 0 deletions src/accelerator/ogl/image/image_kernel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,8 @@ struct image_kernel::impl

shader_->use();

shader_->set("is_straight_alpha", params.pix_desc.is_straight);

shader_->set("plane[0]", texture_id::plane0);
shader_->set("plane[1]", texture_id::plane1);
shader_->set("plane[2]", texture_id::plane2);
Expand Down
Loading
Loading