New upstream version 26.1.0+dfsg1
This commit is contained in:
parent
040dcc3fc2
commit
013818c4af
594 changed files with 19576 additions and 4478 deletions
|
|
@ -1,5 +1,9 @@
|
|||
project(obs-ffmpeg-mux)
|
||||
|
||||
if(DEBUG_FFMPEG_MUX)
|
||||
add_definitions(-DDEBUG_FFMPEG)
|
||||
endif()
|
||||
|
||||
find_package(FFmpeg REQUIRED
|
||||
COMPONENTS avcodec avutil avformat)
|
||||
include_directories(${FFMPEG_INCLUDE_DIRS})
|
||||
|
|
@ -15,6 +19,7 @@ add_executable(obs-ffmpeg-mux
|
|||
${obs-ffmpeg-mux_HEADERS})
|
||||
|
||||
target_link_libraries(obs-ffmpeg-mux
|
||||
libobs
|
||||
${FFMPEG_LIBRARIES})
|
||||
|
||||
set_target_properties(obs-ffmpeg-mux PROPERTIES FOLDER "plugins/obs-ffmpeg")
|
||||
|
|
|
|||
|
|
@ -22,13 +22,17 @@
|
|||
|
||||
#endif
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "ffmpeg-mux.h"
|
||||
|
||||
#include <util/dstr.h>
|
||||
#include <libavformat/avformat.h>
|
||||
|
||||
#define ANSI_COLOR_RED "\x1b[0;91m"
|
||||
#define ANSI_COLOR_MAGENTA "\x1b[0;95m"
|
||||
#define ANSI_COLOR_RESET "\x1b[0m"
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 58
|
||||
#define CODEC_FLAG_GLOBAL_H AV_CODEC_FLAG_GLOBAL_HEADER
|
||||
#else
|
||||
|
|
@ -37,6 +41,8 @@
|
|||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static char *global_stream_key = "";
|
||||
|
||||
struct resize_buf {
|
||||
uint8_t *buf;
|
||||
size_t size;
|
||||
|
|
@ -70,6 +76,8 @@ static inline void resize_buf_free(struct resize_buf *rb)
|
|||
|
||||
struct main_params {
|
||||
char *file;
|
||||
/* printable_file is file with any stream key information removed */
|
||||
struct dstr printable_file;
|
||||
int has_video;
|
||||
int tracks;
|
||||
char *vcodec;
|
||||
|
|
@ -172,6 +180,8 @@ static void ffmpeg_mux_free(struct ffmpeg_mux *ffm)
|
|||
free(ffm->audio);
|
||||
}
|
||||
|
||||
dstr_free(&ffm->params.printable_file);
|
||||
|
||||
memset(ffm, 0, sizeof(*ffm));
|
||||
}
|
||||
|
||||
|
|
@ -218,6 +228,44 @@ static bool get_audio_params(struct audio_params *audio, int *argc,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void ffmpeg_log_callback(void *param, int level, const char *format,
|
||||
va_list args)
|
||||
{
|
||||
#ifdef DEBUG_FFMPEG
|
||||
char out_buffer[4096];
|
||||
struct dstr out = {0};
|
||||
|
||||
vsnprintf(out_buffer, sizeof(out_buffer), format, args);
|
||||
dstr_copy(&out, out_buffer);
|
||||
dstr_replace(&out, global_stream_key, "{stream_key}");
|
||||
|
||||
switch (level) {
|
||||
case AV_LOG_INFO:
|
||||
fprintf(stdout, "info: [ffmpeg_muxer] %s", out.array);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
case AV_LOG_WARNING:
|
||||
fprintf(stdout, "%swarning: [ffmpeg_muxer] %s%s",
|
||||
ANSI_COLOR_MAGENTA, out.array, ANSI_COLOR_RESET);
|
||||
fflush(stdout);
|
||||
break;
|
||||
|
||||
case AV_LOG_ERROR:
|
||||
fprintf(stderr, "%serror: [ffmpeg_muxer] %s%s", ANSI_COLOR_RED,
|
||||
out.array, ANSI_COLOR_RESET);
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
dstr_free(&out);
|
||||
#else
|
||||
UNUSED_PARAMETER(level);
|
||||
UNUSED_PARAMETER(format);
|
||||
UNUSED_PARAMETER(args);
|
||||
#endif
|
||||
UNUSED_PARAMETER(param);
|
||||
}
|
||||
|
||||
static bool init_params(int *argc, char ***argv, struct main_params *params,
|
||||
struct audio_params **p_audio)
|
||||
{
|
||||
|
|
@ -287,6 +335,16 @@ static bool init_params(int *argc, char ***argv, struct main_params *params,
|
|||
|
||||
*p_audio = audio;
|
||||
|
||||
dstr_copy(¶ms->printable_file, params->file);
|
||||
|
||||
get_opt_str(argc, argv, &global_stream_key, "stream key");
|
||||
if (strcmp(global_stream_key, "") != 0) {
|
||||
dstr_replace(¶ms->printable_file, global_stream_key,
|
||||
"{stream_key}");
|
||||
}
|
||||
|
||||
av_log_set_callback(ffmpeg_log_callback);
|
||||
|
||||
get_opt_str(argc, argv, ¶ms->muxer_settings, "muxer settings");
|
||||
|
||||
return true;
|
||||
|
|
@ -353,6 +411,10 @@ static void create_video_stream(struct ffmpeg_mux *ffm)
|
|||
(AVRational){ffm->params.fps_den, ffm->params.fps_num};
|
||||
|
||||
ffm->video_stream->time_base = context->time_base;
|
||||
#if LIBAVFORMAT_VERSION_MAJOR < 59
|
||||
// codec->time_base may still be used if LIBAVFORMAT_VERSION_MAJOR < 59
|
||||
ffm->video_stream->codec->time_base = context->time_base;
|
||||
#endif
|
||||
ffm->video_stream->avg_frame_rate = av_inv_q(context->time_base);
|
||||
|
||||
if (ffm->output->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
|
|
@ -521,7 +583,8 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
AVIO_FLAG_WRITE);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Couldn't open '%s', %s\n",
|
||||
ffm->params.file, av_err2str(ret));
|
||||
ffm->params.printable_file.array,
|
||||
av_err2str(ret));
|
||||
return FFM_ERROR;
|
||||
}
|
||||
}
|
||||
|
|
@ -548,8 +611,8 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
|
||||
ret = avformat_write_header(ffm->output, &dict);
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "Error opening '%s': %s\n", ffm->params.file,
|
||||
av_err2str(ret));
|
||||
fprintf(stderr, "Error opening '%s': %s",
|
||||
ffm->params.printable_file.array, av_err2str(ret));
|
||||
|
||||
av_dict_free(&dict);
|
||||
|
||||
|
|
@ -564,29 +627,43 @@ static inline int open_output_file(struct ffmpeg_mux *ffm)
|
|||
#define SRT_PROTO "srt"
|
||||
#define UDP_PROTO "udp"
|
||||
#define TCP_PROTO "tcp"
|
||||
#define HTTP_PROTO "http"
|
||||
|
||||
static bool ffmpeg_mux_is_network(struct ffmpeg_mux *ffm)
|
||||
{
|
||||
return !strncmp(ffm->params.file, SRT_PROTO, sizeof(SRT_PROTO) - 1) ||
|
||||
!strncmp(ffm->params.file, UDP_PROTO, sizeof(UDP_PROTO) - 1) ||
|
||||
!strncmp(ffm->params.file, TCP_PROTO, sizeof(TCP_PROTO) - 1) ||
|
||||
!strncmp(ffm->params.file, HTTP_PROTO, sizeof(HTTP_PROTO) - 1);
|
||||
}
|
||||
|
||||
static int ffmpeg_mux_init_context(struct ffmpeg_mux *ffm)
|
||||
{
|
||||
AVOutputFormat *output_format;
|
||||
int ret;
|
||||
bool isNetwork = false;
|
||||
if (strncmp(ffm->params.file, SRT_PROTO, sizeof(SRT_PROTO) - 1) == 0 ||
|
||||
strncmp(ffm->params.file, UDP_PROTO, sizeof(UDP_PROTO) - 1) == 0 ||
|
||||
strncmp(ffm->params.file, TCP_PROTO, sizeof(TCP_PROTO) - 1) == 0)
|
||||
isNetwork = true;
|
||||
bool is_http = false;
|
||||
is_http = (strncmp(ffm->params.file, HTTP_PROTO,
|
||||
sizeof(HTTP_PROTO) - 1) == 0);
|
||||
|
||||
if (isNetwork) {
|
||||
bool is_network = ffmpeg_mux_is_network(ffm);
|
||||
|
||||
if (is_network) {
|
||||
avformat_network_init();
|
||||
output_format = av_guess_format("mpegts", NULL, "video/M2PT");
|
||||
} else {
|
||||
output_format = av_guess_format(NULL, ffm->params.file, NULL);
|
||||
}
|
||||
|
||||
if (is_network && !is_http)
|
||||
output_format = av_guess_format("mpegts", NULL, "video/M2PT");
|
||||
else
|
||||
output_format = av_guess_format(NULL, ffm->params.file, NULL);
|
||||
|
||||
if (output_format == NULL) {
|
||||
fprintf(stderr, "Couldn't find an appropriate muxer for '%s'\n",
|
||||
ffm->params.file);
|
||||
ffm->params.printable_file.array);
|
||||
return FFM_ERROR;
|
||||
}
|
||||
printf("info: Output format name and long_name: %s, %s\n",
|
||||
output_format->name ? output_format->name : "unknown",
|
||||
output_format->long_name ? output_format->long_name : "unknown");
|
||||
|
||||
ret = avformat_alloc_output_context2(&ffm->output, output_format, NULL,
|
||||
ffm->params.file);
|
||||
|
|
@ -726,8 +803,13 @@ static inline bool ffmpeg_mux_packet(struct ffmpeg_mux *ffm, uint8_t *buf,
|
|||
int ret = av_interleaved_write_frame(ffm->output, &packet);
|
||||
|
||||
if (ret < 0) {
|
||||
fprintf(stderr, "av_interleaved_write_frame failed: %s\n",
|
||||
av_err2str(ret));
|
||||
fprintf(stderr, "av_interleaved_write_frame failed: %d: %s\n",
|
||||
ret, av_err2str(ret));
|
||||
}
|
||||
|
||||
/* Treat "Invalid data found when processing input" and "Invalid argument" as non-fatal */
|
||||
if (ret == AVERROR_INVALIDDATA || ret == EINVAL) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ret >= 0;
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <stdint.h>
|
||||
|
||||
enum ffm_packet_type {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue