Compare commits

...
17 Commits
Author SHA1 Message Date
wm4 4fa0853c34 Release 0.3.8 2014-04-17 22:58:58 +02:00
wm4 6598b55c35 af_lavcac3enc: detach on any passthrough format, not just ac3 2014-04-17 22:58:48 +02:00
wm4 848d7979e5 README: mention minimum FFmpeg/Libav versions 2014-04-17 22:58:48 +02:00
Kevin Mitchell 13301daf6a talloc README: more human readible api reference 2014-04-17 22:58:48 +02:00
Ricardo Vieira 763a38f889 wayland: don't schedule resize if going fullscreen
mpv was resizing to the same size before it went to fullscreen, we don't need to schedule a resize because the compositor will send a configure event with the new dimensions and thats when we should do it.
2014-04-17 22:58:48 +02:00
James Ross-Gowan ed1e4de452 manpage: fix --vf=scale options 2014-04-17 22:58:48 +02:00
wm4 0e2fe55fde encode: write 2-pass stats only per-packet
The stats were retrieved and written on every encode call, instead of
every encode call that actually returned a packet. ffmpeg.c also does it
this way, so it must be "more correct". Fixes 2-pass encoding.
2014-04-17 22:58:48 +02:00
wm4 22cfb48b52 encode: add a missing \n to a log call
Conflicts:
	audio/out/ao_lavc.c
2014-04-17 22:58:48 +02:00
wm4 4a07120f83 terminal-unix: reject overlong termcap strings
Our own tables have size for only 8 chars, so these sequences must be
rejected. It seems strings of length 8 are still ok, because the code
uses memcmp and not strcmp, so still allow these.

Based on mplayer-svn commit r37129.
2014-04-17 22:58:48 +02:00
wm4 d06ff691ed vo_vdpau: add an additional check for timestamp robustness
This might be a good idea in order to prevent queuing a frame too far in
the future (causing apparent freezing of the video display), or dropping
an infinite number of frames (also apparent as freezing).

I think at this point this is most of what we can do if the vdpau time
source is unreliable (like with Mesa). There are still inherent race
conditions which can't be fixed.
2014-04-17 22:58:48 +02:00
wm4 34cee2a77d vo_vdpau: document what WRAP_ADD does
This wasn't necessarily clear.
2014-04-17 22:58:47 +02:00
wm4 8f5eb7b780 vo_vdpau: simplify previous vsync timestamp calculation
The strange thing about this code was the shift parameter of the
prev_vs2 function. The parameter is used to handle timestamps before the
last vsync, since the % operator handles negative values incorrectly.
Most callers set shift to 0, and _usually_ pass a timestamp after the
last vsync. One caller sets it to 16, and can pass a timestamp before
the last timestamp.

The mystery is why prev_vs2 doesn't just compensate for the % operator
semantics in the most simple way: if the result of the operator is
negative, add the divisor to it. Instead, it adds a huge value to it
(how huge is influenced by shift). If shift is 0, the result of the
function will not be aligned to vsyncs.

I have no idea why it was written in this way. Were there concerns about
certain numeric overflows that could happen in the calculations? But I
can't think of any (the difference between ts and vc->recent_vsync_time
is usually not that huge). Or is there something more clever about it,
which is important for the timing code? I can't think of anything
either.

So scrap it and simplify it.
2014-04-17 22:58:47 +02:00
wm4 b991c072f6 vo_vdpau: simplify time management and make it more robust
vo_vdpau used a somewhat complicated and fragile mechanism to convert
the vdpau time to internal mpv time. This was fragile as in it couldn't
deal well with Mesa's (apparently) random timestamps, which can change
the base offset in multiple situations. It can happen when moving the
mpv window to a different screen, and somehow it also happens when
pausing the player.

It seems this mechanism to synchronize the vdpau time is not actually
needed. There are only 2 places where sync_vdptime() is used (i.e.
returning the current vdpau time interpolated by system time).

The first call is for determining the PTS used to queue a frame. This
also uses convert_to_vdptime(). It's easily replaced by querying the
time directly, and adding the wait time to it (rel_pts_ns in the patch).

