Compare commits

...
44 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
wm4 2758bc462d Release 0.3.7 2014-03-30 17:56:54 +02:00
wm4 2687b43dd0 vf_eq: don't malloc priv struct
There wasn't any reason for this. In fact, it's a memory leak. The
proper priv struct is already allocated vf.c and the option parser.
2014-03-30 17:55:12 +02:00
Sebastian Morr bb40daf367 player: add missing "-" to options in workaround notice on A/V desynchronization
While it technically works, using GNU-style options seems cleaner nowadays.

Signed-off-by: wm4 <wm4@nowhere>
2014-03-30 17:55:07 +02:00
wm4 cc1f926441 player: dvdnav: fix start time when entering and leaving menu
Unfortunately, quite a hack, because we have check the nav state
outside of discnav.c.
2014-03-30 17:54:50 +02:00
wm4 67f653324a mf: fix operation with --cache
demux_mf.c explicitly checks for the stream type to check whether images
are opened via pattern (mf://..., i.e. stream_mf.c) or directly. Of
course the stream type is not set to STREAMTYPE_MF if the stream is
wrapped through the cache, so it tried to open the pattern directly as
file, which failed.

Fix this by disabling caching for mf://. The cache doesn't make sense
here anyway, because each file is opened and closed every frame (perhaps
to avoid memory bloat).
2014-03-30 17:54:33 +02:00
wm4 6e2c29b786 player: fix unchecked access for chapter metadata
It's possible that MPContext has a chapter list, but the demuxer
doesn't. In this case, accesing the chapter-metadata property would
lead to invalid accesses.

(This fixes the out of bound access, but in theory, the returned data
can still be incorrect, since MPContext chapters don't need to map
directly to demuxer chapters.)
2014-03-30 17:54:30 +02:00
wm4 e565217f22 stream_cdda: print cd text header only if there are any cd text fields 2014-03-30 17:54:18 +02:00
wm4 144c67efaf stream_cdda: remove unused stuff
This cd_info_t struct was practically unused. The only thing it did was
storing the track name of the form "Track %d" in a very roundabout way.
Remove it. (It made more sense when there was still CDDB support.)
2014-03-30 17:54:15 +02:00
wm4 96d7e80ddf stream_cdda: fix track time accuracy
Don't use an integer division to get the time, since that would round on
second boundaries. Also round up the time by sector size. Seeking rounds
down due to alignment constraints, but if we round up the time, we can
make it land on the exact destination sector.

This fixes that the track change code printed the previous track when
seeking by chapter.
2014-03-30 17:54:10 +02:00
wm4 dde72c5c54 stream_cdda: report track times
Report the time for each chapter (tracks are treated as chapters). This
allows us to get rid of the "old" chapter mechanism, and also behaves
better with the frontend.

This makes assumptions about the audio formats, but that format is
hardcoded anyway in the rawaudio demuxer defaults (and always was).
2014-03-30 17:54:05 +02:00
wm4 577d03da0c dvdnav: fix minor memory leak
This was usually handled at the end of the switch statement, so if
something returns from the function before that, the event has to be
freed explicitly.
2014-03-30 17:53:46 +02:00
xylosper fc510f0da8 dvdnav: make MP_NAV_EVENT_RESET_ALL handled properly
dvdnav.c did not handle event in regular sequence. Usually this
does not make any trouble except around MP_NAV_EVENT_RESET_ALL.
Those events should be handled in regular sequence. If they're
mixed, it can make wrong result.
For instance, MP_NAV_EVENT_HIGHLIGHT right after
MP_NAV_EVENT_RESET_ALL should not be ignored but it might be
because MP_NAV_EVENT_RESET_ALL makes the demuxer reloaded and osd
hidden.
2014-03-30 17:53:05 +02:00
xylosper 8d5775a8d2 dvdnav: prevent reallocation of fake highlight buffer
Since subsizes were never updated, the bitmap buffer was always
reallocated whenever mp_nav_get_highlight() called.
2014-03-30 17:52:43 +02:00
xylosper cf8ff2fd87 stream_bluray: fix for significant memory leak
It's obvious but, since STREAM_CTRL_GET_TIME_LENGTH is called
frequently, the amount of leaked memory here is quite big.
2014-03-30 17:51:45 +02:00
wm4 852c924a60 manpage: clarify what to pass to --hwdec-codecs option 2014-03-30 17:51:28 +02:00
wm4 1685d198b9 vd_lavc: ridiculous workaround for Libav 9 compatibility
This "sometimes" crashed when seeking. The fault apparently lies in
libavcodec: the decoder returns an unreferenced frame! This is
completely insane, but somehow I'm apparently still expected to
work this around. As a reaction, I will drop Libav 9 support in the
next commit. (While this commit will go into release/0.3.)
2014-03-30 17:50:11 +02:00
wm4 1e2d28f567 DOCS/coding-style: add another requirement for commit messages 2014-03-30 17:50:02 +02:00
wm4 89973ebca1 options: fix off-by-1 error in option help output 2014-03-30 17:49:57 +02:00
wm4 3f4e528f73 manpage: af: minor syntax improvements
Conflicts:
	DOCS/man/en/af.rst
2014-03-30 17:49:19 +02:00
Ryan Goulden 6f7c9f516e build: fix unicode handling of the version string
Don't pass unicode types to waf ENV.
As per https://code.google.com/p/waf/issues/detail?id=1420
This directly fixes the "CFVersion" key in the .app bundle plist.
2014-03-30 17:47:57 +02:00
James Ross-Gowan 33e0074603 player/main: Fix Cygwin build
Xlib.h (included from x11_common.h) defines a macro 'Status' as 'int'.
This messed up a bunch of definitions in windows.h and broke the build
in Cygwin. Including windows.h first seems to solve the problem.

This commit also removes the definition of an unused flag.

Conflicts:
	player/main.c
2014-03-30 17:47:44 +02:00
wm4 b6ed94fa7c DOCS/coding-style: add an example and another rule 2014-03-30 17:42:40 +02:00
wm4 a419703549 README: split list of dependencies
And make some additions.

I'm not really sure why we list dependencies that are not ours, but that
of external libraries. Still might be useful, though.
2014-03-30 17:42:30 +02:00
wm4 5171da86e3 DOCS: add coding style
I've tried not to be too detailed (because it's not a reference, just
some guidelines), but it still got relatively long. Also contains
conventions for sending patches.
2014-03-30 17:42:11 +02:00
James Ross-Gowan 7bd670949c w32_common: prevent MOUSE_BTN0 sticking after drag
The window doesn't recieve a WM_LBUTTONUP message after it's dragged,
probably because it's swallowed by the modal loop. To stop the button
from sticking, release it manually when the drag is complete.
2014-03-30 17:42:07 +02:00
James Ross-Gowan 421b2be348 w32_common: capture mouse input
Mouse buttons can get stuck down if the button is pressed inside the
video window and released outside. Avoid this by capturing mouse input
when a button is pressed.
2014-03-30 17:42:02 +02:00
Diogo Franco b659476ed9 options.rst: correct broken URL 2014-03-30 17:39:31 +02:00
35 changed files with 334 additions and 429 deletions

