Skip to content

Commit

Permalink
Update to GCC 14.1.0
Browse files Browse the repository at this point in the history
  • Loading branch information
Kartatz committed Jun 15, 2024
1 parent dd448dc commit 3252f8a
Show file tree
Hide file tree
Showing 11 changed files with 219 additions and 7 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,7 @@ add_executable(
src/readlines.c
src/terminal.c
src/ffmpeg_muxer.c
src/ffmpegc_muxer.c
src/sslcerts.c
src/showformats.c
src/callbacks.c
Expand Down
122 changes: 122 additions & 0 deletions src/ffmpegc_muxer.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#include <stdlib.h>

#include "os.h"
#include "m3u8errors.h"
#include "ffmpegc_muxer.h"

static const char* const FFMPEG_DEFAULT_INPUT_FLAGS[] = {
"-y", "-nostdin", "-nostats", "-loglevel", "error"
};

static const char* const FFMPEG_DEFAULT_OUTPUT_FLAGS[] = {
"-map", "a",
"-c", "copy",
"-movflags", "+faststart",
"-max_interleave_delta", "0",
"-fflags", "+bitexact+autobsf"
};

int ffmpegc_mux_streams(char* const* const sources, const char* const destination) {

int err = M3U8ERR_SUCCESS;

char* executable = NULL;
char* command = NULL;
char**argv = NULL;

size_t index = 0;
size_t argvpos = 0;
size_t size = 0;
size_t argc = 0;

argc += sizeof(FFMPEG_DEFAULT_INPUT_FLAGS) / sizeof(*FFMPEG_DEFAULT_INPUT_FLAGS);
argc += sizeof(FFMPEG_DEFAULT_OUTPUT_FLAGS) / sizeof(*FFMPEG_DEFAULT_OUTPUT_FLAGS);

for (index = 0; 1; index++) {
const char* const item = sources[index];

if (item == NULL) {
break;
}
}

argc += 1; /* <command> */
argc += index * 2; /* -i <input> */
argc += 1; /* <output> */

executable = find_exe("ffmpeg");

if (executable == NULL) {
err = M3U8ERR_FFMPEG_COMMAND_NOT_FOUND;
goto end;
}

argv = malloc(sizeof(*argv) * argc);

if (argv == NULL) {
err = M3U8ERR_MEMORY_ALLOCATE_FAILURE;
goto end;
}

argv[argvpos++] = executable;

for (index = 0; index < sizeof(FFMPEG_DEFAULT_INPUT_FLAGS) / sizeof(*FFMPEG_DEFAULT_INPUT_FLAGS); index++) {
const char* const item = FFMPEG_DEFAULT_INPUT_FLAGS[index];
argv[argvpos++] = (char*) item;
}

for (index = 0; 1; index++) {
const char* const item = sources[index];

if (item == NULL) {
break;
}

argv[argvpos++] = "-i";
argv[argvpos++] = (char*) item;
}

for (index = 0; index < sizeof(FFMPEG_DEFAULT_OUTPUT_FLAGS) / sizeof(*FFMPEG_DEFAULT_OUTPUT_FLAGS); index++) {
const char* const item = FFMPEG_DEFAULT_OUTPUT_FLAGS[index];
argv[argvpos++] = (char*) item;
}

argv[argvpos++] = (char*) destination;

for (index = 0; index < argvpos; index++) {
const char* const arg = argv[index];
size += strlen(arg) + 1;
}

size += 1; /* \0 */

command = malloc(size);

if (command == NULL) {
err = M3U8ERR_MEMORY_ALLOCATE_FAILURE;
goto end;
}

command[0] = '\0';

for (index = 0; index < argvpos; index++) {
const char* const arg = argv[index];
strcat(command, arg);
strcat(command, " ");
}
puts(command);

if (execute_shell_command(command) != 0) {
err = M3U8ERR_FFMPEG_MUXING_FAILURE;
goto end;
}

end:;

free(executable);
free(argv);
free(command);

return err;

}
6 changes: 6 additions & 0 deletions src/ffmpegc_muxer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#if !defined(FFMPEGC_MUXER_H)
#define FFMPEGC_MUXER_H

int ffmpegc_mux_streams(char* const* const sources, const char* const destination);

#endif
2 changes: 2 additions & 0 deletions src/m3u8.c
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ The longest M3U8 tag name is 'EXT-X-DISCONTINUITY-SEQUENCE', which contains
#define M3U8_PLAYLIST_COMMENT 2
#define M3U8_PLAYLIST_URI 3

/* M3U8 tags. */
static const char M3U8K_EXTM3U[] = "EXTM3U";
static const char M3U8K_EXT_X_VERSION[] = "EXT-X-VERSION";
static const char M3U8K_EXTINF[] = "EXTINF";
Expand Down Expand Up @@ -103,6 +104,7 @@ static const char M3U8K_EXT_X_SKIP[] = "EXT-X-SKIP";
static const char M3U8K_EXT_X_PRELOAD_HINT[] = "EXT-X-PRELOAD-HINT";
static const char M3U8K_EXT_X_RENDITION_REPORT[] = "EXT-X-RENDITION-REPORT";

/* M3U8 attributes. */
static const char M3U8K_METHOD[] = "METHOD";
static const char M3U8K_URI[] = "URI";
static const char M3U8K_IV[] = "IV";
Expand Down
2 changes: 2 additions & 0 deletions src/m3u8errors.c
Original file line number Diff line number Diff line change
Expand Up @@ -211,6 +211,8 @@ const char* m3u8err_getmessage(const int code) {
return "Could not create the temporary directory";
case M3U8ERR_DOWNLOAD_COULD_NOT_MOVE_FILE:
return "Could not move file to specified location";
case M3U8ERR_FFMPEG_COMMAND_NOT_FOUND:
return "Could locate the FFmpeg executable";
default:
return "Unknown error code";
}
Expand Down
2 changes: 2 additions & 0 deletions src/m3u8errors.h
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,8 @@
#define M3U8ERR_TAG_NON_MATCHING_ATTRIBUTES -97 /* The attributes of this M3U8 tag do not match those of the other M3U8 tag with the same ID */
#define M3U8ERR_TAG_TRAILING_OPTIONS -98 /* This M3U8 tag does not require any value to be supplied, but trailing options were found */

#define M3U8ERR_FFMPEG_COMMAND_NOT_FOUND -99 /* Could locate the FFmpeg executable */

const char* m3u8err_getmessage(const int code);

#endif
35 changes: 29 additions & 6 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
#include <errno.h>

#include <curl/curl.h>
#include <libavutil/error.h>

#include "m3u8stream.h"
#include "m3u8types.h"
Expand All @@ -19,6 +20,7 @@
#include "os.h"
#include "sutils.h"
#include "ffmpeg_muxer.h"
#include "ffmpegc_muxer.h"
#include "terminal.h"
#include "pathsep.h"
#include "filesystem.h"
Expand Down Expand Up @@ -162,6 +164,7 @@ int main(int argc, argv_t* argv[]) {
int debug = 0;
int disable_autoselection = 0;
int disable_progress = 0;
int prefer_ffmpegc = 0;

int select_all_medias = 0;
int exists = 0;
Expand Down Expand Up @@ -604,6 +607,13 @@ int main(int argc, argv_t* argv[]) {
}

debug = 1;
} else if (strcmp(argument->key, "prefer-ffmpegc-muxer") == 0) {
if (prefer_ffmpegc) {
err = M3U8ERR_CLI_DUPLICATE_ARGUMENT;
goto end;
}

prefer_ffmpegc = 1;
} else if (strcmp(argument->key, "disable-autoselection") == 0) {
if (disable_autoselection) {
err = M3U8ERR_CLI_DUPLICATE_ARGUMENT;
Expand Down Expand Up @@ -992,11 +1002,20 @@ int main(int argc, argv_t* argv[]) {

printf("- Merging media streams into a single file at '%s'\n", temporary_file);

fferr = ffmpeg_mux_streams(downloaded_streams.items, temporary_file);

if (fferr < 0) {
err = M3U8ERR_FFMPEG_MUXING_FAILURE;
goto end;
if (prefer_ffmpegc) {
err = ffmpegc_mux_streams(downloaded_streams.items, temporary_file);

if (err != M3U8ERR_SUCCESS) {
fferr = AVERROR_INVALIDDATA;
goto end;
}
} else {
fferr = ffmpeg_mux_streams(downloaded_streams.items, temporary_file);

if (fferr < 0) {
err = M3U8ERR_FFMPEG_MUXING_FAILURE;
goto end;
}
}

fstream_close(output_stream);
Expand Down Expand Up @@ -1073,6 +1092,10 @@ int main(int argc, argv_t* argv[]) {

show_cursor();

return (err == M3U8ERR_SUCCESS) ? EXIT_SUCCESS : EXIT_FAILURE;
if (err != M3U8ERR_SUCCESS) {
return EXIT_FAILURE;
}

return EXIT_SUCCESS;

}
44 changes: 44 additions & 0 deletions src/os.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,50 @@ static const char* strip_trailing_separator(char* const s) {

}

int execute_shell_command(const char* const command) {
/*
Executes a shell command.
Returns the exit code for the command, which is (0) on success.
*/

int code = 0;

#if defined(_WIN32) && defined(_UNICODE)
wchar_t* wcommand = NULL;

const int wcommands = MultiByteToWideChar(CP_UTF8, 0, command, -1, NULL, 0);

if (wcommands == 0) {
return -1;
}

wcommand = malloc((size_t) wcommands);

if (wcommand == NULL) {
return -1;
}

if (MultiByteToWideChar(CP_UTF8, 0, command, -1, wcommand, wcommands) == 0) {
free(wcommand);
return -1;
}

code = _wsystem(wcommand);

free(wcommand);
#else
code = system(command);
#endif

#if defined(_WIN32)
code = WIFSIGNALED(code) ? 128 + WTERMSIG(code) : WEXITSTATUS(code);
#endif

return code;

}

#if !defined(__HAIKU__)
int is_administrator(void) {
/*
Expand Down
1 change: 1 addition & 0 deletions src/os.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
int is_administrator(void);
#endif

int execute_shell_command(const char* const command);
char* get_configuration_directory(void);
char* get_temporary_directory(void);
char* get_home_directory(void);
Expand Down
4 changes: 3 additions & 1 deletion src/program_help.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ This file is auto-generated. Use the ../tools/program_help.h.py tool to regenera
#define PROGRAM_HELP_H

#define PROGRAM_HELP \
"usage: kai [-h] [-v] -u URL [-k] [-A USER_AGENT] [-x URI] [--doh-url URL] [-e URL] [-r COUNT] [--debug] [-S] [--select-media MEDIA] [--select-stream VARIANT_STREAM] [--disable-autoselection] [--disable-progress-meter] [-c CONCURRENCY] -o FILENAME\n" \
"usage: kai [-h] [-v] -u URL [-k] [-A USER_AGENT] [-x URI] [--doh-url URL] [-e URL] [-r COUNT] [--debug] [-S] [--select-media MEDIA] [--select-stream VARIANT_STREAM] [--disable-autoselection] [--disable-progress-meter] [--prefer-ffmpegc-muxer] [-c CONCURRENCY] -o FILENAME\n" \
"\n" \
"A command-line utility to download contents from M3U8 playlists.\n" \
"\n" \
Expand All @@ -32,6 +32,8 @@ This file is auto-generated. Use the ../tools/program_help.h.py tool to regenera
" Avoid autoselection of streams based on predefined preferences set by the master playlist.\n" \
" --disable-progress-meter\n" \
" Disable showing download progress meter.\n" \
" --prefer-ffmpegc-muxer\n" \
" Prefer using the FFmpeg CLI tool instead of the builtin implementation when muxing media streams.\n" \
" -c CONCURRENCY, --concurrency CONCURRENCY\n" \
" Specify how many media segments should be downloaded simultaneously. Defaults to 1.\n" \
" -o FILENAME, --output FILENAME\n" \
Expand Down
7 changes: 7 additions & 0 deletions tools/program_help.h.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,13 @@
help = "Disable showing download progress meter."
)

parser.add_argument(
"--prefer-ffmpegc-muxer",
required = False,
action = "store_true",
help = "Prefer using the FFmpeg CLI tool instead of the builtin implementation when muxing media streams."
)

parser.add_argument(
"-c",
"--concurrency",
Expand Down

0 comments on commit 3252f8a

Please sign in to comment.