The second call is pretty odd: it updates the vdpau time a second time
in the same function. From what I can see, this can matter only if
update_presentation_queue_status() is very slow. I'm not sure what to
make out of this, because the call merely queries the presentation
queue. Just assume it isn't slow, and that we don't have to update the
time.

Another potential issue with this is that we call VdpPresentationQueueGetTime()
every frame now, instead of every 5 seconds and interpolating the other
calls via system time. More over, this is per video frame (which can be
portantially dropped, and not per actually displayed frame. Assume this
doesn't matter.

This simplifies the code, and should make it more robust on Mesa. But
note that what Mesa does is obviously insane - this is one situation
where you really need a stable time source. There are still plenty of
race condition windows where things can go wrong, although this commit
should drastically reduce the possibility of this.

In my tests, everything worked well. But I have no access to a Mesa
system with vdpau, so it needs testing by others.

See github issues #520, #694, #695.
2014-04-17 22:58:47 +02:00
wm4 3c2777994b vo_vdpau: more debugging output
Might help to debug certain problems with Mesa.
2014-04-17 22:58:47 +02:00
Kevin Mitchell 80741f27f3 remove redundant/outdated line from encodeing.rst:"what works" 2014-04-17 22:58:47 +02:00
wm4 3d18ab77b3 DOCS/encoding: make "What does not work yet" a proper RST section 2014-04-17 22:58:47 +02:00
wm4 8d2baaa318 ass_mp: don't use --subcp for --ass-styles
The --ass-styles option is implemented by calling ass_read_styles().
This function can take a codepage (so libass will use iconv to convert
it). This was implemented before our --subcp option was changed, and
this code was not updated. Now libass fails opening iconv, because
--subcp is not always (and not by default) a valid iconv codepage.

Just always pass NULL, which means the file passed to --ass-styles must
be in UTF-8. The --ass-styles option is a fringe option anyway (and will
destroy your subtitles), so having codepage support for it isn't
important at all.
2014-04-17 22:58:46 +02:00
12 changed files with 66 additions and 85 deletions

No files matched your search

+1 -1
View File
@@ -134,9 +134,9 @@ What works
* Deinterlacing/Inverse Telecine with any of mpv's filters for that
* Audio file converting: mpv -o outfile.mp3 infile.flac -no-video -oac
libmp3lame -oacopts ab=320k
* inverse telecine filters (confirmed working: detc, pullup, filmdint)
What does not work yet
======================
* 3-pass encoding (ensuring constant total size and bitrate constraints while
having VBR audio; mencoder calls this "frameno")
+3 -3
View File
@@ -98,7 +98,7 @@ Available filters are:
:2: Rotate by 90 degrees counterclockwise.
:3: Rotate by 90 degrees counterclockwise and flip.
``scale[=w:h[:interlaced[:chr_drop[:par[:par2[:noup[:arnd]]]]]]]``
``scale[=w:h[:interlaced[:chr-drop[:param[:param2[:noup[:arnd]]]]]]]``
Scales the image with the software scaler (slow) and performs a YUV<->RGB
colorspace conversion (see also ``--sws``).
@@ -114,7 +114,7 @@ Available filters are:
:-(n+8): Like -n above, but rounding the dimension to the closest
multiple of 16.
``<chr_drop>``
``<chr-drop>``
chroma skipping
:0: Use all available input lines for chroma.
@@ -122,7 +122,7 @@ Available filters are:
:2: Use only every 4. input line for chroma.
:3: Use only every 8. input line for chroma.
``<par>[:<par2>]`` (see also ``--sws``)
``<param>[:<param2>]`` (see also ``--sws``)
Set some scaling parameters depending on the type of scaler selected
with ``--sws``::
+2
View File
@@ -46,6 +46,8 @@ Essential dependencies (incomplete list):
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
- Audio output development headers (libasound, pulseaudio)
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libavresample)
At least FFmpeg 1.2.4 or Libav 9.10 is required. (If FFmpeg was compiled
without libavresample, at least FFmpeg 2.0 is required.)
- libjpeg (for screenshots)
- libquvi if you want to play Youtube videos directly
+1 -1
View File
@@ -1 +1 @@
0.3.7
0.3.8
+1 -1
View File
@@ -74,7 +74,7 @@ static int control(struct af_instance *af, int cmd, void *arg)
struct mp_audio *in = arg;
struct mp_audio orig_in = *in;
if (AF_FORMAT_IS_AC3(in->format) || in->nch < s->cfg_min_channel_num)
if (AF_FORMAT_IS_SPECIAL(in->format) || in->nch < s->cfg_min_channel_num)
return AF_DETACH;
mp_audio_set_format(in, s->in_sampleformat);
+1 -1
View File
@@ -179,7 +179,7 @@ static void uninit(struct ao *ao, bool cut_audio)
struct encode_lavc_context *ectx = ao->encode_lavc_ctx;
if (!encode_lavc_start(ectx)) {
MP_WARN(ao, "not even ready to encode audio at end -> dropped");
MP_WARN(ao, "not even ready to encode audio at end -> dropped\n");
return;
}
+3
View File
@@ -86,6 +86,9 @@ static char *term_smkx = NULL;
#endif
static keycode_st *keys_push(char *p, int code) {
if (strlen(p) > 8)
return NULL;
if (getch2_keys.len == getch2_keys.cap) {
getch2_keys.cap *= 2;
if (getch2_keys.cap == 0)
+1 -1
View File
@@ -83,7 +83,7 @@ void mp_ass_set_style(ASS_Style *style, double res_y,
void mp_ass_add_default_styles(ASS_Track *track, struct MPOpts *opts)
{
if (opts->ass_styles_file && opts->ass_style_override)
ass_read_styles(track, opts->ass_styles_file, opts->sub_cp);
ass_read_styles(track, opts->ass_styles_file, NULL);
if (track->n_styles == 0) {
if (!track->PlayResY) {
+1 -1
View File
@@ -31,7 +31,7 @@ will be replaced with TA calls, and the talloc wrapper will be removed.
Documentation for the talloc API is here:
http://git.samba.org/?p=samba.git;a=blob;f=lib/talloc/talloc.h;hb=HEAD
http://talloc.samba.org/talloc/doc/html/modules.html
There are some minor differences with mpv's talloc bridge. mpv calls abort()
on allocation failures, and the talloc_set_destructor() signature is slightly
+2 -1
View File
@@ -267,7 +267,8 @@ static int encode_video(struct vo *vo, AVFrame *frame, AVPacket *packet)
frame->pts * (double) vc->stream->codec->time_base.num /
(double) vc->stream->codec->time_base.den, size);
encode_lavc_write_stats(vo->encode_lavc_ctx, vc->stream);
if (got_packet)
encode_lavc_write_stats(vo->encode_lavc_ctx, vc->stream);
return size;
}
}
+50 -74
View File
@@ -50,6 +50,8 @@
#include "osdep/timer.h"
#include "bitmap_packer.h"
// Returns x + a, but wrapped around to the range [0, m)
// a must be within [-m, m], x within [0, m)
#define WRAP_ADD(x, a, m) ((a) < 0 \
? ((x)+(a)+(m) < (m) ? (x)+(a)+(m) : (x)+(a)) \
: ((x)+(a) < (m) ? (x)+(a) : (x)+(a)-(m)))
@@ -76,8 +78,6 @@ struct vdpctx {
VdpPresentationQueueTarget flip_target;
VdpPresentationQueue flip_queue;
uint64_t last_vdp_time;
uint64_t last_sync_update;
VdpOutputSurface output_surfaces[MAX_OUTPUT_SURFACES];
VdpOutputSurface screenshot_surface;
@@ -160,53 +160,6 @@ struct vdpctx {
static bool status_ok(struct vo *vo);
static int change_vdptime_sync(struct vo *vo, int64_t *t)
{
struct vdpctx *vc = vo->priv;
struct vdp_functions *vdp = vc->vdp;
VdpStatus vdp_st;
VdpTime vdp_time;
vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &vdp_time);
CHECK_VDP_ERROR(vo, "Error when calling vdp_presentation_queue_get_time");
uint64_t t1 = *t;
uint64_t t2 = mp_time_us();
uint64_t old = vc->last_vdp_time + (t1 - vc->last_sync_update) * 1000ULL;
if (vdp_time > old) {
if (vdp_time > old + (t2 - t1) * 1000ULL)
vdp_time -= (t2 - t1) * 1000ULL;
else
vdp_time = old;
} else if (!vdp_time) {
/* Some drivers do not return timestamps. */
vdp_time = old;
}
MP_DBG(vo, "adjusting VdpTime offset by %f µs\n",
(int64_t)(vdp_time - old) / 1000.);
vc->last_vdp_time = vdp_time;
vc->last_sync_update = t1;
*t = t2;
return 0;
}
static uint64_t sync_vdptime(struct vo *vo)
{
struct vdpctx *vc = vo->priv;
uint64_t t = mp_time_us();
if (t - vc->last_sync_update > 5000000)
change_vdptime_sync(vo, &t);
uint64_t now = (t - vc->last_sync_update) * 1000ULL + vc->last_vdp_time;
// Make sure nanosecond inaccuracies don't make things inconsistent
now = FFMAX(now, vc->recent_vsync_time);
return now;
}
static uint64_t convert_to_vdptime(struct vo *vo, uint64_t t)
{
struct vdpctx *vc = vo->priv;
return (t - vc->last_sync_update) * 1000LL + vc->last_vdp_time;
}
static int render_video_to_output_surface(struct vo *vo,
VdpOutputSurface output_surface,
VdpRect *output_rect,
@@ -485,12 +438,6 @@ static int win_x11_init_vdpau_flip_queue(struct vo *vo)
CHECK_VDP_WARNING(vo, "Error setting colorkey");
}
VdpTime vdp_time;
vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &vdp_time);
CHECK_VDP_ERROR(vo, "Error when calling vdp_presentation_queue_get_time");
vc->last_vdp_time = vdp_time;
vc->last_sync_update = mp_time_us();
vc->vsync_interval = 1;
if (vc->composite_detect && vo_x11_screen_is_composited(vo)) {
MP_INFO(vo, "Compositing window manager detected. Assuming timing info "
@@ -1019,6 +966,15 @@ static int update_presentation_queue_status(struct vo *vo)
&status, &vtime);
CHECK_VDP_WARNING(vo, "Error calling "
"presentation_queue_query_surface_status");
if (mp_msg_test(vo->log, MSGL_TRACE)) {
VdpTime current;
vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &current);
CHECK_VDP_WARNING(vo, "Error when calling "
"vdp_presentation_queue_get_time");
MP_TRACE(vo, "Vdpau time: %"PRIu64"\n", (uint64_t)current);
MP_TRACE(vo, "Surface %d status: %d time: %"PRIu64"\n",
(int)surface, (int)status, (uint64_t)vtime);
}
if (status == VDP_PRESENTATION_QUEUE_STATUS_QUEUED)
break;
if (vc->vsync_interval > 1) {
@@ -1040,12 +996,13 @@ static int update_presentation_queue_status(struct vo *vo)
return num_queued;
}
static inline uint64_t prev_vs2(struct vdpctx *vc, uint64_t ts, int shift)
// Return the timestamp of the vsync that must have happened before ts.
static inline uint64_t prev_vsync(struct vdpctx *vc, uint64_t ts)
{
uint64_t offset = ts - vc->recent_vsync_time;
// Fix negative values for 1<<shift vsyncs before vc->recent_vsync_time
offset += (uint64_t)vc->vsync_interval << shift;
offset %= vc->vsync_interval;
int64_t diff = (int64_t)(ts - vc->recent_vsync_time);
int64_t offset = diff % vc->vsync_interval;
if (offset < 0)
offset += vc->vsync_interval;
return ts - offset;
}
@@ -1067,18 +1024,36 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
if (vc->vsync_interval == 1)
duration = -1; // Make sure drop logic is disabled
/* If the presentation time may not be before our last timestamp sync. */
if (pts_us && pts_us < vc->last_sync_update)
pts_us = vc->last_sync_update;
VdpTime vdp_time = 0;
vdp_st = vdp->presentation_queue_get_time(vc->flip_queue, &vdp_time);
CHECK_VDP_WARNING(vo, "Error when calling vdp_presentation_queue_get_time");
uint64_t now = sync_vdptime(vo);
uint64_t pts = pts_us ? convert_to_vdptime(vo, pts_us) : now;
int64_t rel_pts_ns = (pts_us - mp_time_us()) * 1000;
if (!pts_us || rel_pts_ns < 0)
rel_pts_ns = 0;
uint64_t now = vdp_time;
uint64_t pts = now + rel_pts_ns;
uint64_t ideal_pts = pts;
uint64_t npts = duration >= 0 ? pts + duration : UINT64_MAX;
#define PREV_VS2(ts, shift) prev_vs2(vc, ts, shift)
// Only gives accurate results for ts >= vc->recent_vsync_time
#define PREV_VSYNC(ts) PREV_VS2(ts, 0)
/* This should normally never happen.
* - The last queued frame can't have a PTS that goes more than 50ms in the
* future. This is guaranteed by the playloop, which currently actually
* roughly queues 50ms ahead, plus the flip queue offset. Just to be sure
* give some additional room by doubling the time.
* - The last vsync can never be in the future.
*/
int64_t max_pts_ahead = (vo->flip_queue_offset + 0.050) * 2 * 1e9;
if (vc->last_queue_time > now + max_pts_ahead ||
vc->recent_vsync_time > now)
{
vc->last_queue_time = 0;
vc->recent_vsync_time = 0;
MP_WARN(vo, "Inconsistent timing detected.\n");
}
#define PREV_VSYNC(ts) prev_vsync(vc, ts)
/* We hope to be here at least one vsync before the frame should be shown.
* If we are running late then don't drop the frame unless there is
@@ -1107,7 +1082,7 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
*/
uint64_t vsync = PREV_VSYNC(pts);
if (pts < vsync + vsync_interval / 4
&& (vsync - PREV_VS2(vc->last_queue_time, 16)
&& (vsync - PREV_VSYNC(vc->last_queue_time)
> pts - vc->last_ideal_time + vsync_interval / 2
|| vc->dropped_frame && vsync > vc->dropped_time))
pts -= vsync_interval / 2;
@@ -1122,19 +1097,20 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
int num_flips = update_presentation_queue_status(vo);
vsync = vc->recent_vsync_time + num_flips * vc->vsync_interval;
now = sync_vdptime(vo);
pts = FFMAX(pts, now);
pts = FFMAX(pts, vsync + (vsync_interval >> 2));
vsync = PREV_VSYNC(pts);
if (npts < vsync + vsync_interval)
return;
pts = vsync + (vsync_interval >> 2);
vdp_st =
vdp->presentation_queue_display(vc->flip_queue,
vc->output_surfaces[vc->surface_num],
vo->dwidth, vo->dheight, pts);
VdpOutputSurface frame = vc->output_surfaces[vc->surface_num];
vdp_st = vdp->presentation_queue_display(vc->flip_queue, frame,
vo->dwidth, vo->dheight, pts);
CHECK_VDP_WARNING(vo, "Error when calling vdp_presentation_queue_display");
MP_TRACE(vo, "Queue new surface %d: Vdpau time: %"PRIu64" "
"pts: %"PRIu64"\n", (int)frame, now, pts);
vc->last_queue_time = pts;
vc->queue_time[vc->surface_num] = pts;
vc->last_ideal_time = ideal_pts;
-1
View File
@@ -960,7 +960,6 @@ int vo_wayland_control (struct vo *vo, int *events, int request, void *arg)
return VO_TRUE;
case VOCTRL_FULLSCREEN:
vo_wayland_fullscreen(vo);
*events |= VO_EVENT_RESIZE;
return VO_TRUE;
case VOCTRL_ONTOP:
vo_wayland_ontop(vo);