Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3b0f28b2e3 | ||
|
|
f12ed5fd8f | ||
|
|
317f2399a7 | ||
|
|
228b652ad5 | ||
|
|
20e08ac84e | ||
|
|
93518bc652 | ||
|
|
38885269b3 | ||
|
|
485c658f3f | ||
|
|
b9585e518b | ||
|
|
a9858ab117 | ||
|
|
eeb37de8ca | ||
|
|
bbff558e6e | ||
|
|
022735fa72 | ||
|
|
600193749d | ||
|
|
fc465f1f26 | ||
|
|
bf39906cd5 | ||
|
|
dac0726e98 | ||
|
|
0268f2431a | ||
|
|
441af64005 | ||
|
|
f450e5c397 | ||
|
|
e70580df30 | ||
|
|
9eaba0c176 | ||
|
|
196c7abcdb | ||
|
|
253623d9e8 | ||
|
|
b9f40d650a | ||
|
|
dc1aaf695f | ||
|
|
b24fd52268 | ||
|
|
dd25c08713 | ||
|
|
327edcec3f | ||
|
|
5281a9865d | ||
|
|
6fcdb4ced3 | ||
|
|
e773bda893 | ||
|
|
d74e82cb50 | ||
|
|
37fe0444e3 | ||
|
|
64a66364ad | ||
|
|
2995bf176d | ||
|
|
0d3e7f5c3e | ||
|
|
8fe6f2542a | ||
|
|
b553a43667 | ||
|
|
6de5bf12a5 | ||
|
|
78adec6c9c | ||
|
|
0fed032ca0 | ||
|
|
96532916fe | ||
|
|
c265855d44 | ||
|
|
7816fa9745 | ||
|
|
e76076da3d | ||
|
|
90015a8b8b | ||
|
|
d1a8dfb8c4 | ||
|
|
e68fcbfa39 | ||
|
|
391c087d75 | ||
|
|
b4f6e57d2c | ||
|
|
854cdb796e | ||
|
|
504c452568 | ||
|
|
ee54711ceb | ||
|
|
3ac568714c | ||
|
|
d64b165b2a | ||
|
|
78a57135f9 | ||
|
|
09f00db142 | ||
|
|
673919df7d | ||
|
|
d2fc1534c8 | ||
|
|
10c3b71720 | ||
|
|
0ba3760745 | ||
|
|
1dbbd845a4 | ||
|
|
131fad8bc9 | ||
|
|
6af87017d1 | ||
|
|
bd70c32504 | ||
|
|
4c88ac3434 | ||
|
|
4cd36b999f | ||
|
|
1b3155cf51 | ||
|
|
ace9a4b6c6 | ||
|
|
84cd043f85 | ||
|
|
6cdc5627f0 | ||
|
|
cb355443dc | ||
|
|
cc2b5c16fa | ||
|
|
bf345136b9 | ||
|
|
6b525b84bb | ||
|
|
ea17adcd66 | ||
|
|
31cdb96474 | ||
|
|
b3233fa3ff | ||
|
|
132528ff67 | ||
|
|
efc32ac0df | ||
|
|
042302fa65 | ||
|
|
93ce083bd8 | ||
|
|
97c93918fe | ||
|
|
7078df4f5e | ||
|
|
8e642809bf | ||
|
|
8c4cf5ce84 | ||
|
|
16cbc4a014 | ||
|
|
2aff8b7523 | ||
|
|
5d9353f0d5 | ||
|
|
6f139ad981 | ||
|
|
0052445e86 | ||
|
|
2cf8d4ffdb | ||
|
|
e6236e22db |
No files matched your search
@@ -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.
|
||||
|
||||
|
||||
+10
-3
@@ -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,...>``
|
||||
@@ -1045,9 +1047,14 @@ OPTIONS
|
||||
|
||||
``mpv --heartbeat-cmd="gnome-screensaver-command -p" file``
|
||||
|
||||
|
||||
``--heartbeat-interval=<sec>``
|
||||
Time between ``--heartbeat-cmd`` invocations in seconds (default: 30).
|
||||
|
||||
.. note::
|
||||
|
||||
This does not affect the normal screensaver operation in any way.
|
||||
|
||||
``--help``
|
||||
Show short summary of options.
|
||||
|
||||
@@ -1415,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)
|
||||
@@ -2108,7 +2115,7 @@ OPTIONS
|
||||
``--stop-screensaver``, ``--no-stop-screensaver``
|
||||
Turns off the screensaver (or screen blanker and similar mechanisms) at
|
||||
startup and turns it on again on exit (default: yes). The screensaver is
|
||||
always reenabled when the player is paused.
|
||||
always re-enabled when the player is paused.
|
||||
|
||||
This is not supported on all video outputs or platforms. Sometimes it is
|
||||
implemented, but does not work (happens often on GNOME). You might be able
|
||||
@@ -2591,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
@@ -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.
|
||||
|
||||
+3
-3
@@ -422,8 +422,8 @@ Available video output drivers are:
|
||||
Selects the internal format of textures used for FBOs. The format can
|
||||
influence performance and quality of the video output. (FBOs are not
|
||||
always used, and typically only when using extended scalers.)
|
||||
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb16, rgb16f, rgb32f,
|
||||
rgba12, rgba16, rgba16f, rgba32f.
|
||||
``fmt`` can be one of: rgb, rgba, rgb8, rgb10, rgb10_a2, rgb16, rgb16f,
|
||||
rgb32f, rgba12, rgba16, rgba16f, rgba32f.
|
||||
Default: rgb.
|
||||
|
||||
``gamma``
|
||||
@@ -776,4 +776,4 @@ Available video output drivers are:
|
||||
|
||||
``alpha``
|
||||
Use a buffer format that supports videos and images with alpha
|
||||
informations
|
||||
information
|
||||
@@ -63,6 +63,13 @@ mpv's configure script is greedy and automatically enables features as a result
|
||||
of autodetection. The cases where you may want to use `--enable-*` are very
|
||||
limited.
|
||||
|
||||
FFmpeg vs. Libav
|
||||
----------------
|
||||
|
||||
Generally, mpv should work with the latest release as well as the git version
|
||||
of both FFmpeg and Libav. But FFmpeg is preferred, and some mpv features work
|
||||
with FFmpeg only. See the [wiki article][ffmpeg_vs_libav] about the issue.
|
||||
|
||||
Bug reports
|
||||
-----------
|
||||
|
||||
@@ -97,3 +104,4 @@ To contact the `mpv` team in private write to `mpv-team@googlegroups.com`.
|
||||
[issue-tracker]: https://github.com/mpv-player/mpv/issues
|
||||
[mpv-users]: https://groups.google.com/forum/?hl=en#!forum/mpv-users
|
||||
[mpv-devel]: https://groups.google.com/forum/?hl=en#!forum/mpv-devel
|
||||
[ffmpeg_vs_libav]: https://github.com/mpv-player/mpv/wiki/FFmpeg-versus-Libav
|
||||
@@ -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>
|
||||
@@ -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)
|
||||
|
||||
@@ -41,6 +41,7 @@
|
||||
#define avresample_alloc_context swr_alloc
|
||||
#define avresample_open swr_init
|
||||
#define avresample_close(x) do { } while(0)
|
||||
#define avresample_free swr_free
|
||||
#define avresample_available(x) 0
|
||||
#define avresample_convert(ctx, out, out_planesize, out_samples, in, in_planesize, in_samples) \
|
||||
swr_convert(ctx, out, out_samples, (const uint8_t**)(in), in_samples)
|
||||
@@ -275,8 +276,10 @@ static void uninit(struct af_instance *af)
|
||||
struct af_resample *s = af->priv;
|
||||
if (s->avrctx)
|
||||
avresample_close(s->avrctx);
|
||||
avresample_free(&s->avrctx);
|
||||
if (s->avrctx_out)
|
||||
avresample_close(s->avrctx_out);
|
||||
avresample_free(&s->avrctx_out);
|
||||
}
|
||||
|
||||
static bool needs_reorder(int *reorder, int num_ch)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -33,7 +33,6 @@
|
||||
#include <ctype.h>
|
||||
#include <math.h>
|
||||
#include <string.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#include "config.h"
|
||||
#include "mpvcore/options.h"
|
||||
|
||||
@@ -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
@@ -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
@@ -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);
|
||||
|
||||
@@ -125,7 +125,6 @@ static int init(struct ao *ao)
|
||||
case AF_FORMAT_S24_LE:
|
||||
case AF_FORMAT_S32_LE:
|
||||
case AF_FORMAT_FLOAT_LE:
|
||||
case AF_FORMAT_AC3_BE:
|
||||
case AF_FORMAT_AC3_LE:
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -147,7 +147,6 @@ static const struct format_map {
|
||||
};
|
||||
|
||||
static const int speaker_map[][2] = {
|
||||
{PA_CHANNEL_POSITION_MONO, MP_SPEAKER_ID_FC},
|
||||
{PA_CHANNEL_POSITION_FRONT_LEFT, MP_SPEAKER_ID_FL},
|
||||
{PA_CHANNEL_POSITION_FRONT_RIGHT, MP_SPEAKER_ID_FR},
|
||||
{PA_CHANNEL_POSITION_FRONT_CENTER, MP_SPEAKER_ID_FC},
|
||||
@@ -174,6 +173,10 @@ static bool chmap_pa_from_mp(pa_channel_map *dst, struct mp_chmap *src)
|
||||
if (src->num > PA_CHANNELS_MAX)
|
||||
return false;
|
||||
dst->channels = src->num;
|
||||
if (mp_chmap_equals(src, &(const struct mp_chmap)MP_CHMAP_INIT_MONO)) {
|
||||
dst->map[0] = PA_CHANNEL_POSITION_MONO;
|
||||
return true;
|
||||
}
|
||||
for (int n = 0; n < src->num; n++) {
|
||||
int mp_speaker = src->speaker[n];
|
||||
int pa_speaker = PA_CHANNEL_POSITION_INVALID;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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},
|
||||
};
|
||||
|
||||
|
||||
@@ -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}
|
||||
};
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -68,6 +68,7 @@ ovcopts = qscale=4
|
||||
profile-desc = "H.264 (x264)"
|
||||
ovc = libx264
|
||||
ovcopts = preset=medium,crf=23,threads=0
|
||||
vf-add = noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
|
||||
[enc-v-mpeg2]
|
||||
profile-desc = "MPEG-2 Video (FFmpeg)"
|
||||
@@ -152,15 +153,14 @@ profile-desc = "MP4 for Blackberry Bold 9000"
|
||||
profile = enc-f-mp4
|
||||
vf-add = dsize=480:360:0:2,scale=w=0:h=0,dsize=-1:-1 # native screen res, letterbox
|
||||
ovcopts-add = maxrate=1500k,bufsize=1000k,rc_init_occupancy=900k,refs=1,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-nok-n900]
|
||||
profile-desc = "MP4 for Nokia N900"
|
||||
profile = enc-f-mp4
|
||||
vf-add = dsize=800:480:0:2,scale=w=0:h=0:noup=1 # native screen res, letterbox
|
||||
# DW = 800, DH = 480, SAR = 1
|
||||
vf-add = lavfi=graph="scale=floor(min(min(800\,dar*480)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(min(800/dar\,480)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
ovcopts-add = profile=baseline,level=30,maxrate=10000k,bufsize=10000k,rc_init_occupancy=9000k,refs=5
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-nok-6300]
|
||||
@@ -180,14 +180,12 @@ vf-add = scale=w=480:h=272,dsize=480:270
|
||||
srate = 48000
|
||||
channels = 2
|
||||
ovcopts-add = b=512k,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
|
||||
[enc-to-iphone-noscale]
|
||||
profile-desc = "MP4 for iPhone (no scaling)"
|
||||
profile = enc-f-mp4
|
||||
oautofps = yes # iphone supports 30fps max
|
||||
ovcopts-add = maxrate=2500k,bufsize=1000k,rc_init_occupancy=900k,level=30,profile=baseline
|
||||
vf-add=noformat=444p,noformat=444p9,noformat=444p10,noformat=422p,noformat=422p9,noformat=422p10
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-iphone]
|
||||
@@ -207,3 +205,51 @@ profile-desc = "MP4 for iPhone 5 (1136x640)"
|
||||
profile = enc-to-iphone-noscale
|
||||
vf-add = dsize=1136:480:1:2,scale=w=0:h=0,dsize=-1:-1 # panscan
|
||||
omaxfps = 30
|
||||
|
||||
[enc-to-hp-slate-7]
|
||||
profile-desc = "MP4 for HP Slate 7 (1024x600, crazy aspect)"
|
||||
profile = enc-f-mp4
|
||||
omaxfps = 30
|
||||
ovcopts-add = profile=high
|
||||
# DW = 1024, DH = 600, DAR = 97:54 (=> SAR = 2425:2304)
|
||||
vf-add = lavfi=graph="scale=floor(min(1024*min(1\,dar*54/97)\,in_w*max(1\,sar*2304/2425))/2+0.5)*2:floor(min(600*min(97/54/dar\,1)\,in_h*max(2425/2304/sar\,1))/2+0.5)*2,setsar=1"
|
||||
|
||||
# Advanced scaling for specific output devices - how it works:
|
||||
# DW = display width (px) (1024)
|
||||
# DH = display height (px) (600)
|
||||
# SAR = display sample aspect ratio, i.e. DAR * DH / DW (2425:2304)
|
||||
# DAR = display aspect ratio, i.e. SAR * DW / DH (97:54)
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*min(1\,dar/DAR)\,in_w*max(1\,sar/SAR))/2+0.5)*2:floor(min(DH*min(DAR/dar\,1)\,in_h*max(SAR/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*max(1\,dar/DAR)\,in_w*max(1\,sar/SAR))/2+0.5)*2:floor(min(DH*max(DAR/dar\,1)\,in_h*max(SAR/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# How it works:
|
||||
# 1a: DW, DH*dar/DAR - fit to display width
|
||||
# 1b: DH*DAR/dar, DH - fit to display height
|
||||
# 1: the min of 1a and 1b these (i.e. fit inside both width and height); for zoomed in view, use the max
|
||||
# 2a: in_w, in_h*SAR/sar - fit to original width
|
||||
# 2b: in_w*sar/SAR, in_h - fit to original height
|
||||
# 2: the max of 2a and 2b (i.e. avoid enlarging both dimensions - let HW scaling handle this)
|
||||
# output: the min of 1 and 2 (i.e. fulfill both constraints)
|
||||
# setsar=1 to prevent scaling on the device (skip this if the device actually wants the proper SAR to be specified for not performing needless scaling)
|
||||
#
|
||||
# Simplified special case for SAR == 1, DAR == DW/DH:
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(min(DW\,dar*DH)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(min(DW/dar\,DH)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(max(DW\,dar*DH)\,in_w*max(1\,sar))/2+0.5)*2:floor(min(max(DW/dar\,DH)\,in_h*max(1/sar\,1))/2+0.5)*2,setsar=1"
|
||||
# setsar=1 to prevent nasty almost-1 SAR to be passed to the codec due to the rounding which can fail
|
||||
#
|
||||
# If the device supports file SAR properly, we can make use of it to avoid
|
||||
# upscaling. Note that setsar cannot be used to fake a different output SAR by
|
||||
# applying a multiplier to the original one, so e..g it can't be used for the
|
||||
# HP Slate 7!
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*min(1\,dar/DAR)\,in_w)/2+0.5)*2:floor(min(DH*min(DAR/dar\,1)\,in_h)/2+0.5)*2"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(DW*max(1\,dar/DAR)\,in_w)/2+0.5)*2:floor(min(DH*max(DAR/dar\,1)\,in_h)/2+0.5)*2"
|
||||
# Simplified special case for SAR == 1, DAR == DW/DH:
|
||||
# Variant: zoomed out
|
||||
# vf-add = lavfi=graph="scale=floor(min(min(DW\,dar*DH)\,in_w)/2+0.5)*2:floor(min(min(DW/dar\,DH)\,in_h)/2+0.5)*2"
|
||||
# Variant: zoomed in
|
||||
# vf-add = lavfi=graph="scale=floor(min(max(DW\,dar*DH)\,in_w)/2+0.5)*2:floor(min(max(DW/dar\,DH)\,in_h)/2+0.5)*2"
|
||||
+7
-3
@@ -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
|
||||
|
||||
+3
-1
@@ -3,6 +3,7 @@ Type=Application
|
||||
Name=mpv Media Player
|
||||
Name[ca]=Reproductor multimèdia mpv
|
||||
Name[pl]=mpv odtwarzacz multimedialny
|
||||
Name[ru]=Проигрыватель mpv
|
||||
GenericName=Multimedia player
|
||||
Comment=Play movies and songs
|
||||
Comment[ca]=Reproduïu vídeos i cançons
|
||||
@@ -10,8 +11,9 @@ Comment[de]=Filme und Musik abspielen
|
||||
Comment[es]=Reproduzca vídeos y canciones
|
||||
Comment[fr]=Lecteur multimédia
|
||||
Comment[it]=Lettore multimediale
|
||||
Comment[zh]=多媒体播放器
|
||||
Comment[pl]=Odtwarzaj filmy i muzykę
|
||||
Comment[ru]=Воспроизвести фильмы и музыку
|
||||
Comment[zh]=多媒体播放器
|
||||
Icon=mpv
|
||||
TryExec=mpv
|
||||
Exec=mpv --really-quiet --force-window -- %F
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
+24
-6
@@ -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);
|
||||
@@ -1783,7 +1801,7 @@ static void input_wait_read(struct input_ctx *ictx, int time)
|
||||
*/
|
||||
static void read_events(struct input_ctx *ictx, int time)
|
||||
{
|
||||
if (ictx->num_key_down) {
|
||||
if (ictx->num_key_down && ictx->ar_rate > 0) {
|
||||
time = FFMIN(time, 1000 / ictx->ar_rate);
|
||||
time = FFMIN(time, ictx->ar_delay);
|
||||
}
|
||||
|
||||
+10
-4
@@ -52,7 +52,7 @@ local osc_styles = {
|
||||
|
||||
-- internal states, do not touch
|
||||
local state = {
|
||||
showtime, -- time of last invokation (last mouse move)
|
||||
showtime, -- time of last invocation (last mouse move)
|
||||
osc_visible = false,
|
||||
anistart, -- time when the animation started
|
||||
anitype, -- current type of animation
|
||||
@@ -636,7 +636,7 @@ function osc_init()
|
||||
-- kill old Elements
|
||||
elements = {}
|
||||
|
||||
-- set canvas resolution acording to display aspect and scaling setting
|
||||
-- set canvas resolution according to display aspect and scaling setting
|
||||
local baseResY = 720
|
||||
local display_w, display_h, display_aspect = mp.get_screen_size()
|
||||
local scale = 1
|
||||
@@ -650,13 +650,19 @@ function osc_init()
|
||||
end
|
||||
|
||||
|
||||
if user_opts.vidscale == true then
|
||||
if user_opts.vidscale then
|
||||
osc_param.playresy = baseResY / scale
|
||||
else
|
||||
osc_param.playresy = display_h / scale
|
||||
end
|
||||
osc_param.playresx = osc_param.playresy * display_aspect
|
||||
|
||||
-- make sure the OSC actually fits into the video
|
||||
if (osc_param.playresx < (osc_param.osc_w + (2 * osc_param.osc_p))) then
|
||||
osc_param.playresy = (osc_param.osc_w + (2 * osc_param.osc_p)) / display_aspect
|
||||
osc_param.playresx = osc_param.playresy * display_aspect
|
||||
end
|
||||
|
||||
-- position of the controller according to video aspect and valignment
|
||||
osc_param.posX = math.floor(get_align(user_opts.halign, osc_param.playresx, osc_param.osc_w, 0))
|
||||
osc_param.posY = math.floor(get_align(user_opts.valign, osc_param.playresy, osc_param.osc_h, 0))
|
||||
@@ -999,7 +1005,7 @@ end
|
||||
|
||||
function show_osc()
|
||||
|
||||
--remember last time of invokation (mouse move)
|
||||
--remember last time of invocation (mouse move)
|
||||
state.showtime = mp.get_timer()
|
||||
|
||||
state.osc_visible = true
|
||||
|
||||
+9
-3
@@ -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]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+29
-9
@@ -185,6 +185,7 @@ static const char av_desync_help_text[] = _(
|
||||
" Download the file instead.\n"
|
||||
"- Try to find out whether audio or video is causing this by experimenting\n"
|
||||
" with --no-video and --no-audio.\n"
|
||||
"- If you swiched audio or video tracks, try seeking to force synchronization.\n"
|
||||
"If none of this helps you, file a bug report.\n\n");
|
||||
|
||||
|
||||
@@ -240,7 +241,8 @@ static double get_play_end_pts(struct MPContext *mpctx)
|
||||
if (opts->play_end.type) {
|
||||
return rel_time_to_abs(mpctx, opts->play_end, MP_NOPTS_VALUE);
|
||||
} else if (opts->play_length.type) {
|
||||
double start = rel_time_to_abs(mpctx, opts->play_start, 0);
|
||||
double startpts = get_start_time(mpctx);
|
||||
double start = rel_time_to_abs(mpctx, opts->play_start, startpts);
|
||||
double length = rel_time_to_abs(mpctx, opts->play_length, -1);
|
||||
if (start != -1 && length != -1)
|
||||
return start + length;
|
||||
@@ -2276,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;
|
||||
|
||||
@@ -2314,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) {
|
||||
@@ -2479,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;
|
||||
@@ -2990,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) ||
|
||||
@@ -3052,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) {
|
||||
@@ -3420,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;
|
||||
@@ -3510,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.
|
||||
@@ -4251,6 +4266,8 @@ static void add_subtitle_fonts_from_sources(struct MPContext *mpctx)
|
||||
static struct mp_resolve_result *resolve_url(const char *filename,
|
||||
struct MPOpts *opts)
|
||||
{
|
||||
if (!mp_is_url(bstr0(filename)))
|
||||
return NULL;
|
||||
#if defined(CONFIG_LIBQUVI) || defined(CONFIG_LIBQUVI9)
|
||||
return mp_resolve_quvi(filename, opts);
|
||||
#else
|
||||
@@ -4351,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 {
|
||||
@@ -4669,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;
|
||||
}
|
||||
|
||||
+7
-2
@@ -34,6 +34,7 @@
|
||||
#ifdef CONFIG_IOCTL
|
||||
#include <sys/ioctl.h>
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#ifdef HAVE_TERMIOS
|
||||
#ifdef HAVE_TERMIOS_H
|
||||
@@ -369,8 +370,10 @@ bool getch2(struct input_ctx *input_ctx)
|
||||
* happen if the terminal state change done in getch2_enable()
|
||||
* works.
|
||||
*/
|
||||
if (retval < 1)
|
||||
return retval;
|
||||
if (retval == 0)
|
||||
return false;
|
||||
if (retval == -1)
|
||||
return errno != EBADF && errno != EINVAL;
|
||||
getch2_len += retval;
|
||||
|
||||
static enum {
|
||||
@@ -558,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();
|
||||
@@ -574,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();
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
* with mplayer2. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
@@ -77,6 +77,7 @@ static NSString *escape_loadfile_name(NSString *input)
|
||||
@synthesize inputContext = _input_context;
|
||||
@synthesize eventsResponder = _events_responder;
|
||||
@synthesize menuItems = _menu_items;
|
||||
@synthesize input_ready = _input_ready;
|
||||
|
||||
- (void)sendEvent:(NSEvent *)event
|
||||
{
|
||||
@@ -94,6 +95,7 @@ static NSString *escape_loadfile_name(NSString *input)
|
||||
self.argumentsList = [[[NSMutableArray alloc] init] autorelease];
|
||||
self.eventsResponder = [[[EventsResponder alloc] init] autorelease];
|
||||
self.willStopOnOpenEvent = NO;
|
||||
self.input_ready = [[[NSCondition alloc] init] autorelease];
|
||||
|
||||
[NSEvent addLocalMonitorForEventsMatchingMask:NSKeyDownMask|NSKeyUpMask
|
||||
handler:^(NSEvent *event) {
|
||||
@@ -325,6 +327,11 @@ int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[])
|
||||
init_cocoa_application();
|
||||
macosx_finder_args_preinit(&argc, &argv);
|
||||
pthread_create(&playback_thread_id, NULL, playback_thread, &ctx);
|
||||
|
||||
[mpv_shared_app().input_ready lock];
|
||||
[mpv_shared_app().input_ready wait];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
|
||||
cocoa_run_runloop();
|
||||
|
||||
// This should never be reached: cocoa_run_runloop blocks until the
|
||||
@@ -380,6 +387,12 @@ 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().inputContext = input_context;
|
||||
}
|
||||
|
||||
@@ -450,10 +463,15 @@ static bool bundle_started_from_finder(int argc, char **argv)
|
||||
bool bundle_detected = [[NSBundle mainBundle] bundleIdentifier];
|
||||
int major, minor, bugfix;
|
||||
get_system_version(&major, &minor, &bugfix);
|
||||
bool without_psn = bundle_detected && argc==1;
|
||||
bool with_psn = bundle_detected && argc==2 && is_psn_argument(argv[1]);
|
||||
|
||||
if ((major == 10) && (minor >= 9)) {
|
||||
return bundle_detected && argc==1;
|
||||
// Looks like opening quarantined files from the finder inserts the
|
||||
// -psn argument while normal files do not. Hurr.
|
||||
return with_psn || without_psn;
|
||||
} else {
|
||||
return bundle_detected && argc==2 && is_psn_argument(argv[1]);
|
||||
return with_psn;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@
|
||||
@property(nonatomic, retain) NSArray *files;
|
||||
@property(nonatomic, retain) NSMutableArray *argumentsList;
|
||||
@property(nonatomic, assign) BOOL willStopOnOpenEvent;
|
||||
@property(nonatomic, retain) NSCondition *input_ready;
|
||||
@end
|
||||
|
||||
Application *mpv_shared_app(void);
|
||||
@@ -19,7 +19,6 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/time.h>
|
||||
#include <alloca.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 },
|
||||
};
|
||||
@@ -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>
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -136,6 +136,12 @@ static void decode(struct sd *sd, struct demux_packet *packet)
|
||||
AVSubtitle sub;
|
||||
AVPacket pkt;
|
||||
|
||||
// libavformat sets duration==0, even if the duration is unknown.
|
||||
// Assume there are no bitmap subs that actually use duration==0 for
|
||||
// hidden subtitle events.
|
||||
if (duration == 0)
|
||||
duration = -1;
|
||||
|
||||
clear(priv);
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = packet->buffer;
|
||||
|
||||
@@ -26,6 +26,12 @@
|
||||
#define TA_TYPEOF(t) void *
|
||||
#endif
|
||||
|
||||
// Broken crap with __USE_MINGW_ANSI_STDIO
|
||||
#ifdef __MINGW32__
|
||||
#undef TA_PRF
|
||||
#define TA_PRF(a1, a2) __attribute__ ((format (gnu_printf, a1, a2)))
|
||||
#endif
|
||||
|
||||
#define TA_STRINGIFY_(x) # x
|
||||
#define TA_STRINGIFY(x) TA_STRINGIFY_(x)
|
||||
|
||||
|
||||
+1
-1
@@ -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.
|
||||
|
||||
+15
-7
@@ -349,7 +349,6 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||
ctx->image_params = (struct mp_image_params){0};
|
||||
ctx->vo_image_params = (struct mp_image_params){0};
|
||||
ctx->hwdec = hwdec;
|
||||
ctx->pic = avcodec_alloc_frame();
|
||||
ctx->avctx = avcodec_alloc_context3(lavc_codec);
|
||||
AVCodecContext *avctx = ctx->avctx;
|
||||
avctx->opaque = sh;
|
||||
@@ -358,6 +357,14 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||
|
||||
avctx->thread_count = lavc_param->threads;
|
||||
|
||||
|
||||
#if HAVE_AVUTIL_REFCOUNTING
|
||||
avctx->refcounted_frames = 1;
|
||||
ctx->pic = av_frame_alloc();
|
||||
#else
|
||||
ctx->pic = avcodec_alloc_frame();
|
||||
#endif
|
||||
|
||||
if (ctx->hwdec && ctx->hwdec->allocate_image) {
|
||||
ctx->do_hw_dr1 = true;
|
||||
avctx->thread_count = 1;
|
||||
@@ -369,9 +376,7 @@ static void init_avctx(sh_video_t *sh, const char *decoder,
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
#if HAVE_AVUTIL_REFCOUNTING
|
||||
avctx->refcounted_frames = 1;
|
||||
#else
|
||||
#if !HAVE_AVUTIL_REFCOUNTING
|
||||
if (lavc_codec->capabilities & CODEC_CAP_DR1) {
|
||||
ctx->do_dr1 = true;
|
||||
avctx->get_buffer = mp_codec_get_buffer;
|
||||
@@ -449,12 +454,14 @@ static void uninit_avctx(sh_video_t *sh)
|
||||
}
|
||||
|
||||
av_freep(&ctx->avctx);
|
||||
avcodec_free_frame(&ctx->pic);
|
||||
|
||||
if (ctx->hwdec && ctx->hwdec->uninit)
|
||||
ctx->hwdec->uninit(ctx);
|
||||
|
||||
#if !HAVE_AVUTIL_REFCOUNTING
|
||||
#if HAVE_AVUTIL_REFCOUNTING
|
||||
av_frame_free(&ctx->pic);
|
||||
#else
|
||||
avcodec_free_frame(&ctx->pic);
|
||||
mp_buffer_pool_free(&ctx->dr1_buffer_pool);
|
||||
#endif
|
||||
ctx->last_sample_aspect_ratio = (AVRational){0, 0};
|
||||
@@ -603,7 +610,6 @@ static int get_buffer2_hwdec(AVCodecContext *avctx, AVFrame *pic, int flags)
|
||||
static void setup_refcounting_hw(AVCodecContext *avctx)
|
||||
{
|
||||
avctx->get_buffer2 = get_buffer2_hwdec;
|
||||
avctx->refcounted_frames = 1;
|
||||
}
|
||||
|
||||
#else /* HAVE_AVUTIL_REFCOUNTING */
|
||||
@@ -785,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;
|
||||
}
|
||||
|
||||
@@ -257,6 +257,7 @@ static struct mp_image *process_image(struct lavc_ctx *ctx, struct mp_image *img
|
||||
}
|
||||
|
||||
const struct vd_lavc_hwdec mp_vd_lavc_vdpau_old = {
|
||||
.type = HWDEC_VDPAU,
|
||||
.image_formats = (const int[]) {
|
||||
IMGFMT_VDPAU_MPEG1, IMGFMT_VDPAU_MPEG2, IMGFMT_VDPAU_H264,
|
||||
IMGFMT_VDPAU_WMV3, IMGFMT_VDPAU_VC1, IMGFMT_VDPAU_MPEG4,
|
||||
|
||||
+37
-14
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -361,7 +361,7 @@ static int control(struct vf_instance *vf, int request, void *data)
|
||||
break;
|
||||
return CONTROL_TRUE;
|
||||
case VFCTRL_SET_EQUALIZER:
|
||||
if (mp_sws_get_vf_equalizer(sws, data) < 1)
|
||||
if (mp_sws_set_vf_equalizer(sws, data) < 1)
|
||||
break;
|
||||
return CONTROL_TRUE;
|
||||
default:
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
@@ -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);
|
||||
}
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <libavutil/common.h>
|
||||
|
||||
#include "mpvcore/input/keycodes.h"
|
||||
|
||||
#include "osdep/macosx_application.h"
|
||||
@@ -29,6 +31,7 @@
|
||||
@implementation MpvVideoWindow {
|
||||
NSSize _queued_video_size;
|
||||
bool _fs_resize_scheduled;
|
||||
bool _recenter_window_during_constraint;
|
||||
}
|
||||
|
||||
@synthesize adapter = _adapter;
|
||||
@@ -115,17 +118,27 @@
|
||||
CGFloat dx = (f.size.width - ns.width) / 2;
|
||||
CGFloat dy = (f.size.height - ns.height - [self titleHeight]) / 2;
|
||||
NSRect nf = NSRectFromCGRect(CGRectInset(NSRectToCGRect(f), dx, dy));
|
||||
self->_recenter_window_during_constraint = true;
|
||||
[self setFrame:nf display:NO animate:NO];
|
||||
}
|
||||
|
||||
- (NSRect)constrainFrameRect:(NSRect)nf toScreen:(NSScreen *)screen
|
||||
{
|
||||
NSRect s = [[self screen] visibleFrame];
|
||||
if (nf.origin.y + nf.size.height > s.origin.y + s.size.height)
|
||||
if (nf.origin.y + nf.size.height > s.origin.y + s.size.height) {
|
||||
if (self->_recenter_window_during_constraint)
|
||||
nf.size.height = s.size.height;
|
||||
nf.origin.y = s.origin.y + s.size.height - nf.size.height;
|
||||
}
|
||||
return nf;
|
||||
}
|
||||
|
||||
- (void)setFrame:(NSRect)frame display:(BOOL)display animate:(BOOL)animate
|
||||
{
|
||||
[super setFrame:frame display:display animate:animate];
|
||||
self->_recenter_window_during_constraint = false;
|
||||
}
|
||||
|
||||
- (void)queueNewVideoSize:(NSSize)new_size
|
||||
{
|
||||
NSSize prev_size = self->_queued_video_size;
|
||||
|
||||
@@ -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);
|
||||
@@ -438,16 +439,17 @@ void vo_cocoa_set_current_context(struct vo *vo, bool current)
|
||||
{
|
||||
struct vo_cocoa_state *s = vo->cocoa;
|
||||
|
||||
if (s->inside_sync_section) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (current) {
|
||||
[s->lock lock];
|
||||
if (!s->inside_sync_section)
|
||||
[s->lock lock];
|
||||
|
||||
[s->gl_ctx makeCurrentContext];
|
||||
} else {
|
||||
const bool locked = !![NSOpenGLContext currentContext];
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
[s->lock unlock];
|
||||
|
||||
if (!s->inside_sync_section && locked)
|
||||
[s->lock unlock];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,8 +946,13 @@ 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))
|
||||
{
|
||||
MP_WARN(ctx->vo, "OpenGL version too old. Try: --vo=opengl-old\n");
|
||||
}
|
||||
}
|
||||
|
||||
MP_ERR(ctx->vo, "OpenGL context creation failed!\n");
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
|
||||
#include "video/mp_image.h"
|
||||
|
||||
#if defined(CONFIG_GL_COCOA) && !defined(CONFIG_GL_X11)
|
||||
#if defined(CONFIG_GL_COCOA)
|
||||
#ifdef GL_VERSION_3_0
|
||||
#include <OpenGL/gl3.h>
|
||||
#else
|
||||
@@ -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
@@ -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)
|
||||
|
||||
@@ -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.
|
||||
@@ -304,6 +304,7 @@ const struct m_sub_options gl_video_conf = {
|
||||
{"rgba", GL_RGBA},
|
||||
{"rgb8", GL_RGB8},
|
||||
{"rgb10", GL_RGB10},
|
||||
{"rgb10_a2", GL_RGB10_A2},
|
||||
{"rgb16", GL_RGB16},
|
||||
{"rgb16f", GL_RGB16F},
|
||||
{"rgb32f", GL_RGB32F},
|
||||
|
||||
+1
-1
@@ -123,7 +123,7 @@ static bool create_context_x11_gl3(struct MPGLContext *ctx, bool debug)
|
||||
glx_ctx->fbc, 0, True,
|
||||
context_attribs);
|
||||
if (!context) {
|
||||
MP_FATAL(vo, "Could not create GLX context!\n");
|
||||
MP_ERR(vo, "Could not create GL3 context. Retrying with legacy context.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
+3
-1
@@ -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;
|
||||
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
+24
-6
@@ -114,7 +114,7 @@ static const struct fmt_entry fmt_table[] = {
|
||||
{0}
|
||||
};
|
||||
|
||||
static void allocate_xvimage(struct vo *, int);
|
||||
static bool allocate_xvimage(struct vo *, int);
|
||||
static void deallocate_xvimage(struct vo *vo, int foo);
|
||||
static struct mp_image get_xv_buffer(struct vo *vo, int buf_index);
|
||||
|
||||
@@ -473,8 +473,12 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
|
||||
|
||||
ctx->num_buffers = 2;
|
||||
|
||||
for (i = 0; i < ctx->num_buffers; i++)
|
||||
allocate_xvimage(vo, i);
|
||||
for (i = 0; i < ctx->num_buffers; i++) {
|
||||
if (!allocate_xvimage(vo, i)) {
|
||||
MP_FATAL(vo, "could not allocate Xv image data\n");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
ctx->current_buf = 0;
|
||||
ctx->current_ip_buf = 0;
|
||||
@@ -485,7 +489,7 @@ static int config(struct vo *vo, uint32_t width, uint32_t height,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void allocate_xvimage(struct vo *vo, int foo)
|
||||
static bool allocate_xvimage(struct vo *vo, int foo)
|
||||
{
|
||||
struct xvctx *ctx = vo->priv;
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
@@ -506,12 +510,16 @@ static void allocate_xvimage(struct vo *vo, int foo)
|
||||
ctx->xv_format, NULL,
|
||||
aligned_w, ctx->image_height,
|
||||
&ctx->Shminfo[foo]);
|
||||
if (!ctx->xvimage[foo])
|
||||
return false;
|
||||
|
||||
ctx->Shminfo[foo].shmid = shmget(IPC_PRIVATE,
|
||||
ctx->xvimage[foo]->data_size,
|
||||
IPC_CREAT | 0777);
|
||||
ctx->Shminfo[foo].shmaddr = (char *) shmat(ctx->Shminfo[foo].shmid, 0,
|
||||
0);
|
||||
if (ctx->Shminfo[foo].shmaddr == (void *)-1)
|
||||
return false;
|
||||
ctx->Shminfo[foo].readOnly = False;
|
||||
|
||||
ctx->xvimage[foo]->data = ctx->Shminfo[foo].shmaddr;
|
||||
@@ -525,13 +533,17 @@ static void allocate_xvimage(struct vo *vo, int foo)
|
||||
(XvImage *) XvCreateImage(x11->display, ctx->xv_port,
|
||||
ctx->xv_format, NULL, aligned_w,
|
||||
ctx->image_height);
|
||||
if (!ctx->xvimage[foo])
|
||||
return false;
|
||||
ctx->xvimage[foo]->data = av_malloc(ctx->xvimage[foo]->data_size);
|
||||
if (!ctx->xvimage[foo]->data)
|
||||
return false;
|
||||
XSync(x11->display, False);
|
||||
}
|
||||
struct mp_image img = get_xv_buffer(vo, foo);
|
||||
img.w = aligned_w;
|
||||
mp_image_clear(&img, 0, 0, img.w, img.h);
|
||||
return;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void deallocate_xvimage(struct vo *vo, int foo)
|
||||
@@ -546,7 +558,13 @@ static void deallocate_xvimage(struct vo *vo, int foo)
|
||||
{
|
||||
av_free(ctx->xvimage[foo]->data);
|
||||
}
|
||||
XFree(ctx->xvimage[foo]);
|
||||
if (ctx->xvimage[foo])
|
||||
XFree(ctx->xvimage[foo]);
|
||||
|
||||
ctx->xvimage[foo] = NULL;
|
||||
#ifdef HAVE_SHM
|
||||
ctx->Shminfo[foo] = (XShmSegmentInfo){0};
|
||||
#endif
|
||||
|
||||
XSync(vo->x11->display, False);
|
||||
return;
|
||||
|
||||
+40
-26
@@ -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);
|
||||
|
||||
@@ -313,6 +312,9 @@ static void pointer_handle_enter(void *data,
|
||||
wl->cursor.serial = serial;
|
||||
wl->cursor.pointer = pointer;
|
||||
|
||||
/* Release the left button on pointer enter again
|
||||
* because after moving the shell surface no release event is sent */
|
||||
mp_input_put_key(wl->vo->input_ctx, MP_MOUSE_BTN0 | MP_KEY_STATE_UP);
|
||||
show_cursor(wl);
|
||||
}
|
||||
|
||||
@@ -334,9 +336,11 @@ static void pointer_handle_motion(void *data,
|
||||
struct vo_wayland_state *wl = data;
|
||||
|
||||
wl->cursor.pointer = pointer;
|
||||
wl->window.surf_x = wl_fixed_to_int(sx_w);
|
||||
wl->window.surf_y = wl_fixed_to_int(sy_w);
|
||||
|
||||
vo_mouse_movement(wl->vo, wl_fixed_to_int(sx_w),
|
||||
wl_fixed_to_int(sy_w));
|
||||
vo_mouse_movement(wl->vo, wl->window.surf_x,
|
||||
wl->window.surf_y);
|
||||
}
|
||||
|
||||
static void pointer_handle_button(void *data,
|
||||
@@ -351,6 +355,10 @@ static void pointer_handle_button(void *data,
|
||||
mp_input_put_key(wl->vo->input_ctx, MP_MOUSE_BTN0 + (button - BTN_LEFT) |
|
||||
((state == WL_POINTER_BUTTON_STATE_PRESSED)
|
||||
? MP_KEY_STATE_DOWN : MP_KEY_STATE_UP));
|
||||
|
||||
if (!mp_input_test_dragging(wl->vo->input_ctx, wl->window.surf_x, wl->window.surf_y) &&
|
||||
(button == BTN_LEFT) && (state == WL_POINTER_BUTTON_STATE_PRESSED))
|
||||
wl_shell_surface_move(wl->window.shell_surface, wl->input.seat, serial);
|
||||
}
|
||||
|
||||
static void pointer_handle_axis(void *data,
|
||||
@@ -538,32 +546,34 @@ static void shedule_resize(struct vo_wayland_state *wl,
|
||||
if (height < minimum_size)
|
||||
height = minimum_size;
|
||||
|
||||
/* if only the height is changed we have to calculate the width
|
||||
* in any other case we calculate the height */
|
||||
switch (edges) {
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
||||
width = wl->window.aspect * height;
|
||||
break;
|
||||
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
default:
|
||||
if (wl->window.aspect < temp_aspect)
|
||||
// don't keep the aspect ration in fullscreen mode, because the compositor
|
||||
// shows the desktop in the border regions if the video has not the same
|
||||
// aspect ration as the screen
|
||||
if (!wl->window.is_fullscreen) {
|
||||
/* if only the height is changed we have to calculate the width
|
||||
* in any other case we calculate the height */
|
||||
switch (edges) {
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM:
|
||||
width = wl->window.aspect * height;
|
||||
else
|
||||
break;
|
||||
case WL_SHELL_SURFACE_RESIZE_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_LEFT: // just a preference
|
||||
case WL_SHELL_SURFACE_RESIZE_TOP_RIGHT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_LEFT:
|
||||
case WL_SHELL_SURFACE_RESIZE_BOTTOM_RIGHT:
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
break;
|
||||
default:
|
||||
if (wl->window.aspect < temp_aspect)
|
||||
width = wl->window.aspect * height;
|
||||
else
|
||||
height = (1 / wl->window.aspect) * width;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
wl->vo->dwidth = width;
|
||||
wl->vo->dheight = height;
|
||||
|
||||
if (edges & WL_SHELL_SURFACE_RESIZE_LEFT)
|
||||
x = wl->window.width - width;
|
||||
else
|
||||
@@ -579,6 +589,8 @@ static void shedule_resize(struct vo_wayland_state *wl,
|
||||
wl->window.sh_x = x;
|
||||
wl->window.sh_y = y;
|
||||
wl->window.events |= VO_EVENT_RESIZE;
|
||||
wl->vo->dwidth = width;
|
||||
wl->vo->dheight = height;
|
||||
}
|
||||
|
||||
|
||||
@@ -765,6 +777,7 @@ static void vo_wayland_fullscreen (struct vo *vo)
|
||||
|
||||
if (vo->opts->fullscreen) {
|
||||
MP_DBG(wl, "going fullscreen\n");
|
||||
wl->window.is_fullscreen = true;
|
||||
wl->window.p_width = wl->window.width;
|
||||
wl->window.p_height = wl->window.height;
|
||||
wl_shell_surface_set_fullscreen(wl->window.shell_surface,
|
||||
@@ -774,6 +787,7 @@ static void vo_wayland_fullscreen (struct vo *vo)
|
||||
|
||||
else {
|
||||
MP_DBG(wl, "leaving fullscreen\n");
|
||||
wl->window.is_fullscreen = false;
|
||||
wl_shell_surface_set_toplevel(wl->window.shell_surface);
|
||||
shedule_resize(wl, 0, wl->window.p_width, wl->window.p_height);
|
||||
}
|
||||
|
||||
@@ -70,7 +70,11 @@ struct vo_wayland_state {
|
||||
int32_t sh_y;
|
||||
float aspect;
|
||||
|
||||
bool is_fullscreen; // don't keep aspect ratio in fullscreen mode
|
||||
|
||||
struct wl_surface *surface;
|
||||
int32_t surf_x;
|
||||
int32_t surf_y;
|
||||
struct wl_shell_surface *shell_surface;
|
||||
int events; /* mplayer events (VO_EVENT_RESIZE) */
|
||||
} window;
|
||||
|
||||
@@ -605,7 +605,7 @@ static void vo_x11_decoration(struct vo *vo, int d)
|
||||
|
||||
vo_MotifHints = XInternAtom(x11->display, "_MOTIF_WM_HINTS", 0);
|
||||
if (vo_MotifHints != None) {
|
||||
if (!d) {
|
||||
if (!x11->got_motif_hints) {
|
||||
MotifWmHints *mhints = NULL;
|
||||
|
||||
XGetWindowProperty(x11->display, x11->window,
|
||||
@@ -620,6 +620,7 @@ static void vo_x11_decoration(struct vo *vo, int d)
|
||||
XFree(mhints);
|
||||
}
|
||||
}
|
||||
x11->got_motif_hints = true;
|
||||
|
||||
memset(&vo_MotifWmHints, 0, sizeof(MotifWmHints));
|
||||
vo_MotifWmHints.flags =
|
||||
@@ -667,7 +668,7 @@ void vo_x11_uninit(struct vo *vo)
|
||||
XFreeGC(vo->x11->display, x11->f_gc);
|
||||
if (x11->vo_gc != None)
|
||||
XFreeGC(vo->x11->display, x11->vo_gc);
|
||||
if (x11->window != None) {
|
||||
if (x11->window != None && x11->window != x11->rootwin) {
|
||||
XClearWindow(x11->display, x11->window);
|
||||
XUnmapWindow(x11->display, x11->window);
|
||||
|
||||
@@ -1140,6 +1141,8 @@ void vo_x11_config_vo_window(struct vo *vo, XVisualInfo *vis, int x, int y,
|
||||
struct vo_x11_state *x11 = vo->x11;
|
||||
|
||||
if (opts->WinID >= 0) {
|
||||
if (opts->WinID == 0)
|
||||
x11->window = x11->rootwin;
|
||||
XSelectInput(x11->display, opts->WinID, StructureNotifyMask);
|
||||
vo_x11_update_geometry(vo);
|
||||
x = x11->win_x; y = x11->win_y;
|
||||
@@ -1373,7 +1376,7 @@ static void vo_x11_update_geometry(struct vo *vo)
|
||||
unsigned w, h, dummy_uint;
|
||||
int dummy_int;
|
||||
Window dummy_win;
|
||||
Window win = vo->opts->WinID >= 0 ? vo->opts->WinID : x11->window;
|
||||
Window win = vo->opts->WinID > 0 ? vo->opts->WinID : x11->window;
|
||||
XGetGeometry(x11->display, win, &dummy_win, &dummy_int, &dummy_int,
|
||||
&w, &h, &dummy_int, &dummy_uint);
|
||||
if (w <= INT_MAX && h <= INT_MAX) {
|
||||
@@ -1498,7 +1501,7 @@ static void vo_x11_ontop(struct vo *vo)
|
||||
static void vo_x11_border(struct vo *vo)
|
||||
{
|
||||
vo->opts->border = !vo->opts->border;
|
||||
vo_x11_decoration(vo, vo->opts->border && !vo->x11->fs);
|
||||
vo_x11_decoration(vo, vo->opts->border);
|
||||
}
|
||||
|
||||
int vo_x11_control(struct vo *vo, int *events, int request, void *arg)
|
||||
@@ -1543,7 +1546,7 @@ static void xscreensaver_heartbeat(struct vo_x11_state *x11)
|
||||
double time = mp_time_sec();
|
||||
|
||||
if (x11->display && x11->screensaver_off &&
|
||||
(time - x11->screensaver_time_last) > 30)
|
||||
(time - x11->screensaver_time_last) >= 10)
|
||||
{
|
||||
x11->screensaver_time_last = time;
|
||||
|
||||
|
||||
@@ -90,8 +90,10 @@ struct vo_x11_state {
|
||||
bool size_changed_during_fs;
|
||||
bool pos_changed_during_fs;
|
||||
|
||||
bool got_motif_hints;
|
||||
unsigned int olddecor;
|
||||
unsigned int oldfuncs;
|
||||
|
||||
XComposeStatus compose_status;
|
||||
|
||||
/* XShm stuff */
|
||||
|
||||
+2
-1
@@ -24,6 +24,7 @@
|
||||
|
||||
#include "sws_utils.h"
|
||||
|
||||
#include "mpvcore/mp_common.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "video/img_format.h"
|
||||
#include "fmt-conversion.h"
|
||||
@@ -327,7 +328,7 @@ int mp_sws_set_vf_equalizer(struct mp_sws_context *sws, struct vf_seteq *eq)
|
||||
if (!strcmp(eq->item, "brightness"))
|
||||
sws->brightness = ((eq->value << 16) + 50) / 100;
|
||||
else if (!strcmp(eq->item, "contrast"))
|
||||
sws->contrast = (((eq->value + 100) << 16) + 50) / 100;
|
||||
sws->contrast = MPMAX(1, (((eq->value + 100) << 16) + 50) / 100);
|
||||
else if (!strcmp(eq->item, "saturation"))
|
||||
sws->saturation = (((eq->value + 100) << 16) + 50) / 100;
|
||||
else
|
||||
|
||||
Reference in new issue
Block a user