Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
12 changes: 12 additions & 0 deletions libcam/libcam/camview.c
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,8 @@ static int statusForceGles = 0; //forceGles 1,强走GLES

static int is_pgux = 0; //是否是pugx

static int hw_encode_status = 0; //是否开启硬编(卓怡 NL60R 定制)

static char libva_driver_name[200];

static char libvdpau_driver_name[200];
Expand Down Expand Up @@ -1427,6 +1429,16 @@ int get_pugx_status()
return is_pgux;
}

void set_hw_encode_status(int status)
{
hw_encode_status = status;
}

int get_hw_encode_status()
{
return hw_encode_status;
}

void set_project_id(const char *id)
{
if (id != NULL) {
Expand Down
24 changes: 24 additions & 0 deletions libcam/libcam/camview.h
Original file line number Diff line number Diff line change
Expand Up @@ -436,6 +436,30 @@ void set_pugx_status(int status);

int get_pugx_status();

/*
* set hardware encode status (project customization, only for 卓怡 NL60R)
* args:
* status - 1 to enable VAAPI hardware encode, 0 to keep software encode
*
* asserts:
* none
*
* returns: none
*/
void set_hw_encode_status(int status);

/*
* get hardware encode status
* args:
* none
*
* asserts:
* none
*
* returns: 1 if hardware encode enabled, 0 otherwise
*/
int get_hw_encode_status();

void set_forceGles(int status);

int is_forceGles();
Expand Down
44 changes: 28 additions & 16 deletions libcam/libcam_encoder/encoder.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,13 @@
/* support for internationalization - i18n */
#include <locale.h>
#include <libintl.h>
#include <pciaccess.h>

Check warning on line 46 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <pciaccess.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include <va/va.h>

Check warning on line 48 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <va/va.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <va/va_x11.h>

Check warning on line 49 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <va/va_x11.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#include "cameraconfig.h"

Check warning on line 51 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "cameraconfig.h" not found.
#include "core_time.h"

Check warning on line 52 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: "core_time.h" not found.
#include "gviewencoder.h"
#include "encoder.h"
#include "stream_io.h"
Expand Down Expand Up @@ -2308,15 +2309,19 @@
static encoder_video_context_t *encoder_video_init_vaapi(encoder_context_t *encoder_ctx)
{
struct pci_device_iterator *iter;
int ret;

Check warning on line 2312 in libcam/libcam_encoder/encoder.c

View workflow job for this annotation

GitHub Actions / cppcheck

Unused variable: ret
is_vaapi = HW_VAAPI_OK;

if(!check_vaapi_support())
{
is_vaapi = HW_VAAPI_FAIL1;
/*
* 仅对开启硬编的定制机型(卓怡 NL60R,DConfig: hwEncodeStatus=true)跳过 check_vaapi_support():
* 该探测与下面的 av_hwdevice_ctx_create 重复,且部分 VA 驱动对 vaQueryConfigProfiles(NULL)
* 空列表处理不当会崩溃;其余机型完全保持原有逻辑:check_vaapi_support() 恒失败 -> 软编。
*/
if (!get_hw_encode_status() && !check_vaapi_support()) {
is_vaapi = HW_VAAPI_FAIL1;
fprintf(stderr, "no gpu card for vaapi\n");
return NULL;
}
}

//assertions
assert(encoder_ctx != NULL);
Expand Down Expand Up @@ -2368,7 +2373,20 @@
}


int err = getAvutil()->m_av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
/*
* 先用 FFmpeg 默认后端(多数平台走 DRM),失败再回退 X11 后端
* (部分 VA 驱动只实现了 X11 后端,DRM 会 init 失败)。
*/
int err = getAvutil()->m_av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0);
if (err < 0) {
getAvutil()->m_av_buffer_unref(&hw_device_ctx);
AVDictionary *hwopts = NULL;
if (getAvutil()->m_av_dict_set)
getAvutil()->m_av_dict_set(&hwopts, "connection_type", "x11", 0);
err = getAvutil()->m_av_hwdevice_ctx_create(&hw_device_ctx, AV_HWDEVICE_TYPE_VAAPI, NULL, hwopts, 0);
if (getAvutil()->m_av_dict_free)
getAvutil()->m_av_dict_free(&hwopts);
}
if (err < 0) {
fprintf(stderr, "Failed to create a VAAPI device. Error code: %s\n", vm_err22str(err));
is_vaapi = HW_VAAPI_FAIL5;
Expand Down Expand Up @@ -2509,24 +2527,18 @@

/* open codec*/
if ((ret = getLoadLibsInstance()->m_avcodec_open2(video_codec_data->codec_context,video_codec_data->codec,&video_codec_data->private_options)) < 0){
fprintf(stderr, "ENCODER: could not open video codec (%s): %i - using raw input\n", video_defaults->codec_name, ret);
/* VAAPI 编码器无法打开(例如该设备 VAAPI 只有解码、没有 H264 编码入口)。
* 直接返回 NULL,由 encoder_init() 回退到软件编码(encoder_video_init),与 FAIL8 一致;
* 这里不能再调用 encoder_set_raw_video_input():它会把 video_codec_ind 置为 0(raw),
* 使回退退化成“raw 直通”,导致封装异常/崩溃。 */
fprintf(stderr, "ENCODER: could not open VAAPI video codec: %i - fallback to software\n", ret);
free(video_codec_data->codec_context);
video_codec_data->codec_context = NULL;
video_codec_data->codec = 0;
/*we will use raw data so free the codec data*/
free(video_codec_data);
video_defaults = encoder_get_video_codec_defaults(0);
encoder_set_raw_video_input(encoder_ctx, video_defaults);

//alloc outbuf
if(enc_video_ctx->outbuf_size <= 0)
enc_video_ctx->outbuf_size = 240000;//1792
if(enc_video_ctx->outbuf != NULL)
free(enc_video_ctx->outbuf);
is_vaapi = HW_VAAPI_FAIL9;
getAvutil()->m_av_buffer_unref(&hw_device_ctx);
fprintf(stderr, "FAIL to encoder_video_init_vaapi:%d.\n", is_vaapi);
free(video_codec_data);
return NULL;
}

Expand Down
1 change: 1 addition & 0 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,7 @@ pkg_check_modules(3rd_lib REQUIRED
pciaccess
libva
libva-x11
x11
# libv4l2
# libudev
# libusb-1.0
Expand Down
10 changes: 10 additions & 0 deletions src/assets/org.deepin.camera.encode.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,16 @@
"permissions": "readwrite",
"visibility": "private"
},
"hwEncodeStatus": {
"value": false,
"serial": 0,
"flags": ["global"],
"name": "enable hardware encode",
"name[zh_CN]": "启用硬件编码",
"description": "Whether to enable VAAPI hardware encoding (project customization, currently only for 卓怡 NL60R)",
"permissions": "readwrite",
"visibility": "private"
},
"libVaDriverName": {
"value": "",
"serial": 0,
Expand Down
19 changes: 19 additions & 0 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,10 @@
#include <QVector>

#include <unistd.h>
#include <fcntl.h>

Check warning on line 37 in src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <fcntl.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <stdio.h>

Check warning on line 38 in src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <stdio.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <csignal>

Check warning on line 39 in src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <csignal> not found. Please note: Cppcheck does not need standard library headers to get proper results.
#include <X11/Xlib.h>

Check warning on line 40 in src/main.cpp

View workflow job for this annotation

GitHub Actions / cppcheck

Include file: <X11/Xlib.h> not found. Please note: Cppcheck does not need standard library headers to get proper results.

#ifndef DEEPIN_CAMERA_PRO
#include "config.h"
Expand Down Expand Up @@ -111,6 +112,24 @@

int main(int argc, char *argv[])
{
// 硬编定制开关:仅卓怡 NL60R 通过 os-config 下发的 DConfig override 将其置为 true。
// 只有开启时才尝试 VAAPI 硬编并开启 Xlib 线程安全;其余机型行为完全不变。
bool hwEncodeEnabled = false;
#ifdef DTKCORE_CLASS_DConfigFile
{
DConfig *encodeCfg = DConfig::create("org.deepin.camera", "org.deepin.camera.encode");
if (encodeCfg && encodeCfg->isValid() && encodeCfg->keyList().contains("hwEncodeStatus")) {
hwEncodeEnabled = encodeCfg->value("hwEncodeStatus").toBool();
}
}
#endif
set_hw_encode_status(hwEncodeEnabled ? 1 : 0);
if (hwEncodeEnabled) {
// 编码子线程会经 libva-x11 调用 XOpenDisplay;
// 必须在任何 Xlib/Qt 使用之前开启 Xlib 线程安全,否则子线程里 XOpenDisplay 返回 NULL。
XInitThreads();
}

// 将日志配置提前,以确保所有日志没有遗漏
//qputenv("QT_LOGGING_RULES", "*.debug=true;*.info=true");
DLogManager::registerConsoleAppender();
Expand Down
Loading