Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6bb684d55 | ||
|
|
4c97c3a1b3 | ||
|
|
4b36023273 | ||
|
|
864a2da9ea | ||
|
|
e6ac54e333 | ||
|
|
54c2a95792 | ||
|
|
661633b689 | ||
|
|
a0eea7aba8 | ||
|
|
9de0db208d | ||
|
|
d52c491fec | ||
|
|
ff2e39a3d2 | ||
|
|
844656d135 | ||
|
|
c0f85c18f8 | ||
|
|
60111d3f0f | ||
|
|
2f86a06528 | ||
|
|
7e61bf134a | ||
|
|
61a2f3d2bf | ||
|
|
213ea94ee3 |
No files matched your search
@@ -134,6 +134,8 @@ Sending patches
|
||||
Important: put an empty line between the subject line and the commit message.
|
||||
If this is missing, it will break display in common git tools.
|
||||
- Try to separate cosmetic and functional changes. It's ok to make a few
|
||||
additional cosmetic changes in the same file you're working on, but don't do
|
||||
something like reformatting a whole file and hiding an actual functional
|
||||
additional cosmetic changes in the same file you're working on. But don't do
|
||||
something like reformatting a whole file, and hiding an actual functional
|
||||
change in the same commit.
|
||||
- If you add a new command line option, document it in options.rst. If you
|
||||
add a new input property, document it in input.rst.
|
||||
+3
-3
@@ -36,14 +36,14 @@ Available audio output drivers are:
|
||||
``alsa`` (Linux only)
|
||||
ALSA audio output driver
|
||||
|
||||
``device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
``no-block``
|
||||
Sets noblock-mode.
|
||||
``resample=yes``
|
||||
Enable ALSA resampling plugin. (This is disabled by default, because
|
||||
some drivers report incorrect audio delay in some cases.)
|
||||
``device=<device>``
|
||||
Sets the device name. For ac3 output via S/PDIF, use an "iec958" or
|
||||
"spdif" device, unless you really know how to set it correctly.
|
||||
``mixer-device=<device>``
|
||||
Set the mixer device used with ``--no-softvol`` (default: ``default``).
|
||||
``mixer-name=<name>``
|
||||
|
||||
+1
-1
@@ -724,8 +724,8 @@ const struct ao_driver audio_out_alsa = {
|
||||
.cfg_mixer_index = 0,
|
||||
},
|
||||
.options = (const struct m_option[]) {
|
||||
OPT_FLAG("resample", cfg_resample, 0),
|
||||
OPT_STRING("device", cfg_device, 0),
|
||||
OPT_FLAG("resample", cfg_resample, 0),
|
||||
OPT_FLAG("block", cfg_block, 0),
|
||||
OPT_STRING("mixer-device", cfg_mixer_device, 0),
|
||||
OPT_STRING("mixer-name", cfg_mixer_name, 0),
|
||||
|
||||
+4
-1
@@ -114,10 +114,13 @@ void playlist_clear(struct playlist *pl)
|
||||
pl->current_was_replaced = false;
|
||||
}
|
||||
|
||||
// Moves entry such that entry->prev = at (even if at is NULL)
|
||||
// Moves the entry so that it takes "at"'s place (or move to end, if at==NULL).
|
||||
void playlist_move(struct playlist *pl, struct playlist_entry *entry,
|
||||
struct playlist_entry *at)
|
||||
{
|
||||
if (entry == at)
|
||||
return;
|
||||
|
||||
struct playlist_entry *save_current = pl->current;
|
||||
bool save_replaced = pl->current_was_replaced;
|
||||
|
||||
|
||||
+6
-20
@@ -44,10 +44,6 @@
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#if MP_INPUT_BUFFER_PADDING_SIZE < FF_INPUT_BUFFER_PADDING_SIZE
|
||||
#error MP_INPUT_BUFFER_PADDING_SIZE is too small!
|
||||
#endif
|
||||
|
||||
// Demuxer list
|
||||
extern const struct demuxer_desc demuxer_desc_edl;
|
||||
extern const struct demuxer_desc demuxer_desc_cue;
|
||||
@@ -117,7 +113,7 @@ static void packet_destroy(void *ptr)
|
||||
{
|
||||
struct demux_packet *dp = ptr;
|
||||
talloc_free(dp->avpacket);
|
||||
free(dp->allocation);
|
||||
av_free(dp->allocation);
|
||||
}
|
||||
|
||||
static struct demux_packet *create_packet(size_t len)
|
||||
@@ -143,12 +139,12 @@ static struct demux_packet *create_packet(size_t len)
|
||||
struct demux_packet *new_demux_packet(size_t len)
|
||||
{
|
||||
struct demux_packet *dp = create_packet(len);
|
||||
dp->buffer = malloc(len + MP_INPUT_BUFFER_PADDING_SIZE);
|
||||
dp->buffer = av_malloc(len + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!dp->buffer) {
|
||||
fprintf(stderr, "Memory allocation failure!\n");
|
||||
abort();
|
||||
}
|
||||
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
||||
memset(dp->buffer + len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
dp->allocation = dp->buffer;
|
||||
return dp;
|
||||
}
|
||||
@@ -168,21 +164,11 @@ struct demux_packet *new_demux_packet_from(void *data, size_t len)
|
||||
return dp;
|
||||
}
|
||||
|
||||
void resize_demux_packet(struct demux_packet *dp, size_t len)
|
||||
void demux_packet_shorten(struct demux_packet *dp, size_t len)
|
||||
{
|
||||
if (len > 1000000000) {
|
||||
fprintf(stderr, "Attempt to realloc demux packet over 1 GB!\n");
|
||||
abort();
|
||||
}
|
||||
assert(dp->allocation);
|
||||
dp->buffer = realloc(dp->buffer, len + MP_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!dp->buffer) {
|
||||
fprintf(stderr, "Memory allocation failure!\n");
|
||||
abort();
|
||||
}
|
||||
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
|
||||
assert(len <= dp->len);
|
||||
dp->len = len;
|
||||
dp->allocation = dp->buffer;
|
||||
memset(dp->buffer + dp->len, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
}
|
||||
|
||||
void free_demux_packet(struct demux_packet *dp)
|
||||
|
||||
+1
-4
@@ -80,9 +80,6 @@ enum demux_check {
|
||||
DEMUX_CHECK_NORMAL, // normal, safe detection
|
||||
};
|
||||
|
||||
// demux_lavf can pass lavf buffers using FF_INPUT_BUFFER_PADDING_SIZE instead
|
||||
#define MP_INPUT_BUFFER_PADDING_SIZE 16
|
||||
|
||||
#define MAX_SH_STREAMS 256
|
||||
|
||||
struct demuxer;
|
||||
@@ -210,7 +207,7 @@ struct demux_packet *new_demux_packet(size_t len);
|
||||
// data must already have suitable padding
|
||||
struct demux_packet *new_demux_packet_fromdata(void *data, size_t len);
|
||||
struct demux_packet *new_demux_packet_from(void *data, size_t len);
|
||||
void resize_demux_packet(struct demux_packet *dp, size_t len);
|
||||
void demux_packet_shorten(struct demux_packet *dp, size_t len);
|
||||
void free_demux_packet(struct demux_packet *dp);
|
||||
struct demux_packet *demux_copy_packet(struct demux_packet *dp);
|
||||
|
||||
|
||||
+1
-1
@@ -204,7 +204,7 @@ static int raw_fill_buffer(demuxer_t *demuxer)
|
||||
dp->pts = (dp->pos / p->frame_size) / p->frame_rate;
|
||||
|
||||
int len = stream_read(demuxer->stream, dp->buffer, dp->len);
|
||||
resize_demux_packet(dp, len);
|
||||
demux_packet_shorten(dp, len);
|
||||
demuxer_add_packet(demuxer, demuxer->streams[0], dp);
|
||||
|
||||
return 1;
|
||||
|
||||
@@ -79,6 +79,7 @@
|
||||
#Q quit_watch_later
|
||||
#q {encode} quit
|
||||
#ESC quit
|
||||
#ESC {encode} quit
|
||||
#p cycle pause # toggle pause/playback mode
|
||||
#. frame_step # advance one frame and pause
|
||||
#, frame_back_step # go back by one frame and pause
|
||||
|
||||
@@ -278,6 +278,12 @@ bool mp_input_is_abort_cmd(struct mp_cmd *cmd)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd)
|
||||
{
|
||||
return (cmd->def && cmd->def->allow_auto_repeat) ||
|
||||
cmd->id == MP_CMD_COMMAND_LIST;
|
||||
}
|
||||
|
||||
void mp_print_cmd_list(struct mp_log *out)
|
||||
{
|
||||
for (int i = 0; mp_cmds[i].name; i++) {
|
||||
|
||||
@@ -110,6 +110,8 @@ enum mp_command_type {
|
||||
struct mp_cmd;
|
||||
bool mp_input_is_abort_cmd(struct mp_cmd *cmd);
|
||||
|
||||
bool mp_input_is_repeatable_cmd(struct mp_cmd *cmd);
|
||||
|
||||
struct bstr;
|
||||
bool mp_replace_legacy_cmd(void *talloc_ctx, struct bstr *s);
|
||||
|
||||
|
||||
+2
-2
@@ -517,7 +517,7 @@ static void update_mouse_section(struct input_ctx *ictx)
|
||||
}
|
||||
|
||||
// Called when the currently held-down key is released. This (usually) sends
|
||||
// the a key-up versiob of the command associated with the keys that were held
|
||||
// the a key-up version of the command associated with the keys that were held
|
||||
// down.
|
||||
// If the drop_current parameter is set to true, then don't send the key-up
|
||||
// command. Unless we've already sent a key-down event, in which case the
|
||||
@@ -1155,7 +1155,7 @@ mp_cmd_t *mp_input_get_cmd(struct input_ctx *ictx, int time, int peek_only)
|
||||
struct mp_cmd *repeated = check_autorepeat(ictx);
|
||||
if (repeated) {
|
||||
repeated->repeated = true;
|
||||
if (repeated->def && repeated->def->allow_auto_repeat) {
|
||||
if (mp_input_is_repeatable_cmd(repeated)) {
|
||||
queue_add_tail(queue, repeated);
|
||||
} else {
|
||||
talloc_free(repeated);
|
||||
|
||||
+49
-22
@@ -40,15 +40,13 @@ known issues:
|
||||
#include <pthread.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#if HAVE_SYS_SYSINFO_H
|
||||
#include <sys/sysinfo.h>
|
||||
#endif
|
||||
#if HAVE_SYS_VIDEOIO_H
|
||||
#include <sys/videoio.h>
|
||||
#else
|
||||
@@ -71,6 +69,13 @@ known issues:
|
||||
#define v4l2_munmap munmap
|
||||
#endif
|
||||
|
||||
// flag introduced in kernel 3.10
|
||||
#ifndef V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC
|
||||
#define V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC 0x2000
|
||||
#endif
|
||||
|
||||
#define HAVE_CLOCK_GETTIME (defined(_POSIX_TIMERS) && _POSIX_TIMERS > 0)
|
||||
|
||||
#define info tvi_info_v4l2
|
||||
static tvi_handle_t *tvi_init_v4l2(struct mp_log *log, tv_param_t* tv_param);
|
||||
/* information about this file */
|
||||
@@ -112,8 +117,10 @@ typedef struct priv {
|
||||
struct map *map;
|
||||
int mapcount;
|
||||
int frames;
|
||||
volatile long long first_frame;
|
||||
long long curr_frame;
|
||||
volatile long long first_frame; ///< number of useconds
|
||||
long long curr_frame; ///< usec, using kernel timestamps
|
||||
int clk_id; /**< clk_id from clock_gettime
|
||||
used in frame timestamps */
|
||||
/* audio video interleaving ;-) */
|
||||
volatile int streamon;
|
||||
pthread_t audio_grabber_thread;
|
||||
@@ -500,6 +507,30 @@ static int getstd(priv_t *priv)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if HAVE_CLOCK_GETTIME
|
||||
/*
|
||||
** Gets current timestamp, using specified clock id.
|
||||
** @return number of microseconds.
|
||||
*/
|
||||
static long long get_curr_timestamp(int clk_id)
|
||||
{
|
||||
struct timespec ts;
|
||||
clock_gettime(clk_id, &ts);
|
||||
return (long long)ts.tv_sec * 1000000 + ts.tv_nsec / 1000;
|
||||
}
|
||||
#else
|
||||
/*
|
||||
** Gets current timestamp, using system time.
|
||||
** @return number of microseconds.
|
||||
*/
|
||||
static long long get_curr_timestamp(int clk_id)
|
||||
{
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
return (long long)tv.tv_sec * 1000000 + tv.tv_usec;
|
||||
}
|
||||
#endif
|
||||
|
||||
/***********************************************************************\
|
||||
* *
|
||||
* *
|
||||
@@ -1230,13 +1261,6 @@ static int get_capture_buffer_size(priv_t *priv)
|
||||
if (priv->tv_param->buffer_size >= 0) {
|
||||
bufsize = priv->tv_param->buffer_size*1024*1024;
|
||||
} else {
|
||||
#if HAVE_SYS_SYSINFO_H
|
||||
struct sysinfo si;
|
||||
|
||||
sysinfo(&si);
|
||||
bufsize = (si.freeram/2)*si.mem_unit;
|
||||
if ( bufsize < 16*1024*1024)
|
||||
#endif
|
||||
bufsize = 16*1024*1024;
|
||||
}
|
||||
|
||||
@@ -1378,6 +1402,13 @@ static int start(priv_t *priv)
|
||||
return 0;
|
||||
}
|
||||
priv->map[i].len = priv->map[i].buf.length;
|
||||
#ifdef HAVE_CLOCK_GETTIME
|
||||
priv->clk_id = (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
|
||||
? CLOCK_MONOTONIC : CLOCK_REALTIME;
|
||||
#else
|
||||
if (priv->map[i].buf.flags & V4L2_BUF_FLAG_TIMESTAMP_MONOTONIC)
|
||||
mp_msg(MSGT_TV, MSGL_WARN, "MPlayer compiled without clock_gettime() that is needed to handle monotone video timestamps from the kernel. Expect desync.\n");
|
||||
#endif
|
||||
/* count up to make sure this is correct everytime */
|
||||
priv->mapcount++;
|
||||
|
||||
@@ -1653,13 +1684,11 @@ static int get_video_framesize(priv_t *priv)
|
||||
static void *audio_grabber(void *data)
|
||||
{
|
||||
priv_t *priv = (priv_t*)data;
|
||||
struct timeval tv;
|
||||
int i, audio_skew_ptr = 0;
|
||||
long long current_time, prev_skew = 0, prev_skew_uncorr = 0;
|
||||
long long start_time_avg;
|
||||
long long start_time_avg, curr_timestamp;
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
|
||||
start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id);
|
||||
audio_in_start_capture(&priv->audio_in);
|
||||
for (i = 0; i < priv->aud_skew_cnt; i++)
|
||||
priv->audio_skew_buffer[i] = 0;
|
||||
@@ -1673,21 +1702,19 @@ static void *audio_grabber(void *data)
|
||||
pthread_mutex_lock(&priv->skew_mutex);
|
||||
if (priv->first_frame == 0) {
|
||||
// there is no first frame yet (unlikely to happen)
|
||||
gettimeofday(&tv, NULL);
|
||||
start_time_avg = priv->audio_start_time = (long long)1e6*tv.tv_sec + tv.tv_usec;
|
||||
start_time_avg = priv->audio_start_time = get_curr_timestamp(priv->clk_id);
|
||||
// fprintf(stderr, "warning - first frame not yet available!\n");
|
||||
pthread_mutex_unlock(&priv->skew_mutex);
|
||||
continue;
|
||||
}
|
||||
pthread_mutex_unlock(&priv->skew_mutex);
|
||||
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
priv->audio_recv_blocks_total++;
|
||||
current_time = (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_start_time;
|
||||
curr_timestamp = get_curr_timestamp(priv->clk_id);
|
||||
current_time = curr_timestamp - priv->audio_start_time;
|
||||
|
||||
if (priv->audio_recv_blocks_total < priv->aud_skew_cnt*2) {
|
||||
start_time_avg += (long long)1e6*tv.tv_sec + tv.tv_usec - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
|
||||
start_time_avg += curr_timestamp - priv->audio_usecs_per_block*priv->audio_recv_blocks_total;
|
||||
priv->audio_start_time = start_time_avg/(priv->audio_recv_blocks_total+1);
|
||||
}
|
||||
|
||||
|
||||
@@ -290,6 +290,14 @@ struct mp_image *video_decode(struct dec_video *d_video,
|
||||
bool sort_pts =
|
||||
(opts->user_pts_assoc_mode != 1 || d_video->header->video->avi_dts)
|
||||
&& opts->correct_pts;
|
||||
|
||||
struct demux_packet packet_copy;
|
||||
if (packet && packet->dts == MP_NOPTS_VALUE) {
|
||||
packet_copy = *packet;
|
||||
packet = &packet_copy;
|
||||
packet->dts = packet->pts;
|
||||
}
|
||||
|
||||
double pkt_pts = packet ? packet->pts : MP_NOPTS_VALUE;
|
||||
double pkt_dts = packet ? packet->dts : MP_NOPTS_VALUE;
|
||||
|
||||
@@ -323,7 +331,7 @@ struct mp_image *video_decode(struct dec_video *d_video,
|
||||
|
||||
if (pts == MP_NOPTS_VALUE) {
|
||||
d_video->codec_pts = prev_codec_pts;
|
||||
} else if (pts <= prev_codec_pts) {
|
||||
} else if (pts < prev_codec_pts) {
|
||||
d_video->num_codec_pts_problems++;
|
||||
}
|
||||
|
||||
|
||||
@@ -334,11 +334,12 @@ static struct mp_image *allocate_image(struct lavc_ctx *ctx, int format,
|
||||
|
||||
static void destroy_va_dummy_ctx(struct priv *p)
|
||||
{
|
||||
va_destroy(p->ctx);
|
||||
p->ctx = NULL;
|
||||
p->display = NULL;
|
||||
if (p->x11_display)
|
||||
XCloseDisplay(p->x11_display);
|
||||
p->x11_display = NULL;
|
||||
va_destroy(p->ctx);
|
||||
p->ctx = NULL;
|
||||
}
|
||||
|
||||
// Creates a "private" VADisplay, disconnected from the VO. We just create a
|
||||
@@ -372,6 +373,7 @@ static void uninit(struct lavc_ctx *ctx)
|
||||
|
||||
destroy_decoder(ctx);
|
||||
va_surface_pool_release(p->pool);
|
||||
p->pool = NULL;
|
||||
|
||||
if (p->x11_display)
|
||||
destroy_va_dummy_ctx(p);
|
||||
|
||||
@@ -502,7 +502,7 @@ void mpgl_load_functions(GL *gl, void *(*getProcAddress)(const GLubyte *),
|
||||
if (!gl->GetString)
|
||||
gl->GetString = glGetString;
|
||||
|
||||
GLint major = 0, minor = 0;
|
||||
int major = 0, minor = 0;
|
||||
const char *version = gl->GetString(GL_VERSION);
|
||||
sscanf(version, "%d.%d", &major, &minor);
|
||||
gl->version = MPGL_VER(major, minor);
|
||||
|
||||
@@ -571,16 +571,17 @@ static int preinit(struct vo *vo)
|
||||
VAStatus status;
|
||||
|
||||
if (!vo_x11_init(vo))
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
p->display = vaGetDisplay(vo->x11->display);
|
||||
if (!p->display)
|
||||
return -1;
|
||||
goto fail;
|
||||
|
||||
p->mpvaapi = va_initialize(p->display, p->log);
|
||||
if (!p->mpvaapi) {
|
||||
vaTerminate(p->display);
|
||||
return -1;
|
||||
p->display = NULL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
p->pool = va_surface_pool_alloc(p->mpvaapi, VA_RT_FORMAT_YUV420);
|
||||
@@ -630,6 +631,10 @@ static int preinit(struct vo *vo)
|
||||
p->va_num_display_attrs = 0;
|
||||
}
|
||||
return 0;
|
||||
|
||||
fail:
|
||||
uninit(vo);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define OPT_BASE_STRUCT struct priv
|
||||
|
||||
@@ -668,7 +668,7 @@ static void vo_x11_classhint(struct vo *vo, Window window, const char *name)
|
||||
struct mp_vo_opts *opts = vo->opts;
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
XClassHint wmClass;
|
||||
pid_t pid = getpid();
|
||||
long pid = getpid();
|
||||
|
||||
wmClass.res_name = opts->winname ? opts->winname : (char *)name;
|
||||
wmClass.res_class = "mpv";
|
||||
@@ -680,7 +680,8 @@ static void vo_x11_classhint(struct vo *vo, Window window, const char *name)
|
||||
void vo_x11_uninit(struct vo *vo)
|
||||
{
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
assert(x11);
|
||||
if (!x11)
|
||||
return;
|
||||
|
||||
mp_input_put_key(vo->input_ctx, MP_INPUT_RELEASE_ALL);
|
||||
|
||||
|
||||
@@ -4,9 +4,11 @@ def __get_version__(ctx):
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
cwd=ctx.srcnode.abspath())
|
||||
process.wait()
|
||||
(version, err) = process.communicate()
|
||||
return version.strip().decode('utf-8').encode('ascii', 'ignore')
|
||||
version = version.strip()
|
||||
if not isinstance(version, str):
|
||||
version = version.decode('utf-8')
|
||||
return version
|
||||
|
||||
def __get_build_date__():
|
||||
import time
|
||||
|
||||
@@ -187,11 +187,6 @@ iconv support use --disable-iconv.",
|
||||
'name': 'setmode',
|
||||
'desc': 'setmode()',
|
||||
'func': check_statement('io.h', 'setmode(0, 0)')
|
||||
}, {
|
||||
'name': 'sys-sysinfo-h',
|
||||
'desc': 'sys/sysinfo.h',
|
||||
'func': check_statement('sys/sysinfo.h',
|
||||
'struct sysinfo s_info; s_info.mem_unit=0; sysinfo(&s_info)')
|
||||
}, {
|
||||
'name': '--libguess',
|
||||
'desc': 'libguess support',
|
||||
|
||||
Reference in new issue
Block a user