Compare commits

...
50 Commits
Author SHA1 Message Date
wm4 3b0f28b2e3 Release 0.2.4 2013-12-01 20:48:37 +01:00
wm4 f12ed5fd8f mp_image: deal with FFmpeg PSEUDOPAL braindeath
We got a crash in libavutil when encoding with Y8 (GRAY8). The reason
was that libavutil was copying an Y8 image allocated by us, and expected
a palette. This is because GRAY8 is a PSEUDOPAL format. It's not clear
what PSEUDOPAL means, and it makes literally no sense at all. However,
it does expect a palette allocated for some formats that are not
paletted, and libavutil crashed when trying to access the non-existent
palette.
2013-12-01 20:45:44 +01:00
wm4 317f2399a7 input: don't emit command when using multiple mouse buttons at once
This is for key bindings that use multiple mouse buttons at once. (Yes,
this is weird, but MPlayer always had this feature, and apparently
there are people using it!)

Before this commit, clicking another mouse button while still holding
the previous mouse button forced the command bound to the previous
mouse button to be emitted. This is usually needed to make sure the
input consumer (the player and the OSC) stays in sync with the actual
mouse button state. If there's no command sent, the OSC in particular
would think the button is still held down. However, sending the command
is undesired behavior if you want to use these multiple-key binds.

Solve this by emitting commands in this situation only if a key down
command was sent earlier. Since mouse button key bindings are normally
executed on key-up only, this happens with special commands like
script_dispatch only (used by the OSD to track mouse buttons, but
also used for other OSC bindings).

See github issue #390.
2013-12-01 19:40:39 +01:00
wm4 228b652ad5 ao_oss: SNDCTL_DSP_CHANNELS takes int, not uint8_t
This caused weird issue, probably caused by setting up the wrong number
of channels, or similar. See github issue #383.

Patch by bugmen0t on github.
2013-12-01 19:40:14 +01:00
wm4 20e08ac84e vf_pullup: properly reset on seek
Sometimes, vf_pullup hanged on seek. This was because it never was
properly reset. Old timestamps messed up the timestamp calculations,
which made the player show frames for a ridiculously long time, which is
perceived as pausing or hanging.
2013-12-01 19:39:42 +01:00
wm4 93518bc652 player: simple hack to make backstep code somewhat more robust
The hr-seek code assumes that when seeking the demuxer, the first image
decoded after the seek will have a PTS exactly equal to the demuxer seek
target time, or before that target time. Incorrect timestamps,
implicitly dropped initial frames, or broken files/demuxers can all
break this assumption, and lead to hr-seek missing the seek target.

Generally, this is not much a problem (the user won't notice being off
by one frame), but it really shows when using the backstep feature. In
this case, backstepping would simply hang.

Add a simple hack that basically forces a minimal value for the --hr-
seek-demuxer-offset option (which is 0 by default) when doing a
backstep-seek. The chosen minimum value is arbitrary. There's no perfect
value, though in general it should perhaps be slightly longer than the
frametime, which the chosen value is more than enough for typical
framerates.

Conflicts:
	mpvcore/player/playloop.c
2013-12-01 19:39:21 +01:00
Stefano Pigozzi 38885269b3 ao_coreaudio: simplify ch label to speaker id conversion
Previous code was using the values of the AudioChannelLabel enum directly to
create the channel bitmap. While this was quite smart it was pretty unreadable
and fragile (what if Apple changes the values of those enums?).

Change it to use a 'dumb' conversion table.
2013-12-01 19:37:37 +01:00
Stefano Pigozzi 485c658f3f old-build: fix iconv check on openbsd 2013-12-01 19:37:29 +01:00
wm4 b9585e518b af_lavi: actually free the filter graph on uninit
This was a memory leak.

Also remove the AF_CONTROL_COMMAND_LINE code, which was inactive. (It's
never called if the new option parser is used.)
2013-12-01 19:37:19 +01:00
Stefano Pigozzi a9858ab117 ao_coreaudio: map channel labels needed for 8ch layouts
The code stopped at kAudioChannelLabel_TopBackRight and missed mapping for
5 more channel labels. These are in a completely different order that the mpv
ones so they must be mapped manually.
2013-12-01 19:37:09 +01:00
Stefano Pigozzi eeb37de8ca cocoa: unlock on uninit
NSLock should be unlocked before dealloc is called on it.
2013-12-01 19:36:02 +01:00
wm4 bbff558e6e player: only pause for waiting on cache if it makes sense
If the value for --cache-on-pause is larger than --cache-min, and the
cache runs below --cache-on-pause, but above --cache-min, the logic
would demand to pause the player and then unpause immediately again.
This doesn't make much sense, and alternating the pause state in each
playloop iteration has negative consequences. Add an explicit check to
avoid this situation.

Conflicts:
	mpvcore/player/playloop.c
2013-12-01 19:35:21 +01:00
Stefano Pigozzi 022735fa72 input: discard precise scrolling commands with no value
Apparently Cocoa precise scrolling generates a lot of spurious events with
a delta that is equal to 0.0. Make sure that they are discarded and not added
to the input queue.

Even though this only known to happen with Cocoa, I implemented this at core
level since it makes sense in general.

Fixes: #310
2013-12-01 19:33:52 +01:00
wm4 600193749d vd_lavc: when falling back to software, revert filter error status
When mpv is started with some video filters set (--vf is used), and
hardware decoding is requested, and hardware decoding would be possible,
but is prevented due to video filters that accept software formats only,
the fallback didn't work properly sometimes.

This fallback works rather violently: it tries to initialize the filter
chain, and if it fails it throws away the frame decoded using the
hardware, and retries with software. The case that didn't work was when
decoding the current packet didn't immediately lead to a new frame. Then
the filter chain wouldn't be reinitialized, and the playloop would stop
playback as soon as it encounters the error flag.

Fix this by resetting the filter error flag (back to "uninitialized"),
which is a rather violent, but somewhat working solution.

The fallback in general should perhaps be cleaned up later.

Conflicts:
	video/decode/vd_lavc.c
2013-12-01 19:32:44 +01:00
wm4 fc465f1f26 audio: respect --end/--length with spdif passthrough
In theory, we can't really do this, because we don't know when a spdif
frame ends. Spdif transports compressed audio through audio setups that
were originally designed for PCM only (which includes the audio filter
chain, the AO API, most audio output APIs, etc.), and to reach this
goal, spdif pretends to be PCM. Compressed data frames are padded with
zeros, until a certain data rate is reached, which corresponds to a
pseudo-PCM format with 2 bytes per sample and 2 channels at 48000 Hz.
Of course an actual spdif frame is significantly larger than a frame
of the PCM format it pretends to be, so cutting audio data on frame
boundaries (as according to the pseudo-PCM format) merely yields an
incomplete and broken frame, not audio that plays for the desired
duration.

However, sending an incomplete frame might still be much better than the
current behavior, which simply ignores --end/--length (but still lets
the video end at the exact end time).

Should this result in trouble with real spdif receivers, this commit
probably has to be reverted.

Conflicts:
	mpvcore/player/audio.c
2013-12-01 19:31:29 +01:00
wm4 bf39906cd5 ao_rsound: fix option types
These are option values, and the option code expects char*.

Not actually tested.
2013-12-01 19:30:13 +01:00
enkore dac0726e98 manpage: document , mapping (frame_back_step)
See #356
2013-12-01 19:29:22 +01:00
wm4 0268f2431a input.conf: fix typo 2013-12-01 19:29:18 +01:00
Josh Driver 441af64005 Fixing list of vo's that vavpp works with, in man page. 2013-12-01 19:29:15 +01:00
wm4 f450e5c397 stream_lavf: fix a small memory leak
Also add an explanation why this special code path for rtsp is needed.
2013-12-01 19:28:46 +01:00
wm4 e70580df30 ta: fix typo in comment 2013-12-01 19:28:05 +01:00
wm4 9eaba0c176 osdep/io.c: include config.h
This possibly enables code that has never been tested before
(accidentally), so let's hope this works out ok.
2013-12-01 19:27:54 +01:00
wm4 196c7abcdb manpage: fix typo in --video-align-y description 2013-12-01 19:27:36 +01:00
wm4 253623d9e8 player: deselect video track if initialization fails
This didn't have any consequences, other than suddenly reinitializing
video when it works again (such as with EDL timeline mixing video and
audio-only files).

Conflicts:
	mpvcore/player/video.c
2013-12-01 19:27:29 +01:00
wm4 b9f40d650a stream_dvb: remove bogus free calls
The priv struct is now allocated by talloc in stream.c. It doesn't need
to be manually freed, and using free() instead of talloc_free() probably
crashes.
2013-12-01 19:26:34 +01:00
wm4 dc1aaf695f vo_vdpau: don't calculate destination alpha when drawing OSD
Same as MPlayer svn commit r36515 "Chose cheaper alpha blend equation."

No idea if this is actually faster, but can't hurt.
2013-12-01 19:26:30 +01:00
wm4 b24fd52268 player: don't remove playback status when reinitializing DVB
Also break that line a bit.

Conflicts:
	mpvcore/player/loadfile.c
2013-12-01 19:26:17 +01:00
wm4 dd25c08713 encode_lavc: add missing newline in error message 2013-12-01 19:24:12 +01:00
wm4 327edcec3f manpage: mark DTS-HD passthough as broken 2013-12-01 19:23:58 +01:00
Stefano Pigozzi 5281a9865d osx bundle: remove embedded fonts.conf
This could cause the bundle to recache stuff because of differences with
configuration of other software using fonconfig. The defaults OS X directories
should be added to fontconfig at build time (through configure).
2013-12-01 19:23:53 +01:00
wm4 6fcdb4ced3 gl_common: print SW renderer warning only if it was the only reason we rejected it 2013-12-01 19:22:34 +01:00
bugmen0t e773bda893 configure: enable v4l2 input on freebsd 2013-12-01 19:22:17 +01:00
bugmen0t d74e82cb50 tvi_v4l2: let libv4l2 convert to a known pixel format
Signed-off-by: wm4 <wm4@nowhere>

Significant modifications over the original patch by not overriding
syscalls with macros ("#define open v4l2open") for fallback, but the
other way around ("#define v4l2open open"). As consequence, the calls
have to be replaced throughout the file.

Untested, although the original patch probably was tested.
2013-12-01 19:21:44 +01:00
wm4 37fe0444e3 stream: don't include linux/types.h in some files
Apparently this is not portable to FreeBSD. It turns out that we
(probably) don't use any symbols defined by this header directly, so
the includes are not needed.

Conflicts:
	stream/stream_radio.c
2013-12-01 19:21:28 +01:00
wm4 64a66364ad m_option: handle audio/filter filters with old option parsing
These use the _oldargs_ hack, which failed in combination with playback
resume. Make it work.

It would be better to port all filters to new option parsing, but that's
obviously too much work, and most filters will probably be deleted and
replaced by libavfilter in the long run.
2013-12-01 19:20:35 +01:00
Alexander Preisinger 2995bf176d wayland: create xkbcommon keymap from string
Fixes a problem where the passed size doesn't match the actuall string.
2013-12-01 19:20:04 +01:00
William Light 0d3e7f5c3e ao_jack: refactoring, also fix "no-connect" option 2013-12-01 19:19:49 +01:00
wm4 8fe6f2542a demux_mkv: add support for HEVC
Note that you still need --vd-lavc-o='strict=-2' to enable the decoder.

Also, there's no guarantee that all required features for HEVC demuxing
are actually implemented, nor that the current muxing schema is the
final one.
2013-12-01 19:18:50 +01:00
Rudolf Polzer b553a43667 vo_lavc: fix -ovoffset.
Previously, using it led to no single frame being output, ever.
2013-12-01 19:17:38 +01:00
wm4 6de5bf12a5 vo_opengl: fix alpha values written to the framebuffer
When blending OSD and subtitles onto the video, we write bogus alpha
values. This doesn't normally matter, because these values are normally
unused and discarded. But at least on Wayland, the alpha values are used
by the compositor and leads to transparent windows even with opaque
video on places where the OSD happens to use transparency.

