@@ -782,30 +782,102 @@ int cls_netcam::decode_packet()
782782
783783void 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