Compare commits

..
102 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
wm4 689c3f47a8 Release 0.3.6 2014-03-11 00:23:11 +01:00
wm4 677d4615ba Revert "player: simplify audio reset when seeking"
This reverts commit 75dd3ec210.

This broke seeking with ordered chapters in some situations. While
the reverted commit was perfectly fine for playback of normal files,
it overlooked that in the ordered chapters case switching segments
actually reinitialized the audio chain completely, including the
decoder. And decoders still read packets on initialization. We can
restore the original commit as soon as decoders stop doing this.
2014-03-11 00:22:33 +01:00
wm4 5f788a7812 ao_alsa: fix return value for volume operations with spdif
This AO pretended to support volume operations when in spdif passthrough
mode, but actually did nothing. This is wrong: at least the GET
operations must write their argument. Signal that volume is unsupported
instead.

This was probably a hack to prevent insertion of volume filters or so,
but it didn't work anyway, while recovering after failed volume filter
insertion does work, so this is not needed at all.
2014-03-11 00:21:45 +01:00
foo86 dba25e13c0 ao_alsa: check ALSA PCM state before pause and resume
It is possible to have ao->reset() called between ao->pause() and
ao->resume() when seeking during the pause. If the underlying PCM
supports pausing, resuming an already reset PCM will produce an error.
Avoid that by explicitly checking PCM state before calling
snd_pcm_pause().

Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:21:32 +01:00
Hans-Kristian Arntzen 623b97e45a ao_rsound: pass correct data type to rsd_set_param()
Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:20:56 +01:00
Hans-Kristian Arntzen 7a645ba62f build: fix compilation with MinGW-w64
References to WinMM/OLE/UUID were missing.

Signed-off-by: wm4 <wm4@nowhere>
2014-03-11 00:20:53 +01:00
wm4 63afe3eb98 lua: add license header
Oops.
2014-03-11 00:20:26 +01:00
wm4 72c70eb05b ao_jack: fix termination on the end of file
The player didn't quit when the end of a file was reached. The reason
for this is that jack reported a constant audio delay even when all
audio was done playing. Whether that was recognized as EOF by the player
depended whether the exact value was higher or lower than the player's
threshhold for what it considers no more audio.

get_delay() should return amount of time it takes until the last sample
written to the audio buffer reaches the speaker. Therefore, we have to
track the estimated time when the last sample is done, and subtract it
from the calculated latency. Basically, the latency is the only amount
of time left in the delay, and it should go towards 0 as audio reaches
ths speakers.

I'm not sure if this is correct, but at least it solves the problem. One
suspicious thing is that we use system time to estimate the end of the
audio time. Maybe using jack_frame_time() would be more correct. But
apart from this, there doesn't seem to be a better way to handle this.
2014-03-11 00:19:56 +01:00
wm4 df0ec55499 build: update waf
<lachs0r> it fixes issues with recent python3
2014-03-11 00:19:43 +01:00
wm4 542bcdfc9d command: fix null pointer dereference in idle mode
Pressing 'h' in idle mode -> crash.
2014-03-11 00:19:26 +01:00
Andrey Morozov 218667b5a2 vdpau: change the error message when video too large 2014-03-11 00:16:46 +01:00
wm4 13a0e34aec example.conf: change subtitle codepage example to use UTF-8 fallback
This should be pretty safe compared to forcing the codepage.
2014-03-11 00:16:20 +01:00
Yaser Alraddadi 76b7a1a713 example.conf: subtitle encoding
Signed-off-by: wm4 <wm4@nowhere>

Closes #580.
2014-03-11 00:16:18 +01:00
wm4 6d6eee2e70 manpage: fix yadif example in one case 2014-03-11 00:15:53 +01:00
wm4 89f20cd2f3 input: check for abort cmd in multi-commands
MP_CMD_COMMAND_LIST commands (used to implement key bindings with
multiple commands) were not checked for abort commands. Implement it.

Remove the remarks about multi-commands being special from the manpage.
Seek coalescing is handled differently now, and the issue with abort
commands is fixed with this commit.
2014-03-11 00:14:30 +01:00
James Ross-Gowan cce2b675ac input: ignore modifiers when releasing keys
This prevents keys from getting stuck if the modifier is released before
the base key.
2014-03-11 00:14:22 +01:00
wm4 c1ed4dc242 video: add rounding to aspect ratio calculations
Small errors are unavoidable, but truncation can cause anamorphic video
to be off by 1 or 2 pixels.
2014-03-11 00:13:57 +01:00
wm4 712657a894 player: fix start time if timeline is used (ordered chapters, EDL)
When timeline was used, and the --start option was not used, the initial
seek (needed to switch to the first timeline segment) seeked to -1 due
to an oversight.

Conflicts:
	player/loadfile.c
2014-03-11 00:13:39 +01:00
wm4 496956de3d edl: fix offset of user-visible chapters
Basically, chapter marks and chapter seek-points were incorrect, while
the rest worked.
2014-03-11 00:12:25 +01:00
James Ross-Gowan 483e703793 w32_common: don't set small icon
Windows will automatically choose the correct icon size if this field is
unset.
2014-03-11 00:12:00 +01:00
elevengu 717cdeb95d win32: restore support for exe directory as config directory
Same rationale as b2c2fe7a but updated to work with path-win.c

Signed-off-by: wm4 <wm4@nowhere>

Merges/closes #543.
2014-03-11 00:10:20 +01:00
wm4 315f3a9218 crosscompile-mingw: improve instructions for MXE 2014-03-11 00:10:17 +01:00
xylosper d857722618 sd_lavc: handle subtitles with no subtitle resolution set
Set subtitle resolution to video resolution when avctx->width and
avctx->height are zero.

This can happen with broken vobsubs that have no size set in their
.idx file (or Matroska extradata). At least with the test file provided
in issue #551, using the video resolution as fallback instead of what
guess_resolution() does is better.

Note that these files clearly are broken. It seems this particular
file was created by trying to use ffmpeg to transcode DVB subtitles
to vobsub, and ffmpeg "forgot" to set the subtitle resolution in the
destination file. On the other hand, ffmpeg DVB and PGS decoders set
the resolution on the first subtitle packet (or somewhere close), so
it's not really clear what to do here.

Closes #551.

Signed-off-by: wm4 <wm4@nowhere>

