Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
777295ce28 | ||
|
|
d50be0a2a6 | ||
|
|
2d8e26bb72 | ||
|
|
7ee275095f | ||
|
|
5a5b219853 | ||
|
|
608bed1aed | ||
|
|
636b62fc1a | ||
|
|
78195cd742 | ||
|
|
e7fc048eca | ||
|
|
0ab7d01425 | ||
|
|
bd0b661183 | ||
|
|
0989d8358c | ||
|
|
c979ee34e1 | ||
|
|
bb00774514 |
No files matched your search
@@ -193,6 +193,8 @@ List of Input Commands
|
||||
Stop playback of the current file, and play the new file immediately.
|
||||
<append>
|
||||
Append the file to the playlist.
|
||||
<append-play>
|
||||
Append the file, and if nothing is currently playing, start playback.
|
||||
|
||||
The third argument is a list of options and values which should be set
|
||||
while the file is playing. It is of the form ``opt1=value1,opt2=value2,..``.
|
||||
|
||||
@@ -1366,13 +1366,13 @@ OPTIONS
|
||||
example files or playlists loaded with the ``loadfile`` or ``loadlist``
|
||||
commands.
|
||||
|
||||
``--mf=<option1:option2:...>``
|
||||
Used when decoding from multiple PNG or JPEG files with ``mf://``.
|
||||
``--mf-fps=<value>``
|
||||
Framerate used when decoding from multiple PNG or JPEG files with ``mf://``
|
||||
(default: 1).
|
||||
|
||||
Available options are:
|
||||
|
||||
:fps=<value>: output fps (default: 1)
|
||||
:type=<value>: input file type (available: jpeg, png, tga, sgi)
|
||||
``--mf-type=<value>``
|
||||
Input file type for ``mf://`` (available: jpeg, png, tga, sgi). By default,
|
||||
this is guessed from the file extension.
|
||||
|
||||
``--monitoraspect=<ratio>``
|
||||
Set the aspect ratio of your monitor or TV screen. A value of 0 disables a
|
||||
|
||||
@@ -1,3 +1,68 @@
|
||||
Release 0.4.2
|
||||
=============
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Include changes from point releases in the release notes.
|
||||
- Fix --cache-file operation when file size is unknown (e.g. when playing from
|
||||
a pipe).
|
||||
- Don't sleep if playback is stopped when reconnecting for remote stream.
|
||||
- Suspend read on vts change even if the requested title is not found when
|
||||
using dvdnav (dvd://) (this fixes a bug where the DVD menu was not shown
|
||||
properly after a DVD track ended).
|
||||
- Avoid draining if the audio output is paused (this fixes a bug where mpv would
|
||||
hang when switching tracks when paused).
|
||||
- Drop buffered audio when switching tracks or filters (this fixes a possible
|
||||
regression when using gapless audio).
|
||||
- Reverse video rotation direction.
|
||||
- Fix initialization of the input when playing from a pipe.
|
||||
- Fix description of the --mf option in the manpage (the --mf syntax changed a
|
||||
while ago, but was not documented).
|
||||
- Actually append entries to the end of the playlist instead of after the
|
||||
current entry with the "loadlist append" command.
|
||||
|
||||
New features
|
||||
------------
|
||||
|
||||
- Add "append-play" mode for the loadfile command.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log bb00774..d50be0a`` in
|
||||
the git repository.
|
||||
|
||||
Release 0.4.1
|
||||
=============
|
||||
|
||||
Bug fixes
|
||||
---------
|
||||
|
||||
- Fix af_volume bug that caused negative ReplayGain values to increase volume
|
||||
instead of decreasing it in some situations.
|
||||
- Actually use "weak" as --gapless-audio default value (as documented in the
|
||||
0.4.0 release notes).
|
||||
- Fix cache resizing bug that caused seeking to not work anymore.
|
||||
- Escape all colons in the options descriptions in the zsh completion script.
|
||||
- Don't consume an extra argument with --ao/af and --vo/vf options in the zsh
|
||||
completion script (as side effect, the completion now uses --opt=val instead
|
||||
of --opt val).
|
||||
- Allow client applications to call mpv_terminate_destroy(NULL).
|
||||
- Make sure seeking bounds are within range with dvdnav://.
|
||||
- Check the length of the last title too with dvdnav://longest.
|
||||
- Properly flush buffers on DVD seek (this fixes some seeking problems when
|
||||
playing DVDs).
|
||||
- Allow compilation without atomics (for compilers that don't support atomic
|
||||
operations).
|
||||
- Disable ao_null latency emulation.
|
||||
- Restore ability to combine mouse buttons.
|
||||
|
||||
This listing is not complete. There are many more bug fixes and changes. The
|
||||
complete change log can be viewed by running ``git log 0075f8e..b18c2d9`` in
|
||||
the git repository.
|
||||
|
||||
Release 0.4.0
|
||||
=============
|
||||
|
||||
Changes
|
||||
-------
|
||||
|
||||
@@ -8,6 +73,8 @@ Changes
|
||||
- Lower --auto-pause/resume defaults values to improve web streams playback.
|
||||
- Use dvdnav support instead of the internal dvd implementation for dvd:// URLs
|
||||
(the old implementation is available under dvdread://).
|
||||
- DVD (dvd://) tracks IDs now start from 0 instead of 1.
|
||||
- Play the longest track by default with dvd://.
|
||||
- Rename some options to make them more consistent. Here's a partial list of
|
||||
renamed options:
|
||||
|
||||
|
||||
+1
-13
@@ -31,7 +31,6 @@
|
||||
|
||||
#include "options/options.h"
|
||||
#include "options/m_config.h"
|
||||
#include "osdep/timer.h"
|
||||
#include "common/msg.h"
|
||||
#include "common/common.h"
|
||||
#include "common/global.h"
|
||||
@@ -309,22 +308,11 @@ void ao_resume(struct ao *ao)
|
||||
ao->api->resume(ao);
|
||||
}
|
||||
|
||||
// Be careful with locking
|
||||
void ao_wait_drain(struct ao *ao)
|
||||
{
|
||||
// This is probably not entirely accurate, but good enough.
|
||||
mp_sleep_us(ao_get_delay(ao) * 1000000);
|
||||
ao_reset(ao);
|
||||
}
|
||||
|
||||
// Block until the current audio buffer has played completely.
|
||||
void ao_drain(struct ao *ao)
|
||||
{
|
||||
if (ao->api->drain) {
|
||||
if (ao->api->drain)
|
||||
ao->api->drain(ao);
|
||||
} else {
|
||||
ao_wait_drain(ao);
|
||||
}
|
||||
}
|
||||
|
||||
bool ao_eof_reached(struct ao *ao)
|
||||
|
||||
@@ -158,7 +158,6 @@ struct ao_driver {
|
||||
// These functions can be called by AOs.
|
||||
|
||||
int ao_play_silence(struct ao *ao, int samples);
|
||||
void ao_wait_drain(struct ao *ao);
|
||||
int ao_read_data(struct ao *ao, void **data, int samples, int64_t out_time_us);
|
||||
struct pollfd;
|
||||
int ao_wait_poll(struct ao *ao, struct pollfd *fds, int num_fds,
|
||||
|
||||
@@ -193,6 +193,14 @@ static void resume(struct ao *ao)
|
||||
ao->driver->resume(ao);
|
||||
}
|
||||
|
||||
static void drain(struct ao *ao)
|
||||
{
|
||||
struct ao_pull_state *p = ao->api_priv;
|
||||
if (atomic_load(&p->state) == AO_STATE_PLAY)
|
||||
mp_sleep_us(get_delay(ao) * 1000000);
|
||||
reset(ao);
|
||||
}
|
||||
|
||||
static void uninit(struct ao *ao)
|
||||
{
|
||||
ao->driver->uninit(ao);
|
||||
@@ -212,6 +220,7 @@ const struct ao_driver ao_api_pull = {
|
||||
.init = init,
|
||||
.control = control,
|
||||
.uninit = uninit,
|
||||
.drain = drain,
|
||||
.reset = reset,
|
||||
.get_space = get_space,
|
||||
.play = play,
|
||||
|
||||
+6
-1
@@ -146,6 +146,10 @@ static void drain(struct ao *ao)
|
||||
struct ao_push_state *p = ao->api_priv;
|
||||
|
||||
pthread_mutex_lock(&p->lock);
|
||||
if (p->paused) {
|
||||
pthread_mutex_unlock(&p->lock);
|
||||
return;
|
||||
}
|
||||
p->final_chunk = true;
|
||||
p->drain = true;
|
||||
wakeup_playthread(ao);
|
||||
@@ -154,7 +158,8 @@ static void drain(struct ao *ao)
|
||||
pthread_mutex_unlock(&p->lock);
|
||||
|
||||
if (!ao->driver->drain)
|
||||
ao_wait_drain(ao);
|
||||
mp_sleep_us(get_delay(ao) * 1000000);
|
||||
reset(ao);
|
||||
}
|
||||
|
||||
static int unlocked_get_space(struct ao *ao)
|
||||
|
||||
@@ -215,6 +215,15 @@ void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl)
|
||||
}
|
||||
}
|
||||
|
||||
void playlist_append_entries(struct playlist *pl, struct playlist *source_pl)
|
||||
{
|
||||
while (source_pl->first) {
|
||||
struct playlist_entry *e = source_pl->first;
|
||||
playlist_unlink(source_pl, e);
|
||||
playlist_add(pl, e);
|
||||
}
|
||||
}
|
||||
|
||||
// Return number of entries between list start and e.
|
||||
// Return -1 if e is not on the list, or if e is NULL.
|
||||
int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e)
|
||||
|
||||
@@ -74,6 +74,7 @@ void playlist_shuffle(struct playlist *pl);
|
||||
struct playlist_entry *playlist_get_next(struct playlist *pl, int direction);
|
||||
void playlist_add_base_path(struct playlist *pl, bstr base_path);
|
||||
void playlist_transfer_entries(struct playlist *pl, struct playlist *source_pl);
|
||||
void playlist_append_entries(struct playlist *pl, struct playlist *source_pl);
|
||||
|
||||
int playlist_entry_to_index(struct playlist *pl, struct playlist_entry *e);
|
||||
int playlist_entry_count(struct playlist *pl);
|
||||
|
||||
@@ -583,6 +583,11 @@ static struct demuxer *open_given_type(struct mpv_global *global,
|
||||
.filename = talloc_strdup(demuxer, stream->url),
|
||||
.metadata = talloc_zero(demuxer, struct mp_tags),
|
||||
};
|
||||
demuxer->seekable = stream->seekable;
|
||||
if (demuxer->stream->uncached_stream &&
|
||||
!demuxer->stream->uncached_stream->seekable)
|
||||
demuxer->seekable = false;
|
||||
|
||||
demuxer->params = params; // temporary during open()
|
||||
int64_t start_pos = stream_tell(stream);
|
||||
|
||||
|
||||
+1
-1
@@ -507,7 +507,7 @@ static void handle_stream(demuxer_t *demuxer, int i)
|
||||
#if HAVE_AV_DISPLAYMATRIX
|
||||
uint8_t *sd = av_stream_get_side_data(st, AV_PKT_DATA_DISPLAYMATRIX, NULL);
|
||||
if (sd)
|
||||
sh_video->rotate = av_display_rotation_get((uint32_t *)sd);
|
||||
sh_video->rotate = -av_display_rotation_get((uint32_t *)sd);
|
||||
#else
|
||||
AVDictionaryEntry *rot = av_dict_get(st->metadata, "rotate", NULL, 0);
|
||||
if (rot && rot->value) {
|
||||
|
||||
+2
-1
@@ -111,7 +111,8 @@ const struct mp_cmd_def mp_cmds[] = {
|
||||
{ MP_CMD_LOADFILE, "loadfile", {
|
||||
ARG_STRING,
|
||||
OARG_CHOICE(0, ({"replace", 0}, {"0", 0},
|
||||
{"append", 1}, {"1", 1})),
|
||||
{"append", 1}, {"1", 1},
|
||||
{"append-play", 2})),
|
||||
OPT_KEYVALUELIST(ARG(str_list), MP_CMD_OPT_ARG),
|
||||
}},
|
||||
{ MP_CMD_LOADLIST, "loadlist", {
|
||||
|
||||
+4
-3
@@ -2995,6 +2995,7 @@ static bool reinit_filters(MPContext *mpctx, enum stream_type mediatype)
|
||||
case STREAM_VIDEO:
|
||||
return reinit_video_filters(mpctx) >= 0;
|
||||
case STREAM_AUDIO:
|
||||
clear_audio_output_buffers(mpctx);
|
||||
return reinit_audio_filters(mpctx) >= 0;
|
||||
}
|
||||
return false;
|
||||
@@ -3549,7 +3550,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
|
||||
case MP_CMD_LOADFILE: {
|
||||
char *filename = cmd->args[0].v.s;
|
||||
bool append = cmd->args[1].v.i;
|
||||
int append = cmd->args[1].v.i;
|
||||
|
||||
if (!append)
|
||||
playlist_clear(mpctx->playlist);
|
||||
@@ -3564,7 +3565,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
}
|
||||
playlist_add(mpctx->playlist, entry);
|
||||
|
||||
if (!append)
|
||||
if (!append || (append == 2 && !mpctx->playlist->current))
|
||||
mp_set_playlist_entry(mpctx, mpctx->playlist->first);
|
||||
break;
|
||||
}
|
||||
@@ -3576,7 +3577,7 @@ int run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
if (pl) {
|
||||
if (!append)
|
||||
playlist_clear(mpctx->playlist);
|
||||
playlist_transfer_entries(mpctx->playlist, pl);
|
||||
playlist_append_entries(mpctx->playlist, pl);
|
||||
talloc_free(pl);
|
||||
|
||||
if (!append && mpctx->playlist->first) {
|
||||
|
||||
@@ -598,6 +598,7 @@ void mp_switch_track_n(struct MPContext *mpctx, int order, enum stream_type type
|
||||
uninit |= mpctx->opts->fixed_vo && track ? 0 : INITIALIZED_VO;
|
||||
uninit_player(mpctx, uninit);
|
||||
} else if (type == STREAM_AUDIO) {
|
||||
clear_audio_output_buffers(mpctx);
|
||||
uninit_player(mpctx, INITIALIZED_AO | INITIALIZED_ACODEC);
|
||||
} else if (type == STREAM_SUB) {
|
||||
uninit_player(mpctx, INITIALIZED_SUB);
|
||||
|
||||
+3
-2
@@ -66,7 +66,7 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len)
|
||||
if (s->pos >= p->size - BLOCK_SIZE) {
|
||||
int64_t new_size = -1;
|
||||
stream_control(s, STREAM_CTRL_GET_SIZE, &new_size);
|
||||
if (new_size != p->size)
|
||||
if (p->size >= 0 && new_size != p->size)
|
||||
set_bit(p, BLOCK_ALIGN(p->size), 0);
|
||||
p->size = MPMIN(p->max_size, new_size);
|
||||
}
|
||||
@@ -94,7 +94,8 @@ static int fill_buffer(stream_t *s, char *buffer, int max_len)
|
||||
// align/limit to blocks
|
||||
max_len = MPMIN(max_len, BLOCK_SIZE - (s->pos % BLOCK_SIZE));
|
||||
// Limit to max. known file size
|
||||
max_len = MPMIN(max_len, p->size - s->pos);
|
||||
if (p->size >= 0)
|
||||
max_len = MPMIN(max_len, p->size - s->pos);
|
||||
return fread(buffer, 1, max_len, p->cache_file);
|
||||
}
|
||||
|
||||
|
||||
@@ -388,6 +388,8 @@ static int stream_reconnect(stream_t *s)
|
||||
return 0;
|
||||
if (!s->seekable)
|
||||
return 0;
|
||||
if (stream_check_interrupt(s))
|
||||
return 0;
|
||||
int64_t pos = s->pos;
|
||||
int sleep_ms = 5;
|
||||
for (int retry = 0; retry < MAX_RECONNECT_RETRIES; retry++) {
|
||||
|
||||
@@ -443,7 +443,6 @@ static int fill_buffer(stream_t *s, char *buf, int max_len)
|
||||
if (priv->title > 0 && tit != priv->title) {
|
||||
priv->next_event |= 1 << MP_NAV_EVENT_EOF;;
|
||||
MP_WARN(s, "Requested title not found\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (priv->nav_enabled)
|
||||
|
||||
Reference in new issue
Block a user