Compare commits

...
58 Commits
Author SHA1 Message Date
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
48 changed files with 346 additions and 181 deletions

No files matched your search

+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.
-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
----------------------
+8 -1
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).
+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.6
+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
@@ -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;
}
+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"
+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
@@ -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) {
+4 -4
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;
@@ -2941,7 +2941,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 +2979,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,
+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>
+15 -10
View File
@@ -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));
+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);
}
+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) {
+8 -19
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;
}
+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;
}
}
}
+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);
+7
View File
@@ -176,6 +176,9 @@ static int change_vdptime_sync(struct vo *vo, int64_t *t)
vdp_time -= (t2 - t1) * 1000ULL;
else
vdp_time = old;
} else if (!vdp_time) {
/* Some drivers do not return timestamps. */
vdp_time = old;
}
MP_DBG(vo, "adjusting VdpTime offset by %f µs\n",
(int64_t)(vdp_time - old) / 1000.);
@@ -1064,6 +1067,10 @@ static void flip_page_timed(struct vo *vo, int64_t pts_us, int duration)
if (vc->vsync_interval == 1)
duration = -1; // Make sure drop logic is disabled
/* If the presentation time may not be before our last timestamp sync. */
if (pts_us && pts_us < vc->last_sync_update)
pts_us = vc->last_sync_update;
uint64_t now = sync_vdptime(vo);
uint64_t pts = pts_us ? convert_to_vdptime(vo, pts_us) : now;
uint64_t ideal_pts = 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 {
+1 -4
View File
@@ -647,17 +647,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)) {
+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__,
+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'),
}
]