Patch by xylosper, rewritten commit message by wm4.
2014-03-11 00:09:52 +01:00
Diogo Franco (Kovensky) 6d9d597b10 Parse::Matroska::Reader: get rid of bigrat
It seems that it was causing issues with certain perl setups (such as
the one on issue #549). It also turns out that it was not behaving correctly
(not all constants were being promoted to big nums as they should), so we
use explicit objects to derive the constants.

There were also precedence issues. I wonder if this even worked right to
begin with.

The 'double' path (8-byte floats) is untested, as I couldn't easily find
a file with such a field.

Closes #549.
2014-03-11 00:08:57 +01:00
Diogo Franco (Kovensky) c4d905b567 build: Add -U__STRICT_ANSI__ to CFLAGS on Cygwin
Cygwin's libc (newlib) doesn't obey a lot of unix feature test macros,
including _GNU_SOURCE; as a result, a lot of functions and defines get
masked out -- important defines such as M_PI and strcasecmp. Work around
it by undefining __STRICT_ANSI__ on cygwin systems.

This will still cause compilation issues on any non-cygwin system that
uses newlib, but hopefully nobody does that, or if they do, they will
find this commit message and know to add -U__STRICT_ANSI__ to their
CFLAGS. Hopefully.
2014-03-11 00:08:53 +01:00
wm4 e4c69376fc sub: handle vobsub-in-mp4
The mplayer decoder (spudec.c) actually handled this. There was explicit
code for binary palettes (16 32 bit values), and the subtitle resolution
was handled by video resolution coincidentally matching the subtitle
resolution.

Whoever puts vobsub into mp4 should be punished.

Fixes the sample gundam_sample.mp4, closes github issue #547.
2014-03-11 00:08:29 +01:00
wm4 842689bbf6 sd_lavc: use mp_lavc_set_extradata()
This includes the magical input padding required by libavcodec, which we
possibly didn't do before this commit.
2014-03-11 00:07:57 +01:00
wm4 5ab2aa84e0 Factor out setting AVCodecContext extradata 2014-03-11 00:07:51 +01:00
Stefano Pigozzi 229d398ba9 cocoa: fix deadlock during initialization [2]
Fixup commit for 20fa191ad.
2014-03-11 00:04:15 +01:00
wm4 5f1b155307 build: bump libmpg123 version
The minimum required version was bumped in the old configure script, but
for the waf build system is was somehow forgotten or overlooked.
Probably happened while the waf build system was developed in a separate
branch.

Closes #546.
2014-03-11 00:04:10 +01:00
Stefano Pigozzi 241cbe5065 cocoa: fix deadlock during initialization
Thanks to @wm4 for catching the bug.

Fixes #405
2014-03-11 00:04:07 +01:00
wm4 76d771a6fa Release 0.3.5 2014-02-12 22:39:52 +01:00
nand 19caba0794 vo_opengl: make :srgb decompand the BT.709 values correctly
This is the same issue as addressed by 257d9f1, except this time for
the :srgb option as well. (257d9f1 only addressed :icc-profile)

The conditions of the srgb_compand mix() call are also flipped to
prevent an off-by-one error.
2014-02-12 22:34:44 +01:00
wm4 391546c52f command: fix metadata property
This crashed when retrieving the raw property value. Oops.
2014-02-12 22:34:28 +01:00
Alexander Preisinger a8af6a7852 wayland/shm: prevent the window from flying away
With the new xdg_shell the problem will be no gone by itself.
2014-02-12 22:34:09 +01:00
wm4 960aca3386 manpage: document --aspect special values
Use of these is "discouraged", but they're there to select these special
cases with the "aspect" property. They really should use some sort of
choice option type, but since it would be some work to make these work
with float values, the simple and dumb alternative was picked.
2014-02-12 22:33:54 +01:00
wm4 e72a327d74 video: fix --no-aspect
This also affects the --aspect option and the "aspect" property.
2014-02-12 22:33:52 +01:00
nand 87f955f3e9 vo_opengl: fix typo in gamma function's parameter
The correct value is 0.081, not 0.18. The scale factor also needed
slight adjustment due to the order of operations.
2014-02-12 22:33:32 +01:00
Jonas Zetterberg 5536ebe82f vo_vdpau: Discard zero timestamps
Some drivers do not supply timestamps, use old timestamp in these conditions.
2014-02-12 22:33:29 +01:00
Jonas Zetterberg ef8b37ca2a vo_vdpau: Ensure presentation time is within bounds
When a time sync happens the last sync time is the minimum time that can be
used for presentation.
2014-02-12 22:33:27 +01:00
wm4 d4a5513847 demux: fix some newlines in output messages 2014-02-12 22:33:09 +01:00
wm4 d42212cd67 player: fix an assert when reinitializing audio in some cases
This sometimes happened when changing playback speed (= reinitializing
audio) after seeking of playback start. The assertion in audio.c:441 was
triggered, because buffer_playable_samples wasn't reset correctly when
the audio buffer was cleared or shortened. The assertion is correct and
should hold up any time.
2014-02-12 22:33:03 +01:00
nand 674cc1d3a9 vo_opengl: use exactly the values defined by BT.709 for CMS
I could not see any difference whatsoever, but for usage with a 3DLUT
there's zero performance difference so we might as well follow the spec to
the letter.
2014-02-12 22:32:56 +01:00
wm4 c47bb9ca42 gl_x11: don't require a X visual for modern GL context creation
Legacy GL context creation (glXCreateContext) explicitly requires a X
visual, while the modern one (glXCreateContextAttribsARB) does not for
some reason. So fail only on the legacy code path if we don't find a
visual. Note that vo_x11_config_vo_window() will select a default visual
if a NULL visual is passed to it.
2014-02-12 22:32:43 +01:00
wm4 938dad0b88 gl_x11: always request true color visual
This fixes issue #504. For some reason, glXChooseFBConfig() will return
a fbconfig with no associated visual. (I'm not sure if this allowed.
They don't always have a visual, but since GLX_X_RENDERABLE is set
and GLX_DRAWABLE_TYPE is (implicitly) set to GLX_WINDOW_BIT, why would
there be no visual?)

Even worse, a test program seems to show that a 16 bit fbconfig is
selected (instead of 24/32 bit), which doesn't sound nice at all. Since
there _are_ better fbconfigs available, glXChooseFBConfig() should
normally sort them by quality, and return the better ones first. It's
worth noting that this function should also prefer GLX_TRUE_COLOR
over anything else, although this comes last in the sort order.

Whatever is going on, requesting GLX_X_VISUAL_TYPE with GLX_TRUE_COLOR
seems to fix it.
2014-02-12 22:32:40 +01:00
wm4 82b5361946 umpv: silence mpv terminal output
Now it does basically the same as mkv.desktop. Explanation is included
in the description comment.
2014-02-12 22:32:06 +01:00
wm4 f99f48684b umpv: improve description 2014-02-12 22:32:04 +01:00
wm4 25864a5539 umpv: use --force-window
This makes it show a window even when playing audio-only files.
2014-02-12 22:32:02 +01:00
wm4 524d9585fd audio: fix signedness of AF_FORMAT_S32P
This was marked as unsigned, but it's signed. Found by xylosper.
2014-02-12 22:32:00 +01:00
wm4 95a72baf92 mf: don't limit filename length with PATH_MAX
Use an arbitrary constant instead, which is as good as PATH_MAX.

This helps us to avoid having to think about pull request #523.

Also fix a case where a potentially signed char was passed to isspace().
2014-02-12 22:31:54 +01:00
wm4 48112a74ed player: refresh OSD on track switching
Apparently, at least sub_reload was missing a refresh at all.
2014-02-12 22:31:40 +01:00
Alexander Preisinger 8427cdc717 wayland: change minimum version
Change minimum version to 1.3 and remove the version checking in the source
code.
2014-02-12 22:31:27 +01:00
wm4 b695ca1e27 x11: fix initial VO size
This was done incorrectly in the previous commit: the fallback size used
the window size as requested with the first config call, which is the
size of the hidden window in the vo_opengl case. (That damn hidden
window again...)

Conflicts:
	video/out/x11_common.c
2014-02-12 22:31:21 +01:00
wm4 801feb6420 x11: remove apparently useless code
This code essentially does nothing. As far as I could find out, this
actually used to do something. Then it was removed with commit efe7c39f,
leaving some leftover code that didn't do anything useful. This happened
12 years ago!

Also remove a commented debug printf.
2014-02-12 22:30:34 +01:00
wm4 de6a452039 x11: fix race condition when setting aspect when leaving fullscreen
vo_opengl creates a hidden X11 window to probe the OpenGL context. It
must do that before creating a visible window, because VO creation and
VO config are separate phases.

There's a race condition involving the hidden window: when starting with
--fs, and then leaving fullscreen, the unfullscreened window is
sometimes set to the aspect ratio of the hidden window. I'm not sure why
the window size itself uses the correct size (but corrupted by the wrong
aspect), but that's perhaps because the window manager is free to ignore
the size hint while honoring the aspect, or something equally messed up.

It turns out this happens because x11_common.c thinks the size of the
hidden window is the size of the unfullscreened window. This in turn
happens because vo_x11_update_geometry() reads the size of the hidden
window when called in vo_x11_fullscreen() (called from
vo_x11_config_vo_window()) when mapping the fullscreen window. At that
point, the window could be mapped, but not necessarily. If it's not
mapped, it will get the size of the unfullscreened window... I think.

One could fix this by actively waiting until the window is mapped. Try
to pick a less hacky approach instead, and never read the window size
until MapNotify is received.

vo_x11_create_window() needs a hack, because we'd possibly set the VO's
size to 0, resulting e.g. in vdpau to fail initialization. (It'll print
error messages until a proper resize is received.)

Conflicts:
	video/out/x11_common.c
2014-02-12 22:30:23 +01:00
wm4 4b764b6cc6 old-configure: use -std=c99
See previous commit.
2014-02-12 22:29:50 +01:00
wm4 7b7c31b190 build: switch to -std=c99 for saner float semantics
This fixes a weird bug with aspect ratio handling. It has to do with
float handling: with -std=gnu99, gcc implicitly enables broken non-
standard semantics giving float variables excess precision. This can for
example make this fail in theory: "float a = 0.1; assert(a == a);"

While standard C allows excess precision _within_ expressions, it
requires truncation when storing float values in variables of types
"float" or "double". The "gnu99" mode breaks this. It can be unbroken by
using "c99", or by specifying -fexcess-precision=standard. The former
seems less likely to break compilers other than modern gcc. Note that
-ffloat-store would also fix this, but also makes float expressions less
efficient and less precise for no reason.

The code that mistakenly fails because of this is dec_video.c line 393.
It caused the container aspect to be ignored in some or all situations,
depending how the compiler optimizes. For example, on gcc-4.6 with -Os,
the aspect is always ignored.

In future, we should probably just get rid of storing aspects as floats.

Note: requires mingw-w64 trunk for math.h fixes (M_PI was hidden).
2014-02-12 22:29:21 +01:00
wm4 70a66b461d cache: refuse to seek outside of cache boundaries
Note that this still happens in the stream level, so we can't have
nice highlevel behavior restricting seeking. Instead, if a seek leads
to the demuxer requesting data outside of the cached range, the seek
will simply fail. This might confuse the demuxer, and the resulting
behavior is not necessarily useful.

Note that this also doesn't try to skip data on a forward seek. This
would just freeze the stream with slow unseekable streams.

One nice thing is that stream.h has a separate function for merely
skipping data (separate from seeking forward), which is pretty useful
in this case: we want skipping of data to work, even if we reject
seeking forward by skipping data as too expensive. This probably is
or will be useful for demux_mkv.c.
2014-02-12 22:29:11 +01:00
76 changed files with 673 additions and 603 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.
+2
View File
@@ -9,6 +9,8 @@ Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
Alternatively, use MXE: http://mxe.cc
With MXE, you have to modify the file settings.mk to target MinGW-w64 (even if
you compile to 32 bit).
Warning: the original MinGW (http://www.mingw.org) is unsupported.
+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
-5
View File
@@ -52,11 +52,6 @@ You can bind multiple commands to one key. For example:
| a show_text "command 1" ; show_text "command 2"
Note that some magic is disabled for keys: seek commands inside lists are not
coalesced (seeking will appear slower), and no check is done for abort commands
(so these commands can't be used to abort playback if the network cache is
stuck).
List of Input Commands
----------------------
+12 -3
View File
@@ -103,6 +103,13 @@ OPTIONS
Override movie aspect ratio, in case aspect information is incorrect or
missing in the file being played. See also ``--no-aspect``.
Two values have special meaning:
:0: disable aspect ratio handling, pretend the video has square pixels
:-1: use the video stream or container aspect (default)
But note that handling of these special values might change in the future.
.. admonition:: Examples
- ``--aspect=4:3`` or ``--aspect=1.3333``
@@ -789,7 +796,7 @@ OPTIONS
``--field-dominance=<auto|top|bottom>``
Set first field for interlaced content. Useful for deinterlacers that
double the framerate: ``--vf=yadif=1`` and ``--vo=vdpau:deint``.
double the framerate: ``--vf=yadif=field`` and ``--vo=vdpau:deint``.
:auto: (default) If the decoder does not export the appropriate
information, it falls back on ``top`` (top field first).
@@ -1145,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.
@@ -1773,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
+20 -17
View File
@@ -132,7 +132,8 @@ sub _bin2int($) {
# creates a floating-point number with the given mantissa and exponent
sub _ldexp {
my ($mantissa, $exponent) = @_;
return $mantissa * Math::BigRat->new(2)**$exponent;
my $r = new Math::BigRat($mantissa);
return $r * Math::BigRat->new(2)**$exponent;
}
# NOTE: the read_* functions are hard to read because they're ports
@@ -252,25 +253,27 @@ bytes from the internal filehandle.
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
=cut
sub read_float {
my ($self, $length) = @_;
my $i = $self->read_uint($length);
my $f;
{
my $b1 = new Math::BigInt 1;
use bigrat try => BIGINT_TRY;
sub read_float {
my ($self, $length) = @_;
my $i = new Math::BigInt $self->read_uint($length)->bstr;
my $f;
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & (1<<23 - 1)) + (1<<23), ($i>>23 & (1<<8 - 1)) - 150);
$f = -$f if $i & (1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (1<<52 - 1)) + (1<<52), ($i>>52 & (1<<12 - 1)) - 1075);
$f = -$f if $i & (1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
# These evil expressions reinterpret an unsigned int as IEEE binary floats
if ($length == 4) {
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
$f = -$f if $i & ($b1<<31);
} elsif ($length == 8) {
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
$f = -$f if $i & ($b1<<63);
} else {
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
}
return $f;
}
return $f;
}
=method read_ebml_id($length)
+15 -13
View File
@@ -3,20 +3,18 @@
"""
This script emulates "unique application" functionality on Linux. When starting
playback with this script, it will try to reuse an already running instance of
mpv (but only if that was started with umpv).
mpv (but only if that was started with umpv). Other mpv instances (not started
by umpv) are ignored, and the script doesn't know about them.
This script only uses mpv instances started with umpv. Other instances are
ignored, and don't exist for the script.
This only takes filenames as arguments. If mpv is already running, they are
appended to mpv's internal playlist. If the file does not exist or is otherwise
not playable, mpv will skip the playlist entry when attempting to play it (from
the GUI perspective, it's silently ignored).
This only takes filenames as arguments. Custom options can't be used; the script
interprets them as filenames. If mpv is already running, the files passed to
umpv are appended to mpv's internal playlist. If a file does not exist or is
otherwise not playable, mpv will skip the playlist entry when attempting to
play it (from the GUI perspective, it's silently ignored).
If mpv isn't running yet, this script will start mpv and let it control the
current terminal. If you play an audio-only file, mpv will not open a window
(that is its normal behavior; but it might not be what a user expects if this
script is used in a GUI setting).
current terminal. It will not write output to stdout/stderr, because this
will typically just fill ~/.xsession-errors with garbage.
mpv will terminate if there are no more files to play, and running the umpv
script after that will start a new mpv instance.
@@ -28,7 +26,10 @@ Note that you can control the mpv instance by writing to the command fifo:
Warning:
The script attempts to make sure the FIFO is safely created (i.e. not world-
readable, not trying to open a bogus
writable), and checks that it's really a FIFO. This is important for security,
because the FIFO allows anyone with write access to run arbitrary commands
in mpv's context using the "run" input command. If you are worried about
security, you should verify that the code handles these concerns correctly.
"""
import sys
@@ -88,4 +89,5 @@ else:
raise e
os.mkfifo(FIFO, 0600)
subprocess.check_call(["mpv", "--input-file=" + FIFO] + files)
subprocess.check_call(["mpv", "--really-quiet", "--force-window",
"--input-file=" + FIFO, "--"] + files)
+1 -1
View File
@@ -1 +1 @@
0.3.4
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);
}
+4 -10
View File
@@ -172,11 +172,8 @@ static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf)
avctx->block_align = wf->nBlockAlign;
avctx->bits_per_coded_sample = wf->wBitsPerSample;
if (wf->cbSize > 0) {
avctx->extradata = av_mallocz(wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE);
avctx->extradata_size = wf->cbSize;
memcpy(avctx->extradata, wf + 1, avctx->extradata_size);
}
if (wf->cbSize > 0)
mp_lavc_set_extradata(avctx, wf + 1, wf->cbSize);
}
static int init(struct dec_audio *da, const char *decoder)
@@ -244,11 +241,8 @@ static int init(struct dec_audio *da, const char *decoder)
// demux_mkv, demux_mpg
if (sh_audio->codecdata_len && sh_audio->codecdata &&
!lavc_context->extradata) {
lavc_context->extradata = av_malloc(sh_audio->codecdata_len +
FF_INPUT_BUFFER_PADDING_SIZE);
lavc_context->extradata_size = sh_audio->codecdata_len;
memcpy(lavc_context->extradata, (char *)sh_audio->codecdata,
lavc_context->extradata_size);
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata,
sh_audio->codecdata_len);
}
if (sh->lav_headers)
+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
@@ -112,7 +112,7 @@ enum af_format {
// Planar variants
AF_FORMAT_U8P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_8BIT|AF_FORMAT_NE),
AF_FORMAT_S16P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_16BIT|AF_FORMAT_NE),
AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_US|AF_FORMAT_32BIT|AF_FORMAT_NE),
AF_FORMAT_S32P = (AF_INTP|AF_FORMAT_SI|AF_FORMAT_32BIT|AF_FORMAT_NE),
AF_FORMAT_FLOATP = (AF_FLTP|AF_FORMAT_32BIT|AF_FORMAT_NE),
AF_FORMAT_DOUBLEP = (AF_FLTP|AF_FORMAT_64BIT|AF_FORMAT_NE),
+10 -6
View File
@@ -100,7 +100,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
float f_multi;
if (AF_FORMAT_IS_IEC61937(ao->format))
return CONTROL_TRUE;
return CONTROL_FALSE;
//allocate simple id
snd_mixer_selem_id_alloca(&sid);
@@ -561,9 +561,11 @@ static void audio_pause(struct ao *ao)
int err;
if (p->can_pause) {
p->delay_before_pause = get_delay(ao);
err = snd_pcm_pause(p->alsa, 1);
CHECK_ALSA_ERROR("pcm pause error");
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_RUNNING) {
p->delay_before_pause = get_delay(ao);
err = snd_pcm_pause(p->alsa, 1);
CHECK_ALSA_ERROR("pcm pause error");
}
} else {
MP_VERBOSE(ao, "pause not supported by hardware\n");
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
@@ -591,8 +593,10 @@ static void audio_resume(struct ao *ao)
}
if (p->can_pause) {
err = snd_pcm_pause(p->alsa, 0);
CHECK_ALSA_ERROR("pcm resume error");
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED) {
err = snd_pcm_pause(p->alsa, 0);
CHECK_ALSA_ERROR("pcm resume error");
}
} else {
MP_VERBOSE(ao, "resume not supported by hardware\n");
err = snd_pcm_prepare(p->alsa);
+19 -3
View File
@@ -60,10 +60,12 @@ struct priv {
int connect;
int autostart;
int stdlayout;
int last_chunk;
volatile int paused;
volatile int underrun;
volatile float callback_interval;
volatile float callback_time;
volatile float last_ok_time; // last time real audio was played
int num_ports;
struct port_ring ports[MP_NUM_CHANNELS];
@@ -128,11 +130,15 @@ process(jack_nframes_t nframes, void *arg)
underrun = 1;
}
float now = mp_time_us() / 1000000.0;
if (underrun)
p->underrun = 1;
if (!p->underrun)
p->last_ok_time = now;
if (p->estimate) {
float now = mp_time_us() / 1000000.0;
float diff = p->callback_time + p->callback_interval - now;
if ((diff > -0.002) && (diff < 0.002))
p->callback_time += p->callback_interval;
@@ -289,14 +295,23 @@ static float get_delay(struct ao *ao)
struct priv *p = ao->priv;
int buffered = mp_ring_buffered(p->ports[0].ring); // could be less
float in_jack = p->jack_latency;
float now = mp_time_us() / 1000000.0;
if (p->estimate && p->callback_interval > 0) {
float elapsed = mp_time_us() / 1000000.0 - p->callback_time;
in_jack += p->callback_interval - elapsed;
if (in_jack < 0)
in_jack = 0;
}
if (p->underrun && !buffered && p->last_chunk) {
// Report correct buffer drainage, when our buffer is empty, but jack
// and/or the audio device still have some audio to play.
// Assumes audio clock goes at about the same speed as the system time.
in_jack += p->last_ok_time - now;
}
if (in_jack < 0)
in_jack = 0;
return (float)buffered / (float)ao->bps + in_jack;
}
@@ -369,6 +384,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
}
p->underrun = 0;
p->last_chunk = flags & AOPLAY_FINAL_CHUNK;
return ret / ao->sstride;
}
+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;
}
+2 -2
View File
@@ -111,8 +111,8 @@ static int init(struct ao *ao)
return -1;
}
rsd_set_param(priv->rd, RSD_SAMPLERATE, &ao->samplerate);
rsd_set_param(priv->rd, RSD_CHANNELS, &ao->channels.num);
rsd_set_param(priv->rd, RSD_SAMPLERATE, (int[]) { ao->samplerate });
rsd_set_param(priv->rd, RSD_CHANNELS, (int[]) { ao->channels.num });
ao->format = af_fmt_from_planar(ao->format);
+2 -2
View File
@@ -5,9 +5,9 @@
from __future__ import print_function
import os, sys, stat, hashlib, subprocess
WAFRELEASE = "waf-1.7.13"
WAFRELEASE = "waf-1.7.15"
WAFURL = "https://waf.googlecode.com/files/" + WAFRELEASE
SHA256HASH = "03cc750049350ee01cdbc584b70924e333fcc17ba4a2d04648dab1535538a873"
SHA256HASH = "e5ae7028f9b2d8ce1acb9fe1092e8010a90ba764d3ac065ea4e846743290b1d6"
if os.path.exists("waf"):
wafver = subprocess.check_output(['./waf', '--version']).decode()
+14 -10
View File
@@ -29,6 +29,19 @@
#include "osdep/numcores.h"
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size)
{
if (size) {
av_free(avctx->extradata);
avctx->extradata_size = 0;
avctx->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
if (!avctx->extradata)
return -1;
avctx->extradata_size = size;
memcpy(avctx->extradata, ptr, size);
}
return 0;
}
// Copy the codec-related fields from st into avctx. This does not set the
// codec itself, only codec related header data provided by libavformat.
@@ -38,16 +51,7 @@
// This is strictly for decoding only.
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
{
if (st->extradata_size) {
av_free(avctx->extradata);
avctx->extradata_size = 0;
avctx->extradata =
av_mallocz(st->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
if (avctx->extradata) {
avctx->extradata_size = st->extradata_size;
memcpy(avctx->extradata, st->extradata, st->extradata_size);
}
}
mp_lavc_set_extradata(avctx, st->extradata, st->extradata_size);
avctx->codec_tag = st->codec_tag;
avctx->stream_codec_tag = st->stream_codec_tag;
avctx->bit_rate = st->bit_rate;
+1
View File
@@ -27,6 +27,7 @@
struct mp_decoder_list;
struct demux_packet;
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size);
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb);
int64_t mp_pts_to_av(double mp_pts, AVRational *tb);
+2 -2
View File
@@ -226,7 +226,7 @@ struct demux_packet *demux_copy_packet(struct demux_packet *dp)
struct sh_stream *new_sh_stream(demuxer_t *demuxer, enum stream_type type)
{
if (demuxer->num_streams > MAX_SH_STREAMS) {
MP_WARN(demuxer, "Too many streams.");
MP_WARN(demuxer, "Too many streams.\n");
return NULL;
}
@@ -373,7 +373,7 @@ static bool demux_check_queue_full(demuxer_t *demux)
overflow:
if (!demux->warned_queue_overflow) {
MP_ERR(demux, "\nToo many packets in the demuxer "
MP_ERR(demux, "Too many packets in the demuxer "
"packet queue (video: %d packets in %d bytes, audio: %d "
"packets in %d bytes, sub: %d packets in %d bytes).\n",
count_packs(demux, STREAM_VIDEO), count_bytes(demux, STREAM_VIDEO),
+2
View File
@@ -458,6 +458,8 @@ static void handle_stream(demuxer_t *demuxer, int i)
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
sh_sub->extradata_len = codec->extradata_size;
}
sh_sub->w = codec->width;
sh_sub->h = codec->height;
// Hack for MicroDVD: if time_base matches the ffmpeg microdvd reader's
// default FPS (23.976), assume the MicroDVD file did not declare a
+3 -3
View File
@@ -64,11 +64,11 @@ mf_t *open_mf_pattern(void *talloc_ctx, struct mp_log *log, char *filename)
if (filename[0] == '@') {
FILE *lst_f = fopen(filename + 1, "r");
if (lst_f) {
char *fname = talloc_size(mf, MP_PATH_MAX);
while (fgets(fname, MP_PATH_MAX, lst_f)) {
char *fname = talloc_size(mf, 512);
while (fgets(fname, 512, lst_f)) {
/* remove spaces from end of fname */
char *t = fname + strlen(fname) - 1;
while (t > fname && isspace(*t))
while (t > fname && isspace((unsigned char)*t))
*(t--) = 0;
if (!mp_path_exists(fname)) {
mp_verbose(log, "file not found: '%s'\n", fname);
+1
View File
@@ -87,6 +87,7 @@ typedef struct sh_video {
typedef struct sh_sub {
unsigned char *extradata; // extra header data passed from demuxer
int extradata_len;
int w, h; // mp4 vobsubs
int frame_based; // timestamps are frame-based
bool is_utf8; // if false, subtitle packet charset is unknown
struct ass_track *track; // loaded by libass
+4
View File
@@ -83,6 +83,10 @@
# Play Finnish audio if available, fall back to English otherwise.
#alang = fi,en
# Change subtitle encoding. For Arabic subtitles use 'cp1256'.
# If the file seems to be valid UTF-8, prefer UTF-8.
#subcp = utf8:cp1256
# Enable hardware decoding if available. Often, this requires using an certain
# video output, otherwise no hardware decoding will be used.
#hwdec = auto
+15 -1
View File
@@ -253,7 +253,7 @@ bool mp_replace_legacy_cmd(void *t, bstr *s)
return false;
}
bool mp_input_is_abort_cmd(int cmd_id)
static bool is_abort_cmd(int cmd_id)
{
switch (cmd_id) {
case MP_CMD_QUIT:
@@ -264,6 +264,20 @@ bool mp_input_is_abort_cmd(int cmd_id)
return false;
}
bool mp_input_is_abort_cmd(struct mp_cmd *cmd)
{
if (is_abort_cmd(cmd->id))
return true;
if (cmd->id == MP_CMD_COMMAND_LIST) {
for (struct mp_cmd *sub = cmd->args[0].v.p; sub; sub = sub->queue_next)
{
if (mp_input_is_abort_cmd(cmd))
return true;
}
}
return false;
}
void mp_print_cmd_list(struct mp_log *out)
{
for (int i = 0; mp_cmds[i].name; i++) {
+2 -1
View File
@@ -107,7 +107,8 @@ enum mp_command_type {
};
// Executing this command will abort playback (play something else, or quit).
bool mp_input_is_abort_cmd(int cmd_id);
struct mp_cmd;
bool mp_input_is_abort_cmd(struct mp_cmd *cmd);
struct bstr;
bool mp_replace_legacy_cmd(void *talloc_ctx, struct bstr *s);
+4 -4
View File
@@ -237,7 +237,7 @@ static bool queue_has_abort_cmds(struct cmd_queue *queue)
{
bool ret = false;
for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next)
if (mp_input_is_abort_cmd(cmd->id)) {
if (mp_input_is_abort_cmd(cmd)) {
ret = true;
break;
}
@@ -544,9 +544,9 @@ static void release_down_cmd(struct input_ctx *ictx, bool drop_current)
static int find_key_down(struct input_ctx *ictx, int code)
{
code &= ~(MP_KEY_STATE_UP | MP_KEY_STATE_DOWN);
code &= ~(MP_KEY_STATE_UP | MP_KEY_STATE_DOWN | MP_KEY_MODIFIER_MASK);
for (int j = 0; j < ictx->num_key_down; j++) {
if (ictx->key_down[j] == code)
if ((ictx->key_down[j] & ~MP_KEY_MODIFIER_MASK) == code)
return j;
}
return -1;
@@ -580,7 +580,7 @@ static bool should_drop_cmd(struct input_ctx *ictx, struct mp_cmd *cmd)
{
struct cmd_queue *queue = &ictx->cmd_queue;
return (queue_count_cmds(queue) >= ictx->key_fifo_size &&
(!mp_input_is_abort_cmd(cmd->id) || queue_has_abort_cmds(queue)));
(!mp_input_is_abort_cmd(cmd) || queue_has_abort_cmds(queue)));
}
static void interpret_key(struct input_ctx *ictx, int code, double scale)
+2 -2
View File
@@ -1169,10 +1169,10 @@ fi
if test "$cc_vendor" = "gnu" ; then
cflag_check -Wundef && WARNFLAGS="-Wundef $WARNFLAGS"
# -std=gnu99 is not a warning flag but is placed in WARN_CFLAGS because
# -std=c99 is not a warning flag but is placed in WARN_CFLAGS because
# that's the only variable specific to C now, and this option is not valid
# for C++.
cflag_check -std=gnu99 && WARN_CFLAGS="-std=gnu99 $WARN_CFLAGS"
cflag_check -std=c99 && WARN_CFLAGS="-std=c99 $WARN_CFLAGS"
cflag_check -Wno-pointer-sign && WARN_CFLAGS="-Wno-pointer-sign $WARN_CFLAGS"
cflag_check -Wdisabled-optimization && WARN_CFLAGS="-Wdisabled-optimization $WARN_CFLAGS"
cflag_check -Wmissing-prototypes && WARN_CFLAGS="-Wmissing-prototypes $WARN_CFLAGS"
+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 \
+5 -7
View File
@@ -330,7 +330,8 @@ int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[])
pthread_create(&playback_thread_id, NULL, playback_thread, &ctx);
[mpv_shared_app().input_ready lock];
[mpv_shared_app().input_ready wait];
while (!mpv_shared_app().inputContext)
[mpv_shared_app().input_ready wait];
[mpv_shared_app().input_ready unlock];
cocoa_run_runloop();
@@ -388,13 +389,10 @@ void cocoa_stop_runloop(void)
void cocoa_set_input_context(struct input_ctx *input_context)
{
if (input_context) {
[mpv_shared_app().input_ready lock];
[mpv_shared_app().input_ready signal];
[mpv_shared_app().input_ready unlock];
}
[mpv_shared_app().input_ready lock];
mpv_shared_app().inputContext = input_context;
[mpv_shared_app().input_ready signal];
[mpv_shared_app().input_ready unlock];
}
void cocoa_post_fake_event(void)
+5 -1
View File
@@ -59,7 +59,11 @@ char *mp_get_win_config_path(const char *filename)
res = mp_path_join(NULL, bstr0(temp), bstr0(filename));
if (!mp_path_exists(res) || mp_path_isdir(res)) {
talloc_free(res);
res = NULL;
res = mp_path_join(NULL, bstr0(dir), bstr0(filename));
if (!mp_path_exists(res) || mp_path_isdir(res)) {
talloc_free(res);
res = NULL;
}
}
}
+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)
+3
View File
@@ -334,11 +334,13 @@ static int audio_start_sync(struct MPContext *mpctx, int playsize)
res = audio_decode(d_audio, ao->buffer, a);
if (skip_samples <= mp_audio_buffer_samples(ao->buffer)) {
mp_audio_buffer_skip(ao->buffer, skip_samples);
ao->buffer_playable_samples = 0;
if (res < 0)
return res;
return audio_decode(d_audio, ao->buffer, playsize);
}
mp_audio_buffer_clear(ao->buffer);
ao->buffer_playable_samples = 0;
if (res < 0)
return res;
}
@@ -442,6 +444,7 @@ int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
mp_audio_buffer_peek(ao->buffer, &data);
data.samples = MPMIN(data.samples, playsize);
int played = write_to_ao(mpctx, &data, playflags, written_audio_pts(mpctx));
assert(played >= 0 && played <= data.samples);
ao->buffer_playable_samples = playsize - played;
if (played > 0) {
+5 -7
View File
@@ -700,8 +700,8 @@ static int tag_property(m_option_t *prop, int action, void *arg,
char **slist = NULL;
int num = 0;
for (int n = 0; n < tags->num_keys; n++) {
MP_TARRAY_APPEND(NULL, slist, num, tags->keys[n]);
MP_TARRAY_APPEND(NULL, slist, num, tags->values[n]);
MP_TARRAY_APPEND(NULL, slist, num, talloc_strdup(NULL, tags->keys[n]));
MP_TARRAY_APPEND(NULL, slist, num, talloc_strdup(NULL, tags->values[n]));
}
MP_TARRAY_APPEND(NULL, slist, num, NULL);
*(char ***)arg = slist;
@@ -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);
}
@@ -2941,7 +2939,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
}
#endif /* HAVE_PVR */
#if HAVE_DVBIN
if (mpctx->stream->type == STREAMTYPE_DVB) {
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
int dir;
int v = cmd->args[0].v.i;
@@ -2979,7 +2977,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
#if HAVE_DVBIN
case MP_CMD_DVB_SET_CHANNEL:
if (mpctx->stream->type == STREAMTYPE_DVB) {
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
mpctx->last_dvb_step = 1;
if (dvb_set_channel(mpctx->stream, cmd->args[1].v.i,
+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 -7
View File
@@ -672,6 +672,8 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
}
}
osd_changed_all(mpctx->osd);
talloc_free(mpctx->track_layout_hash);
mpctx->track_layout_hash = talloc_steal(mpctx, track_layout_hash(mpctx));
}
@@ -1012,7 +1014,7 @@ static bool demux_was_interrupted(struct MPContext *mpctx)
mp_cmd_t *cmd = mp_input_get_cmd(mpctx->input, 0, 0);
if (!cmd)
break;
if (mp_input_is_abort_cmd(cmd->id))
if (mp_input_is_abort_cmd(cmd))
run_command(mpctx, cmd);
mp_cmd_free(cmd);
}
@@ -1305,14 +1307,13 @@ goto_reopen_demuxer: ;
// If there's a timeline force an absolute seek to initialize state
double startpos = rel_time_to_abs(mpctx, opts->play_start, -1);
if (startpos != -1 || mpctx->timeline) {
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, 0);
execute_queued_seek(mpctx);
}
if (startpos == -1 && mpctx->resolve_result &&
mpctx->resolve_result->start_time > 0)
{
queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->resolve_result->start_time, 0);
startpos = mpctx->resolve_result->start_time;
if (startpos == -1 && mpctx->timeline)
startpos = 0;
if (startpos != -1) {
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, 0);
execute_queued_seek(mpctx);
}
if (opts->chapterrange[0] > 0) {
+17
View File
@@ -1,3 +1,20 @@
/*
* This file is part of mpv.
*
* mpv 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.
*
* mpv 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 mpv. If not, see <http://www.gnu.org/licenses/>.
*/
#include <assert.h>
#include <string.h>
+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);
}
+16 -11
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"
@@ -168,14 +168,14 @@ void add_step_frame(struct MPContext *mpctx, int dir)
}
}
static void seek_reset(struct MPContext *mpctx, bool reset_ao)
static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
{
if (mpctx->d_video) {
video_reset_decoding(mpctx->d_video);
vo_seek_reset(mpctx->video_out);
}
if (mpctx->d_audio) {
if (mpctx->d_audio && reset_ac) {
audio_reset_decoding(mpctx->d_audio);
if (reset_ao)
clear_audio_output_buffers(mpctx);
@@ -204,9 +204,6 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
}
// return -1 if seek failed (non-seekable stream?), 0 otherwise
// timeline_fallthrough: true if used to explicitly switch timeline - in this
// case, don't drop buffered AO audio data, so that
// timeline segment transition is seemless
static int mp_seek(MPContext *mpctx, struct seek_params seek,
bool timeline_fallthrough)
{
@@ -253,6 +250,9 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
seek.amount += get_current_time(mpctx);
}
/* At least the liba52 decoder wants to read from the input stream
* during initialization, so reinit must be done after the demux_seek()
* call that clears possible stream EOF. */
bool need_reset = false;
double demuxer_amount = seek.amount;
if (mpctx->timeline) {
@@ -271,7 +271,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
}
if (need_reset) {
reinit_video_chain(mpctx);
reinit_audio_chain(mpctx);
reinit_subs(mpctx, 0);
reinit_subs(mpctx, 1);
}
@@ -296,8 +295,10 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
demuxer_amount -= hr_seek_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style);
if (seekresult == 0) {
if (need_reset)
seek_reset(mpctx, !timeline_fallthrough);
if (need_reset) {
reinit_audio_chain(mpctx);
seek_reset(mpctx, !timeline_fallthrough, false);
}
return -1;
}
@@ -315,7 +316,11 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
}
}
seek_reset(mpctx, !timeline_fallthrough);
if (need_reset)
reinit_audio_chain(mpctx);
/* If we just reinitialized audio it doesn't need to be reset,
* and resetting could lose audio some decoders produce during init. */
seek_reset(mpctx, !timeline_fallthrough, !need_reset);
if (timeline_fallthrough) {
// Important if video reinit happens.
@@ -571,7 +576,7 @@ bool mp_seek_chapter(struct MPContext *mpctx, int chapter)
if (res >= 0) {
if (pts == -1) {
// for DVD/BD - seek happened via stream layer
seek_reset(mpctx, true);
seek_reset(mpctx, true, true);
mpctx->seek = (struct seek_params){0};
return true;
}
+1 -1
View File
@@ -164,7 +164,7 @@ static void copy_chapters(struct chapter **chapters, int *num_chapters,
double time = demuxer_chapter_time(src, n);
if (time >= start && time <= start + len) {
struct chapter ch = {
.start = dest_offset + time,
.start = dest_offset + time - start,
.name = talloc_steal(*chapters, demuxer_chapter_name(src, n)),
};
MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch);
+18 -4
View File
@@ -75,6 +75,7 @@ struct priv {
int64_t fill_limit; // we should fill buffer only if space>=fill_limit
int64_t seek_limit; // keep filling cache if distance is less that seek limit
struct byte_meta *bm; // additional per-byte metadata
bool seekable; // underlying stream is seekable
struct mp_log *log;
@@ -475,6 +476,7 @@ static int cache_seek(stream_t *cache, int64_t pos)
{
struct priv *s = cache->priv;
assert(s->cache_thread_running);
int r = 1;
pthread_mutex_lock(&s->mutex);
@@ -482,12 +484,21 @@ static int cache_seek(stream_t *cache, int64_t pos)
" (cur=%" PRId64 ") <= %" PRId64 " \n",
s->min_filepos, pos, s->read_filepos, s->max_filepos);
cache->pos = s->read_filepos = pos;
s->eof = false; // so that cache_read() will actually wait for new data
pthread_cond_signal(&s->wakeup);
if (!s->seekable && pos > s->max_filepos) {
MP_ERR(s, "Attempting to seek past cached data in unseekable stream.\n");
r = 0;
} else if (!s->seekable && pos < s->min_filepos) {
MP_ERR(s, "Attempting to seek before cached data in unseekable stream.\n");
r = 0;
} else {
cache->pos = s->read_filepos = pos;
s->eof = false; // so that cache_read() will actually wait for new data
pthread_cond_signal(&s->wakeup);
}
pthread_mutex_unlock(&s->mutex);
return 1;
return r;
}
static int cache_control(stream_t *cache, int cmd, void *arg)
@@ -600,6 +611,9 @@ int stream_cache_init(stream_t *cache, stream_t *stream, int64_t size,
if (min > s->buffer_size - s->fill_limit)
min = s->buffer_size - s->fill_limit;
s->seekable = (stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK &&
stream->end_pos > 0;
if (pthread_create(&s->cache_thread, NULL, cache_thread, s) != 0) {
MP_ERR(s, "Starting cache process/thread failed: %s.\n",
strerror(errno));
-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) {
+2
View File
@@ -175,6 +175,8 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_stream *sh)
struct sd init_sd = sub->init_sd;
init_sd.codec = sh->codec;
init_sd.ass_track = sh->sub->track;
init_sd.sub_stream_w = sh->sub->w;
init_sd.sub_stream_h = sh->sub->h;
while (sub->num_sd < MAX_NUM_SD) {
struct sd *sd = talloc(NULL, struct sd);
+3
View File
@@ -25,6 +25,9 @@ struct sd {
// the resolution of the VO, nor does it have to be the OSD resolution.
int sub_video_w, sub_video_h;
// Resolution hints stored in mp4 files.
int sub_stream_w, sub_stream_h;
// Make sd_ass use an existing track
struct ass_track *ass_track;
+42 -2
View File
@@ -21,12 +21,14 @@
#include <libavcodec/avcodec.h>
#include <libavutil/common.h>
#include <libavutil/intreadwrite.h>
#include "talloc.h"
#include "common/msg.h"
#include "common/av_common.h"
#include "options/options.h"
#include "video/mp_image.h"
#include "video/csputils.h"
#include "sd.h"
#include "dec_sub.h"
@@ -89,9 +91,42 @@ static void get_resolution(struct sd *sd, int wh[2])
struct sd_lavc_priv *priv = sd->priv;
wh[0] = priv->avctx->width;
wh[1] = priv->avctx->height;
if (wh[0] <= 0 || wh[1] <= 0) {
wh[0] = priv->video_params.w;
wh[1] = priv->video_params.h;
}
guess_resolution(priv->avctx->codec_id, &wh[0], &wh[1]);
}
static void set_mp4_vobsub_idx(AVCodecContext *avctx, char *src, int w, int h)
{
char pal_s[128];
int pal_s_pos = 0;
for (int i = 0; i < 16; i++) {
unsigned int e = AV_RB32(src + i * 4);
// lavc doesn't accept YUV palette - "does god hate me?"
struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
csp.int_bits_in = 8;
csp.int_bits_out = 8;
float cmatrix[3][4];
mp_get_yuv2rgb_coeffs(&csp, cmatrix);
int c[3] = {(e >> 16) & 0xff, (e >> 8) & 0xff, e & 0xff};
mp_map_int_color(cmatrix, 8, c);
e = (c[2] << 16) | (c[1] << 8) | c[0];
snprintf(pal_s + pal_s_pos, sizeof(pal_s) - pal_s_pos, "%06x%s", e,
i != 15 ? ", " : "");
pal_s_pos = strlen(pal_s);
if (pal_s_pos >= sizeof(pal_s))
break;
}
char buf[256] = "";
snprintf(buf, sizeof(buf), "size: %dx%d\npalette: %s\n", w, h, pal_s);
mp_lavc_set_extradata(avctx, buf, strlen(buf));
}
static int init(struct sd *sd)
{
struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
@@ -103,8 +138,12 @@ static int init(struct sd *sd)
ctx = avcodec_alloc_context3(sub_codec);
if (!ctx)
goto error;
ctx->extradata_size = sd->extradata_len;
ctx->extradata = sd->extradata;
mp_lavc_set_extradata(ctx, sd->extradata, sd->extradata_len);
if (sd->extradata_len == 64 && sd->sub_stream_w && sd->sub_stream_h &&
cid == AV_CODEC_ID_DVD_SUBTITLE)
{
set_mp4_vobsub_idx(ctx, sd->extradata, sd->sub_stream_w, sd->sub_stream_h);
}
if (avcodec_open2(ctx, sub_codec, NULL) < 0)
goto error;
priv->avctx = ctx;
@@ -264,6 +303,7 @@ static void uninit(struct sd *sd)
clear(priv);
avcodec_close(priv->avctx);
av_free(priv->avctx->extradata);
av_free(priv->avctx);
talloc_free(priv);
}
+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 -2
View File
@@ -399,10 +399,10 @@ int video_reconfig_filters(struct dec_video *d_video,
}
float force_aspect = opts->movie_aspect;
if (force_aspect > -1.0 && d_video->stream_aspect != 0.0)
if (force_aspect > 0.0 && d_video->stream_aspect != 0.0)
force_aspect = d_video->stream_aspect;
if (force_aspect > 0)
if (force_aspect >= 0.0)
vf_set_dar(&p.d_w, &p.d_h, p.w, p.h, force_aspect);
if (abs(p.d_w - p.w) >= 4 || abs(p.d_h - p.h) >= 4) {
+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;
+20 -20
View File
@@ -318,10 +318,7 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format,
if (bih->biSize <= sizeof(*bih))
break;
av_opt_set_int(avctx, "extern_huff", 1, AV_OPT_SEARCH_CHILDREN);
avctx->extradata_size = bih->biSize - sizeof(*bih);
avctx->extradata = av_mallocz(avctx->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
break;
case MP_FOURCC('R','V','1','0'):
@@ -331,29 +328,21 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format,
case MP_FOURCC('R','V','4','0'):
if (bih->biSize < sizeof(*bih) + 8) {
// only 1 packet per frame & sub_id from fourcc
avctx->extradata_size = 8;
avctx->extradata = av_mallocz(avctx->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
((uint32_t *)avctx->extradata)[0] = 0;
((uint32_t *)avctx->extradata)[1] =
format == MP_FOURCC('R','V','1','3') ?
0x10003001 : 0x10000000;
uint32_t extradata[2] = {
0,
format == MP_FOURCC('R','V','1','3') ? 0x10003001 : 0x10000000,
};
mp_lavc_set_extradata(avctx, &extradata, 8);
} else {
// has extra slice header (demux_rm or rm->avi streamcopy)
avctx->extradata_size = bih->biSize - sizeof(*bih);
avctx->extradata = av_mallocz(avctx->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
}
break;
default:
if (bih->biSize <= sizeof(*bih))
break;
avctx->extradata_size = bih->biSize - sizeof(*bih);
avctx->extradata = av_mallocz(avctx->extradata_size +
FF_INPUT_BUFFER_PADDING_SIZE);
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
break;
}
@@ -717,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 {
@@ -763,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);
+2 -1
View File
@@ -126,7 +126,8 @@ static bool create_vdp_decoder(struct lavc_ctx *ctx)
goto fail;
}
if (p->vid_width > maxw || p->vid_height > maxh) {
MP_ERR(p, "Video too large.\n");
MP_ERR(p, "Video resolution(%dx%d) is larger than the maximum size(%dx%d) supported.\n",
p->vid_width, p->vid_height, maxw, maxh);
goto fail;
}
+2 -2
View File
@@ -599,11 +599,11 @@ void vf_set_dar(int *d_w, int *d_h, int w, int h, double dar)
*d_w = w;
*d_h = h;
if (dar > 0.01) {
*d_w = h * dar;
*d_w = h * dar + 0.5;
// we don't like horizontal downscale
if (*d_w < w) {
*d_w = w;
*d_h = w / dar;
*d_h = w / dar + 0.5;
}
}
}
-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;
+9 -3
View File
@@ -157,14 +157,20 @@ struct lut3d *mp_load_icc(struct mp_icc_opts *opts, struct mp_log *log,
if (!profile)
goto error_exit;
cmsCIExyY d65;
cmsWhitePointFromTemp(&d65, 6504);
cmsCIExyY d65 = {0.3127, 0.3290, 1.0};
static const cmsCIExyYTRIPLE bt709prim = {
.Red = {0.64, 0.33, 1.0},
.Green = {0.30, 0.60, 1.0},
.Blue = {0.15, 0.06, 1.0},
};
cmsToneCurve *tonecurve = cmsBuildGamma(NULL, 1.0/0.45);
/* Rec BT.709 defines the tone curve as:
V = 1.099 * L^0.45 - 0.099 for L >= 0.018
V = 4.500 * L for L < 0.018
The 0.081 parameter comes from inserting 0.018 into the function */
cmsToneCurve *tonecurve = cmsBuildParametricToneCurve(NULL, 4,
(cmsFloat64Number[5]){1/0.45, 1/1.099, 0.099/1.099, 1/4.5, 0.081});
cmsHPROFILE vid_profile = cmsCreateRGBProfile(&d65, &bt709prim,
(cmsToneCurve*[3]){tonecurve, tonecurve, tonecurve});
cmsFreeToneCurve(tonecurve);
+15 -2
View File
@@ -45,8 +45,14 @@
#if __VERSION__ >= 130
vec3 srgb_compand(vec3 v)
{
return mix(1.055 * pow(v, vec3(1.0/2.4)) - vec3(0.055), v * 12.92,
lessThanEqual(v, vec3(0.0031308)));
return mix(v * 12.92, 1.055 * pow(v, vec3(1.0/2.4)) - vec3(0.055),
lessThanEqual(vec3(0.0031308), v));
}
vec3 bt709_expand(vec3 v)
{
return mix(v / 4.5, pow((v + vec3(0.099))/1.099, vec3(1/0.45)),
lessThanEqual(vec3(0.0812), v));
}
#endif
@@ -384,6 +390,13 @@ void main() {
color = texture3D(lut_3d, color).rgb;
#endif
#ifdef USE_SRGB
// Go from "linear" (0.45) to BT.709 to true linear to sRGB
#ifndef USE_3DLUT
// Unless we are using a 3DLUT, in which case USE_LINEAR_CONV_INV
// already triggered earlier.
color = pow(color, vec3(0.45));
#endif
color = bt709_expand(color.rgb);
color.rgb = srgb_compand(color.rgb);
#endif
#ifdef USE_DITHER
+11 -4
View File
@@ -44,6 +44,11 @@ static bool create_context_x11_old(struct MPGLContext *ctx)
if (glx_ctx->context)
return true;
if (!glx_ctx->vinfo) {
MP_FATAL(vo, "Can't create a legacy GLX context without X visual\n");
return false;
}
GLXContext new_context = glXCreateContext(display, glx_ctx->vinfo, NULL,
True);
if (!new_context) {
@@ -219,6 +224,7 @@ static bool config_window_x11(struct MPGLContext *ctx, uint32_t d_width,
int glx_attribs[] = {
GLX_STEREO, False,
GLX_X_RENDERABLE, True,
GLX_X_VISUAL_TYPE, GLX_TRUE_COLOR,
GLX_RED_SIZE, 1,
GLX_GREEN_SIZE, 1,
GLX_BLUE_SIZE, 1,
@@ -254,12 +260,13 @@ static bool config_window_x11(struct MPGLContext *ctx, uint32_t d_width,
glx_ctx->fbc = fbc;
glx_ctx->vinfo = glXGetVisualFromFBConfig(vo->x11->display, fbc);
if (!glx_ctx->vinfo) {
MP_ERR(vo, "Selected GLX FB config has no associated X visual\n");
return false;
if (glx_ctx->vinfo) {
MP_VERBOSE(vo, "GLX chose visual with ID 0x%x\n",
(int)glx_ctx->vinfo->visualid);
} else {
MP_WARN(vo, "Selected GLX FB config has no associated X visual\n");
}
MP_VERBOSE(vo, "GLX chose visual with ID 0x%x\n", (int)glx_ctx->vinfo->visualid);
glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_RED_SIZE, &ctx->depth_r);
glXGetFBConfigAttrib(vo->x11->display, fbc, GLX_GREEN_SIZE, &ctx->depth_g);
+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;
}
}
+51 -68
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,50 +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;
}
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,
@@ -482,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 "
@@ -1016,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) {
@@ -1037,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;
}
@@ -1064,14 +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
uint64_t now = sync_vdptime(vo);
uint64_t pts = pts_us ? convert_to_vdptime(vo, pts_us) : now;
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");
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
@@ -1100,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;
@@ -1115,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;
+2 -9
View File
@@ -41,13 +41,6 @@
#define MAX_BUFFERS 2
// minium target version for the new formats (1.2.90)
#define MINIMUM_VERSION (1 << 16 | 2 << 8 | 90)
#define CURRENT_VERSION (WAYLAND_VERSION_MAJOR << 16 | \
WAYLAND_VERSION_MINOR << 8 | \
WAYLAND_VERSION_MICRO)
static void draw_image(struct vo *vo, mp_image_t *mpi);
static const struct wl_callback_listener frame_listener;
@@ -65,7 +58,6 @@ struct fmtentry {
static const struct fmtentry fmttable[] = {
{WL_SHM_FORMAT_ARGB8888, IMGFMT_BGRA}, // 8b 8g 8r 8a
{WL_SHM_FORMAT_XRGB8888, IMGFMT_BGR0},
#if CURRENT_VERSION >= MINIMUM_VERSION
{WL_SHM_FORMAT_RGB332, IMGFMT_BGR8}, // 3b 3g 2r
{WL_SHM_FORMAT_BGR233, IMGFMT_RGB8}, // 3r 3g 3b,
{WL_SHM_FORMAT_XRGB4444, IMGFMT_BGR12_LE}, // 4b 4g 4r 4a
@@ -94,7 +86,6 @@ static const struct fmtentry fmttable[] = {
{WL_SHM_FORMAT_ABGR8888, IMGFMT_RGBA},
{WL_SHM_FORMAT_RGBA8888, IMGFMT_ABGR},
{WL_SHM_FORMAT_BGRA8888, IMGFMT_ARGB},
#endif
};
#define MAX_FORMAT_ENTRIES (sizeof(fmttable) / sizeof(fmttable[0]))
@@ -496,6 +487,8 @@ static void frame_handle_redraw(void *data,
if (p->resize_attach) {
destroy_shm_buffer(&p->tmp_buffer);
p->resize_attach = false;
p->x = 0;
p->y = 0;
}
}
else {
+8 -4
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);
@@ -647,17 +654,14 @@ int vo_w32_init(struct vo *vo)
HINSTANCE hInstance = GetModuleHandleW(NULL);
HICON mplayerIcon = LoadIconW(hInstance, L"IDI_ICON1");
WNDCLASSEXW wcex = {
.cbSize = sizeof wcex,
.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
.lpfnWndProc = WndProc,
.hInstance = hInstance,
.hIcon = mplayerIcon,
.hIcon = LoadIconW(hInstance, L"IDI_ICON1"),
.hCursor = LoadCursor(NULL, IDC_ARROW),
.lpszClassName = classname,
.hIconSm = mplayerIcon,
};
if (!RegisterClassExW(&wcex)) {
-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);
+11 -9
View File
@@ -757,7 +757,6 @@ int vo_x11_check_events(struct vo *vo)
vo_x11_update_geometry(vo);
while (XPending(display)) {
XNextEvent(display, &Event);
// printf("\rEvent.type=%X \n",Event.type);
switch (Event.type) {
case Expose:
x11->pending_vo_events |= VO_EVENT_EXPOSE;
@@ -818,14 +817,9 @@ int vo_x11_check_events(struct vo *vo)
(MP_MOUSE_BTN0 + Event.xbutton.button - 1) |
get_mods(Event.xbutton.state) | MP_KEY_STATE_UP);
break;
case PropertyNotify: {
char *name = XGetAtomName(display, Event.xproperty.atom);
if (!name)
break;
XFree(name);
break;
}
case MapNotify:
x11->window_hidden = false;
vo_x11_update_geometry(vo);
x11->vo_hint.win_gravity = x11->old_gravity;
XSetWMNormalHints(display, x11->window, &x11->vo_hint);
x11->fs_flip = 0;
@@ -1135,7 +1129,6 @@ static void vo_x11_map_window(struct vo *vo, int x, int y, int w, int h)
{
struct vo_x11_state *x11 = vo->x11;
x11->window_hidden = false;
vo_x11_move_resize(vo, true, true, x, y, w, h);
if (!vo->opts->border)
vo_x11_decoration(vo, 0);
@@ -1230,6 +1223,13 @@ void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
XSync(x11->display, False);
vo_x11_update_geometry(vo);
if (x11->window_hidden) {
// The real size is only known when the window is mapped, which
// unfortunately happens asynchronous to VO initialization. At least
// vdpau needs a _some_ window size, though.
x11->win_width = width;
x11->win_height = height;
}
update_vo_size(vo);
x11->pending_vo_events &= ~VO_EVENT_RESIZE; // implicitly done by the VO
}
@@ -1342,6 +1342,8 @@ static void vo_x11_update_geometry(struct vo *vo)
int dummy_int;
Window dummy_win;
Window win = vo->opts->WinID > 0 ? vo->opts->WinID : x11->window;
if (x11->window_hidden)
return;
XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int,
&w, &h, &dummy_int, &dummy_uint);
if (w <= INT_MAX && h <= INT_MAX) {
+2 -1
View File
@@ -15,7 +15,7 @@ def __add_generic_flags__(ctx):
ctx.env.CFLAGS += ["-D_ISOC99_SOURCE", "-D_GNU_SOURCE",
"-D_LARGEFILE_SOURCE", "-D_FILE_OFFSET_BITS=64",
"-D_LARGEFILE64_SOURCE",
"-std=gnu99", "-Wall"]
"-std=c99", "-Wall"]
if ctx.is_debug_build():
ctx.env.CFLAGS += ['-g']
@@ -40,6 +40,7 @@ def __add_mingw_flags__(ctx):
def __add_cygwin_flags__(ctx):
ctx.env.CFLAGS += ['-mwin32']
ctx.env.CFLAGS += ['-U__STRICT_ANSI__']
__compiler_map__ = {
'__GNUC__': __add_gcc_flags__,
+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
+17 -5
View File
@@ -289,7 +289,7 @@ If you really mean to compile without libass support use --disable-libass."
}, {
'name': '--mpg123',
'desc': 'mpg123 support',
'func': check_pkg_config('libmpg123', '>= 1.2.0'),
'func': check_pkg_config('libmpg123', '>= 1.14.0'),
}, {
'name': '--ladspa',
'desc': 'LADSPA plugin support',
@@ -504,11 +504,23 @@ video_output_features = [
'name': 'gdi',
'desc': 'GDI',
'func': check_cc(lib='gdi32')
} , {
'name': 'winmm',
'desc': 'WinMM',
'func': check_cc(lib='winmm')
} , {
'name': 'ole',
'desc': 'OLE',
'func': check_cc(lib='ole32')
} , {
'name': 'uuid',
'desc': 'UUID',
'func': check_cc(lib='uuid')
} , {
'name': '--wayland',
'desc': 'Wayland',
'func': check_pkg_config('wayland-client', '>= 1.2.0',
'wayland-cursor', '>= 1.2.0',
'func': check_pkg_config('wayland-client', '>= 1.3.0',
'wayland-cursor', '>= 1.3.0',
'xkbcommon', '>= 0.3.0'),
} , {
'name': '--x11',
@@ -570,7 +582,7 @@ video_output_features = [
} , {
'name': '--gl-win32',
'desc': 'OpenGL Win32 Backend',
'deps': [ 'gdi' ],
'deps': [ 'gdi', 'winmm', 'ole', 'uuid' ],
'groups': [ 'gl' ],
'func': check_statement('windows.h', 'wglCreateContext(0)',
lib='opengl32')
@@ -633,7 +645,7 @@ video_output_features = [
}, {
'name': '--direct3d',
'desc': 'Direct3D support',
'deps': [ 'gdi' ],
'deps': [ 'gdi', 'winmm', 'ole', 'uuid' ],
'func': check_cc(header_name='d3d9.h'),
}
]
-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" ),