6767
6868#include "audio/types.h"
6969#include "audio/utils.h"
70- #include "compat/net.h" // for ntohs
70+ #include "compat/c23.h" // IWYU pragma: keep
71+ #include "compat/endian.h" // for be16toh
7172#include "debug.h"
7273#include "host.h"
7374#include "lib_common.h"
@@ -340,7 +341,7 @@ static size_t testcard_load_from_file_pam(const char *filename, struct video_des
340341 uint16_t * in = (uint16_t * )(void * ) data ;
341342 uint16_t * out = (uint16_t * )(void * ) * in_file_contents ;
342343 for (size_t i = 0 ; i < (size_t ) info .width * info .height * 3 ; ++ i ) {
343- * out ++ = ntohs (* in ++ ) * ((1 <<16U ) / (info .maxval + 1 ));
344+ * out ++ = be16toh (* in ++ ) * ((1 <<16U ) / (info .maxval + 1 ));
344345 }
345346 } else {
346347 memcpy (* in_file_contents , data , data_len );
@@ -520,6 +521,37 @@ validate_settings(struct testcard_state *s, struct video_desc desc)
520521 return true;
521522}
522523
524+ static bool
525+ parse_size (struct video_desc * desc , const char * val )
526+ {
527+ // WIDTHxHEIGHT
528+ if (isdigit (val [0 ]) && strchr (val , 'x' ) != nullptr ) {
529+ char * endptr = nullptr ;
530+ desc -> width = strtol (val , & endptr , 10 );
531+ if (* endptr != 'x' ) {
532+ MSG (ERROR , "Excess width chars, got %s!\n" , val );
533+ return false;
534+ }
535+ endptr += 1 ;
536+ desc -> height = strtol (endptr , & endptr , 10 );
537+ if (* endptr != '\0' ) {
538+ MSG (ERROR , "Excess height chars, got %s!\n" , val );
539+ return false;
540+ }
541+ return true;
542+ }
543+
544+ // assuming eg. s=VGA -> set just size 640x480 (differs from mode=)
545+ struct video_desc size_dsc = get_video_desc_from_string (val );
546+ desc -> width = size_dsc .width ;
547+ desc -> height = size_dsc .height ;
548+ if (size_dsc .width * size_dsc .height == 0 ) {
549+ MSG (ERROR , "Wrong size of video mode: %s!\n" , val );
550+ return false;
551+ }
552+ return true;
553+ }
554+
523555static int vidcap_testcard_init (const struct vidcap_params * params , void * * state )
524556{
525557 struct testcard_state * s = NULL ;
@@ -555,6 +587,10 @@ static int vidcap_testcard_init(const struct vidcap_params *params, void **state
555587
556588 tmp = strtok_r (ptr , ":" , & save_ptr );
557589 while (tmp ) {
590+ char * val = strchr (tmp , '=' );
591+ if (val != nullptr ) {
592+ val += 1 ;
593+ }
558594 if (strcmp (tmp , "p" ) == 0 ) {
559595 s -> pan = 48 ;
560596 } else if (strcmp (tmp , "i" ) == 0 ) {
@@ -566,47 +602,34 @@ static int vidcap_testcard_init(const struct vidcap_params *params, void **state
566602 } else if (strcmp (tmp , "still" ) == 0 ) {
567603 s -> still_image = true;
568604 } else if (IS_KEY_PREFIX (tmp , "pattern" )) {
569- const char * pattern = strchr (tmp , '=' ) + 1 ;
570- strncpy (s -> pattern , pattern , sizeof s -> pattern - 1 );
605+ strcpy_ch (s -> pattern , val );
571606 } else if (IS_KEY_PREFIX (tmp , "codec" )) {
572- desc .color_spec = get_codec_from_name (strchr ( tmp , '=' ) + 1 );
607+ desc .color_spec = get_codec_from_name (val );
573608 if (desc .color_spec == VIDEO_CODEC_NONE ) {
574- log_msg ( LOG_LEVEL_ERROR , MOD_NAME "Wrong color spec: %s\n" , strchr ( tmp , '=' ) + 1 );
609+ MSG ( ERROR , "Wrong color spec: %s\n" , val );
575610 goto error ;
576611 }
577612 } else if (IS_KEY_PREFIX (tmp , "mode" )) {
578613 codec_t saved_codec = desc .color_spec ;
579- desc = get_video_desc_from_string (strchr ( tmp , '=' ) + 1 );
614+ desc = get_video_desc_from_string (val );
580615 desc .color_spec = saved_codec ;
581616 } else if (IS_KEY_PREFIX (tmp , "size" )) {
582- if (!strncmp (tmp , "s=" , 2 )) {
583- MSG (WARNING , "parameter s= denotes now size "
584- "(not strip)\n" );
585- }
586- tmp = strchr (tmp , '=' ) + 1 ;
587- if (isdigit (tmp [0 ]) && strchr (tmp , 'x' ) != NULL ) {
588- desc .width = atoi (tmp );
589- desc .height = atoi (strchr (tmp , 'x' ) + 1 );
590- } else {
591- struct video_desc size_dsc =
592- get_video_desc_from_string (tmp );
593- desc .width = size_dsc .width ;
594- desc .height = size_dsc .height ;
617+ if (!parse_size (& desc , val )) {
618+ goto error ;
595619 }
596620 } else if (IS_KEY_PREFIX (tmp , "strip" )) {
597- strip_fmt = strchr ( tmp , '=' ) + 1 ;
621+ strip_fmt = val ;
598622 } else if (IS_KEY_PREFIX (tmp , "fps" )) {
599- if (!parse_fps (strchr ( tmp , '=' ) + 1 , & desc )) {
623+ if (!parse_fps (val , & desc )) {
600624 goto error ;
601625 }
602626 } else if (IS_KEY_PREFIX (tmp , "file" )) {
603- filename = strchr ( tmp , '=' ) + 1 ;
627+ filename = val ;
604628 } else if (strstr (tmp , "afrequency=" ) == tmp ) {
605- s -> audio_frequency = atoi (strchr ( tmp , '=' ) + 1 );
629+ s -> audio_frequency = atoi (val );
606630 } else if (IS_KEY_PREFIX (tmp , "frames" )) {
607631 char * endptr = NULL ;
608- s -> capture_frames =
609- strtoll (strchr (tmp , '=' ) + 1 , & endptr , 0 );
632+ s -> capture_frames = strtoll (val , & endptr , 0 );
610633 if (* endptr == 'q' ) {
611634 s -> quit_after_capture_frames = true;
612635 }
@@ -653,7 +676,11 @@ static int vidcap_testcard_init(const struct vidcap_params *params, void **state
653676 get_bits_per_component (s -> frame -> color_spec ), s -> pattern , (s -> grab_audio ? "on" : "off" ));
654677
655678 if (strip_fmt != NULL ) {
656- log_msg (LOG_LEVEL_ERROR , "Multi-tile testcard (stripping) is currently broken, you can use eg. \"-t aggregate -t testcard[args] -t testcard[args]\" instead!\n" );
679+ MSG (ERROR , "Multi-tile testcard (strip=) is currently "
680+ "deprecated!\n" );
681+ MSG (ERROR , "You can use eg. \"-F split:2:2 -t testcard[args]\" "
682+ "instead (alternatively vcap/aggregate with "
683+ "multiple testcards).\n" );
657684 goto error ;
658685#if 0
659686 if (configure_tiling (s , strip_fmt ) != 0 ) {
0 commit comments