Skip to content

Commit ae70df1

Browse files
committed
dummy display: small refactor (fmt parse func)
+ missing includes + check codec array overflow
1 parent fd9821d commit ae70df1

File tree

1 file changed

+55
-41
lines changed

1 file changed

+55
-41
lines changed

src/video_display/dummy.c

Lines changed: 55 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,11 @@
3838
#include "config.h"
3939
#include "config_unix.h"
4040
#include "config_win32.h"
41+
42+
#include <assert.h>
43+
#include <stdlib.h>
44+
#include <string.h>
45+
4146
#include "debug.h"
4247
#include "host.h"
4348
#include "lib_common.h"
@@ -57,7 +62,7 @@ static const codec_t default_codecs[] = {I420, UYVY, YUYV, v210, R10k, R12L, RGB
5762
struct dummy_display_state {
5863
struct video_frame *f;
5964
codec_t codecs[VIDEO_CODEC_COUNT];
60-
int codec_count;
65+
size_t codec_count;
6166
int rgb_shift[3];
6267

6368
size_t dump_bytes;
@@ -67,72 +72,81 @@ struct dummy_display_state {
6772
int dump_to_file_skip_frames;
6873
};
6974

70-
static void *display_dummy_init(struct module *parent, const char *cfg, unsigned int flags)
71-
{
72-
UNUSED(parent), UNUSED(flags);
73-
if (strcmp(cfg, "help") == 0) {
74-
char desc[] = "Display " TBOLD("dummy") " only consumes the video without displaying it. A difference to avoiding "
75-
"display specification is that it forces decoding (otherwise it will be skipped altogether).\n\n"
76-
"Additionally, options " TBOLD("hexdump") " and " TBOLD("dump") " are available for debugging.\n\n";
77-
color_printf("%s", indent_paragraph(desc));
78-
struct key_val options[] = {
79-
{ "codec=<codec>[,<codec2>]", "force the use of a codec instead of default set" },
80-
{ "rgb_shift=<r>,<g>,<b>", "if using output codec RGBA, use specified shifts instead of default (" TOSTRING(DEFAULT_R_SHIFT) ", " TOSTRING(DEFAULT_G_SHIFT) ", " TOSTRING(DEFAULT_B_SHIFT) ")" },
81-
{ "dump[:skip=<n>][:oneshot][:raw]", "dump first frame to file dummy.<ext> (optionally skip <n> first frames); 'oneshot' - exit after dumping the picture; 'raw' - dump raw data" },
82-
{ "hexdump[=<n>]", "dump first n (default " TOSTRING(DEFAULT_DUMP_LEN) ") bytes of every frame in hexadecimal format" },
83-
{ NULL, NULL }
84-
};
85-
print_module_usage("-d dummy", options, NULL, 0);
86-
return INIT_NOERR;
87-
}
88-
struct dummy_display_state s = { .codec_count = sizeof default_codecs / sizeof default_codecs[0] };
89-
memcpy(s.codecs, default_codecs, sizeof default_codecs);
90-
int rgb_shift_init[] = DEFAULT_RGB_SHIFT_INIT;
91-
memcpy(s.rgb_shift, &rgb_shift_init, sizeof s.rgb_shift);
92-
char *ccpy = alloca(strlen(cfg) + 1);
93-
strcpy(ccpy, cfg);
75+
static _Bool dummy_parse_opts(struct dummy_display_state *s, char *fmt) {
9476
char *item = NULL;
9577
char *save_ptr = NULL;
96-
while ((item = strtok_r(ccpy, ":", &save_ptr)) != NULL) {
78+
while ((item = strtok_r(fmt, ":", &save_ptr)) != NULL) {
79+
fmt = NULL;
9780
if (strstr(item, "codec=") != NULL) {
9881
char *sptr = NULL;
9982
char *tok = NULL;
10083
char *str = strchr(item, '=') + 1;
101-
s.codec_count = 0;
84+
s->codec_count = 0;
10285
while ((tok = strtok_r(str, ",", &sptr))) {
10386
str = NULL;
104-
s.codecs[s.codec_count++] = get_codec_from_name(tok);
105-
if (s.codecs[s.codec_count - 1] == VIDEO_CODEC_NONE) {
87+
assert(s->codec_count < sizeof s->codecs / sizeof s->codecs[0]);
88+
s->codecs[s->codec_count++] = get_codec_from_name(tok);
89+
if (s->codecs[s->codec_count - 1] == VIDEO_CODEC_NONE) {
10690
log_msg(LOG_LEVEL_ERROR, MOD_NAME "Wrong codec spec: %s!\n", tok);
107-
return NULL;
91+
return 0;
10892
}
10993
}
11094
} else if (strstr(item, "dump") != NULL) {
111-
s.dump_to_file = 1;
95+
s->dump_to_file = 1;
11296
} else if (strstr(item, "hexdump") != NULL) {
11397
if (strstr(item, "hexdump=") != NULL) {
114-
s.dump_bytes = atoi(item + strlen("hexdump="));
98+
s->dump_bytes = atoi(item + strlen("hexdump="));
11599
} else {
116-
s.dump_bytes = DEFAULT_DUMP_LEN;
100+
s->dump_bytes = DEFAULT_DUMP_LEN;
117101
}
118102
} else if (strstr(item, "rgb_shift=") != NULL) {
119103
item += strlen("rgb_shift=");
120-
s.rgb_shift[0] = strtol(item, &item, 0);
104+
s->rgb_shift[0] = strtol(item, &item, 0);
121105
item += 1;
122-
s.rgb_shift[1] = strtol(item, &item, 0);
106+
s->rgb_shift[1] = strtol(item, &item, 0);
123107
item += 1;
124-
s.rgb_shift[2] = strtol(item, &item, 0);
108+
s->rgb_shift[2] = strtol(item, &item, 0);
125109
} else if (strstr(item, "skip=") != NULL) {
126-
s.dump_to_file_skip_frames = atoi(strchr(item, '=') + 1);
110+
s->dump_to_file_skip_frames = atoi(strchr(item, '=') + 1);
127111
} else if (strcmp(item, "oneshot") == 0) {
128-
s.oneshot = 1;
112+
s->oneshot = 1;
129113
} else if (strcmp(item, "raw") == 0) {
130-
s.raw = 1;
114+
s->raw = 1;
131115
} else {
132116
log_msg(LOG_LEVEL_ERROR, MOD_NAME "Unrecognized option: %s\n", item);
133-
return NULL;
117+
return 0;
134118
}
135-
ccpy = NULL;
119+
}
120+
return 1;
121+
}
122+
123+
static void *display_dummy_init(struct module *parent, const char *cfg, unsigned int flags)
124+
{
125+
UNUSED(parent), UNUSED(flags);
126+
if (strcmp(cfg, "help") == 0) {
127+
char desc[] = "Display " TBOLD("dummy") " only consumes the video without displaying it. A difference to avoiding "
128+
"display specification is that it forces decoding (otherwise it will be skipped altogether).\n\n"
129+
"Additionally, options " TBOLD("hexdump") " and " TBOLD("dump") " are available for debugging.\n\n";
130+
color_printf("%s", indent_paragraph(desc));
131+
struct key_val options[] = {
132+
{ "codec=<codec>[,<codec2>]", "force the use of a codec instead of default set" },
133+
{ "rgb_shift=<r>,<g>,<b>", "if using output codec RGBA, use specified shifts instead of default (" TOSTRING(DEFAULT_R_SHIFT) ", " TOSTRING(DEFAULT_G_SHIFT) ", " TOSTRING(DEFAULT_B_SHIFT) ")" },
134+
{ "dump[:skip=<n>][:oneshot][:raw]", "dump first frame to file dummy.<ext> (optionally skip <n> first frames); 'oneshot' - exit after dumping the picture; 'raw' - dump raw data" },
135+
{ "hexdump[=<n>]", "dump first n (default " TOSTRING(DEFAULT_DUMP_LEN) ") bytes of every frame in hexadecimal format" },
136+
{ NULL, NULL }
137+
};
138+
print_module_usage("-d dummy", options, NULL, 0);
139+
return INIT_NOERR;
140+
}
141+
struct dummy_display_state s = { .codec_count = sizeof default_codecs / sizeof default_codecs[0] };
142+
memcpy(s.codecs, default_codecs, sizeof default_codecs);
143+
int rgb_shift_init[] = DEFAULT_RGB_SHIFT_INIT;
144+
memcpy(s.rgb_shift, &rgb_shift_init, sizeof s.rgb_shift);
145+
char *ccpy = alloca(strlen(cfg) + 1);
146+
strcpy(ccpy, cfg);
147+
148+
if (!dummy_parse_opts(&s, ccpy)) {
149+
return NULL;
136150
}
137151

138152
struct dummy_display_state *ret = malloc(sizeof s);

0 commit comments

Comments
 (0)