No files matched your search

+139
View File
@@ -0,0 +1,139 @@
Coding style
============
mpv uses C99 with K&R formatting, with some exceptions.
General formatting
------------------
- Use the K&R indent style.
- Use 4 spaces of indentation, never use tabs (except in Makefiles).
- Add a single space between keywords and binary operators. There are some other
cases where spaces should be added. Example:
```C
if ((a * b) > c) {
// code
some_function(a, b, c);
}
```
- Break lines on 80 columns. There is a hard limit of 85 columns. You may ignore
this limit if there's a strong case that not breaking the line will increase
readability. Going over 85 columns might provoke endless discussions about
whether such a limit is needed or not, so avoid it.
- If the body of an if/for/while statement has more than 1 physical lines, then
always add braces, even if they're technically redundant.
Bad:
```C
if (a)
// do something if b
if (b)
do_something();
```
Good:
```C
if (a) {
// do something if b
if (b)
do_something();
}
```
- If the body of an if statement uses braces, the else branch should also
use braces (and reverse).
Example:
```C
if (a) {
// do something
something();
something_else();
} else {
one_line();
}
```
- If an if condition spans multiple physical lines, then put the opening brace
for the if body on the next physical line. (Also, preferably always add a
brace, even if technically none is needed.)
Example:
```C
if (very_long_condition_a &&
very_long_condition_b)
{
code();
}
```
- Remove any trailing whitespace.
- If the file you're editing uses formatting different from from what is
described here, it's probably an old file from times when nobody followed a
consistent style. You're free to use the existing style, or the new style, or
to send a patch to reformat the file to the new style before making functional
changes.
General coding
--------------
- Use C99. Also freely make use of C99 features if it's appropriate, such as
stdbool.h.
- Don't use GNU-only features. In some cases they may be warranted, if they
are optional (such as attributes enabling printf-like format string checks).
But in general, standard C99 should be used.
- The same applies to libc functions. We have to be Windows-compatible too. Use
functions guaranteed by C99 or POSIX only, unless your use is guarded by a
configure check.
- Prefer fusing declaration and initialization, rather than putting declarations
on the top of a block. Obvious data flow is more important than avoiding
mixing declarations and statements, which is just a C90 artifact.
- tech-overview.txt might help to get an overview how mpv is structured.
- If you add features that require intrusive changes, discuss them on the dev
channel first. There might be a better way to add a feature and it can avoid
wasted work.
Sending patches
---------------
- Make a github pull request, or send a link to a plaintext patch created with
``git format-patch``. diffs posted as pastebins (especially if the http link
returns HTML) just cause extra work for everyone, because they lack commit
message and authorship information.
- Write informative commit messages. Use present tense to describe the
situation with the patch applied, and past tense for the situation before
the change.
- The subject line (the first line in a commit message) should contain a
prefix identifying the sub system, followed by a short description what
impact this commit has. This subject line shouldn't be longer than 72
characters, because it messes up the output of many git tools otherwise.
For example, you fixed a crash in af_volume.c:
Bad: ``fixed the bug (wtf?)``
Good: ``af_volume: fix crash due to null pointer access``
Having a prefix gives context, and is especially useful when trying to find
a specific change by looking at the history, or when running ``git blame``.
- The body of the commit message (everything else after the subject line) should
be as informative as possible and contain everything that isn't obvious. Don't
hesitate to dump as much information as you can - it doesn't cost you
anything. Put some effort into it. If someone finds a bug months or years
later, and finds that it's caused by your commit (even though your commit was
supposed to fix another bug), it would be bad if there wasn't enough
information to test the original bug. The old bug might be reintroduced while
fixing the new bug.
The commit message should be wrapped on 72 characters per line, because git
tools usually do not break text automatically. On the other hand, you do not
need to break text that would be unnatural to break (like data for test cases,
or long URLs).
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
change in the same commit.
+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")
+4 -4
View File
@@ -266,7 +266,7 @@ Available filters are:
Filter for internal use only. Converts between signed/unsigned formats
and formats with different endian.
``volume[=volumedb[:softclip[:s16]]]``
``volume[=<volumedb>[:...]]``
Implements software volume control. Use this filter with caution since it
can reduce the signal to noise ratio of the sound. In most cases it is
best to use the *Master* volume control of your sound card or the volume
@@ -279,14 +279,14 @@ Available filters are:
Sets the desired gain in dB for all channels in the stream from -200dB
to +60dB, where -200dB mutes the sound completely and +60dB equals a
gain of 1000 (default: 0).
``<softclip>``
``softclip``
Turns soft clipping on. Soft-clipping can make the
sound more smooth if very high volume levels are used. Enable this
option if the dynamic range of the loudspeakers is very low.
*WARNING*: This feature creates distortion and should be considered a
last resort.
``<s16>``
``s16``
Force S16 sample format if set. Lower quality, but might be faster
in some situations.
@@ -296,7 +296,7 @@ Available filters are:
Would amplify the sound by 10.1dB and hard-clip if the sound level
is too high.
``pan=n[:<matrix>]``
``pan=n:[<matrix>]``
Mixes channels arbitrarily. Basically a combination of the volume and the
channels filter that can be used to down-mix many channels to only a few,
e.g. stereo to mono, or vary the "width" of the center speaker in a
+4 -2
View File
@@ -1152,7 +1152,9 @@ OPTIONS
You can get the list of allowed codecs with ``mpv --vd=help``. Remove the
prefix, e.g. instead of ``lavc:h264`` use ``h264``.
By default this is set to ``h264,vc1,wmv3``.
By default this is set to ``h264,vc1,wmv3``. Note that the hardware
acceleration special codecs like ``h264_vdpau`` are not relevant anymore,
and in fact have been removed from Libav in this form.
This is usually only needed with broken GPUs, where a codec is reported
as supported, but decoding causes more problems than it solves.
@@ -1780,7 +1782,7 @@ OPTIONS
libquvi 0.9.x:
The following explanations are relevant:
`<http://quvi.sourceforge.net/doc/0.9/glossary_termino.html#m_stream_id>`_
`<http://quvi.sourceforge.net/r/api/0.9/glossary_termino.html#m_stream_id>`_
The ``quvi-format`` property can be used at runtime to cycle through the
list of formats. Unfortunately, this is slow. On libquvi 0.4.x, this
+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``::
+15 -4
View File
@@ -45,13 +45,24 @@ Essential dependencies (incomplete list):
- gcc or clang
- X development headers (xlib, X extensions, libvdpau, libGL, libXv, ...)
- Audio output development headers (libasound, pulseaudio)
- fribidi, freetype, fontconfig development headers (for libass)
- libass
- FFmpeg libraries (libavutil libavcodec libavformat libswscale libpostproc)
- libjpeg
- 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
Libass dependencies:
- gcc or clang, yasm on x86 and x86_64
- fribidi, freetype, fontconfig development headers (for libass)
FFmpeg dependencies:
- gcc or clang, yasm on x86 and x86_64
- OpenSSL (has to be explicitly enabled when compiling ffmpeg)
- libx264/libmp3lame/libfdk-aac if you want to use encoding (has to be
explicitly enabled when compiling ffmpeg)
- Libav also works, but some features will not work. (See section below.)
Most of the above libraries are available in suitable versions on normal
Linux distributions. However FFmpeg is an exception (distro versions may be
+1 -1
View File
@@ -1 +1 @@
0.3.6
0.3.8
+1 -1
View File
@@ -485,5 +485,5 @@ void mp_chmap_print_help(struct mp_log *log)
std_layout_names[n][0], std_layout_names[n][1]);
}
for (int n = 0; n < MP_NUM_CHANNELS; n++)
mp_info(log, " unknown%d\n", n);
mp_info(log, " unknown%d\n", n + 1);
}
+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;
}
+1 -2
View File
@@ -27,8 +27,7 @@ SOURCES_AUDIO_INPUT-$(ALSA) += stream/ai_alsa1x.c
SOURCES_AUDIO_INPUT-$(OSS) += stream/ai_oss.c
SOURCES_AUDIO_INPUT-$(SNDIO) += stream/ai_sndio.c
SOURCES-$(AUDIO_INPUT) += $(SOURCES_AUDIO_INPUT-yes)
SOURCES-$(CDDA) += stream/stream_cdda.c \
stream/cdinfo.c
SOURCES-$(CDDA) += stream/stream_cdda.c
SOURCES-$(DVBIN) += stream/dvb_tune.c \
stream/stream_dvb.c
SOURCES-$(DVDREAD) += stream/stream_dvd.c \
+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 -3
View File
@@ -750,11 +750,9 @@ static int mp_property_chapter_metadata(m_option_t *prop, int action, void *arg,
{
struct demuxer *demuxer = mpctx->master_demuxer;
int chapter = get_current_chapter(mpctx);
if (!demuxer || chapter < 0)
if (!demuxer || chapter < 0 || chapter >= demuxer->num_chapters)
return M_PROPERTY_UNAVAILABLE;
assert(chapter < demuxer->num_chapters);
return tag_property(prop, action, arg, demuxer->chapters[chapter].metadata);
}
+6 -1
View File
@@ -140,7 +140,10 @@ void mp_handle_nav(struct MPContext *mpctx)
case MP_NAV_EVENT_RESET_ALL: {
mpctx->stop_play = PT_RELOAD_DEMUXER;
MP_VERBOSE(nav, "reload\n");
break;
// return immediately.
// other events should be handled after reloaded.
talloc_free(ev);
return;
}
case MP_NAV_EVENT_RESET: {
nav->nav_still_frame = 0;
@@ -237,6 +240,8 @@ void mp_nav_get_highlight(struct osd_state *osd, struct mp_osd_res res,
talloc_free(sub->bitmap);
sub->bitmap = talloc_array(sub, uint32_t, sizes[0] * sizes[1]);
memset(sub->bitmap, 0x80, talloc_get_size(sub->bitmap));
nav->subsize[0] = sizes[0];
nav->subsize[1] = sizes[1];
}
sub->x = nav->highlight[0];
+8 -12
View File
@@ -64,6 +64,14 @@
#include "command.h"
#include "screenshot.h"
#if defined(__MINGW32__) || defined(__CYGWIN__)
#include <windows.h>
#ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE (0x0001)
#endif
#endif
#if HAVE_X11
#include "video/out/x11_common.h"
#endif
@@ -76,18 +84,6 @@
#include <pthread.h>
#endif
#if defined(__MINGW32__) || defined(__CYGWIN__)
#include <windows.h>
#ifndef BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE
#define BASE_SEARCH_PATH_ENABLE_SAFE_SEARCHMODE (0x0001)
#endif
#ifndef BASE_SEARCH_PATH_PERMANENT
#define BASE_SEARCH_PATH_PERMANENT (0x8000)
#endif
#endif
const char mp_help_text[] =
"Usage: mpv [options] [url|path/]filename\n"
"\n"
+4
View File
@@ -106,6 +106,10 @@ double get_start_time(struct MPContext *mpctx)
struct demuxer *demuxer = mpctx->demuxer;
if (!demuxer)
return 0;
// We reload the demuxer on menu transitions; don't make it use the first
// timestamp it finds as start PTS.
if (mpctx->nav_state)
return 0;
return demuxer_get_start_time(demuxer);
}
+1 -1
View File
@@ -66,7 +66,7 @@ static const char av_desync_help_text[] =
" Experiment with different values for --autosync, 30 is a good start.\n"
" If you have PulseAudio, try --ao=alsa .\n"
"- Slow video output.\n"
" Try a different -vo driver (-vo help for a list) or try -framedrop!\n"
" Try a different --vo driver (--vo=help for a list) or try --framedrop!\n"
"- Playing a video file with --vo=opengl with higher FPS than the monitor.\n"
" This is due to vsync limiting the framerate.\n"
"- Playing from a slow network source.\n"
-58
View File
@@ -1,58 +0,0 @@
/*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef MPLAYER_CDD_H
#define MPLAYER_CDD_H
#include <sys/types.h>
struct mp_log;
typedef struct cd_track {
char *name;
unsigned int track_nb;
unsigned int min;
unsigned int sec;
unsigned int msec;
unsigned long frame_begin;
unsigned long frame_length;
struct cd_track *prev;
struct cd_track *next;
} cd_track_t;
typedef struct {
char *artist;
char *album;
char *genre;
unsigned int nb_tracks;
unsigned int min;
unsigned int sec;
unsigned msec;
cd_track_t *first;
cd_track_t *last;
cd_track_t *current;
} cd_info_t;
cd_info_t* cd_info_new(void);
void cd_info_free(cd_info_t *cd_info);
cd_track_t* cd_info_add_track(cd_info_t *cd_info, char *track_name, unsigned int track_nb, unsigned int min, unsigned int sec, unsigned int msec, unsigned long frame_begin, unsigned long frame_length);
cd_track_t* cd_info_get_track(cd_info_t *cd_info, unsigned int track_nb);
void cd_info_debug(cd_info_t *cd_info, struct mp_log *log);
#endif /* MPLAYER_CDD_H */
-154
View File
@@ -1,154 +0,0 @@
/*
* CD Info
*
* Copyright (C) 2002 Bertrand Baudet <bertrand_baudet@yahoo.com>
*
* This file is part of MPlayer.
*
* MPlayer is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* MPlayer is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with MPlayer; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "common/msg.h"
#include "cdd.h"
/*******************************************************************************************************************
*
* xmcd parser, cd info list
*
*******************************************************************************************************************/
cd_info_t*
cd_info_new(void) {
cd_info_t *cd_info = NULL;
cd_info = malloc(sizeof(cd_info_t));
if( cd_info==NULL ) {
return NULL;
}
memset(cd_info, 0, sizeof(cd_info_t));
return cd_info;
}
void
cd_info_free(cd_info_t *cd_info) {
cd_track_t *cd_track, *cd_track_next;
if( cd_info==NULL ) return;
free(cd_info->artist);
free(cd_info->album);
free(cd_info->genre);
cd_track_next = cd_info->first;
while( cd_track_next!=NULL ) {
cd_track = cd_track_next;
cd_track_next = cd_track->next;
free(cd_track->name);
free(cd_track);
}
}
cd_track_t*
cd_info_add_track(cd_info_t *cd_info, char *track_name, unsigned int track_nb, unsigned int min, unsigned int sec, unsigned int msec, unsigned long frame_begin, unsigned long frame_length) {
cd_track_t *cd_track;
if( cd_info==NULL || track_name==NULL ) return NULL;
cd_track = malloc(sizeof(cd_track_t));
if( cd_track==NULL ) {
return NULL;
}
memset(cd_track, 0, sizeof(cd_track_t));
cd_track->name = malloc(strlen(track_name)+1);
if( cd_track->name==NULL ) {
free(cd_track);
return NULL;
}
strcpy(cd_track->name, track_name);
cd_track->track_nb = track_nb;
cd_track->min = min;
cd_track->sec = sec;
cd_track->msec = msec;
cd_track->frame_begin = frame_begin;
cd_track->frame_length = frame_length;
if( cd_info->first==NULL ) {
cd_info->first = cd_track;
}
if( cd_info->last!=NULL ) {
cd_info->last->next = cd_track;
}
cd_track->prev = cd_info->last;
cd_info->last = cd_track;
cd_info->current = cd_track;
cd_info->nb_tracks++;
return cd_track;
}
cd_track_t*
cd_info_get_track(cd_info_t *cd_info, unsigned int track_nb) {
cd_track_t *cd_track=NULL;
if( cd_info==NULL ) return NULL;
cd_track = cd_info->first;
while( cd_track!=NULL ) {
if( cd_track->track_nb==track_nb ) {
return cd_track;
}
cd_track = cd_track->next;
}
return NULL;
}
void cd_info_debug(cd_info_t *cd_info, struct mp_log *log)
{
cd_track_t *current_track;
mp_info(log, "================ CD INFO === start =========\n");
if( cd_info==NULL ) {
mp_info(log, "cd_info is NULL\n");
return;
}
mp_info(log, " artist=[%s]\n", cd_info->artist);
mp_info(log, " album=[%s]\n", cd_info->album);
mp_info(log, " genre=[%s]\n", cd_info->genre);
mp_info(log, " nb_tracks=%d\n", cd_info->nb_tracks);
mp_info(log, " length= %2d:%02d.%02d\n", cd_info->min, cd_info->sec, cd_info->msec);
mp_info(log, "ID_CDDB_INFO_ARTIST=%s\n", cd_info->artist);
mp_info(log, "ID_CDDB_INFO_ALBUM=%s\n", cd_info->album);
mp_info(log, "ID_CDDB_INFO_GENRE=%s\n", cd_info->genre);
mp_info(log, "ID_CDDB_INFO_LENGTH_MSF=%02d:%02d.%02d\n", cd_info->min, cd_info->sec, cd_info->msec);
mp_info(log, "ID_CDDB_INFO_TRACKS=%d\n", cd_info->nb_tracks);
current_track = cd_info->first;
while( current_track!=NULL ) {
mp_info(log, " #%2d %2d:%02d.%02d @ %7ld\t[%s] \n", current_track->track_nb, current_track->min, current_track->sec, current_track->msec, current_track->frame_begin, current_track->name);
mp_info(log, "ID_CDDB_INFO_TRACK_%d_NAME=%s\n", current_track->track_nb, current_track->name);
mp_info(log, "ID_CDDB_INFO_TRACK_%d_MSF=%02d:%02d.%02d\n", current_track->track_nb, current_track->min, current_track->sec, current_track->msec);
current_track = current_track->next;
}
mp_info(log, "================ CD INFO === end =========\n");
}
+1
View File
@@ -187,6 +187,7 @@ static int bluray_stream_control(stream_t *s, int cmd, void *arg)
return STREAM_UNSUPPORTED;
*((double *) arg) = BD_TIME_TO_MP(ti->duration);
bd_free_title_info(ti);
return STREAM_OK;
}
+16 -68
View File
@@ -46,8 +46,6 @@
#include "libavutil/common.h"
#include "compat/mpbswap.h"
#include "cdd.h"
#include "common/msg.h"
typedef struct {
@@ -56,7 +54,6 @@ typedef struct {
int sector;
int start_sector;
int end_sector;
cd_info_t *cd_info;
// options
int speed;
@@ -132,8 +129,8 @@ static bool print_cdtext(stream_t *s, int track)
#else
cdtext_t *text = cdio_get_cdtext(p->cd->p_cdio);
#endif
int header = 0;
if (text) {
MP_INFO(s, "CD-Text (%s):\n", track ? "track" : "CD");
for (int i = 0; i < sizeof(cdtext_name) / sizeof(cdtext_name[0]); i++) {
const char *name = cdtext_name[i];
#ifdef OLD_API
@@ -141,8 +138,12 @@ static bool print_cdtext(stream_t *s, int track)
#else
const char *value = cdtext_get_const(text, i, track);
#endif
if (name && value)
if (name && value) {
if (!header)
MP_INFO(s, "CD-Text (%s):\n", track ? "track" : "CD");
header = 1;
MP_INFO(s, " %s: '%s'\n", name, value);
}
}
return true;
}
@@ -151,17 +152,8 @@ static bool print_cdtext(stream_t *s, int track)
static void print_track_info(stream_t *s, int track)
{
cdda_priv* p = (cdda_priv*)s->priv;
cd_track_t *cd_track = cd_info_get_track(p->cd_info, track);
if( cd_track!=NULL ) {
MP_INFO(s, "\n%s\n", cd_track->name);
MP_INFO(s, "ID_CDDA_TRACK=%d\n",
cd_track->track_nb);
}
if (print_cdtext(s, track)) {
// hack for term OSD overwriting the last line of CDTEXT
MP_INFO(s, "\n");
}
MP_INFO(s, "Switched to track %d\n", track);
print_cdtext(s, track);
}
static void cdparanoia_callback(long int inpos, paranoia_cb_mode_t function)
@@ -242,7 +234,6 @@ static void close_cdda(stream_t *s)
cdda_priv *p = (cdda_priv *)s->priv;
paranoia_free(p->cdp);
cdda_close(p->cd);
cd_info_free(p->cd_info);
free(p);
}
@@ -273,37 +264,18 @@ static int control(stream_t *stream, int cmd, void *arg)
*(unsigned int *)arg = end_track + 1 - start_track;
return STREAM_OK;
}
case STREAM_CTRL_SEEK_TO_CHAPTER:
case STREAM_CTRL_GET_CHAPTER_TIME:
{
int r;
unsigned int track = *(unsigned int *)arg;
int track = *(double *)arg;
int start_track = get_track_by_sector(p, p->start_sector);
int end_track = get_track_by_sector(p, p->end_sector);
int seek_sector;
if (start_track == -1 || end_track == -1)
track += start_track + 1;
if (track > end_track)
return STREAM_ERROR;
track += start_track;
if (track > end_track) {
seek(stream, (p->end_sector + 1) * CDIO_CD_FRAMESIZE_RAW);
// seeking beyond EOF should not be an error,
// the cache cannot handle changing stream pos and
// returning error.
return STREAM_OK;
}
seek_sector = track == 0 ? p->start_sector
: p->cd->disc_toc[track].dwStartSector;
r = seek(stream, seek_sector * CDIO_CD_FRAMESIZE_RAW);
if (r)
return STREAM_OK;
break;
}
case STREAM_CTRL_GET_CURRENT_CHAPTER:
{
int start_track = get_track_by_sector(p, p->start_sector);
int cur_track = get_track_by_sector(p, p->sector);
if (start_track == -1 || cur_track == -1)
return STREAM_ERROR;
*(unsigned int *)arg = cur_track - start_track;
int64_t sector = p->cd->disc_toc[track].dwStartSector;
int64_t pos = sector * (CDIO_CD_FRAMESIZE_RAW + 1) - 1;
// Assume standard audio CD: 44.1khz, 2 channels, s16 samples
*(double *)arg = pos / (44100.0 * 2 * 2);
return STREAM_OK;
}
}
@@ -317,10 +289,7 @@ static int open_cdda(stream_t *st, int m)
int mode = p->paranoia_mode;
int offset = p->toc_offset;
cdrom_drive_t *cdd = NULL;
cd_info_t *cd_info;
unsigned int audiolen = 0;
int last_track;
int i;
if (m != STREAM_READ) {
return STREAM_UNSUPPORTED;
@@ -355,29 +324,9 @@ static int open_cdda(stream_t *st, int m)
return STREAM_ERROR;
}
cd_info = cd_info_new();
MP_INFO(st, "Found audio CD with %d tracks.\n",
(int)cdda_tracks(cdd));
for (i = 0; i < cdd->tracks; i++) {
char track_name[80];
long sec = cdda_track_firstsector(cdd, i + 1);
long off = cdda_track_lastsector(cdd, i + 1) - sec + 1;
sprintf(track_name, "Track %d", i + 1);
cd_info_add_track(cd_info, track_name, i + 1,
(unsigned int)(off / (60 * 75)),
(unsigned int)((off / 75) % 60),
(unsigned int)(off % 75), sec, off);
audiolen += off;
}
cd_info->min = (unsigned int)(audiolen / (60 * 75));
cd_info->sec = (unsigned int)((audiolen / 75) % 60);
cd_info->msec = (unsigned int)(audiolen % 75);
priv = malloc(sizeof(cdda_priv));
memset(priv, 0, sizeof(cdda_priv));
priv->cd = cdd;
priv->cd_info = cd_info;
if (p->toc_bias)
offset -= cdda_track_firstsector(cdd, 1);
@@ -411,7 +360,6 @@ static int open_cdda(stream_t *st, int m)
if (priv->cdp == NULL) {
cdda_close(cdd);
free(priv);
cd_info_free(cd_info);
return STREAM_ERROR;
}
+37 -30
View File
@@ -298,42 +298,47 @@ static void handle_cmd(stream_t *s, struct mp_nav_cmd *ev)
}
static inline bool set_event_type(struct priv *priv, int type,
struct mp_nav_event *event)
{
if (!(priv->next_event & (1 << type)))
return false;
priv->next_event &= ~(1 << type);
event->event = type;
return true;
}
static void fill_next_event(stream_t *s, struct mp_nav_event **ret)
{
struct priv *priv = s->priv;
struct mp_nav_event e = {0};
for (int n = 0; n < 30; n++) {
if (priv->next_event & (1 << n)) {
priv->next_event &= ~(1 << n);
e.event = n;
switch (e.event) {
case MP_NAV_EVENT_HIGHLIGHT: {
dvdnav_highlight_event_t hlev = priv->hlev;
e.u.highlight.display = hlev.display;
e.u.highlight.sx = hlev.sx;
e.u.highlight.sy = hlev.sy;
e.u.highlight.ex = hlev.ex;
e.u.highlight.ey = hlev.ey;
e.u.highlight.palette = hlev.palette;
break;
}
case MP_NAV_EVENT_MENU_MODE:
e.u.menu_mode.enable = !dvdnav_is_domain_vts(priv->dvdnav);
break;
case MP_NAV_EVENT_STILL_FRAME:
e.u.still_frame.seconds = priv->still_length;
break;
}
break;
}
if (!set_event_type(priv, MP_NAV_EVENT_RESET_ALL, &e))
for (int n = 0; n < 30 && !set_event_type(priv, n, &e); n++) ;
switch (e.event) {
case MP_NAV_EVENT_NONE:
return;
case MP_NAV_EVENT_HIGHLIGHT: {
dvdnav_highlight_event_t hlev = priv->hlev;
e.u.highlight.display = hlev.display;
e.u.highlight.sx = hlev.sx;
e.u.highlight.sy = hlev.sy;
e.u.highlight.ex = hlev.ex;
e.u.highlight.ey = hlev.ey;
e.u.highlight.palette = hlev.palette;
break;
}
if (e.event) {
*ret = talloc(NULL, struct mp_nav_event);
**ret = e;
case MP_NAV_EVENT_MENU_MODE:
e.u.menu_mode.enable = !dvdnav_is_domain_vts(priv->dvdnav);
break;
case MP_NAV_EVENT_STILL_FRAME:
e.u.still_frame.seconds = priv->still_length;
break;
}
*ret = talloc(NULL, struct mp_nav_event);
**ret = e;
MP_VERBOSE(s, "DVDNAV: player event '%s'\n",
LOOKUP_NAME(mp_nav_event_types, e.event));
}
MP_VERBOSE(s, "DVDNAV: player event '%s'\n",
LOOKUP_NAME(mp_nav_event_types, e.event));
}
static int fill_buffer(stream_t *s, char *buf, int max_len)
@@ -414,6 +419,8 @@ static int fill_buffer(stream_t *s, char *buf, int max_len)
priv->had_initial_vts = true;
break;
}
// clear all previous events
priv->next_event = 0;
priv->next_event |= 1 << MP_NAV_EVENT_RESET;
priv->next_event |= 1 << MP_NAV_EVENT_RESET_ALL;
if (dvdnav_current_title_info(dvdnav, &tit, &part) == DVDNAV_STATUS_OK)
+1
View File
@@ -33,6 +33,7 @@ mf_stream_open (stream_t *stream, int mode)
{
stream->type = STREAMTYPE_MF;
stream->demuxer = "mf";
stream->allow_caching = false;
return STREAM_OK;
}
+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
+1
View File
@@ -91,5 +91,6 @@ void mp_buffer_ref(struct FrameBuffer *buffer);
void mp_buffer_unref(struct FrameBuffer *buffer);
bool mp_buffer_is_unique(struct FrameBuffer *buffer);
void mp_buffer_pool_free(struct FramePool **pool);
bool mp_buffer_check(struct FrameBuffer *buffer);
#endif
+10
View File
@@ -204,6 +204,16 @@ void mp_buffer_ref(struct FrameBuffer *buf)
pool_unlock();
}
bool mp_buffer_check(struct FrameBuffer *buf)
{
pool_lock();
bool ok = buf->refcount > 0;
if (ok)
buf->refcount++;
pool_unlock();
return ok;
}
void mp_buffer_unref(struct FrameBuffer *buf)
{
FramePool *pool = buf->pool;
+12 -1
View File
@@ -706,7 +706,16 @@ static struct mp_image *image_from_decoder(struct dec_video *vd)
mp_image_copy_attributes(mpi, &new);
} else if (ctx->do_dr1 && pic->opaque) {
struct FrameBuffer *fb = pic->opaque;
mp_buffer_ref(fb); // initial reference for mpi
// initial reference for mpi
if (!new.planes[0] || !mp_buffer_check(fb)) {
// Decoder returned an unreferenced buffer! Taking this would just
// lead to an eventual double-free. Nothing we can do about this.
// So just say "fuck you" in a nice way.
MP_FATAL(vd,
"Impossible condition detected! This version of Libav/FFmpeg is not\n"
"supported anymore. Please update.\n");
return NULL;
}
mpi = mp_image_new_external_ref(&new, fb, fb_ref, fb_unref,
fb_is_unique, NULL);
} else {
@@ -752,6 +761,8 @@ static int decode(struct dec_video *vd, struct demux_packet *packet,
// Note: potentially resets ctx->pic as it is transferred to mpi
struct mp_image *mpi = image_from_decoder(vd);
if (!mpi)
return 0;
assert(mpi->planes[0]);
mp_image_set_params(mpi, &params);
-1
View File
@@ -469,7 +469,6 @@ int vf_open(vf_instance_t *vf)
vf->filter = filter;
vf->uninit = uninit;
vf->priv = malloc (sizeof (vf_eq2_t));
eq2 = vf->priv;
eq2->log = vf->log;
+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;
+7
View File
@@ -330,9 +330,16 @@ static LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam,
// Window dragging hack
ReleaseCapture();
SendMessage(hWnd, WM_NCLBUTTONDOWN, HTCAPTION, 0);
mp_input_put_key(vo->input_ctx, MP_MOUSE_BTN0 |
MP_KEY_STATE_UP);
return 0;
}
}
if (mouse_button & MP_KEY_STATE_DOWN)
SetCapture(w32->window);
else
ReleaseCapture();
}
return DefWindowProcW(hWnd, message, wParam, lParam);
-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);
+1 -1
View File
@@ -6,7 +6,7 @@ def __get_version__(ctx):
cwd=ctx.srcnode.abspath())
process.wait()
(version, err) = process.communicate()
return version.strip().decode("utf-8")
return version.strip().decode('utf-8').encode('ascii', 'ignore')
def __get_build_date__():
import time
-1
View File
@@ -239,7 +239,6 @@ def build(ctx):
( "stream/ai_sndio.c", "sndio" ),
( "stream/audio_in.c", "audio-input" ),
( "stream/cache.c" ),
( "stream/cdinfo.c", "cdda"),
( "stream/cookies.c" ),
( "stream/dvb_tune.c", "dvbin" ),
( "stream/frequencies.c", "tv" ),