Imported Upstream version 0.14.2+dfsg1
This commit is contained in:
parent
fb3990e9e5
commit
41a01dbf05
529 changed files with 25112 additions and 2336 deletions
109
deps/file-updater/file-updater/file-updater.c
vendored
109
deps/file-updater/file-updater/file-updater.c
vendored
|
|
@ -29,6 +29,9 @@ struct update_info {
|
|||
obs_data_t *cache_package;
|
||||
obs_data_t *remote_package;
|
||||
|
||||
char *etag_local;
|
||||
char *etag_remote;
|
||||
|
||||
confirm_file_callback_t callback;
|
||||
void *param;
|
||||
|
||||
|
|
@ -76,7 +79,33 @@ static size_t http_write(uint8_t *ptr, size_t size, size_t nmemb,
|
|||
return total;
|
||||
}
|
||||
|
||||
static bool do_http_request(struct update_info *info, const char *url)
|
||||
static size_t http_header(char *buffer, size_t size, size_t nitems,
|
||||
struct update_info *info)
|
||||
{
|
||||
if (!strncmp(buffer, "ETag: ", 6))
|
||||
{
|
||||
char *etag = buffer + 6;
|
||||
if (*etag) {
|
||||
char *etag_clean, *p;
|
||||
|
||||
etag_clean = bstrdup(etag);
|
||||
|
||||
p = strchr(etag_clean, '\r');
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
p = strchr(etag_clean, '\n');
|
||||
if (p)
|
||||
*p = 0;
|
||||
|
||||
info->etag_remote = etag_clean;
|
||||
}
|
||||
}
|
||||
return nitems * size;
|
||||
}
|
||||
|
||||
static bool do_http_request(struct update_info *info, const char *url,
|
||||
long *response_code)
|
||||
{
|
||||
CURLcode code;
|
||||
uint8_t null_terminator = 0;
|
||||
|
|
@ -89,6 +118,17 @@ static bool do_http_request(struct update_info *info, const char *url)
|
|||
curl_easy_setopt(info->curl, CURLOPT_WRITEDATA, info);
|
||||
curl_easy_setopt(info->curl, CURLOPT_FAILONERROR, true);
|
||||
|
||||
if (!info->remote_url) {
|
||||
// We only care about headers from the main package file
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERFUNCTION, http_header);
|
||||
curl_easy_setopt(info->curl, CURLOPT_HEADERDATA, info);
|
||||
}
|
||||
|
||||
#if LIBCURL_VERSION_NUM >= 0x072400
|
||||
// A lot of servers don't yet support ALPN
|
||||
curl_easy_setopt(info->curl, CURLOPT_SSL_ENABLE_ALPN, 0);
|
||||
#endif
|
||||
|
||||
code = curl_easy_perform(info->curl);
|
||||
if (code != CURLE_OK) {
|
||||
warn("Remote update of URL \"%s\" failed: %s", url,
|
||||
|
|
@ -96,6 +136,16 @@ static bool do_http_request(struct update_info *info, const char *url)
|
|||
return false;
|
||||
}
|
||||
|
||||
if (curl_easy_getinfo(info->curl, CURLINFO_RESPONSE_CODE,
|
||||
response_code) != CURLE_OK)
|
||||
return false;
|
||||
|
||||
if (*response_code >= 400) {
|
||||
warn("Remote update of URL \"%s\" failed: HTTP/%ld", url,
|
||||
*response_code);
|
||||
return false;
|
||||
}
|
||||
|
||||
da_push_back(info->file_data, &null_terminator);
|
||||
|
||||
return true;
|
||||
|
|
@ -135,6 +185,25 @@ static bool init_update(struct update_info *info)
|
|||
info->local_package = get_package(info->local, "package.json");
|
||||
info->cache_package = get_package(info->cache, "package.json");
|
||||
|
||||
obs_data_t *metadata = get_package(info->cache, "meta.json");
|
||||
if (metadata) {
|
||||
const char *etag = obs_data_get_string(metadata, "etag");
|
||||
if (etag) {
|
||||
struct dstr if_none_match = { 0 };
|
||||
dstr_copy(&if_none_match, "If-None-Match: ");
|
||||
dstr_cat(&if_none_match, etag);
|
||||
|
||||
info->etag_local = bstrdup(etag);
|
||||
|
||||
info->header = curl_slist_append(info->header,
|
||||
if_none_match.array);
|
||||
|
||||
dstr_free(&if_none_match);
|
||||
}
|
||||
|
||||
obs_data_release(metadata);
|
||||
}
|
||||
|
||||
dstr_copy(&user_agent, "User-Agent: ");
|
||||
dstr_cat(&user_agent, info->user_agent);
|
||||
|
||||
|
|
@ -246,10 +315,11 @@ static int update_local_version(struct update_info *info)
|
|||
static inline bool do_relative_http_request(struct update_info *info,
|
||||
const char *url, const char *file)
|
||||
{
|
||||
long response_code;
|
||||
char *full_url = get_path(url, file);
|
||||
bool success = do_http_request(info, full_url);
|
||||
bool success = do_http_request(info, full_url, &response_code);
|
||||
bfree(full_url);
|
||||
return success;
|
||||
return success && response_code == 200;
|
||||
}
|
||||
|
||||
static inline void write_file_data(struct update_info *info,
|
||||
|
|
@ -320,11 +390,34 @@ static bool update_remote_files(void *param, obs_data_t *remote_file)
|
|||
return true;
|
||||
}
|
||||
|
||||
static void update_save_metadata(struct update_info *info)
|
||||
{
|
||||
struct dstr path = { 0 };
|
||||
|
||||
if (!info->etag_remote)
|
||||
return;
|
||||
|
||||
dstr_copy(&path, info->cache);
|
||||
dstr_cat(&path, "meta.json");
|
||||
|
||||
obs_data_t *data;
|
||||
data = obs_data_create();
|
||||
obs_data_set_string(data, "etag", info->etag_remote);
|
||||
obs_data_save_json(data, path.array);
|
||||
obs_data_release(data);
|
||||
|
||||
dstr_free(&path);
|
||||
}
|
||||
|
||||
static void update_remote_version(struct update_info *info, int cur_version)
|
||||
{
|
||||
int remote_version;
|
||||
long response_code;
|
||||
|
||||
if (!do_http_request(info, info->url))
|
||||
if (!do_http_request(info, info->url, &response_code))
|
||||
return;
|
||||
|
||||
if (response_code == 304)
|
||||
return;
|
||||
|
||||
if (!info->file_data.array || info->file_data.array[0] != '{') {
|
||||
|
|
@ -332,6 +425,8 @@ static void update_remote_version(struct update_info *info, int cur_version)
|
|||
return;
|
||||
}
|
||||
|
||||
update_save_metadata(info);
|
||||
|
||||
info->remote_package = obs_data_create_from_json(
|
||||
(char*)info->file_data.array);
|
||||
if (!info->remote_package) {
|
||||
|
|
@ -371,6 +466,12 @@ static void *update_thread(void *data)
|
|||
cur_version = update_local_version(info);
|
||||
update_remote_version(info, cur_version);
|
||||
os_rmdir(info->temp);
|
||||
|
||||
if (info->etag_local)
|
||||
bfree(info->etag_local);
|
||||
if (info->etag_remote)
|
||||
bfree(info->etag_remote);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
67
deps/libff/libff/ff-audio-decoder.c
vendored
67
deps/libff/libff/ff-audio-decoder.c
vendored
|
|
@ -28,6 +28,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "ff-compat.h"
|
||||
|
||||
static inline void shrink_packet(struct ff_packet *packet, int packet_length)
|
||||
{
|
||||
if (packet_length <= packet->base.size) {
|
||||
|
|
@ -47,11 +49,6 @@ static bool handle_reset_packet(struct ff_decoder *decoder,
|
|||
decoder->clock = packet->clock;
|
||||
av_free_packet(&packet->base);
|
||||
|
||||
// not a real packet, so try to get another packet
|
||||
if (packet_queue_get(&decoder->packet_queue, packet, 1)
|
||||
== FF_PACKET_FAIL)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -73,6 +70,28 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
int ret;
|
||||
|
||||
while (true) {
|
||||
if (decoder->eof)
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet, 0);
|
||||
else
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet, 1);
|
||||
|
||||
if (ret == FF_PACKET_EMPTY) {
|
||||
return 0;
|
||||
} else if (ret == FF_PACKET_FAIL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet->base.data ==
|
||||
decoder->packet_queue.flush_packet.base.data) {
|
||||
avcodec_flush_buffers(decoder->codec);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Packet has a new clock (reset packet)
|
||||
if (packet->clock != NULL)
|
||||
if (!handle_reset_packet(decoder, packet))
|
||||
return -1;
|
||||
|
||||
while (packet->base.size > 0) {
|
||||
int complete;
|
||||
|
||||
|
|
@ -93,33 +112,11 @@ static int decode_frame(struct ff_decoder *decoder,
|
|||
*frame_complete = complete != 0;
|
||||
|
||||
return frame->nb_samples *
|
||||
av_get_bytes_per_sample(frame->format);
|
||||
av_get_bytes_per_sample(frame->format);
|
||||
}
|
||||
|
||||
if (packet->base.data != NULL)
|
||||
av_packet_unref(&packet->base);
|
||||
|
||||
ret = packet_queue_get(&decoder->packet_queue, packet, 1);
|
||||
if (ret == FF_PACKET_FAIL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (packet->base.data ==
|
||||
decoder->packet_queue.flush_packet.base.data) {
|
||||
avcodec_flush_buffers(decoder->codec);
|
||||
|
||||
// we were flushed, so try to get another packet
|
||||
ret = packet_queue_get(&decoder->packet_queue,
|
||||
packet, 1);
|
||||
if (ret == FF_PACKET_FAIL) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Packet has a new clock (reset packet)
|
||||
if (packet->clock != NULL)
|
||||
if (!handle_reset_packet(decoder, packet))
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -143,8 +140,10 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
|||
|| queue_frame->frame->sample_rate != codec->sample_rate
|
||||
|| queue_frame->frame->format != codec->sample_fmt);
|
||||
|
||||
if (queue_frame->frame != NULL)
|
||||
if (queue_frame->frame != NULL) {
|
||||
//FIXME: this shouldn't happen any more!
|
||||
av_frame_free(&queue_frame->frame);
|
||||
}
|
||||
|
||||
queue_frame->frame = av_frame_clone(frame);
|
||||
queue_frame->clock = ff_clock_retain(decoder->clock);
|
||||
|
|
@ -166,10 +165,13 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder)
|
|||
struct ff_packet packet = {0};
|
||||
bool frame_complete;
|
||||
AVFrame *frame = av_frame_alloc();
|
||||
int ret;
|
||||
|
||||
while (!decoder->abort) {
|
||||
if (decode_frame(decoder, &packet, frame, &frame_complete)
|
||||
< 0) {
|
||||
ret = decode_frame(decoder, &packet, frame, &frame_complete);
|
||||
if (ret == 0) {
|
||||
break;
|
||||
} else if (ret < 0) {
|
||||
av_free_packet(&packet.base);
|
||||
continue;
|
||||
}
|
||||
|
|
@ -193,5 +195,8 @@ void *ff_audio_decoder_thread(void *opaque_audio_decoder)
|
|||
ff_clock_release(&decoder->clock);
|
||||
|
||||
av_frame_free(&frame);
|
||||
|
||||
decoder->finished = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
29
deps/libff/libff/ff-compat.h
vendored
Normal file
29
deps/libff/libff/ff-compat.h
vendored
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright (c) 2016 Hugh Bailey <obs.jim@gmail.com>
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 57
|
||||
#define av_free_packet av_packet_unref
|
||||
static inline int av_dup_packet_2(AVPacket *pkt)
|
||||
{
|
||||
AVPacket tmp = *pkt;
|
||||
int ret = av_packet_ref(pkt, &tmp);
|
||||
av_packet_unref(&tmp);
|
||||
return ret;
|
||||
}
|
||||
#define av_dup_packet av_dup_packet_2
|
||||
#endif
|
||||
5
deps/libff/libff/ff-decoder.c
vendored
5
deps/libff/libff/ff-decoder.c
vendored
|
|
@ -42,6 +42,7 @@ struct ff_decoder *ff_decoder_init(AVCodecContext *codec_context,
|
|||
decoder->codec->opaque = decoder;
|
||||
decoder->stream = stream;
|
||||
decoder->abort = false;
|
||||
decoder->finished = false;
|
||||
|
||||
decoder->packet_queue_size = packet_queue_size;
|
||||
if (!packet_queue_init(&decoder->packet_queue))
|
||||
|
|
@ -179,7 +180,7 @@ void ff_decoder_refresh(void *opaque)
|
|||
|
||||
if (decoder && decoder->stream) {
|
||||
if (decoder->frame_queue.size == 0) {
|
||||
if (!decoder->eof) {
|
||||
if (!decoder->eof || !decoder->finished) {
|
||||
// We expected a frame, but there were none
|
||||
// available
|
||||
|
||||
|
|
@ -280,6 +281,8 @@ void ff_decoder_refresh(void *opaque)
|
|||
(int)(delay_until_next_wake * 1000
|
||||
+ 0.5L));
|
||||
|
||||
av_frame_free(&frame->frame);
|
||||
|
||||
ff_circular_queue_advance_read(&decoder->frame_queue);
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
1
deps/libff/libff/ff-decoder.h
vendored
1
deps/libff/libff/ff-decoder.h
vendored
|
|
@ -56,6 +56,7 @@ struct ff_decoder {
|
|||
bool first_frame;
|
||||
bool eof;
|
||||
bool abort;
|
||||
bool finished;
|
||||
};
|
||||
|
||||
typedef struct ff_decoder ff_decoder_t;
|
||||
|
|
|
|||
19
deps/libff/libff/ff-demuxer.c
vendored
19
deps/libff/libff/ff-demuxer.c
vendored
|
|
@ -23,6 +23,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "ff-compat.h"
|
||||
|
||||
#define DEFAULT_AV_SYNC_TYPE AV_SYNC_VIDEO_MASTER
|
||||
|
||||
#define AUDIO_FRAME_QUEUE_SIZE 1
|
||||
|
|
@ -92,7 +94,7 @@ void ff_demuxer_free(struct ff_demuxer *demuxer)
|
|||
ff_decoder_free(demuxer->video_decoder);
|
||||
|
||||
if (demuxer->format_context)
|
||||
avformat_free_context(demuxer->format_context);
|
||||
avformat_close_input(&demuxer->format_context);
|
||||
|
||||
av_free(demuxer);
|
||||
}
|
||||
|
|
@ -342,15 +344,15 @@ void ff_demuxer_reset(struct ff_demuxer *demuxer)
|
|||
packet.clock = clock;
|
||||
|
||||
if (demuxer->audio_decoder != NULL) {
|
||||
ff_clock_retain(clock);
|
||||
packet_queue_put(&demuxer->audio_decoder->packet_queue,
|
||||
&packet);
|
||||
ff_clock_retain(clock);
|
||||
}
|
||||
|
||||
if (demuxer->video_decoder != NULL) {
|
||||
ff_clock_retain(clock);
|
||||
packet_queue_put(&demuxer->video_decoder->packet_queue,
|
||||
&packet);
|
||||
ff_clock_retain(clock);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -500,7 +502,7 @@ static bool handle_seek(struct ff_demuxer *demuxer)
|
|||
seek_stream = demuxer->audio_decoder->stream;
|
||||
}
|
||||
|
||||
if (seek_stream != NULL) {
|
||||
if (seek_stream != NULL && demuxer->format_context->duration != AV_NOPTS_VALUE) {
|
||||
seek_target = av_rescale_q(seek_target,
|
||||
AV_TIME_BASE_Q,
|
||||
seek_stream->time_base);
|
||||
|
|
@ -529,8 +531,13 @@ static bool handle_seek(struct ff_demuxer *demuxer)
|
|||
|
||||
static void seek_beginning(struct ff_demuxer *demuxer)
|
||||
{
|
||||
demuxer->seek_flags = AVSEEK_FLAG_BACKWARD;
|
||||
demuxer->seek_pos = demuxer->format_context->start_time;
|
||||
if (demuxer->format_context->duration == AV_NOPTS_VALUE) {
|
||||
demuxer->seek_flags = AVSEEK_FLAG_FRAME;
|
||||
demuxer->seek_pos = 0;
|
||||
} else {
|
||||
demuxer->seek_flags = AVSEEK_FLAG_BACKWARD;
|
||||
demuxer->seek_pos = demuxer->format_context->start_time;
|
||||
}
|
||||
demuxer->seek_request = true;
|
||||
demuxer->seek_flush = false;
|
||||
av_log(NULL, AV_LOG_VERBOSE, "looping media %s", demuxer->input);
|
||||
|
|
|
|||
5
deps/libff/libff/ff-packet-queue.c
vendored
5
deps/libff/libff/ff-packet-queue.c
vendored
|
|
@ -15,6 +15,7 @@
|
|||
*/
|
||||
|
||||
#include "ff-packet-queue.h"
|
||||
#include "ff-compat.h"
|
||||
|
||||
bool packet_queue_init(struct ff_packet_queue *q)
|
||||
{
|
||||
|
|
@ -60,10 +61,6 @@ int packet_queue_put(struct ff_packet_queue *q, struct ff_packet *packet)
|
|||
{
|
||||
struct ff_packet_list *new_packet;
|
||||
|
||||
if (packet != &q->flush_packet
|
||||
&& av_dup_packet(&packet->base) < 0)
|
||||
return FF_PACKET_FAIL;
|
||||
|
||||
new_packet = av_malloc(sizeof(struct ff_packet_list));
|
||||
|
||||
if (new_packet == NULL)
|
||||
|
|
|
|||
3
deps/libff/libff/ff-timer.c
vendored
3
deps/libff/libff/ff-timer.c
vendored
|
|
@ -51,6 +51,9 @@ static void *timer_thread(void *opaque)
|
|||
- current_time));
|
||||
}
|
||||
|
||||
pthread_mutex_unlock(&timer->mutex);
|
||||
continue;
|
||||
|
||||
// we can be woken up merely to set a sooner wake time
|
||||
|
||||
} else {
|
||||
|
|
|
|||
18
deps/libff/libff/ff-video-decoder.c
vendored
18
deps/libff/libff/ff-video-decoder.c
vendored
|
|
@ -27,6 +27,8 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
#include "ff-compat.h"
|
||||
|
||||
static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
||||
double best_effort_pts)
|
||||
{
|
||||
|
|
@ -49,8 +51,11 @@ static bool queue_frame(struct ff_decoder *decoder, AVFrame *frame,
|
|||
|| queue_frame->frame->height != codec->height
|
||||
|| queue_frame->frame->format != codec->pix_fmt);
|
||||
|
||||
if (queue_frame->frame != NULL)
|
||||
if (queue_frame->frame != NULL) {
|
||||
// This shouldn't happen any more, the frames are freed in
|
||||
// ff_decoder_refresh.
|
||||
av_frame_free(&queue_frame->frame);
|
||||
}
|
||||
|
||||
queue_frame->frame = av_frame_clone(frame);
|
||||
queue_frame->clock = ff_clock_retain(decoder->clock);
|
||||
|
|
@ -76,8 +81,12 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
|||
bool key_frame;
|
||||
|
||||
while (!decoder->abort) {
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 1);
|
||||
if (ret == FF_PACKET_FAIL) {
|
||||
if (decoder->eof)
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 0);
|
||||
else
|
||||
ret = packet_queue_get(&decoder->packet_queue, &packet, 1);
|
||||
|
||||
if (ret == FF_PACKET_EMPTY || ret == FF_PACKET_FAIL) {
|
||||
// should we just use abort here?
|
||||
break;
|
||||
}
|
||||
|
|
@ -135,5 +144,8 @@ void *ff_video_decoder_thread(void *opaque_video_decoder)
|
|||
ff_clock_release(&decoder->clock);
|
||||
|
||||
av_frame_free(&frame);
|
||||
|
||||
decoder->finished = true;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue