Skip to content

Commit 3b82626

Browse files
committed
Add dynamic bitrate update for pyrowave encode.
1 parent 4436277 commit 3b82626

2 files changed

Lines changed: 58 additions & 30 deletions

File tree

video/ffmpeg_encode.cpp

Lines changed: 55 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -133,9 +133,13 @@ struct VideoEncoder::Impl final
133133
bool init_video_codec_av(const AVCodec *codec);
134134
bool init_video_codec_pyro(PyroEnc::Profile profile);
135135
bool init_video_codec_pyrowave();
136+
bool init_video_codec_pyrowave_buffers(unsigned bitrate_kbits);
136137
bool init_video_codec();
137138
bool init_audio_codec();
138139

140+
bool update_bitrate_async();
141+
std::atomic<unsigned> update_bitrate_kbits = {};
142+
139143
std::vector<int16_t> audio_buffer_s16;
140144

141145
struct
@@ -460,10 +464,21 @@ void VideoEncoder::Impl::write_frames_interleaved_f32(const float *data, size_t
460464
}
461465
#endif
462466

467+
bool VideoEncoder::Impl::update_bitrate_async()
468+
{
469+
auto new_value = update_bitrate_kbits.exchange(0, std::memory_order_acq_rel);
470+
if (new_value)
471+
options.bitrate_kbits = new_value;
472+
return new_value != 0;
473+
}
474+
463475
bool VideoEncoder::Impl::encode_frame(const PyroWave::ViewBuffers &views, int64_t pts, int compensate_audio_us)
464476
{
465477
assert(mux_stream_callback);
466478

479+
if (update_bitrate_async() && !init_video_codec_pyrowave_buffers(options.bitrate_kbits))
480+
return false;
481+
467482
auto cmd = device->request_command_buffer(Vulkan::CommandBuffer::Type::AsyncCompute);
468483
pyrowave_encoder.encode(*cmd, views, pyrowave.buffers);
469484
cmd->barrier(VK_PIPELINE_STAGE_COMPUTE_SHADER_BIT, VK_ACCESS_2_SHADER_STORAGE_WRITE_BIT,
@@ -1335,42 +1350,17 @@ bool VideoEncoder::Impl::init_video_codec_av(const AVCodec *codec)
13351350
return true;
13361351
}
13371352

1338-
bool VideoEncoder::Impl::init_video_codec_pyrowave()
1353+
bool VideoEncoder::Impl::init_video_codec_pyrowave_buffers(unsigned bitrate_kbits)
13391354
{
1340-
if (!pyrowave_encoder.init(device, int(options.width), int(options.height),
1341-
format_needs_downsample(options.format) ?
1342-
PyroWave::ChromaSubsampling::Chroma420 :
1343-
PyroWave::ChromaSubsampling::Chroma444))
1344-
return false;
1345-
1346-
pyro_codec.video_codec = PYRO_VIDEO_CODEC_PYROWAVE;
1347-
pyro_codec.width = options.width;
1348-
pyro_codec.height = options.height;
1349-
pyro_codec.frame_rate_num = options.frame_timebase.den;
1350-
pyro_codec.frame_rate_den = options.frame_timebase.num;
1351-
1352-
if (format_needs_downsample(options.format))
1353-
{
1354-
pyro_codec.video_color_profile = options.hdr10 ?
1355-
PYRO_VIDEO_COLOR_BT2020NCL_PQ_FULL_CENTER_CHROMA_420 :
1356-
PYRO_VIDEO_COLOR_BT709_FULL_CENTER_CHROMA_420;
1357-
}
1358-
else
1359-
{
1360-
pyro_codec.video_color_profile = options.hdr10 ?
1361-
PYRO_VIDEO_COLOR_BT2020NCL_PQ_FULL_CHROMA_444 :
1362-
PYRO_VIDEO_COLOR_BT709_FULL_CHROMA_444;
1363-
}
1364-
1365-
pyrowave.payload_size = (1000ull * options.bitrate_kbits * options.frame_timebase.num) /
1355+
pyrowave.payload_size = (1000ull * bitrate_kbits * options.frame_timebase.num) /
13661356
(options.frame_timebase.den * 8);
13671357

13681358
pyrowave.payload_size &= ~3;
13691359

13701360
Vulkan::BufferCreateInfo bufinfo = {};
13711361
bufinfo.usage = VK_BUFFER_USAGE_STORAGE_BUFFER_BIT |
1372-
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
1373-
VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
1362+
VK_BUFFER_USAGE_TRANSFER_DST_BIT |
1363+
VK_BUFFER_USAGE_TRANSFER_SRC_BIT;
13741364

13751365
bufinfo.size = pyrowave.payload_size + pyrowave_encoder.get_meta_required_size();
13761366
bufinfo.domain = Vulkan::BufferDomain::Device;
@@ -1394,7 +1384,37 @@ bool VideoEncoder::Impl::init_video_codec_pyrowave()
13941384

13951385
pyrowave.bitstream.resize(pyrowave.payload_size);
13961386

1397-
return true;
1387+
return pyrowave.bitstream_gpu && pyrowave.bitstream_cpu && pyrowave.meta_gpu && pyrowave.meta_cpu;
1388+
}
1389+
1390+
bool VideoEncoder::Impl::init_video_codec_pyrowave()
1391+
{
1392+
if (!pyrowave_encoder.init(device, int(options.width), int(options.height),
1393+
format_needs_downsample(options.format) ?
1394+
PyroWave::ChromaSubsampling::Chroma420 :
1395+
PyroWave::ChromaSubsampling::Chroma444))
1396+
return false;
1397+
1398+
pyro_codec.video_codec = PYRO_VIDEO_CODEC_PYROWAVE;
1399+
pyro_codec.width = options.width;
1400+
pyro_codec.height = options.height;
1401+
pyro_codec.frame_rate_num = options.frame_timebase.den;
1402+
pyro_codec.frame_rate_den = options.frame_timebase.num;
1403+
1404+
if (format_needs_downsample(options.format))
1405+
{
1406+
pyro_codec.video_color_profile = options.hdr10 ?
1407+
PYRO_VIDEO_COLOR_BT2020NCL_PQ_FULL_CENTER_CHROMA_420 :
1408+
PYRO_VIDEO_COLOR_BT709_FULL_CENTER_CHROMA_420;
1409+
}
1410+
else
1411+
{
1412+
pyro_codec.video_color_profile = options.hdr10 ?
1413+
PYRO_VIDEO_COLOR_BT2020NCL_PQ_FULL_CHROMA_444 :
1414+
PYRO_VIDEO_COLOR_BT709_FULL_CHROMA_444;
1415+
}
1416+
1417+
return init_video_codec_pyrowave_buffers(options.bitrate_kbits);
13981418
}
13991419

14001420
bool VideoEncoder::Impl::init_video_codec_pyro(PyroEnc::Profile profile)
@@ -1940,6 +1960,11 @@ void VideoEncoder::process_rgb(Vulkan::CommandBuffer &cmd, YCbCrPipeline &pipeli
19401960
}
19411961
}
19421962

1963+
void VideoEncoder::update_bitrate_kbits(unsigned bitrate_kbits)
1964+
{
1965+
impl->update_bitrate_kbits.exchange(bitrate_kbits, std::memory_order_acq_rel);
1966+
}
1967+
19431968
bool VideoEncoder::encode_frame(YCbCrPipeline &pipeline_ptr, int64_t pts, int compensate_audio_us)
19441969
{
19451970
auto &pipeline = *pipeline_ptr;

video/ffmpeg_encode.hpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,9 @@ class VideoEncoder
125125

126126
bool encode_frame(YCbCrPipeline &pipeline, int64_t pts, int compensate_audio_us = 0);
127127

128+
// Only implemented for pyrowave atm, updates bitrate on the fly.
129+
void update_bitrate_kbits(unsigned bitrate_kbits);
130+
128131
private:
129132
struct Impl;
130133
std::unique_ptr<Impl> impl;

0 commit comments

Comments
 (0)