New upstream version 21.0.2+dfsg1
This commit is contained in:
parent
1f1bbb3518
commit
baafb6325b
706 changed files with 49633 additions and 5044 deletions
|
|
@ -31,9 +31,6 @@
|
|||
#define FF_BLOG(level, format, ...) \
|
||||
FF_LOG_S(s->source, level, format, ##__VA_ARGS__)
|
||||
|
||||
static bool video_frame(struct ff_frame *frame, void *opaque);
|
||||
static bool video_format(AVCodecContext *codec_context, void *opaque);
|
||||
|
||||
struct ffmpeg_source {
|
||||
mp_media_t media;
|
||||
bool media_valid;
|
||||
|
|
@ -58,6 +55,7 @@ struct ffmpeg_source {
|
|||
bool is_clear_on_media_end;
|
||||
bool restart_on_activate;
|
||||
bool close_when_inactive;
|
||||
bool seekable;
|
||||
};
|
||||
|
||||
static bool is_local_file_modified(obs_properties_t *props,
|
||||
|
|
@ -73,12 +71,14 @@ static bool is_local_file_modified(obs_properties_t *props,
|
|||
obs_property_t *looping = obs_properties_get(props, "looping");
|
||||
obs_property_t *buffering = obs_properties_get(props, "buffering_mb");
|
||||
obs_property_t *close = obs_properties_get(props, "close_when_inactive");
|
||||
obs_property_t *seekable = obs_properties_get(props, "seekable");
|
||||
obs_property_set_visible(input, !enabled);
|
||||
obs_property_set_visible(input_format, !enabled);
|
||||
obs_property_set_visible(buffering, !enabled);
|
||||
obs_property_set_visible(close, enabled);
|
||||
obs_property_set_visible(local_file, enabled);
|
||||
obs_property_set_visible(looping, enabled);
|
||||
obs_property_set_visible(seekable, !enabled);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
@ -181,6 +181,8 @@ static obs_properties_t *ffmpeg_source_getproperties(void *data)
|
|||
obs_property_list_add_int(prop, obs_module_text("ColorRange.Full"),
|
||||
VIDEO_RANGE_FULL);
|
||||
|
||||
obs_properties_add_bool(props, "seekable", obs_module_text("Seekable"));
|
||||
|
||||
return props;
|
||||
}
|
||||
|
||||
|
|
@ -232,7 +234,7 @@ static void media_stopped(void *opaque)
|
|||
struct ffmpeg_source *s = opaque;
|
||||
if (s->is_clear_on_media_end) {
|
||||
obs_source_output_video(s->source, NULL);
|
||||
if (s->close_when_inactive)
|
||||
if (s->close_when_inactive && s->media_valid)
|
||||
s->destroy_media = true;
|
||||
}
|
||||
}
|
||||
|
|
@ -244,11 +246,16 @@ static void ffmpeg_source_open(struct ffmpeg_source *s)
|
|||
s->input, s->input_format,
|
||||
s->buffering_mb * 1024 * 1024,
|
||||
s, get_frame, get_audio, media_stopped,
|
||||
preload_frame, s->is_hw_decoding, s->range);
|
||||
preload_frame,
|
||||
s->is_hw_decoding,
|
||||
s->is_local_file || s->seekable,
|
||||
s->range);
|
||||
}
|
||||
|
||||
static void ffmpeg_source_tick(void *data, float seconds)
|
||||
{
|
||||
UNUSED_PARAMETER(seconds);
|
||||
|
||||
struct ffmpeg_source *s = data;
|
||||
if (s->destroy_media) {
|
||||
if (s->media_valid) {
|
||||
|
|
@ -314,6 +321,7 @@ static void ffmpeg_source_update(void *data, obs_data_t *settings)
|
|||
"color_range");
|
||||
s->buffering_mb = (int)obs_data_get_int(settings, "buffering_mb");
|
||||
s->is_local_file = is_local_file;
|
||||
s->seekable = obs_data_get_bool(settings, "seekable");
|
||||
|
||||
if (s->media_valid) {
|
||||
mp_media_free(&s->media);
|
||||
|
|
@ -335,7 +343,7 @@ static const char *ffmpeg_source_getname(void *unused)
|
|||
return obs_module_text("FFMpegSource");
|
||||
}
|
||||
|
||||
static bool restart_hotkey(void *data, obs_hotkey_id id,
|
||||
static void restart_hotkey(void *data, obs_hotkey_id id,
|
||||
obs_hotkey_t *hotkey, bool pressed)
|
||||
{
|
||||
UNUSED_PARAMETER(id);
|
||||
|
|
@ -345,7 +353,6 @@ static bool restart_hotkey(void *data, obs_hotkey_id id,
|
|||
struct ffmpeg_source *s = data;
|
||||
if (obs_source_active(s->source))
|
||||
ffmpeg_source_start(s);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void restart_proc(void *data, calldata_t *cd)
|
||||
|
|
@ -354,6 +361,53 @@ static void restart_proc(void *data, calldata_t *cd)
|
|||
UNUSED_PARAMETER(cd);
|
||||
}
|
||||
|
||||
static void get_duration(void *data, calldata_t *cd)
|
||||
{
|
||||
struct ffmpeg_source *s = data;
|
||||
int64_t dur = 0;
|
||||
if (s->media.fmt)
|
||||
dur = s->media.fmt->duration;
|
||||
|
||||
calldata_set_int(cd, "duration", dur * 1000);
|
||||
}
|
||||
|
||||
static void get_nb_frames(void *data, calldata_t *cd)
|
||||
{
|
||||
struct ffmpeg_source *s = data;
|
||||
int64_t frames = 0;
|
||||
|
||||
if (!s->media.fmt) {
|
||||
calldata_set_int(cd, "num_frames", frames);
|
||||
return;
|
||||
}
|
||||
|
||||
int video_stream_index = av_find_best_stream(s->media.fmt,
|
||||
AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
|
||||
|
||||
if (video_stream_index < 0) {
|
||||
FF_BLOG(LOG_WARNING, "Getting number of frames failed: No "
|
||||
"video stream in media file!");
|
||||
calldata_set_int(cd, "num_frames", frames);
|
||||
return;
|
||||
}
|
||||
|
||||
AVStream *stream = s->media.fmt->streams[video_stream_index];
|
||||
|
||||
if (stream->nb_frames > 0) {
|
||||
frames = stream->nb_frames;
|
||||
} else {
|
||||
FF_BLOG(LOG_DEBUG, "nb_frames not set, estimating using frame "
|
||||
"rate and duration");
|
||||
AVRational avg_frame_rate = stream->avg_frame_rate;
|
||||
frames = (int64_t)ceil((double)s->media.fmt->duration /
|
||||
(double)AV_TIME_BASE *
|
||||
(double)avg_frame_rate.num /
|
||||
(double)avg_frame_rate.den);
|
||||
}
|
||||
|
||||
calldata_set_int(cd, "num_frames", frames);
|
||||
}
|
||||
|
||||
static void *ffmpeg_source_create(obs_data_t *settings, obs_source_t *source)
|
||||
{
|
||||
UNUSED_PARAMETER(settings);
|
||||
|
|
@ -368,6 +422,10 @@ static void *ffmpeg_source_create(obs_data_t *settings, obs_source_t *source)
|
|||
|
||||
proc_handler_t *ph = obs_source_get_proc_handler(source);
|
||||
proc_handler_add(ph, "void restart()", restart_proc, s);
|
||||
proc_handler_add(ph, "void get_duration(out int duration)",
|
||||
get_duration, s);
|
||||
proc_handler_add(ph, "void get_nb_frames(out int num_frames)",
|
||||
get_nb_frames, s);
|
||||
|
||||
ffmpeg_source_update(s, settings);
|
||||
return s;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue