New upstream version 26.0.0+dfsg1
This commit is contained in:
parent
8e020cdacb
commit
240080891f
837 changed files with 41275 additions and 9196 deletions
|
|
@ -23,6 +23,7 @@
|
|||
#include "../util/circlebuf.h"
|
||||
#include "../util/platform.h"
|
||||
#include "../util/profiler.h"
|
||||
#include "../util/util_uint64.h"
|
||||
|
||||
#include "audio-io.h"
|
||||
#include "audio-resampler.h"
|
||||
|
|
@ -72,51 +73,6 @@ struct audio_output {
|
|||
};
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
/* the following functions are used to calculate frame offsets based upon
|
||||
* timestamps. this will actually work accurately as long as you handle the
|
||||
* values correctly */
|
||||
|
||||
static inline double ts_to_frames(const audio_t *audio, uint64_t ts)
|
||||
{
|
||||
double audio_offset_d = (double)ts;
|
||||
audio_offset_d /= 1000000000.0;
|
||||
audio_offset_d *= (double)audio->info.samples_per_sec;
|
||||
|
||||
return audio_offset_d;
|
||||
}
|
||||
|
||||
static inline double positive_round(double val)
|
||||
{
|
||||
return floor(val + 0.5);
|
||||
}
|
||||
|
||||
static int64_t ts_diff_frames(const audio_t *audio, uint64_t ts1, uint64_t ts2)
|
||||
{
|
||||
double diff = ts_to_frames(audio, ts1) - ts_to_frames(audio, ts2);
|
||||
return (int64_t)positive_round(diff);
|
||||
}
|
||||
|
||||
static int64_t ts_diff_bytes(const audio_t *audio, uint64_t ts1, uint64_t ts2)
|
||||
{
|
||||
return ts_diff_frames(audio, ts1, ts2) * (int64_t)audio->block_size;
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
|
||||
static inline uint64_t min_uint64(uint64_t a, uint64_t b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
static inline size_t min_size(size_t a, size_t b)
|
||||
{
|
||||
return a < b ? a : b;
|
||||
}
|
||||
|
||||
#ifndef CLAMP
|
||||
#define CLAMP(val, minval, maxval) \
|
||||
((val > maxval) ? maxval : ((val < minval) ? minval : val))
|
||||
#endif
|
||||
|
||||
static bool resample_audio_output(struct audio_input *input,
|
||||
struct audio_data *data)
|
||||
|
|
@ -219,9 +175,7 @@ static void input_and_output(struct audio_output *audio, uint64_t audio_time,
|
|||
for (size_t mix_idx = 0; mix_idx < MAX_AUDIO_MIXES; mix_idx++) {
|
||||
struct audio_mix *mix = &audio->mixes[mix_idx];
|
||||
|
||||
memset(mix->buffer[0], 0,
|
||||
AUDIO_OUTPUT_FRAMES * MAX_AUDIO_CHANNELS *
|
||||
sizeof(float));
|
||||
memset(mix->buffer, 0, sizeof(mix->buffer));
|
||||
|
||||
for (size_t i = 0; i < audio->planes; i++)
|
||||
data[mix_idx].data[i] = mix->buffer[i];
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
|
||||
#include "media-io-defs.h"
|
||||
#include "../util/c99defs.h"
|
||||
#include "../util/util_uint128.h"
|
||||
#include "../util/util_uint64.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
|
|
@ -195,18 +195,12 @@ static inline size_t get_audio_size(enum audio_format format,
|
|||
|
||||
static inline uint64_t audio_frames_to_ns(size_t sample_rate, uint64_t frames)
|
||||
{
|
||||
util_uint128_t val;
|
||||
val = util_mul64_64(frames, 1000000000ULL);
|
||||
val = util_div128_32(val, (uint32_t)sample_rate);
|
||||
return val.low;
|
||||
return util_mul_div64(frames, 1000000000ULL, sample_rate);
|
||||
}
|
||||
|
||||
static inline uint64_t ns_to_audio_frames(size_t sample_rate, uint64_t frames)
|
||||
{
|
||||
util_uint128_t val;
|
||||
val = util_mul64_64(frames, sample_rate);
|
||||
val = util_div128_32(val, 1000000000);
|
||||
return val.low;
|
||||
return util_mul_div64(frames, sample_rate, 1000000000ULL);
|
||||
}
|
||||
|
||||
#define AUDIO_OUTPUT_SUCCESS 0
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ static inline bool init_input(media_remux_job_t job, const char *in_filename)
|
|||
return false;
|
||||
}
|
||||
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
av_dump_format(job->ifmt_ctx, 0, in_filename, false);
|
||||
#endif
|
||||
return true;
|
||||
|
|
@ -84,8 +84,12 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename)
|
|||
|
||||
for (unsigned i = 0; i < job->ifmt_ctx->nb_streams; i++) {
|
||||
AVStream *in_stream = job->ifmt_ctx->streams[i];
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
|
||||
AVStream *out_stream = avformat_new_stream(job->ofmt_ctx, NULL);
|
||||
#else
|
||||
AVStream *out_stream = avformat_new_stream(
|
||||
job->ofmt_ctx, in_stream->codec->codec);
|
||||
#endif
|
||||
if (!out_stream) {
|
||||
blog(LOG_ERROR, "media_remux: Failed to allocate output"
|
||||
" stream");
|
||||
|
|
@ -93,30 +97,31 @@ static inline bool init_output(media_remux_job_t job, const char *out_filename)
|
|||
}
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
|
||||
AVCodecParameters *par = avcodec_parameters_alloc();
|
||||
ret = avcodec_parameters_from_context(par, in_stream->codec);
|
||||
if (ret == 0)
|
||||
ret = avcodec_parameters_to_context(out_stream->codec,
|
||||
par);
|
||||
avcodec_parameters_free(&par);
|
||||
ret = avcodec_parameters_copy(out_stream->codecpar,
|
||||
in_stream->codecpar);
|
||||
#else
|
||||
ret = avcodec_copy_context(out_stream->codec, in_stream->codec);
|
||||
#endif
|
||||
|
||||
if (ret < 0) {
|
||||
blog(LOG_ERROR, "media_remux: Failed to copy context");
|
||||
blog(LOG_ERROR,
|
||||
"media_remux: Failed to copy parameters");
|
||||
return false;
|
||||
}
|
||||
out_stream->time_base = out_stream->codec->time_base;
|
||||
|
||||
av_dict_copy(&out_stream->metadata, in_stream->metadata, 0);
|
||||
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(57, 48, 101)
|
||||
out_stream->codecpar->codec_tag = 0;
|
||||
#else
|
||||
out_stream->codec->codec_tag = 0;
|
||||
out_stream->time_base = out_stream->codec->time_base;
|
||||
if (job->ofmt_ctx->oformat->flags & AVFMT_GLOBALHEADER)
|
||||
out_stream->codec->flags |= CODEC_FLAG_GLOBAL_H;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef _NDEBUG
|
||||
#ifndef NDEBUG
|
||||
av_dump_format(job->ofmt_ctx, 0, out_filename, true);
|
||||
#endif
|
||||
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
#include "../util/profiler.h"
|
||||
#include "../util/threading.h"
|
||||
#include "../util/darray.h"
|
||||
#include "../util/util_uint64.h"
|
||||
|
||||
#include "format-conversion.h"
|
||||
#include "video-io.h"
|
||||
|
|
@ -234,8 +235,8 @@ int video_output_open(video_t **video, struct video_output_info *info)
|
|||
goto fail;
|
||||
|
||||
memcpy(&out->info, info, sizeof(struct video_output_info));
|
||||
out->frame_time = (uint64_t)(1000000000.0 * (double)info->fps_den /
|
||||
(double)info->fps_num);
|
||||
out->frame_time =
|
||||
util_mul_div64(1000000000ULL, info->fps_den, info->fps_num);
|
||||
out->initialized = false;
|
||||
|
||||
if (pthread_mutexattr_init(&attr) != 0)
|
||||
|
|
|
|||
|
|
@ -174,11 +174,12 @@ static inline const char *get_video_format_name(enum video_format format)
|
|||
static inline const char *get_video_colorspace_name(enum video_colorspace cs)
|
||||
{
|
||||
switch (cs) {
|
||||
case VIDEO_CS_DEFAULT:
|
||||
case VIDEO_CS_709:
|
||||
return "709";
|
||||
case VIDEO_CS_601:
|
||||
case VIDEO_CS_DEFAULT:
|
||||
case VIDEO_CS_SRGB:;
|
||||
case VIDEO_CS_SRGB:
|
||||
return "sRGB";
|
||||
case VIDEO_CS_601:;
|
||||
}
|
||||
|
||||
return "601";
|
||||
|
|
|
|||
|
|
@ -171,8 +171,8 @@ bool video_format_get_parameters(enum video_colorspace color_space,
|
|||
matrices_initialized = true;
|
||||
}
|
||||
#endif
|
||||
if (color_space == VIDEO_CS_DEFAULT)
|
||||
color_space = VIDEO_CS_601;
|
||||
if ((color_space == VIDEO_CS_DEFAULT) || (color_space == VIDEO_CS_SRGB))
|
||||
color_space = VIDEO_CS_709;
|
||||
|
||||
for (size_t i = 0; i < NUM_FORMATS; i++) {
|
||||
if (format_info[i].color_space != color_space)
|
||||
|
|
|
|||
|
|
@ -18,11 +18,15 @@
|
|||
#include "../util/bmem.h"
|
||||
#include "video-scaler.h"
|
||||
|
||||
#include <libavutil/imgutils.h>
|
||||
#include <libswscale/swscale.h>
|
||||
|
||||
struct video_scaler {
|
||||
struct SwsContext *swscale;
|
||||
int src_height;
|
||||
int dst_heights[4];
|
||||
uint8_t *dst_pointers[4];
|
||||
int dst_linesizes[4];
|
||||
};
|
||||
|
||||
static inline enum AVPixelFormat
|
||||
|
|
@ -87,16 +91,9 @@ static inline int get_ffmpeg_scale_type(enum video_scale_type type)
|
|||
|
||||
static inline const int *get_ffmpeg_coeffs(enum video_colorspace cs)
|
||||
{
|
||||
switch (cs) {
|
||||
case VIDEO_CS_DEFAULT:
|
||||
return sws_getCoefficients(SWS_CS_ITU601);
|
||||
case VIDEO_CS_601:
|
||||
return sws_getCoefficients(SWS_CS_ITU601);
|
||||
case VIDEO_CS_709:
|
||||
return sws_getCoefficients(SWS_CS_ITU709);
|
||||
default:
|
||||
return sws_getCoefficients(SWS_CS_ITU601);
|
||||
}
|
||||
const int colorspace = (cs == VIDEO_CS_601) ? SWS_CS_ITU601
|
||||
: SWS_CS_ITU709;
|
||||
return sws_getCoefficients(colorspace);
|
||||
}
|
||||
|
||||
static inline int get_ffmpeg_range_type(enum video_range_type type)
|
||||
|
|
@ -139,6 +136,28 @@ int video_scaler_create(video_scaler_t **scaler_out,
|
|||
scaler = bzalloc(sizeof(struct video_scaler));
|
||||
scaler->src_height = src->height;
|
||||
|
||||
const AVPixFmtDescriptor *desc = av_pix_fmt_desc_get(format_dst);
|
||||
bool has_plane[4] = {0};
|
||||
for (size_t i = 0; i < 4; i++)
|
||||
has_plane[desc->comp[i].plane] = 1;
|
||||
|
||||
scaler->dst_heights[0] = dst->height;
|
||||
for (size_t i = 1; i < 4; ++i) {
|
||||
if (has_plane[i]) {
|
||||
const int s = (i == 1 || i == 2) ? desc->log2_chroma_h
|
||||
: 0;
|
||||
scaler->dst_heights[i] = dst->height >> s;
|
||||
}
|
||||
}
|
||||
|
||||
ret = av_image_alloc(scaler->dst_pointers, scaler->dst_linesizes,
|
||||
dst->width, dst->height, format_dst, 32);
|
||||
if (ret < 0) {
|
||||
blog(LOG_WARNING,
|
||||
"video_scaler_create: av_image_alloc failed: %d", ret);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
scaler->swscale = sws_getCachedContext(NULL, src->width, src->height,
|
||||
format_src, dst->width,
|
||||
dst->height, format_dst,
|
||||
|
|
@ -169,6 +188,10 @@ void video_scaler_destroy(video_scaler_t *scaler)
|
|||
{
|
||||
if (scaler) {
|
||||
sws_freeContext(scaler->swscale);
|
||||
|
||||
if (scaler->dst_pointers[0])
|
||||
av_freep(scaler->dst_pointers);
|
||||
|
||||
bfree(scaler);
|
||||
}
|
||||
}
|
||||
|
|
@ -182,13 +205,37 @@ bool video_scaler_scale(video_scaler_t *scaler, uint8_t *output[],
|
|||
return false;
|
||||
|
||||
int ret = sws_scale(scaler->swscale, input, (const int *)in_linesize, 0,
|
||||
scaler->src_height, output,
|
||||
(const int *)out_linesize);
|
||||
scaler->src_height, scaler->dst_pointers,
|
||||
scaler->dst_linesizes);
|
||||
if (ret <= 0) {
|
||||
blog(LOG_ERROR, "video_scaler_scale: sws_scale failed: %d",
|
||||
ret);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (size_t plane = 0; plane < 4; ++plane) {
|
||||
if (!scaler->dst_pointers[plane])
|
||||
continue;
|
||||
|
||||
const size_t scaled_linesize = scaler->dst_linesizes[plane];
|
||||
const size_t plane_linesize = out_linesize[plane];
|
||||
uint8_t *dst = output[plane];
|
||||
const uint8_t *src = scaler->dst_pointers[plane];
|
||||
const size_t height = scaler->dst_heights[plane];
|
||||
if (scaled_linesize == plane_linesize) {
|
||||
memcpy(dst, src, scaled_linesize * height);
|
||||
} else {
|
||||
size_t linesize = scaled_linesize;
|
||||
if (linesize > plane_linesize)
|
||||
linesize = plane_linesize;
|
||||
|
||||
for (size_t y = 0; y < height; y++) {
|
||||
memcpy(dst, src, linesize);
|
||||
dst += plane_linesize;
|
||||
src += scaled_linesize;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue