Skip to content

Commit 7159691

Browse files
committed
Change default to use a hardware decoder for netcams if available
1 parent 9e6a404 commit 7159691

1 file changed

Lines changed: 99 additions & 31 deletions

File tree

src/netcam.cpp

Lines changed: 99 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -782,30 +782,102 @@ int cls_netcam::decode_packet()
782782

783783
void cls_netcam::hwdecoders()
784784
{
785+
AVBufferRef *hw_test_ctx = nullptr;
786+
int indx;
787+
785788
/* High Res pass through does not decode images into frames*/
786-
if (high_resolution && passthrough) {
789+
if ((high_resolution && passthrough) || (first_image == false) ||
790+
(decoder_nm != "DEFAULT")) {
787791
return;
788792
}
789-
if ((hw_type == AV_HWDEVICE_TYPE_NONE) && (first_image)) {
793+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
794+
,_("%s:Testing for hardware decoders")
795+
, cameratype.c_str());
796+
797+
/* Use VAAPI if available*/
798+
if (av_hwdevice_find_type_by_name("vaapi") == AV_HWDEVICE_TYPE_NONE) {
790799
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
791-
,_("%s:HW Devices:")
800+
,_("%s:vaapi hardware decoding is not available")
792801
, cameratype.c_str());
793-
while((hw_type = av_hwdevice_iterate_types(hw_type)) != AV_HWDEVICE_TYPE_NONE){
794-
if ((hw_type == AV_HWDEVICE_TYPE_VAAPI) ||
795-
(hw_type == AV_HWDEVICE_TYPE_CUDA) ||
796-
(hw_type == AV_HWDEVICE_TYPE_DRM)) {
802+
} else {
803+
if (av_hwdevice_ctx_create(&hw_device_ctx
804+
, AV_HWDEVICE_TYPE_VAAPI, NULL, NULL, 0) == 0) {
805+
decoder_nm = "VAAPI";
806+
} else {
807+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
808+
,_("%s:vaapi hardware decoding is not available")
809+
, cameratype.c_str());
810+
}
811+
if (hw_test_ctx != nullptr) {
812+
av_buffer_unref(&hw_device_ctx);
813+
hw_test_ctx = nullptr;
814+
}
815+
}
816+
817+
/* If still default, use CUDA if available*/
818+
if (decoder_nm == "DEFAULT") {
819+
if (av_hwdevice_find_type_by_name("cuda") == AV_HWDEVICE_TYPE_NONE) {
820+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
821+
,_("%s:cuda hardware decoding is not available")
822+
, cameratype.c_str());
823+
} else {
824+
if (av_hwdevice_ctx_create(&hw_device_ctx
825+
, AV_HWDEVICE_TYPE_CUDA, NULL, NULL, 0) == 0) {
826+
decoder_nm = "CUDA";
827+
} else {
797828
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
798-
,_("%s: %s(available)")
799-
, cameratype.c_str()
800-
, av_hwdevice_get_type_name(hw_type));
829+
,_("%s:cuda hardware decoding is not available")
830+
, cameratype.c_str());
831+
}
832+
if (hw_test_ctx != nullptr) {
833+
av_buffer_unref(&hw_device_ctx);
834+
hw_test_ctx = nullptr;
835+
}
836+
}
837+
}
838+
839+
/* If still default, use DRM if available*/
840+
if (decoder_nm == "DEFAULT") {
841+
if (av_hwdevice_find_type_by_name("drm") == AV_HWDEVICE_TYPE_NONE) {
842+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
843+
,_("%s:drm hardware decoding is not available")
844+
, cameratype.c_str());
845+
} else {
846+
if (av_hwdevice_ctx_create(&hw_device_ctx
847+
, AV_HWDEVICE_TYPE_DRM, NULL, NULL, 0) == 0) {
848+
decoder_nm = "DRM";
801849
} else {
802850
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
803-
,_("%s: %s(not implemented)")
804-
, cameratype.c_str()
805-
, av_hwdevice_get_type_name(hw_type));
851+
,_("%s:drm hardware decoding is not available")
852+
, cameratype.c_str());
853+
}
854+
if (hw_test_ctx != nullptr) {
855+
av_buffer_unref(&hw_device_ctx);
856+
hw_test_ctx = nullptr;
806857
}
807858
}
808859
}
860+
861+
/* If still default, use Software*/
862+
if (decoder_nm == "DEFAULT") {
863+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
864+
,_("%s:No hardware decoders available. Using software decoding")
865+
, cameratype.c_str());
866+
decoder_nm = "SW";
867+
} else {
868+
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
869+
,_("%s:Using %s hardware decoder.")
870+
, cameratype.c_str(), decoder_nm.c_str());
871+
}
872+
873+
/* Update parms_array and config line*/
874+
for (indx=0;indx<params->params_cnt;indx++) {
875+
if (params->params_array[indx].param_name == "decoder") {
876+
params->params_array[indx].param_value = decoder_nm;
877+
break;
878+
}
879+
}
880+
util_parms_update(params, cfg_params);
809881
return;
810882
}
811883

@@ -835,19 +907,19 @@ void cls_netcam::decoder_error(int retcd, const char* fnc_nm)
835907
,_("%s:Decoder %s did not work.")
836908
,cameratype.c_str(), decoder_nm.c_str());
837909
MOTION_LOG(NTC, TYPE_NETCAM, NO_ERRNO
838-
,_("%s:Ignoring and removing the user requested decoder %s")
910+
,_("%s:Ignoring requested decoder %s")
839911
,cameratype.c_str(), decoder_nm.c_str());
840912

841913
for (indx=0;indx<params->params_cnt;indx++) {
842914
if (params->params_array[indx].param_name == "decoder") {
843-
params->params_array[indx].param_value = "NULL";
915+
params->params_array[indx].param_value = "SW";
844916
break;
845917
}
846918
}
847919

848920
util_parms_update(params, cfg_params);
849-
850-
decoder_nm = "NULL";
921+
hw_type = AV_HWDEVICE_TYPE_NONE;
922+
decoder_nm = "SW";
851923
}
852924
}
853925

@@ -1054,7 +1126,7 @@ int cls_netcam::init_swdecoder()
10541126
MOTION_LOG(INF, TYPE_NETCAM, NO_ERRNO
10551127
,_("%s:Initializing decoder"),cameratype.c_str());
10561128

1057-
if (decoder_nm != "NULL") {
1129+
if (decoder_nm != "SW") {
10581130
decoder = avcodec_find_decoder_by_name(
10591131
decoder_nm.c_str());
10601132
if (decoder == nullptr) {
@@ -1123,18 +1195,15 @@ int cls_netcam::open_codec()
11231195

11241196
if (decoder_nm == "vaapi") {
11251197
if (init_vaapi() < 0) {
1126-
decoder_error(retcd, "hwvaapi_init");
1127-
return -1;
1198+
init_swdecoder();
11281199
}
11291200
} else if (decoder_nm == "cuda"){
1130-
if (init_cuda() <0 ) {
1131-
decoder_error(retcd, "hwcuda_init");
1132-
return -1;
1201+
if (init_cuda() < 0 ) {
1202+
init_swdecoder();
11331203
}
11341204
} else if (decoder_nm == "drm"){
11351205
if (init_drm() < 0) {;
1136-
decoder_error(retcd, "hwdrm_init");
1137-
return -1;
1206+
init_swdecoder();
11381207
}
11391208
} else {
11401209
init_swdecoder();
@@ -1694,7 +1763,7 @@ void cls_netcam::set_parms ()
16941763
, cameratype.c_str(), camera_name.c_str());
16951764

16961765
status = NETCAM_NOTCONNECTED;
1697-
util_parms_add_default(params,"decoder","NULL");
1766+
util_parms_add_default(params,"decoder","DEFAULT");
16981767
img_recv =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff));
16991768
img_recv->ptr =(char*) mymalloc(NETCAM_BUFFSIZE);
17001769
img_latest =(netcam_buff_ptr) mymalloc(sizeof(netcam_buff));
@@ -1881,15 +1950,14 @@ int cls_netcam::open_context()
18811950
retcd = open_codec();
18821951
mythreadname_set(nullptr, 0, threadname.c_str());
18831952
if ((retcd < 0) || (interrupted) || (handler_stop) ) {
1884-
av_strerror(retcd, errstr, sizeof(errstr));
18851953
if (status == NETCAM_NOTCONNECTED) {
18861954
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO
1887-
,_("%s:Unable to open codec context:%s")
1888-
,cameratype.c_str(), errstr);
1955+
,_("%s:Unable to open codec context")
1956+
,cameratype.c_str());
18891957
} else {
18901958
MOTION_LOG(ERR, TYPE_NETCAM, NO_ERRNO
1891-
,_("%s:Connected and unable to open codec context:%s")
1892-
,cameratype.c_str(), errstr);
1959+
,_("%s:Connected and unable to open codec context")
1960+
,cameratype.c_str());
18931961
}
18941962
context_close();
18951963
return -1;

0 commit comments

Comments
 (0)