(Also see github issue #338.)

Until now, the alpha basically contained garbage. The source factor
GL_SRC_ALPHA meant that alpha was multiplied with itself. Use GL_ONE
instead (which is why we have to use glBlendFuncSeparate()). This should
give correct results, even with video that has alpha. (Or at least it's
something close to correct, I haven't thought too hard how the
compositor will blend it, and in fact I couldn't manage to test it.)

If glBlendFuncSeparate() is not available, fall back to glBlendFunc(),
which does the same as the code did before this commit. Technically, we
support GL 1.1, but glBlendFuncSeparate is 1.4, and I guess we should
try not to crash if vo_opengl_old runs on a system with GL 1.1 drivers
only.
2013-12-01 19:17:25 +01:00
wm4 78adec6c9c Release 0.2.3 2013-11-08 00:01:29 +01:00
wm4 0fed032ca0 audio: fix bogus audio format comparison 2013-11-07 23:59:38 +01:00
wm4 96532916fe osdep: handle SIGTERM
There's no reason why we should e.g. handle SIGQUIT, but not SIGTERM.

Note that sending SIGTERM twice still kills the player.
2013-11-07 23:58:56 +01:00
wm4 c265855d44 input.conf: clarify the magic how default key bindings are added
This is a confusing mechanism, so the explanation should bit more clear.
2013-11-07 23:58:47 +01:00
wm4 7816fa9745 manpage: fix incorrect default for --osc 2013-11-07 23:58:12 +01:00
wm4 e76076da3d stream_lavf: support more libavformat protocols 2013-11-07 23:57:56 +01:00
wm4 90015a8b8b vo_opengl: reserve 4 texture units for video instead of 3
Video has up to 4 textures, if you include obscure formats with alpha.
This means alpha formats could always overwrite the first scaler
texture, leading to corrupted video display. This problem was recently
brought to light, when commit 571e697 started to explicitly unbind all 4
video textures, which broke rendering for non-alpha formats as well.

Fix this by reserving the correct number of texture units.
2013-11-07 23:57:43 +01:00
ChrisK2 d1a8dfb8c4 tools: add --no-cache --no-config to mpv_identify.sh 2013-11-07 23:57:16 +01:00
wm4 e68fcbfa39 player: fix quvi 0.9 playlist loading
The code made no sense at all.

Conflicts:
	mpvcore/player/loadfile.c
2013-11-07 23:57:05 +01:00
wm4 391c087d75 stream: reconnecting doesn't make sense if stream is not seekable
This stops mpv from being stuck in reconnecting at the end of the file
with some unseekable streams.

Test URL: http://playerservices.streamtheworld.com/pls/CBC_R1_VCR_H.pls
2013-11-07 23:55:45 +01:00
43 changed files with 423 additions and 326 deletions

No files matched your search

+4
View File
@@ -90,6 +90,10 @@ p / SPACE
Step forward. Pressing once will pause movie, every consecutive press will
play one frame and then go into pause mode again.
,
Step backward. Pressing once will pause movie, every consecutive press will
play one frame in reverse and then go into pause mode again.
q / ESC
Stop playing and quit.
+4 -2
View File
@@ -55,6 +55,8 @@ OPTIONS
DTS-HD tracks can be sent over HDMI but not over the original
coax/toslink S/PDIF system.
Note: this feature is broken.
``--dtshd`` and ``--no-dtshd`` are deprecated aliases.
``--af=<filter1[=parameter1:parameter2:...],filter2,...>``
@@ -1420,7 +1422,7 @@ OPTIONS
chapter order specified for the main file.
``--osc``, ``--no-osc``
Whether to load the on-screen-controller (default: no).
Whether to load the on-screen-controller (default: yes).
``--no-osd-bar``, ``--osd-bar``
Disable display of the OSD bar. This will make some things (like seeking)
@@ -2596,7 +2598,7 @@ OPTIONS
to pad the video to screen if video and screen aspect ratios are different.
``--video-align-y=-1`` would move the video to the top of the screen
(leaving a border only on the bottom), a value of ``0`` centers it
(default), and a value of ``-1`` would put the video at the bottom of the
(default), and a value of ``1`` would put the video at the bottom of the
screen.
If video and screen aspect match perfectly, these options do nothing.
+4 -4
View File
@@ -863,10 +863,10 @@ Available filters are:
Specify the fourth parameter to pass to the library.
``vavpp``
VA-API video post processing. Works with ``--vo=vaapi`` only. Currently
deinterlaces. This filter is automatically inserted if deinterlacing is
requested (either using the ``D`` key, by default mapped to the command
``cycle deinterlace``, or the ``--deinterlace`` option).
VA-AP-API video post processing. Works with ``--vo=vaapi`` and ``--vo=opengl``
only. Currently deinterlaces. This filter is automatically inserted if
deinterlacing is requested (either using the ``D`` key, by default mapped to
the command ``cycle deinterlace``, or the ``--deinterlace`` option).
``deint=<method>``
Select the deinterlacing algorithm.
+1 -1
View File
@@ -104,7 +104,7 @@ for __midentify__key in $__midentify__allprops; do
eval unset $__midentify__nextprefix$__midentify__key
done
__midentify__output=`$MPV --playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet "$@"`
__midentify__output=`$MPV --playing-msg="$__midentify__propstr" --vo=null --ao=null --frames=1 --quiet --no-cache --no-config "$@"`
__midentify__fileindex=0
__midentify__prefix=
while :; do
@@ -1,120 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE fontconfig SYSTEM "fonts.dtd">
<fontconfig>
<dir>/System/Library/Fonts</dir>
<dir>/Library/Fonts</dir>
<dir>~/Library/Fonts</dir>
<dir>/Network/Library/Fonts</dir>
<cachedir>~/.fontconfig</cachedir>
<!--
Accept deprecated 'mono' alias, replacing it with 'monospace'
-->
<match target="pattern">
<test qual="any" name="family">
<string>mono</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>monospace</string>
</edit>
</match>
<!--
Accept alternate 'sans serif' spelling, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans serif</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<!--
Accept deprecated 'sans' alias, replacing it with 'sans-serif'
-->
<match target="pattern">
<test qual="any" name="family">
<string>sans</string>
</test>
<edit name="family" mode="assign" binding="same">
<string>sans-serif</string>
</edit>
</match>
<config>
<!--
These are the default Unicode chars that are expected to be blank
in fonts. All other blank chars are assumed to be broken and
won't appear in the resulting charsets
-->
<blank>
<int>0x0020</int> <!-- SPACE -->
<int>0x00A0</int> <!-- NO-BREAK SPACE -->
<int>0x00AD</int> <!-- SOFT HYPHEN -->
<int>0x034F</int> <!-- COMBINING GRAPHEME JOINER -->
<int>0x0600</int> <!-- ARABIC NUMBER SIGN -->
<int>0x0601</int> <!-- ARABIC SIGN SANAH -->
<int>0x0602</int> <!-- ARABIC FOOTNOTE MARKER -->
<int>0x0603</int> <!-- ARABIC SIGN SAFHA -->
<int>0x06DD</int> <!-- ARABIC END OF AYAH -->
<int>0x070F</int> <!-- SYRIAC ABBREVIATION MARK -->
<int>0x115F</int> <!-- HANGUL CHOSEONG FILLER -->
<int>0x1160</int> <!-- HANGUL JUNGSEONG FILLER -->
<int>0x1680</int> <!-- OGHAM SPACE MARK -->
<int>0x17B4</int> <!-- KHMER VOWEL INHERENT AQ -->
<int>0x17B5</int> <!-- KHMER VOWEL INHERENT AA -->
<int>0x180E</int> <!-- MONGOLIAN VOWEL SEPARATOR -->
<int>0x2000</int> <!-- EN QUAD -->
<int>0x2001</int> <!-- EM QUAD -->
<int>0x2002</int> <!-- EN SPACE -->
<int>0x2003</int> <!-- EM SPACE -->
<int>0x2004</int> <!-- THREE-PER-EM SPACE -->
<int>0x2005</int> <!-- FOUR-PER-EM SPACE -->
<int>0x2006</int> <!-- SIX-PER-EM SPACE -->
<int>0x2007</int> <!-- FIGURE SPACE -->
<int>0x2008</int> <!-- PUNCTUATION SPACE -->
<int>0x2009</int> <!-- THIN SPACE -->
<int>0x200A</int> <!-- HAIR SPACE -->
<int>0x200B</int> <!-- ZERO WIDTH SPACE -->
<int>0x200C</int> <!-- ZERO WIDTH NON-JOINER -->
<int>0x200D</int> <!-- ZERO WIDTH JOINER -->
<int>0x200E</int> <!-- LEFT-TO-RIGHT MARK -->
<int>0x200F</int> <!-- RIGHT-TO-LEFT MARK -->
<int>0x2028</int> <!-- LINE SEPARATOR -->
<int>0x2029</int> <!-- PARAGRAPH SEPARATOR -->
<int>0x202A</int> <!-- LEFT-TO-RIGHT EMBEDDING -->
<int>0x202B</int> <!-- RIGHT-TO-LEFT EMBEDDING -->
<int>0x202C</int> <!-- POP DIRECTIONAL FORMATTING -->
<int>0x202D</int> <!-- LEFT-TO-RIGHT OVERRIDE -->
<int>0x202E</int> <!-- RIGHT-TO-LEFT OVERRIDE -->
<int>0x202F</int> <!-- NARROW NO-BREAK SPACE -->
<int>0x205F</int> <!-- MEDIUM MATHEMATICAL SPACE -->
<int>0x2060</int> <!-- WORD JOINER -->
<int>0x2061</int> <!-- FUNCTION APPLICATION -->
<int>0x2062</int> <!-- INVISIBLE TIMES -->
<int>0x2063</int> <!-- INVISIBLE SEPARATOR -->
<int>0x206A</int> <!-- INHIBIT SYMMETRIC SWAPPING -->
<int>0x206B</int> <!-- ACTIVATE SYMMETRIC SWAPPING -->
<int>0x206C</int> <!-- INHIBIT ARABIC FORM SHAPING -->
<int>0x206D</int> <!-- ACTIVATE ARABIC FORM SHAPING -->
<int>0x206E</int> <!-- NATIONAL DIGIT SHAPES -->
<int>0x206F</int> <!-- NOMINAL DIGIT SHAPES -->
<int>0x2800</int> <!-- BRAILLE PATTERN BLANK -->
<int>0x3000</int> <!-- IDEOGRAPHIC SPACE -->
<int>0x3164</int> <!-- HANGUL FILLER -->
<int>0xFEFF</int> <!-- ZERO WIDTH NO-BREAK SPACE -->
<int>0xFFA0</int> <!-- HALFWIDTH HANGUL FILLER -->
<int>0xFFF9</int> <!-- INTERLINEAR ANNOTATION ANCHOR -->
<int>0xFFFA</int> <!-- INTERLINEAR ANNOTATION SEPARATOR -->
<int>0xFFFB</int> <!-- INTERLINEAR ANNOTATION TERMINATOR -->
</blank>
<!--
Rescan configuration every 30 seconds when FcFontSetList is called
-->
<rescan>
<int>30</int>
</rescan>
</config>
</fontconfig>
+1 -1
View File
@@ -1 +1 @@
0.2.2
0.2.4
+1 -5
View File
@@ -206,11 +206,6 @@ static int control(struct af_instance *af, int cmd, void *arg)
return mp_audio_config_equals(in, &orig_in) ? AF_OK : AF_FALSE;
}
case AF_CONTROL_COMMAND_LINE: {
talloc_free(p->cfg_graph);
p->cfg_graph = talloc_strdup(p, (char *)arg);
return AF_OK;
}
}
return AF_UNKNOWN;
}
@@ -291,6 +286,7 @@ static struct mp_audio *play(struct af_instance *af, struct mp_audio *data)
static void uninit(struct af_instance *af)
{
destroy_graph(af);
}
static int af_open(struct af_instance *af)
+1 -1
View File
@@ -43,7 +43,7 @@ enum AVSampleFormat af_to_avformat(int fmt)
if (audio_conversion_map[i].fmt == fmt)
break;
sample_fmt = audio_conversion_map[i].sample_fmt;
if (sample_fmt == AF_FORMAT_UNKNOWN)
if (sample_fmt == AV_SAMPLE_FMT_NONE)
mp_msg(MSGT_GLOBAL, MSGL_V, "Unsupported sample format: %s\n",
af_fmt2str_short(fmt));
return sample_fmt;
+44 -4
View File
@@ -336,6 +336,47 @@ bool ca_change_format(struct ao *ao, AudioStreamID stream,
return format_set;
}
static const int speaker_map[][2] = {
{ kAudioChannelLabel_Left, MP_SPEAKER_ID_FL },
{ kAudioChannelLabel_Right, MP_SPEAKER_ID_FR },
{ kAudioChannelLabel_Center, MP_SPEAKER_ID_FC },
{ kAudioChannelLabel_LFEScreen, MP_SPEAKER_ID_LFE },
{ kAudioChannelLabel_LeftSurround, MP_SPEAKER_ID_BL },
{ kAudioChannelLabel_RightSurround, MP_SPEAKER_ID_BR },
{ kAudioChannelLabel_LeftCenter, MP_SPEAKER_ID_FLC },
{ kAudioChannelLabel_RightCenter, MP_SPEAKER_ID_FRC },
{ kAudioChannelLabel_CenterSurround, MP_SPEAKER_ID_BC },
{ kAudioChannelLabel_LeftSurroundDirect, MP_SPEAKER_ID_SL },
{ kAudioChannelLabel_RightSurroundDirect, MP_SPEAKER_ID_SR },
{ kAudioChannelLabel_TopCenterSurround, MP_SPEAKER_ID_TC },
{ kAudioChannelLabel_VerticalHeightLeft, MP_SPEAKER_ID_TFL },
{ kAudioChannelLabel_VerticalHeightCenter, MP_SPEAKER_ID_TFC },
{ kAudioChannelLabel_VerticalHeightRight, MP_SPEAKER_ID_TFR },
{ kAudioChannelLabel_TopBackLeft, MP_SPEAKER_ID_TBL },
{ kAudioChannelLabel_TopBackCenter, MP_SPEAKER_ID_TBC },
{ kAudioChannelLabel_TopBackRight, MP_SPEAKER_ID_TBR },
// unofficial extensions
{ kAudioChannelLabel_RearSurroundLeft, MP_SPEAKER_ID_SDL },
{ kAudioChannelLabel_RearSurroundRight, MP_SPEAKER_ID_SDR },
{ kAudioChannelLabel_LeftWide, MP_SPEAKER_ID_WL },
{ kAudioChannelLabel_RightWide, MP_SPEAKER_ID_WR },
{ kAudioChannelLabel_LFE2, MP_SPEAKER_ID_LFE2 },
{ kAudioChannelLabel_HeadphonesLeft, MP_SPEAKER_ID_DL },
{ kAudioChannelLabel_HeadphonesRight, MP_SPEAKER_ID_DR },
{ kAudioChannelLabel_Unknown, -1 },
};
static int ca_label_to_mp_speaker_id(AudioChannelLabel label)
{
for (int i = 0; speaker_map[i][0] != kAudioChannelLabel_Unknown; i++)
if (speaker_map[i][0] == label)
return speaker_map[i][1];
return -1;
}
static bool ca_bitmap_from_ch_desc(struct ao *ao, AudioChannelLayout *layout,
uint32_t *bitmap)
{
@@ -355,14 +396,13 @@ static bool ca_bitmap_from_ch_desc(struct ao *ao, AudioChannelLayout *layout,
for (int j=0; j < ch_num && all_channels_valid; j++) {
AudioChannelLabel label = layout->mChannelDescriptions[j].mChannelLabel;
if (label == kAudioChannelLabel_UseCoordinates ||
label == kAudioChannelLabel_Unknown ||
label > kAudioChannelLabel_TopBackRight) {
const int mp_speaker_id = ca_label_to_mp_speaker_id(label);
if (mp_speaker_id < 0) {
MP_VERBOSE(ao, "channel label=%d unusable to build channel "
"bitmap, skipping layout\n", label);
all_channels_valid = false;
} else {
*bitmap |= 1ULL << (label - 1);
*bitmap |= 1ULL << mp_speaker_id;
}
}
+108 -68
View File
@@ -38,9 +38,6 @@
#include <jack/jack.h>
//! maximum number of channels supported, avoids lots of mallocs
#define MAX_CHANS MP_NUM_CHANNELS
//! size of one chunk, if this is too small MPlayer will start to "stutter"
//! after a short time of playback
#define CHUNK_SIZE (24 * 1024)
@@ -48,7 +45,7 @@
#define NUM_CHUNKS 8
struct priv {
jack_port_t * ports[MAX_CHANS];
jack_port_t * ports[MP_NUM_CHANNELS];
int num_ports; // Number of used ports == number of channels
jack_client_t *client;
int outburst;
@@ -144,7 +141,7 @@ static int outputaudio(jack_nframes_t nframes, void *arg)
{
struct ao *ao = arg;
struct priv *p = ao->priv;
float *bufs[MAX_CHANS];
float *bufs[MP_NUM_CHANNELS];
int i;
for (i = 0; i < p->num_ports; i++)
bufs[i] = jack_port_get_buffer(p->ports[i], nframes);
@@ -164,79 +161,119 @@ static int outputaudio(jack_nframes_t nframes, void *arg)
return 0;
}
static int init(struct ao *ao)
static int
connect_to_outports(struct ao *ao)
{
struct priv *p = ao->priv;
char *port_name = (p->cfg_port && p->cfg_port[0]) ? p->cfg_port : NULL;
const char **matching_ports = NULL;
char *port_name = p->cfg_port && p->cfg_port[0] ? p->cfg_port : NULL;
jack_options_t open_options = JackNullOption;
int port_flags = JackPortIsInput;
int i;
struct mp_chmap_sel sel = {0};
if (!port_name)
port_flags |= JackPortIsPhysical;
if (p->stdlayout == 0) {
mp_chmap_sel_add_waveext(&sel);
} else if (p->stdlayout == 1) {
mp_chmap_sel_add_alsa_def(&sel);
} else {
mp_chmap_sel_add_any(&sel);
matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags);
if (!matching_ports || !matching_ports[0]) {
MP_FATAL(ao, "no ports to connect to\n");
goto err_get_ports;
}
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
goto err_out;
if (!p->autostart)
open_options |= JackNoStartServer;
p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
if (!p->client) {
MP_FATAL(ao, "cannot open server\n");
goto err_out;
}
jack_set_process_callback(p->client, outputaudio, ao);
// list matching ports if connections should be made
if (p->connect) {
if (!port_name)
port_flags |= JackPortIsPhysical;
matching_ports = jack_get_ports(p->client, port_name, NULL, port_flags);
if (!matching_ports || !matching_ports[0]) {
MP_FATAL(ao, "no physical ports available\n");
goto err_out;
}
i = 1;
p->num_ports = ao->channels.num;
while (matching_ports[i])
i++;
if (p->num_ports > i)
p->num_ports = i;
}
// create out output ports
for (i = 0; i < p->num_ports; i++) {
char pname[30];
snprintf(pname, 30, "out_%d", i);
p->ports[i] =
jack_port_register(p->client, pname, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (!p->ports[i]) {
MP_FATAL(ao, "not enough ports available\n");
goto err_out;
}
}
if (jack_activate(p->client)) {
MP_FATAL(ao, "activate failed\n");
goto err_out;
}
for (i = 0; i < p->num_ports; i++) {
for (i = 0; i < p->num_ports && matching_ports[i]; i++) {
if (jack_connect(p->client, jack_port_name(p->ports[i]),
matching_ports[i]))
{
MP_FATAL(ao, "connecting failed\n");
goto err_out;
goto err_connect;
}
}
free(matching_ports);
return 0;
err_connect:
free(matching_ports);
err_get_ports:
return -1;
}
static int
create_ports(struct ao *ao, int nports)
{
struct priv *p = ao->priv;
int i;
/* register our output ports */
for (i = 0; i < nports; i++) {
char pname[30];
snprintf(pname, sizeof(pname), "out_%d", i);
p->ports[i] =
jack_port_register(p->client, pname, JACK_DEFAULT_AUDIO_TYPE,
JackPortIsOutput, 0);
if (!p->ports[i]) {
MP_FATAL(ao, "not enough ports available\n");
goto err_port_register;
}
}
p->num_ports = nports;
return 0;
err_port_register:
return -1;
}
static int init(struct ao *ao)
{
struct priv *p = ao->priv;
struct mp_chmap_sel sel = {0};
jack_options_t open_options;
switch (p->stdlayout) {
case 0:
mp_chmap_sel_add_waveext(&sel);
break;
case 1:
mp_chmap_sel_add_alsa_def(&sel);
break;
default:
mp_chmap_sel_add_any(&sel);
}
if (!ao_chmap_sel_adjust(ao, &sel, &ao->channels))
goto err_chmap;
open_options = JackNullOption;
if (!p->autostart)
open_options |= JackNoStartServer;
p->client = jack_client_open(p->cfg_client_name, open_options, NULL);
if (!p->client) {
MP_FATAL(ao, "cannot open server\n");
goto err_client_open;
}
if (create_ports(ao, ao->channels.num))
goto err_create_ports;
jack_set_process_callback(p->client, outputaudio, ao);
if (jack_activate(p->client)) {
MP_FATAL(ao, "activate failed\n");
goto err_activate;
}
ao->samplerate = jack_get_sample_rate(p->client);
if (p->connect)
if (connect_to_outports(ao))
goto err_connect;
jack_latency_range_t jack_latency_range;
jack_port_get_latency_range(p->ports[0], JackPlaybackLatency,
&jack_latency_range);
@@ -245,19 +282,22 @@ static int init(struct ao *ao)
p->callback_interval = 0;
if (!ao_chmap_sel_get_def(ao, &sel, &ao->channels, p->num_ports))
goto err_out;
goto err_chmap_sel_get_def;
ao->format = AF_FORMAT_FLOAT_NE;
int unitsize = ao->channels.num * sizeof(float);
p->outburst = (CHUNK_SIZE + unitsize - 1) / unitsize * unitsize;
p->ring = mp_ring_new(p, NUM_CHUNKS * p->outburst);
free(matching_ports);
return 0;
err_out:
free(matching_ports);
if (p->client)
jack_client_close(p->client);
err_chmap_sel_get_def:
err_connect:
jack_deactivate(p->client);
err_activate:
err_create_ports:
jack_client_close(p->client);
err_client_open:
err_chmap:
return -1;
}
+3 -2
View File
@@ -430,10 +430,11 @@ static void reset(struct ao *ao)
ioctl(p->audio_fd, SNDCTL_DSP_SPEED, &ao->samplerate);
ioctl(p->audio_fd, SNDCTL_DSP_SETFMT, &oss_format);
if (!AF_FORMAT_IS_AC3(ao->format)) {
int c = ao->channels.num;
if (ao->channels.num > 2)
ioctl(p->audio_fd, SNDCTL_DSP_CHANNELS, &ao->channels.num);
ioctl(p->audio_fd, SNDCTL_DSP_CHANNELS, &c);
else {
int c = ao->channels.num - 1;
c--;
ioctl(p->audio_fd, SNDCTL_DSP_STEREO, &c);
}
ioctl(p->audio_fd, SNDCTL_DSP_SPEED, &ao->samplerate);
+2 -2
View File
@@ -36,8 +36,8 @@
struct priv {
rsound_t *rd;
const char *host;
const char *port;
char *host;
char *port;
};
static int set_format(struct ao *ao)
Vendored
+24 -3
View File
@@ -311,6 +311,7 @@ Optional features:
--disable-radio-v4l2 disable Video4Linux2 radio interface [autodetect]
--disable-tv disable TV interface (TV/DVB grabbers) [enable]
--disable-tv-v4l2 disable Video4Linux2 TV interface [autodetect]
--disable-libv4l2 disable libv4l2 [autodetect]
--disable-pvr disable Video4Linux2 MPEG PVR [autodetect]
--enable-smb enable Samba (SMB) input [autodetect]
--disable-libquvi4 disable libquvi 0.4.x [autodetect]
@@ -468,6 +469,7 @@ _radio_capture=no
_radio_v4l2=auto
_tv=yes
_tv_v4l2=auto
_libv4l2=auto
_pvr=auto
_smb=auto
_libquvi4=auto
@@ -665,6 +667,8 @@ for ac_option do
--disable-tv) _tv=no ;;
--enable-tv-v4l2) _tv_v4l2=yes ;;
--disable-tv-v4l2) _tv_v4l2=no ;;
--enable-libv4l2) _libv4l2=yes ;;
--disable-libv4l2) _libv4l2=no ;;
--enable-radio) _radio=yes ;;
--enable-radio-capture) _radio_capture=yes ;;
--disable-radio-capture) _radio_capture=no ;;
@@ -889,7 +893,7 @@ extra_cflags="-I. -D_GNU_SOURCE $extra_cflags"
_timer=timer-linux.c
_getch=getch2.c
if freebsd ; then
if freebsd || openbsd ; then
extra_ldflags="$extra_ldflags -L/usr/local/lib"
extra_cflags="$extra_cflags -I/usr/local/include"
fi
@@ -2931,6 +2935,8 @@ if test "$_tv_v4l2" = auto ; then
_tv_v4l2=no
if test "$_tv" = yes && linux ; then
header_check_broken sys/time.h linux/videodev2.h && _tv_v4l2=yes
elif test "$_tv" = yes && freebsd ; then
header_check linux/videodev2.h && _tv_v4l2=yes
elif test "$_tv" = yes && test "$sys_videoio_h" = "yes" ; then
_tv_v4l2=yes
fi
@@ -2945,6 +2951,19 @@ else
fi
echores "$_tv_v4l2"
echocheck "libv4l2 support"
if test "$_libv4l2" = auto ; then
_libv4l2=no
if pkg_config_add "libv4l2" ; then
_libv4l2=yes
fi
fi
if test "$_libv4l2" = yes; then
def_libv4l2="#define HAVE_LIBV4L2 1"
else
def_libv4l2="#define HAVE_LIBV4L2 0"
fi
echores "$_libv4l2"
echocheck "Radio interface"
if test "$_radio" = yes ; then
@@ -2972,7 +2991,7 @@ echores "$_radio_capture"
echocheck "Video 4 Linux 2 Radio interface"
if test "$_radio_v4l2" = auto ; then
_radio_v4l2=no
if test "$_radio" = yes && linux ; then
if test "$_radio" = yes && (linux || freebsd) ; then
header_check linux/videodev2.h && _radio_v4l2=yes
fi
fi
@@ -2991,7 +3010,7 @@ fi
echocheck "Video 4 Linux 2 MPEG PVR interface"
if test "$_pvr" = auto ; then
_pvr=no
if test "$_tv_v4l2" = yes && linux ; then
if test "$_tv_v4l2" = yes ; then
cat > $TMPC <<EOF
#include <sys/time.h>
#include <linux/videodev2.h>
@@ -3315,6 +3334,7 @@ SNDIO = $_sndio
STREAM_CACHE = $_stream_cache
TV = $_tv
TV_V4L2 = $_tv_v4l2
LIBV4L2 = $_libv4l2
VCD = $_vcd
VDPAU = $_vdpau
VDPAU_DEC = $_vdpau_dec
@@ -3464,6 +3484,7 @@ $def_radio_capture
$def_radio_v4l2
$def_tv
$def_tv_v4l2
$def_libv4l2
/* font stuff */
+1
View File
@@ -313,6 +313,7 @@ static const struct mp_codec_tag mp_video_codec_tags[] = {
{MKTAG('C', '9', '3', 'V'), "c93"},
{MKTAG('V', 'P', '9', '0'), "vp9"},
{MKTAG('p', 'r', '0', '0'), "prores"},
{MKTAG('H', 'E', 'V', 'C'), "hevc"},
{0},
};
+1
View File
@@ -1169,6 +1169,7 @@ static const videocodec_info_t vinfo[] = {
{MKV_V_VP9, mmioFOURCC('V', 'P', '9', '0'), 0},
{MKV_V_DIRAC, mmioFOURCC('d', 'r', 'a', 'c'), 0},
{MKV_V_PRORES, mmioFOURCC('p', 'r', '0', '0'), 0},
{MKV_V_HEVC, mmioFOURCC('H', 'E', 'V', 'C'), 1},
{NULL, 0, 0}
};
+2
View File
@@ -80,6 +80,8 @@
#define MKV_V_UNCOMPRESSED "V_UNCOMPRESSED"
#define MKV_V_DIRAC "V_DIRAC"
#define MKV_V_PRORES "V_PRORES"
#define MKV_V_PRORES "V_PRORES"
#define MKV_V_HEVC "V_MPEGH/ISO/HEVC"
#define MKV_S_TEXTASCII "S_TEXT/ASCII"
#define MKV_S_TEXTUTF8 "S_TEXT/UTF8"
+7 -3
View File
@@ -31,9 +31,13 @@
# file to ~/.mpv/input.conf, and uncomment and edit the binding you want to
# change.
# Developer note: this file is baked into the mpv binary, and internally,
# entries are uncommented and added as default bindings. Lines that have a
# space after the '#' are ignored.
# Developer note:
# etc/input.conf from the mpv source tree is baked into the mpv binary, with
# all entries magically uncommented and parsed on initialization. Thus, this
# file defines the mpv default key bindings. If this file is read as normal
# config file, all lines starting with '#' are treated as comments (and this
# file, if unedited, doesn't define any bindings).
# Lines that have a space after the '#' are always ignored as real comments.
#MOUSE_BTN0 ignore # don't do anything
#MOUSE_BTN0_DBL cycle fullscreen # toggle fullscreen on/off
+1 -1
View File
@@ -680,7 +680,7 @@ int encode_lavc_open_codec(struct encode_lavc_context *ctx, AVStream *stream)
if (ret < 0)
encode_lavc_fail(ctx,
"unable to open encoder (see above for the cause)");
"unable to open encoder (see above for the cause)\n");
return ret;
}
+23 -5
View File
@@ -549,6 +549,7 @@ struct input_ctx {
int key_down[MP_MAX_KEY_DOWN];
unsigned int num_key_down;
int64_t last_key_down;
bool current_down_cmd_need_release;
struct mp_cmd *current_down_cmd;
int doubleclick_time;
@@ -1425,9 +1426,20 @@ static void update_mouse_section(struct input_ctx *ictx)
}
}
static void release_down_cmd(struct input_ctx *ictx)
// Called when the currently held-down key is released. This (usually) sends
// the a key-up versiob of the command associated with the keys that were held
// down.
// If the drop_current parameter is set to true, then don't send the key-up
// command. Unless we've already sent a key-down event, in which case the
// input receiver (the player) must get a key-up event, or it would get stuck
// thinking a key is still held down.
static void release_down_cmd(struct input_ctx *ictx, bool drop_current)
{
if (ictx->current_down_cmd && ictx->current_down_cmd->key_up_follows) {
if (ictx->current_down_cmd_need_release)
drop_current = false;
if (!drop_current && ictx->current_down_cmd &&
ictx->current_down_cmd->key_up_follows)
{
ictx->current_down_cmd->key_up_follows = false;
queue_add_tail(&ictx->cmd_queue, ictx->current_down_cmd);
ictx->got_new_events = true;
@@ -1435,6 +1447,7 @@ static void release_down_cmd(struct input_ctx *ictx)
talloc_free(ictx->current_down_cmd);
}
ictx->current_down_cmd = NULL;
ictx->current_down_cmd_need_release = false;
ictx->last_key_down = 0;
ictx->ar_state = -1;
}
@@ -1517,7 +1530,7 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
if (key_was_down)
return;
// Cancel current down-event (there can be only one)
release_down_cmd(ictx);
release_down_cmd(ictx, true);
ictx->key_down[ictx->num_key_down] = code & ~MP_KEY_STATE_DOWN;
ictx->num_key_down++;
update_mouse_section(ictx);
@@ -1532,10 +1545,11 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
if (cmd && (code & MP_KEY_EMIT_ON_UP))
cmd->key_up_follows = true;
ictx->current_down_cmd = mp_cmd_clone(cmd);
ictx->current_down_cmd_need_release = false;
} else if (code & MP_KEY_STATE_UP) {
if (key_was_down) {
remove_key_down(ictx, code);
release_down_cmd(ictx);
release_down_cmd(ictx, false);
}
update_mouse_section(ictx);
} else {
@@ -1580,6 +1594,8 @@ static void interpret_key(struct input_ctx *ictx, int code, double scale)
cmd->scale = scale;
if (cmd->key_up_follows)
ictx->current_down_cmd_need_release = true;
queue_add_tail(&ictx->cmd_queue, cmd);
}
@@ -1588,7 +1604,7 @@ static void mp_input_feed_key(struct input_ctx *ictx, int code, double scale)
if (code == MP_INPUT_RELEASE_ALL) {
MP_DBG(ictx, "release all\n");
ictx->num_key_down = 0;
release_down_cmd(ictx);
release_down_cmd(ictx, false);
update_mouse_section(ictx);
return;
}
@@ -1639,6 +1655,8 @@ void mp_input_put_key_utf8(struct input_ctx *ictx, int mods, struct bstr t)
void mp_input_put_axis(struct input_ctx *ictx, int direction, double value)
{
if (value == 0.0)
return;
input_lock(ictx);
mp_input_feed_key(ictx, direction, value);
input_unlock(ictx);
+9 -3
View File
@@ -2430,9 +2430,15 @@ static char *print_obj_settings_list(const m_option_t *opt, const void *val)
for (int i = 0; entry->attribs[i * 2 + 0]; i++) {
if (i > 0)
res = talloc_strdup_append(res, ":");
append_param(&res, entry->attribs[i * 2 + 0]);
res = talloc_strdup_append(res, "=");
append_param(&res, entry->attribs[i * 2 + 1]);
if (strcmp(entry->attribs[i * 2 + 0], "_oldargs_") == 0) {
// Compatibility crap; write just the arg without escaping,
// and hope it won't crash and burn.
res = talloc_strdup_append(res, entry->attribs[i * 2 + 1]);
} else {
append_param(&res, entry->attribs[i * 2 + 0]);
res = talloc_strdup_append(res, "=");
append_param(&res, entry->attribs[i * 2 + 1]);
}
}
}
}
+24 -8
View File
@@ -2278,6 +2278,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
bool audio_eof = false;
bool partial_fill = false;
sh_audio_t * const sh_audio = mpctx->sh_audio;
// Can't adjust the start of audio with spdif pass-through.
bool modifiable_audio_format = !(ao->format & AF_FORMAT_SPECIAL_MASK);
int unitsize = ao->channels.num * af_fmt2bits(ao->format) / 8;
@@ -2316,7 +2317,7 @@ static int fill_audio_out_buffers(struct MPContext *mpctx, double endpts)
audio_eof = true;
}
if (endpts != MP_NOPTS_VALUE && modifiable_audio_format) {
if (endpts != MP_NOPTS_VALUE) {
double bytes = (endpts - written_audio_pts(mpctx) + mpctx->audio_delay)
* ao->bps / opts->playback_speed;
if (playsize > bytes) {
@@ -2481,6 +2482,7 @@ err_out:
no_video:
uninit_player(mpctx, INITIALIZED_VCODEC | (opts->force_vo ? 0 : INITIALIZED_VO));
cleanup_demux_stream(mpctx, STREAM_VIDEO);
mpctx->current_track[STREAM_VIDEO] = NULL;
handle_force_window(mpctx, true);
mp_tmsg(MSGT_CPLAYER, MSGL_INFO, "Video: no video\n");
return 0;
@@ -2992,6 +2994,15 @@ static int seek(MPContext *mpctx, struct seek_params seek,
if (mpctx->stop_play == AT_END_OF_FILE)
mpctx->stop_play = KEEP_PLAYING;
double hr_seek_offset = opts->hr_seek_demuxer_offset;
// Always try to compensate for possibly bad demuxers in "special"
// situations where we need more robustness from the hr-seek code, even
// if the user doesn't use --hr-seek-demuxer-offset.
// The value is arbitrary, but should be "good enough" in most situations.
if (seek.exact > 1)
hr_seek_offset = MPMAX(hr_seek_offset, 0.5); // arbitrary
bool hr_seek = mpctx->demuxer->accurate_seek && opts->correct_pts;
hr_seek &= seek.exact >= 0 && seek.type != MPSEEK_FACTOR;
hr_seek &= (opts->hr_seek == 0 && seek.type == MPSEEK_ABSOLUTE) ||
@@ -3054,7 +3065,7 @@ static int seek(MPContext *mpctx, struct seek_params seek,
demuxer_style |= SEEK_SUBPREROLL;
if (hr_seek)
demuxer_amount -= opts->hr_seek_demuxer_offset;
demuxer_amount -= hr_seek_offset;
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style);
if (seekresult == 0) {
if (need_reset) {
@@ -3422,7 +3433,9 @@ static void handle_pause_on_low_cache(struct MPContext *mpctx)
unpause_player(mpctx);
}
} else {
if (cache >= 0 && cache <= opts->stream_cache_pause && !idle) {
if (cache >= 0 && cache <= opts->stream_cache_pause && !idle &&
opts->stream_cache_pause < opts->stream_cache_min_percent)
{
bool prev_paused_user = opts->pause;
pause_player(mpctx);
mpctx->paused_for_cache = true;
@@ -3512,14 +3525,14 @@ static void handle_backstep(struct MPContext *mpctx)
if (demuxer_ok && mpctx->sh_video && current_pts != MP_NOPTS_VALUE) {
double seek_pts = find_previous_pts(mpctx, current_pts);
if (seek_pts != MP_NOPTS_VALUE) {
queue_seek(mpctx, MPSEEK_ABSOLUTE, seek_pts, 1);
queue_seek(mpctx, MPSEEK_ABSOLUTE, seek_pts, 2);
} else {
double last = get_last_frame_pts(mpctx);
if (last != MP_NOPTS_VALUE && last >= current_pts &&
mpctx->backstep_start_seek_ts != mpctx->vo_pts_history_seek_ts)
{
mp_msg(MSGT_CPLAYER, MSGL_ERR, "Backstep failed.\n");
queue_seek(mpctx, MPSEEK_ABSOLUTE, current_pts, 1);
queue_seek(mpctx, MPSEEK_ABSOLUTE, current_pts, 2);
} else if (!mpctx->hrseek_active) {
mp_msg(MSGT_CPLAYER, MSGL_V, "Start backstep indexing.\n");
// Force it to index the video up until current_pts.
@@ -4355,8 +4368,9 @@ static void stream_dump(struct MPContext *mpctx)
// from the given playlist pl, so the entries don't actually need to be copied.
static void transfer_playlist(struct MPContext *mpctx, struct playlist *pl)
{
if (mpctx->demuxer->playlist->first) {
playlist_transfer_entries(mpctx->playlist, mpctx->demuxer->playlist);
if (pl->first) {
playlist_transfer_entries(mpctx->playlist, pl);
// current entry is replaced
if (mpctx->playlist->current)
playlist_remove(mpctx->playlist, mpctx->playlist->current);
} else {
@@ -4673,7 +4687,9 @@ goto_reopen_demuxer: ;
#ifdef CONFIG_DVBIN
if (mpctx->dvbin_reopen) {
mpctx->stop_play = 0;
uninit_player(mpctx, INITIALIZED_ALL - (INITIALIZED_STREAM | INITIALIZED_GETCH2 | (opts->fixed_vo ? INITIALIZED_VO : 0)));
uninit_player(mpctx, INITIALIZED_ALL -
(INITIALIZED_PLAYBACK | INITIALIZED_STREAM | INITIALIZED_GETCH2 |
(opts->fixed_vo ? INITIALIZED_VO : 0)));
mpctx->dvbin_reopen = 0;
goto goto_reopen_demuxer;
}
+2
View File
@@ -561,6 +561,7 @@ void getch2_enable(void){
setsigaction(SIGTSTP, stop_sighandler, SA_RESETHAND, false);
setsigaction(SIGINT, quit_request_sighandler, SA_RESETHAND, false);
setsigaction(SIGQUIT, quit_request_sighandler, SA_RESETHAND, false);
setsigaction(SIGTERM, quit_request_sighandler, SA_RESETHAND, false);
setsigaction(SIGTTIN, SIG_IGN, 0, true);
do_activate_getch2();
@@ -577,6 +578,7 @@ void getch2_disable(void){
setsigaction(SIGTSTP, SIG_DFL, 0, false);
setsigaction(SIGINT, SIG_DFL, 0, false);
setsigaction(SIGQUIT, SIG_DFL, 0, false);
setsigaction(SIGTERM, SIG_DFL, 0, false);
setsigaction(SIGTTIN, SIG_DFL, 0, false);
do_deactivate_getch2();
+2
View File
@@ -18,6 +18,8 @@
* with mplayer2. If not, see <http://www.gnu.org/licenses/>.
*/
#include "config.h"
#ifdef _WIN32
#include <windows.h>
+2
View File
@@ -387,6 +387,8 @@ static int stream_reconnect(stream_t *s)
#define RECONNECT_SLEEP_MS 1000
if (!s->streaming)
return 0;
if (!s->end_pos || !s->seek || !(s->flags & MP_STREAM_SEEK))
return 0;
int64_t pos = s->pos;
for (int retry = 0; retry < MAX_RECONNECT_RETRIES; retry++) {
mp_msg(MSGT_STREAM, MSGL_WARN,
-5
View File
@@ -657,7 +657,6 @@ static int dvb_open(stream_t *stream, int mode)
priv->config = dvb_get_config();
if(priv->config == NULL)
{
free(priv);
mp_msg(MSGT_DEMUX, MSGL_ERR, "DVB CONFIGURATION IS EMPTY, exit\n");
return STREAM_ERROR;
}
@@ -674,7 +673,6 @@ static int dvb_open(stream_t *stream, int mode)
if(priv->card == -1)
{
free(priv);
mp_msg(MSGT_DEMUX, MSGL_ERR, "NO CONFIGURATION FOUND FOR CARD N. %d, exit\n", p->cfg_card);
return STREAM_ERROR;
}
@@ -684,7 +682,6 @@ static int dvb_open(stream_t *stream, int mode)
if(tuner_type == 0)
{
free(priv);
mp_msg(MSGT_DEMUX, MSGL_V, "OPEN_DVB: UNKNOWN OR UNDETECTABLE TUNER TYPE, EXIT\n");
return STREAM_ERROR;
}
@@ -705,8 +702,6 @@ static int dvb_open(stream_t *stream, int mode)
if(! dvb_streaming_start(stream, tuner_type, progname))
{
free(stream->priv);
stream->priv = NULL;
return STREAM_ERROR;
}
+8 -2
View File
@@ -157,11 +157,15 @@ static int open_f(stream_t *stream, int mode)
filename += strlen(prefix[i]);
if (!strncmp(filename, "rtsp:", 5)) {
/* This is handled as a special demuxer, without a separate
* stream layer. demux_lavf will do all the real work.
* stream layer. demux_lavf will do all the real work. Note
* that libavformat doesn't even provide a protocol entry for
* this (the rtsp demuxer's probe function checks for a "rtsp:"
* filename prefix), so it has to be handled specially here.
*/
stream->seek = NULL;
stream->demuxer = "lavf";
stream->lavf_type = "rtsp";
talloc_free(temp);
return STREAM_OK;
}
mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] Opening %s\n", filename);
@@ -316,6 +320,8 @@ const stream_info_t stream_info_ffmpeg = {
.open = open_f,
.protocols = (const char*[]){
"lavf", "ffmpeg", "rtmp", "rtsp", "http", "https", "mms", "mmst", "mmsh",
"mmshttp", "udp", "ftp", "rtp", "httpproxy",
"mmshttp", "udp", "ftp", "rtp", "httpproxy", "hls", "rtmpe", "rtmps",
"rtmpt", "rtmpte", "rtmpts", "srtp", "tcp", "udp", "tls", "unix", "sftp",
"md5",
NULL },
};
-1
View File
@@ -37,7 +37,6 @@
#include <fcntl.h>
#include <inttypes.h>
#include <poll.h>
#include <linux/types.h>
#include <linux/videodev2.h>
#include <libavutil/common.h>
-2
View File
@@ -35,8 +35,6 @@
#include <errno.h>
#include <unistd.h>
#include <linux/types.h>
#ifdef CONFIG_RADIO_V4L2
#include <linux/videodev2.h>
#endif
+58 -48
View File
@@ -52,15 +52,25 @@ known issues:
#ifdef HAVE_SYS_VIDEOIO_H
#include <sys/videoio.h>
#else
#include <linux/types.h>
#include <linux/videodev2.h>
#endif
#if HAVE_LIBV4L2
#include <libv4l2.h>
#endif
#include "mpvcore/mp_msg.h"
#include "video/img_fourcc.h"
#include "audio/format.h"
#include "tv.h"
#include "audio_in.h"
#if !HAVE_LIBV4L2
#define v4l2_open open
#define v4l2_close close
#define v4l2_ioctl ioctl
#define v4l2_mmap mmap
#define v4l2_munmap munmap
#endif
#define info tvi_info_v4l2
static tvi_handle_t *tvi_init_v4l2(tv_param_t* tv_param);
/* information about this file */
@@ -453,7 +463,7 @@ static int getfmt(priv_t *priv)
int i;
priv->format.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if ((i = ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
if ((i = v4l2_ioctl(priv->video_fd, VIDIOC_G_FMT, &priv->format)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get format failed: %s\n",
info.short_name, strerror(errno));
}
@@ -469,11 +479,11 @@ static int getstd(priv_t *priv)
v4l2_std_id id;
int i=0;
if (ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_STD, &id) < 0) {
struct v4l2_streamparm parm;
parm.type=V4L2_BUF_TYPE_VIDEO_CAPTURE;
if(ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
if(v4l2_ioctl(priv->video_fd, VIDIOC_G_PARM, &parm) >= 0) {
mp_msg(MSGT_TV, MSGL_WARN, "%s: your device driver does not support VIDIOC_G_STD ioctl,"
" VIDIOC_G_PARM was used instead.\n", info.short_name);
priv->standard.index=0;
@@ -488,7 +498,7 @@ static int getstd(priv_t *priv)
}
do {
priv->standard.index = i++;
if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
return -1;
}
} while (priv->standard.id != id);
@@ -508,7 +518,7 @@ static int set_mute(priv_t *priv, int value)
struct v4l2_control control;
control.id = V4L2_CID_AUDIO_MUTE;
control.value = value;
if (ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_CTRL, &control) < 0) {
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set mute failed: %s\n",
info.short_name, strerror(errno));
return 0;
@@ -523,7 +533,7 @@ static int set_mute(priv_t *priv, int value)
static int set_control(priv_t *priv, struct v4l2_control *control, int val_signed) {
struct v4l2_queryctrl qctrl;
qctrl.id = control->id;
if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -548,7 +558,7 @@ static int set_control(priv_t *priv, struct v4l2_control *control, int val_signe
}
if (ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_CTRL, control) < 0) {
mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl set %s %d failed: %s\n",
info.short_name, qctrl.name, control->value, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -567,13 +577,13 @@ static int get_control(priv_t *priv, struct v4l2_control *control, int val_signe
struct v4l2_queryctrl qctrl;
qctrl.id = control->id;
if (ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QUERYCTRL, &qctrl) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query control failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
}
if (ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_CTRL, control) < 0) {
mp_msg(MSGT_TV, MSGL_ERR,"%s: ioctl get %s failed: %s\n",
info.short_name, qctrl.name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -720,7 +730,7 @@ static int control(priv_t *priv, int cmd, void *arg)
priv->mp_format = *(int *)arg;
mp_msg(MSGT_TV, MSGL_V, "%s: set format: %s\n", info.short_name,
pixfmt2name(priv->format.fmt.pix.pixelformat));
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -742,7 +752,7 @@ static int control(priv_t *priv, int cmd, void *arg)
priv->format.fmt.pix.width = ((int *)arg)[0];
priv->format.fmt.pix.height = ((int *)arg)[1];
priv->format.fmt.pix.field = V4L2_FIELD_ANY;
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0)
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0)
return TVI_CONTROL_FALSE;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_VID_SET_WIDTH:
@@ -750,7 +760,7 @@ static int control(priv_t *priv, int cmd, void *arg)
priv->format.fmt.pix.width = *(int *)arg;
mp_msg(MSGT_TV, MSGL_V, "%s: set width: %d\n", info.short_name,
*(int *)arg);
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set width failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -770,7 +780,7 @@ static int control(priv_t *priv, int cmd, void *arg)
priv->format.fmt.pix.field = V4L2_FIELD_ANY;
mp_msg(MSGT_TV, MSGL_V, "%s: set height: %d\n", info.short_name,
*(int *)arg);
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set height failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -857,7 +867,7 @@ static int control(priv_t *priv, int cmd, void *arg)
case TVI_CONTROL_TUN_GET_FREQ:
frequency.tuner = 0;
frequency.type = V4L2_TUNER_ANALOG_TV;
if (ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_FREQUENCY, &frequency) < 0) {
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl get frequency failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -872,7 +882,7 @@ static int control(priv_t *priv, int cmd, void *arg)
frequency.tuner = 0;
frequency.type = V4L2_TUNER_ANALOG_TV;
frequency.frequency = *(int *)arg;
if (ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FREQUENCY, &frequency) < 0) {
mp_msg(MSGT_TV,MSGL_ERR,"%s: ioctl set frequency failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -884,7 +894,7 @@ static int control(priv_t *priv, int cmd, void *arg)
return TVI_CONTROL_TRUE;
case TVI_CONTROL_TUN_GET_TUNER:
mp_msg(MSGT_TV, MSGL_V, "%s: get tuner\n",info.short_name);
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -892,7 +902,7 @@ static int control(priv_t *priv, int cmd, void *arg)
return TVI_CONTROL_TRUE;
case TVI_CONTROL_TUN_SET_TUNER:
mp_msg(MSGT_TV, MSGL_V, "%s: set tuner\n",info.short_name);
if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -902,7 +912,7 @@ static int control(priv_t *priv, int cmd, void *arg)
*(int *)arg = priv->standard.index;
return TVI_CONTROL_TRUE;
case TVI_CONTROL_TUN_GET_SIGNAL:
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -911,13 +921,13 @@ static int control(priv_t *priv, int cmd, void *arg)
return TVI_CONTROL_TRUE;
case TVI_CONTROL_TUN_SET_NORM:
priv->standard.index = *(int *)arg;
if (ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_ENUMSTD, &priv->standard) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum norm failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
}
mp_msg(MSGT_TV, MSGL_V, "%s: set norm: %s\n", info.short_name, priv->standard.name);
if (ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_STD, &priv->standard.id) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set norm failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -930,7 +940,7 @@ static int control(priv_t *priv, int cmd, void *arg)
struct v4l2_standard standard;
memset(&standard, 0, sizeof(standard));
standard.index = i;
if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
if (-1 == v4l2_ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
return TVI_CONTROL_FALSE;
if (!strcasecmp(standard.name, (char *)arg)) {
*(int *)arg = i;
@@ -940,7 +950,7 @@ static int control(priv_t *priv, int cmd, void *arg)
return TVI_CONTROL_FALSE;
}
case TVI_CONTROL_SPC_GET_INPUT:
if (ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_INPUT, (int *)arg) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -949,12 +959,12 @@ static int control(priv_t *priv, int cmd, void *arg)
case TVI_CONTROL_SPC_SET_INPUT:
mp_msg(MSGT_TV, MSGL_V, "%s: set input: %d\n", info.short_name, *(int *)arg);
priv->input.index = *(int *)arg;
if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &priv->input) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl enum input failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
}
if (ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_INPUT, (int *)arg) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set input failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -1066,7 +1076,7 @@ static int uninit(priv_t *priv)
dropped = frames - priv->frames;
/* turn off streaming */
if (ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_STREAMOFF, &(priv->map[0].buf.type)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamoff failed: %s\n",
info.short_name, strerror(errno));
}
@@ -1076,12 +1086,12 @@ static int uninit(priv_t *priv)
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
while (!ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
while (!v4l2_ioctl(priv->video_fd, VIDIOC_DQBUF, &buf));
}
/* unmap all buffers */
for (i = 0; i < priv->mapcount; i++) {
if (munmap(priv->map[i].addr, priv->map[i].len) < 0) {
if (v4l2_munmap(priv->map[i].addr, priv->map[i].len) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: munmap capture buffer failed: %s\n",
info.short_name, strerror(errno));
}
@@ -1099,7 +1109,7 @@ static int uninit(priv_t *priv)
/* free memory and close device */
free(priv->map); priv->map = NULL;
priv->mapcount = 0;
if(priv->video_fd!=-1)close(priv->video_fd); priv->video_fd = -1;
if(priv->video_fd!=-1)v4l2_close(priv->video_fd); priv->video_fd = -1;
free(priv->video_dev); priv->video_dev = NULL;
if (priv->video_ringbuffer) {
@@ -1138,7 +1148,7 @@ static int init(priv_t *priv)
priv->audio_initialized = 0;
/* Open the video device. */
priv->video_fd = open(priv->video_dev, O_RDWR);
priv->video_fd = v4l2_open(priv->video_dev, O_RDWR);
if (priv->video_fd < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: unable to open '%s': %s\n",
info.short_name, priv->video_dev, strerror(errno));
@@ -1152,7 +1162,7 @@ static int init(priv_t *priv)
** Query the video capabilities and current settings
** for further control calls.
*/
if (ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QUERYCAP, &priv->capability) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query capabilities failed: %s\n",
info.short_name, strerror(errno));
uninit(priv);
@@ -1176,7 +1186,7 @@ static int init(priv_t *priv)
** otherwise set some nice defaults
*/
if (priv->capability.capabilities & V4L2_CAP_TUNER) {
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get tuner failed: %s\n",
info.short_name, strerror(errno));
uninit(priv);
@@ -1223,7 +1233,7 @@ static int init(priv_t *priv)
struct v4l2_standard standard;
memset(&standard, 0, sizeof(standard));
standard.index = i;
if (-1 == ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
if (-1 == v4l2_ioctl(priv->video_fd, VIDIOC_ENUMSTD, &standard))
break;
mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, standard.name);
}
@@ -1232,13 +1242,13 @@ static int init(priv_t *priv)
struct v4l2_input input;
input.index = i;
if (ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_ENUMINPUT, &input) < 0) {
break;
}
mp_msg(MSGT_TV, MSGL_INFO, " %d = %s;", i, input.name);
}
i = -1;
if (ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_INPUT, &i) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl get input failed: %s\n",
info.short_name, strerror(errno));
}
@@ -1248,7 +1258,7 @@ static int init(priv_t *priv)
fmtdesc.index = i;
fmtdesc.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
if (ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_ENUM_FMT, &fmtdesc) < 0) {
break;
}
mp_msg(MSGT_TV, MSGL_V, " Format %-6s (%2d bits, %s)\n",
@@ -1262,7 +1272,7 @@ static int init(priv_t *priv)
if (getfmt(priv) < 0) return 0;
priv->format.fmt.pix.width = 640;
priv->format.fmt.pix.height = 480;
if (ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_FMT, &priv->format) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set format failed: %s\n",
info.short_name, strerror(errno));
uninit(priv);
@@ -1276,7 +1286,7 @@ static int init(priv_t *priv)
if (priv->tv_param->amode >= 0) {
mp_msg(MSGT_TV, MSGL_V, "%s: setting audio mode\n", info.short_name);
priv->tuner.audmode = amode2v4l(priv->tv_param->amode);
if (ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_S_TUNER, &priv->tuner) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl set tuner failed: %s\n",
info.short_name, strerror(errno));
return TVI_CONTROL_FALSE;
@@ -1434,7 +1444,7 @@ static int start(priv_t *priv)
request.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
request.memory = V4L2_MEMORY_MMAP;
if (ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_REQBUFS, &request) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl request buffers failed: %s\n",
info.short_name, strerror(errno));
return 0;
@@ -1453,14 +1463,14 @@ static int start(priv_t *priv)
priv->map[i].buf.index = i;
priv->map[i].buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
priv->map[i].buf.memory = V4L2_MEMORY_MMAP;
if (ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QUERYBUF, &(priv->map[i].buf)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s\n",
info.short_name, strerror(errno));
free(priv->map);
priv->map = NULL;
return 0;
}
priv->map[i].addr = mmap (0, priv->map[i].buf.length, PROT_READ |
priv->map[i].addr = v4l2_mmap (0, priv->map[i].buf.length, PROT_READ |
PROT_WRITE, MAP_SHARED, priv->video_fd, priv->map[i].buf.m.offset);
if (priv->map[i].addr == MAP_FAILED) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: mmap capture buffer failed: %s\n",
@@ -1472,7 +1482,7 @@ static int start(priv_t *priv)
/* count up to make sure this is correct everytime */
priv->mapcount++;
if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
info.short_name, strerror(errno));
return 0;
@@ -1501,7 +1511,7 @@ static inline void copy_frame(priv_t *priv, video_buffer_entry *dest, unsigned c
{
dest->framesize=len;
if(priv->tv_param->automute>0){
if (ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_G_TUNER, &priv->tuner) >= 0) {
if(priv->tv_param->automute<<8>priv->tuner.signal){
fill_blank_frame(dest->data,dest->framesize,fcc_vl2mp(priv->format.fmt.pix.pixelformat));
set_mute(priv,1);
@@ -1532,7 +1542,7 @@ static void *video_grabber(void *data)
prev_skew = 0;
mp_msg(MSGT_TV, MSGL_V, "%s: going to capture\n", info.short_name);
if (ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_STREAMON, &(priv->format.type)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl streamon failed: %s\n",
info.short_name, strerror(errno));
return 0;
@@ -1579,7 +1589,7 @@ static void *video_grabber(void *data)
memset(&buf,0,sizeof(buf));
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
ret = ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
ret = v4l2_ioctl(priv->video_fd, VIDIOC_DQBUF, &buf);
if (ret < 0) {
/*
@@ -1597,14 +1607,14 @@ static void *video_grabber(void *data)
buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE;
buf.memory = V4L2_MEMORY_MMAP;
buf.index = i;
ret = ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
ret = v4l2_ioctl(priv->video_fd, VIDIOC_QUERYBUF, &buf);
if (ret < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl query buffer failed: %s, idx = %d\n",
info.short_name, strerror(errno), buf.index);
return 0;
}
if ((buf.flags & (V4L2_BUF_FLAG_QUEUED | V4L2_BUF_FLAG_MAPPED | V4L2_BUF_FLAG_DONE)) == V4L2_BUF_FLAG_MAPPED) {
if (ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QBUF, &(priv->map[i].buf)) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
info.short_name, strerror(errno));
return 0;
@@ -1695,7 +1705,7 @@ static void *video_grabber(void *data)
priv->video_tail = (priv->video_tail+1)%priv->video_buffer_size_current;
priv->video_cnt++;
}
if (ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
if (v4l2_ioctl(priv->video_fd, VIDIOC_QBUF, &buf) < 0) {
mp_msg(MSGT_TV, MSGL_ERR, "%s: ioctl queue buffer failed: %s\n",
info.short_name, strerror(errno));
return 0;
+1 -1
View File
@@ -241,7 +241,7 @@ bool ta_vasprintf_append(char **str, const char *fmt, va_list ap)
/* Append the formatted string at the end of the allocation of *str. It
* overwrites the last byte of the allocation too (which is assumed to be the
* '\0' terminating the sttring). Compared to ta_asprintf_append(), this is
* '\0' terminating the string). Compared to ta_asprintf_append(), this is
* useful if you know that the string ends with the allocation, so that the
* extra strlen() can be avoided for better performance.
* Returns false on OOM or snprintf() errors, with *str left untouched.
+2
View File
@@ -791,6 +791,8 @@ static struct mp_image *decode_with_fallback(struct sh_video *sh,
init_avctx(sh, decoder, NULL);
if (ctx->avctx) {
mpi = NULL;
if (sh->vf_initialized < 0)
sh->vf_initialized = 0;
decode(sh, packet, flags, reordered_pts, &mpi);
return mpi;
}
+37 -14
View File
@@ -41,8 +41,29 @@ struct vf_priv_s {
int fakecount;
char *qbuf;
double lastpts;
char *args;
};
static void reset(struct vf_instance *vf)
{
if (vf->priv->ctx)
pullup_free_context(vf->priv->ctx);
free(vf->priv->qbuf);
vf->priv->qbuf = NULL;
vf->priv->init = 0;
struct pullup_context *c;
vf->priv->ctx = c = pullup_alloc_context();
vf->priv->fakecount = 1;
c->verbose = verbose>0;
c->junk_left = c->junk_right = 1;
c->junk_top = c->junk_bottom = 4;
c->strict_breaks = 0;
c->metric_plane = 0;
if (vf->priv->args) {
sscanf(vf->priv->args, "%d:%d:%d:%d:%d:%d", &c->junk_left, &c->junk_right, &c->junk_top, &c->junk_bottom, &c->strict_breaks, &c->metric_plane);
}
}
static void init_pullup(struct vf_instance *vf, mp_image_t *mpi)
{
struct pullup_context *c = vf->priv->ctx;
@@ -230,6 +251,7 @@ static int config(struct vf_instance *vf,
int width, int height, int d_width, int d_height,
unsigned int flags, unsigned int outfmt)
{
reset(vf);
if (height&3) return 0;
return vf_next_config(vf, width, height, d_width, d_height, flags, outfmt);
}
@@ -240,25 +262,26 @@ static void uninit(struct vf_instance *vf)
free(vf->priv);
}
static int vf_open(vf_instance_t *vf, char *args)
static int control(vf_instance_t *vf, int request, void *data)
{
struct vf_priv_s *p;
struct pullup_context *c;
switch (request) {
case VFCTRL_SEEK_RESET:
reset(vf);
break;
}
return vf_next_control(vf, request, data);
}
static int vf_open(vf_instance_t *vf, char *args)
{;
vf->filter = filter;
vf->config = config;
vf->query_format = query_format;
vf->control = control;
vf->uninit = uninit;
vf->priv = p = calloc(1, sizeof(struct vf_priv_s));
p->ctx = c = pullup_alloc_context();
p->fakecount = 1;
c->verbose = verbose>0;
c->junk_left = c->junk_right = 1;
c->junk_top = c->junk_bottom = 4;
c->strict_breaks = 0;
c->metric_plane = 0;
if (args) {
sscanf(args, "%d:%d:%d:%d:%d:%d", &c->junk_left, &c->junk_right, &c->junk_top, &c->junk_bottom, &c->strict_breaks, &c->metric_plane);
}
vf->priv = calloc(1, sizeof(struct vf_priv_s));
vf->priv->args = talloc_strdup(vf, args);
reset(vf);
return 1;
}
+5
View File
@@ -226,6 +226,11 @@ static struct mp_imgfmt_desc get_avutil_fmt(enum PixelFormat fmt)
desc.bytes[p] = desc.bpp[p] / 8;
}
// PSEUDOPAL is a complete braindeath nightmare, however it seems various
// parts of FFmpeg expect that it has a palette allocated.
if (pd->flags & (PIX_FMT_PAL | PIX_FMT_PSEUDOPAL))
desc.flags |= MP_IMGFLAG_PAL;
if ((desc.flags & MP_IMGFLAG_YUV) && (desc.flags & MP_IMGFLAG_BYTE_ALIGNED))
{
bool same_depth = true;
+7
View File
@@ -56,6 +56,13 @@
#define MP_IMGFLAG_BE 0x4000
// set if in native (host) endian, or endian independent
#define MP_IMGFLAG_NE MP_SELECT_LE_BE(MP_IMGFLAG_LE, MP_IMGFLAG_BE)
// Carries a palette in plane[1] (see IMGFMT_PAL8 for format of the palette).
// Note that some non-paletted formats have this flag set, because FFmpeg
// mysteriously expects some formats to carry a palette plane for no apparent
// reason. FFmpeg developer braindeath?
// The only real paletted format we support is IMGFMT_PAL8, so check for that
// format directly if you want an actual paletted format.
#define MP_IMGFLAG_PAL 0x8000
// Exactly one of these bits is set in mp_imgfmt_desc.flags
#define MP_IMGFLAG_COLOR_CLASS_MASK \
+3 -3
View File
@@ -135,7 +135,7 @@ static void mp_image_alloc_planes(struct mp_image *mpi)
mpi->stride[n] = FFALIGN(line_bytes, SWS_MIN_BYTE_ALIGN);
plane_size[n] = mpi->stride[n] * alloc_h;
}
if (mpi->imgfmt == IMGFMT_PAL8)
if (mpi->fmt.flags & MP_IMGFLAG_PAL)
plane_size[1] = MP_PALETTE_SIZE;
size_t sum = 0;
@@ -333,7 +333,7 @@ void mp_image_copy(struct mp_image *dst, struct mp_image *src)
memcpy_pic(dst->planes[n], src->planes[n], line_bytes, dst->plane_h[n],
dst->stride[n], src->stride[n]);
}
if (dst->imgfmt == IMGFMT_PAL8)
if (dst->fmt.flags & MP_IMGFLAG_PAL)
memcpy(dst->planes[1], src->planes[1], MP_PALETTE_SIZE);
}
@@ -352,7 +352,7 @@ void mp_image_copy_attributes(struct mp_image *dst, struct mp_image *src)
dst->levels = src->levels;
dst->chroma_location = src->chroma_location;
}
if (dst->imgfmt == IMGFMT_PAL8 && src->imgfmt == IMGFMT_PAL8) {
if ((dst->fmt.flags & MP_IMGFLAG_PAL) && (src->fmt.flags & MP_IMGFLAG_PAL)) {
if (dst->planes[1] && src->planes[1])
memcpy(dst->planes[1], src->planes[1], MP_PALETTE_SIZE);
}
+3 -1
View File
@@ -136,6 +136,7 @@ static void vo_cocoa_set_cursor_visibility(struct vo *vo, bool *visible)
void vo_cocoa_uninit(struct vo *vo)
{
vo_cocoa_set_current_context(vo, false);
dispatch_sync(dispatch_get_main_queue(), ^{
struct vo_cocoa_state *s = vo->cocoa;
enable_power_management(vo);
@@ -444,9 +445,10 @@ void vo_cocoa_set_current_context(struct vo *vo, bool current)
[s->gl_ctx makeCurrentContext];
} else {
const bool locked = !![NSOpenGLContext currentContext];
[NSOpenGLContext clearCurrentContext];
if (!s->inside_sync_section)
if (!s->inside_sync_section && locked)
[s->lock unlock];
}
}
+3 -1
View File
@@ -263,6 +263,8 @@ struct gl_functions gl_functions[] = {
DEF_FN(UniformMatrix2fv),
DEF_FN(UniformMatrix3fv),
DEF_FN(TexImage3D),
// Added in OpenGL 1.4, but vo_opengl_old doesn't need it
DEF_FN(BlendFuncSeparate),
{0},
},
},
@@ -944,7 +946,7 @@ bool mpgl_config_window(struct MPGLContext *ctx, int gl_caps, uint32_t d_width,
MP_WARN(ctx->vo, "Missing OpenGL features:");
list_features(missing, ctx->vo->log, MSGL_WARN, false);
if (missing & MPGL_CAP_NO_SW) {
if (missing == MPGL_CAP_NO_SW) {
MP_WARN(ctx->vo, "Rejecting suspected software OpenGL renderer.\n");
} else if ((missing & MPGL_CAP_GL21) &&
(ctx->gl->mpgl_caps & MPGL_CAP_GL_LEGACY))
+1
View File
@@ -209,6 +209,7 @@ struct GL {
void (GLAPIENTRY *DrawBuffer)(GLenum);
void (GLAPIENTRY *DepthMask)(GLboolean);
void (GLAPIENTRY *BlendFunc)(GLenum, GLenum);
void (GLAPIENTRY *BlendFuncSeparate)(GLenum, GLenum, GLenum, GLenum);
void (GLAPIENTRY *Flush)(void);
void (GLAPIENTRY *Finish)(void);
void (GLAPIENTRY *PixelStorei)(GLenum, GLint);
+13 -5
View File
@@ -29,10 +29,12 @@ struct osd_fmt_entry {
GLenum type;
};
// glBlendFunc() arguments
static const int blend_factors[SUBBITMAP_COUNT][2] = {
[SUBBITMAP_LIBASS] = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA},
[SUBBITMAP_RGBA] = {GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
// glBlendFuncSeparate() arguments
static const int blend_factors[SUBBITMAP_COUNT][4] = {
[SUBBITMAP_LIBASS] = {GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
[SUBBITMAP_RGBA] = {GL_ONE, GL_ONE_MINUS_SRC_ALPHA,
GL_ONE, GL_ONE_MINUS_SRC_ALPHA},
};
static const struct osd_fmt_entry osd_to_gl3_formats[SUBBITMAP_COUNT] = {
@@ -230,7 +232,13 @@ void mpgl_osd_set_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p)
gl->BindTexture(GL_TEXTURE_2D, p->texture);
gl->Enable(GL_BLEND);
gl->BlendFunc(blend_factors[p->format][0], blend_factors[p->format][1]);
const int *factors = &blend_factors[p->format][0];
if (gl->BlendFuncSeparate) {
gl->BlendFuncSeparate(factors[0], factors[1], factors[2], factors[3]);
} else {
gl->BlendFunc(factors[0], factors[1]);
}
}
void mpgl_osd_unset_gl_state(struct mpgl_osd *ctx, struct mpgl_osd_part *p)
+5 -5
View File
@@ -47,11 +47,11 @@ static const char vo_opengl_shaders[] =
// Pixel width of 1D lookup textures.
#define LOOKUP_TEXTURE_SIZE 256
// Texture units 0-2 are used by the video, with unit 0 for free use.
// Units 3-4 are used for scaler LUTs.
#define TEXUNIT_SCALERS 3
#define TEXUNIT_3DLUT 5
#define TEXUNIT_DITHER 6
// Texture units 0-3 are used by the video, with unit 0 for free use.
// Units 4-5 are used for scaler LUTs.
#define TEXUNIT_SCALERS 4
#define TEXUNIT_3DLUT 6
#define TEXUNIT_DITHER 7
// lscale/cscale arguments that map directly to shader filter routines.
// Note that the convolution filters are not included in this list.
+3 -1
View File
@@ -410,7 +410,9 @@ static void draw_image(struct vo *vo, mp_image_t *mpi)
// we will ONLY encode this frame if it can be encoded at at least
// vc->mindeltapts after the last encoded frame!
int64_t skipframes =
vc->lastencodedipts + vc->mindeltapts - vc->lastipts;
(vc->lastencodedipts == MP_NOPTS_VALUE)
? 0
: vc->lastencodedipts + vc->mindeltapts - vc->lastipts;
if (skipframes < 0)
skipframes = 0;
+2 -2
View File
@@ -930,11 +930,11 @@ static void draw_osd_part(struct vo *vo, int index)
.blend_factor_source_color =
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA,
.blend_factor_source_alpha =
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE,
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO,
.blend_factor_destination_color =
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ONE_MINUS_SRC_ALPHA,
.blend_factor_destination_alpha =
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_SRC_ALPHA,
VDP_OUTPUT_SURFACE_RENDER_BLEND_FACTOR_ZERO,
.blend_equation_color = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD,
.blend_equation_alpha = VDP_OUTPUT_SURFACE_RENDER_BLEND_EQUATION_ADD,
};
+1 -2
View File
@@ -208,9 +208,8 @@ static void keyboard_handle_keymap(void *data,
return;
}
wl->input.xkb.keymap = xkb_keymap_new_from_buffer(wl->input.xkb.context,
wl->input.xkb.keymap = xkb_keymap_new_from_string(wl->input.xkb.context,
map_str,
size,
XKB_KEYMAP_FORMAT_TEXT_V1,
0);