mirror of
https://github.com/kunkundi/crossdesk.git
synced 2025-10-27 04:35:34 +08:00
[feat] enable resolution downgrading
This commit is contained in:
49
src/media/resolution_adapter/resolution_adapter.cpp
Normal file
49
src/media/resolution_adapter/resolution_adapter.cpp
Normal file
@@ -0,0 +1,49 @@
|
||||
#include "resolution_adapter.h"
|
||||
|
||||
#include "libyuv.h"
|
||||
|
||||
int ResolutionAdapter::GetResolution(int target_bitrate, int current_width,
|
||||
int current_height, int& target_width,
|
||||
int& target_height) {
|
||||
for (auto& resolution : GetBitrateLimits()) {
|
||||
if (target_bitrate >= resolution.min_start_bitrate_bps &&
|
||||
target_bitrate <= resolution.max_bitrate_bps) {
|
||||
if (current_width * current_height <= resolution.frame_size_pixels) {
|
||||
target_width = current_width;
|
||||
target_height = current_height;
|
||||
return 0;
|
||||
} else {
|
||||
target_width = current_width * 3 / 5;
|
||||
target_height = current_height * 3 / 5;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int ResolutionAdapter::ResolutionDowngrade(const XVideoFrame* video_frame,
|
||||
int target_width, int target_height,
|
||||
XVideoFrame* new_frame) {
|
||||
if (target_width <= 0 || target_height <= 0) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
target_width = video_frame->width * 3 / 5;
|
||||
target_height = video_frame->height * 3 / 5;
|
||||
new_frame->width = target_width;
|
||||
new_frame->height = target_height;
|
||||
new_frame->data = new char[target_width * target_height * 3 / 2];
|
||||
|
||||
libyuv::NV12Scale((const uint8_t*)(video_frame->data), video_frame->width,
|
||||
(const uint8_t*)(video_frame->data +
|
||||
video_frame->width * video_frame->height),
|
||||
video_frame->width, video_frame->width, video_frame->height,
|
||||
(uint8_t*)(new_frame->data), target_width,
|
||||
(uint8_t*)(new_frame->data + target_width * target_height),
|
||||
target_width, target_width, target_height,
|
||||
libyuv::kFilterLinear);
|
||||
|
||||
return 0;
|
||||
}
|
||||
41
src/media/resolution_adapter/resolution_adapter.h
Normal file
41
src/media/resolution_adapter/resolution_adapter.h
Normal file
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-03-06
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RESOLUTION_ADAPTER_H_
|
||||
#define _RESOLUTION_ADAPTER_H_
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "resolution_bitrate_limits.h"
|
||||
#include "x.h"
|
||||
|
||||
class ResolutionAdapter {
|
||||
public:
|
||||
ResolutionAdapter() = default;
|
||||
~ResolutionAdapter() = default;
|
||||
|
||||
public:
|
||||
int GetResolution(int target_bitrate, int current_width, int current_height,
|
||||
int& target_width, int& target_height);
|
||||
|
||||
int ResolutionDowngrade(const XVideoFrame* video_frame, int target_width,
|
||||
int target_height, XVideoFrame* new_frame);
|
||||
|
||||
public:
|
||||
std::vector<ResolutionBitrateLimits> GetBitrateLimits() {
|
||||
return {{0 * 0, 0, 0, 0},
|
||||
{320 * 180, 0, 30000, 300000},
|
||||
{480 * 270, 300000, 30000, 500000},
|
||||
{640 * 360, 500000, 30000, 800000},
|
||||
{960 * 540, 800000, 30000, 1500000},
|
||||
{1280 * 720, 1500000, 30000, 2500000},
|
||||
{1920 * 1080, 2500000, 30000, 4000000}};
|
||||
}
|
||||
|
||||
int SetTargetBitrate(int bitrate);
|
||||
};
|
||||
|
||||
#endif
|
||||
27
src/media/resolution_adapter/resolution_bitrate_limits.h
Normal file
27
src/media/resolution_adapter/resolution_bitrate_limits.h
Normal file
@@ -0,0 +1,27 @@
|
||||
/*
|
||||
* @Author: DI JUNKUN
|
||||
* @Date: 2025-03-07
|
||||
* Copyright (c) 2025 by DI JUNKUN, All Rights Reserved.
|
||||
*/
|
||||
|
||||
#ifndef _RESOLUTION_BITRATE_LIMITS_H_
|
||||
#define _RESOLUTION_BITRATE_LIMITS_H_
|
||||
|
||||
struct ResolutionBitrateLimits {
|
||||
ResolutionBitrateLimits(int frame_size_pixels, int min_start_bitrate_bps,
|
||||
int min_bitrate_bps, int max_bitrate_bps)
|
||||
: frame_size_pixels(frame_size_pixels),
|
||||
min_start_bitrate_bps(min_start_bitrate_bps),
|
||||
min_bitrate_bps(min_bitrate_bps),
|
||||
max_bitrate_bps(max_bitrate_bps) {}
|
||||
int frame_size_pixels = 0;
|
||||
int min_start_bitrate_bps = 0;
|
||||
int min_bitrate_bps = 0;
|
||||
int max_bitrate_bps = 0;
|
||||
bool operator==(const ResolutionBitrateLimits& rhs) const;
|
||||
bool operator!=(const ResolutionBitrateLimits& rhs) const {
|
||||
return !(*this == rhs);
|
||||
}
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -44,7 +44,8 @@ int NvidiaVideoDecoder::Init() {
|
||||
return -1;
|
||||
}
|
||||
|
||||
decoder = new NvDecoder(cuContext, false, cudaVideoCodec_H264, true);
|
||||
decoder = new NvDecoder(cuContext, false, cudaVideoCodec_H264, true, false,
|
||||
nullptr, nullptr, false, 4096, 2160, 1000, false);
|
||||
|
||||
#ifdef SAVE_DECODED_NV12_STREAM
|
||||
file_nv12_ = fopen("decoded_nv12_stream.yuv", "w+b");
|
||||
|
||||
@@ -46,6 +46,12 @@ class AomAv1Encoder : public VideoEncoder {
|
||||
|
||||
int SetTargetBitrate(int bitrate);
|
||||
|
||||
int GetResolution(int& width, int& height) {
|
||||
width = frame_width_;
|
||||
height = frame_height_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetEncoderName() { return "AomAV1"; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -22,6 +22,12 @@ class NvidiaVideoEncoder : public VideoEncoder {
|
||||
|
||||
int SetTargetBitrate(int bitrate);
|
||||
|
||||
int GetResolution(int& width, int& height) {
|
||||
width = frame_width_;
|
||||
height = frame_height_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetEncoderName() { return "NvidiaH264"; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -367,6 +367,10 @@ int OpenH264Encoder::ForceIdr() {
|
||||
}
|
||||
|
||||
int OpenH264Encoder::SetTargetBitrate(int bitrate) {
|
||||
if (!openh264_encoder_) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
target_bitrate_ = bitrate;
|
||||
encoder_params_.iTargetBitrate = target_bitrate_;
|
||||
|
||||
|
||||
@@ -33,6 +33,12 @@ class OpenH264Encoder : public VideoEncoder {
|
||||
|
||||
int SetTargetBitrate(int bitrate);
|
||||
|
||||
int GetResolution(int& width, int& height) {
|
||||
width = frame_width_;
|
||||
height = frame_height_;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::string GetEncoderName() { return "OpenH264"; }
|
||||
|
||||
private:
|
||||
|
||||
@@ -24,6 +24,8 @@ class VideoEncoder {
|
||||
|
||||
virtual int SetTargetBitrate(int bitrate) = 0;
|
||||
|
||||
virtual int GetResolution(int& width, int& height) = 0;
|
||||
|
||||
virtual std::string GetEncoderName() = 0;
|
||||
|
||||
VideoEncoder() = default;
|
||||
|
||||
Reference in New Issue
Block a user