Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
689c3f47a8 | ||
|
|
677d4615ba | ||
|
|
5f788a7812 | ||
|
|
dba25e13c0 | ||
|
|
623b97e45a | ||
|
|
7a645ba62f | ||
|
|
63afe3eb98 | ||
|
|
72c70eb05b | ||
|
|
df0ec55499 | ||
|
|
542bcdfc9d | ||
|
|
218667b5a2 | ||
|
|
13a0e34aec | ||
|
|
76b7a1a713 | ||
|
|
6d6eee2e70 | ||
|
|
89f20cd2f3 | ||
|
|
cce2b675ac | ||
|
|
c1ed4dc242 | ||
|
|
712657a894 | ||
|
|
496956de3d | ||
|
|
483e703793 | ||
|
|
717cdeb95d | ||
|
|
315f3a9218 | ||
|
|
d857722618 | ||
|
|
6d9d597b10 | ||
|
|
c4d905b567 | ||
|
|
e4c69376fc | ||
|
|
842689bbf6 | ||
|
|
5ab2aa84e0 | ||
|
|
229d398ba9 | ||
|
|
5f1b155307 | ||
|
|
241cbe5065 |
No files matched your search
@@ -9,6 +9,8 @@ Using mingw-w64-cmake to setup a MinGW-w64 environment is recommended (this will
|
||||
also build mpv and its dependencies): https://github.com/lachs0r/mingw-w64-cmake
|
||||
|
||||
Alternatively, use MXE: http://mxe.cc
|
||||
With MXE, you have to modify the file settings.mk to target MinGW-w64 (even if
|
||||
you compile to 32 bit).
|
||||
|
||||
Warning: the original MinGW (http://www.mingw.org) is unsupported.
|
||||
|
||||
|
||||
@@ -52,11 +52,6 @@ You can bind multiple commands to one key. For example:
|
||||
|
||||
| a show_text "command 1" ; show_text "command 2"
|
||||
|
||||
Note that some magic is disabled for keys: seek commands inside lists are not
|
||||
coalesced (seeking will appear slower), and no check is done for abort commands
|
||||
(so these commands can't be used to abort playback if the network cache is
|
||||
stuck).
|
||||
|
||||
List of Input Commands
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -796,7 +796,7 @@ OPTIONS
|
||||
|
||||
``--field-dominance=<auto|top|bottom>``
|
||||
Set first field for interlaced content. Useful for deinterlacers that
|
||||
double the framerate: ``--vf=yadif=1`` and ``--vo=vdpau:deint``.
|
||||
double the framerate: ``--vf=yadif=field`` and ``--vo=vdpau:deint``.
|
||||
|
||||
:auto: (default) If the decoder does not export the appropriate
|
||||
information, it falls back on ``top`` (top field first).
|
||||
|
||||
@@ -132,7 +132,8 @@ sub _bin2int($) {
|
||||
# creates a floating-point number with the given mantissa and exponent
|
||||
sub _ldexp {
|
||||
my ($mantissa, $exponent) = @_;
|
||||
return $mantissa * Math::BigRat->new(2)**$exponent;
|
||||
my $r = new Math::BigRat($mantissa);
|
||||
return $r * Math::BigRat->new(2)**$exponent;
|
||||
}
|
||||
|
||||
# NOTE: the read_* functions are hard to read because they're ports
|
||||
@@ -252,25 +253,27 @@ bytes from the internal filehandle.
|
||||
Only lengths C<4> and C<8> are supported (C C<float> and C<double>).
|
||||
|
||||
=cut
|
||||
sub read_float {
|
||||
my ($self, $length) = @_;
|
||||
my $i = $self->read_uint($length);
|
||||
my $f;
|
||||
{
|
||||
my $b1 = new Math::BigInt 1;
|
||||
|
||||
use bigrat try => BIGINT_TRY;
|
||||
sub read_float {
|
||||
my ($self, $length) = @_;
|
||||
my $i = new Math::BigInt $self->read_uint($length)->bstr;
|
||||
my $f;
|
||||
|
||||
# These evil expressions reinterpret an unsigned int as IEEE binary floats
|
||||
if ($length == 4) {
|
||||
$f = _ldexp(($i & (1<<23 - 1)) + (1<<23), ($i>>23 & (1<<8 - 1)) - 150);
|
||||
$f = -$f if $i & (1<<31);
|
||||
} elsif ($length == 8) {
|
||||
$f = _ldexp(($i & (1<<52 - 1)) + (1<<52), ($i>>52 & (1<<12 - 1)) - 1075);
|
||||
$f = -$f if $i & (1<<63);
|
||||
} else {
|
||||
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
|
||||
# These evil expressions reinterpret an unsigned int as IEEE binary floats
|
||||
if ($length == 4) {
|
||||
$f = _ldexp(($i & ((1<<23) - 1)) + (1<<23), ($i>>23 & ((1<<8) - 1)) - 150);
|
||||
$f = -$f if $i & ($b1<<31);
|
||||
} elsif ($length == 8) {
|
||||
$f = _ldexp(($i & (($b1<<52) - 1)) + ($b1<<52), ($i>>52 & ((1<<12) - 1)) - 1075);
|
||||
$f = -$f if $i & ($b1<<63);
|
||||
} else {
|
||||
croak "Matroska Syntax error: unsupported IEEE float byte size $length";
|
||||
}
|
||||
|
||||
return $f;
|
||||
}
|
||||
|
||||
return $f;
|
||||
}
|
||||
|
||||
=method read_ebml_id($length)
|
||||
|
||||
+4
-10
@@ -172,11 +172,8 @@ static void set_from_wf(AVCodecContext *avctx, MP_WAVEFORMATEX *wf)
|
||||
avctx->block_align = wf->nBlockAlign;
|
||||
avctx->bits_per_coded_sample = wf->wBitsPerSample;
|
||||
|
||||
if (wf->cbSize > 0) {
|
||||
avctx->extradata = av_mallocz(wf->cbSize + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
avctx->extradata_size = wf->cbSize;
|
||||
memcpy(avctx->extradata, wf + 1, avctx->extradata_size);
|
||||
}
|
||||
if (wf->cbSize > 0)
|
||||
mp_lavc_set_extradata(avctx, wf + 1, wf->cbSize);
|
||||
}
|
||||
|
||||
static int init(struct dec_audio *da, const char *decoder)
|
||||
@@ -244,11 +241,8 @@ static int init(struct dec_audio *da, const char *decoder)
|
||||
// demux_mkv, demux_mpg
|
||||
if (sh_audio->codecdata_len && sh_audio->codecdata &&
|
||||
!lavc_context->extradata) {
|
||||
lavc_context->extradata = av_malloc(sh_audio->codecdata_len +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
lavc_context->extradata_size = sh_audio->codecdata_len;
|
||||
memcpy(lavc_context->extradata, (char *)sh_audio->codecdata,
|
||||
lavc_context->extradata_size);
|
||||
mp_lavc_set_extradata(lavc_context, sh_audio->codecdata,
|
||||
sh_audio->codecdata_len);
|
||||
}
|
||||
|
||||
if (sh->lav_headers)
|
||||
|
||||
+10
-6
@@ -100,7 +100,7 @@ static int control(struct ao *ao, enum aocontrol cmd, void *arg)
|
||||
float f_multi;
|
||||
|
||||
if (AF_FORMAT_IS_IEC61937(ao->format))
|
||||
return CONTROL_TRUE;
|
||||
return CONTROL_FALSE;
|
||||
|
||||
//allocate simple id
|
||||
snd_mixer_selem_id_alloca(&sid);
|
||||
@@ -561,9 +561,11 @@ static void audio_pause(struct ao *ao)
|
||||
int err;
|
||||
|
||||
if (p->can_pause) {
|
||||
p->delay_before_pause = get_delay(ao);
|
||||
err = snd_pcm_pause(p->alsa, 1);
|
||||
CHECK_ALSA_ERROR("pcm pause error");
|
||||
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_RUNNING) {
|
||||
p->delay_before_pause = get_delay(ao);
|
||||
err = snd_pcm_pause(p->alsa, 1);
|
||||
CHECK_ALSA_ERROR("pcm pause error");
|
||||
}
|
||||
} else {
|
||||
MP_VERBOSE(ao, "pause not supported by hardware\n");
|
||||
if (snd_pcm_delay(p->alsa, &p->prepause_frames) < 0
|
||||
@@ -591,8 +593,10 @@ static void audio_resume(struct ao *ao)
|
||||
}
|
||||
|
||||
if (p->can_pause) {
|
||||
err = snd_pcm_pause(p->alsa, 0);
|
||||
CHECK_ALSA_ERROR("pcm resume error");
|
||||
if (snd_pcm_state(p->alsa) == SND_PCM_STATE_PAUSED) {
|
||||
err = snd_pcm_pause(p->alsa, 0);
|
||||
CHECK_ALSA_ERROR("pcm resume error");
|
||||
}
|
||||
} else {
|
||||
MP_VERBOSE(ao, "resume not supported by hardware\n");
|
||||
err = snd_pcm_prepare(p->alsa);
|
||||
|
||||
+19
-3
@@ -60,10 +60,12 @@ struct priv {
|
||||
int connect;
|
||||
int autostart;
|
||||
int stdlayout;
|
||||
int last_chunk;
|
||||
volatile int paused;
|
||||
volatile int underrun;
|
||||
volatile float callback_interval;
|
||||
volatile float callback_time;
|
||||
volatile float last_ok_time; // last time real audio was played
|
||||
|
||||
int num_ports;
|
||||
struct port_ring ports[MP_NUM_CHANNELS];
|
||||
@@ -128,11 +130,15 @@ process(jack_nframes_t nframes, void *arg)
|
||||
underrun = 1;
|
||||
}
|
||||
|
||||
float now = mp_time_us() / 1000000.0;
|
||||
|
||||
if (underrun)
|
||||
p->underrun = 1;
|
||||
|
||||
if (!p->underrun)
|
||||
p->last_ok_time = now;
|
||||
|
||||
if (p->estimate) {
|
||||
float now = mp_time_us() / 1000000.0;
|
||||
float diff = p->callback_time + p->callback_interval - now;
|
||||
if ((diff > -0.002) && (diff < 0.002))
|
||||
p->callback_time += p->callback_interval;
|
||||
@@ -289,14 +295,23 @@ static float get_delay(struct ao *ao)
|
||||
struct priv *p = ao->priv;
|
||||
int buffered = mp_ring_buffered(p->ports[0].ring); // could be less
|
||||
float in_jack = p->jack_latency;
|
||||
float now = mp_time_us() / 1000000.0;
|
||||
|
||||
if (p->estimate && p->callback_interval > 0) {
|
||||
float elapsed = mp_time_us() / 1000000.0 - p->callback_time;
|
||||
in_jack += p->callback_interval - elapsed;
|
||||
if (in_jack < 0)
|
||||
in_jack = 0;
|
||||
}
|
||||
|
||||
if (p->underrun && !buffered && p->last_chunk) {
|
||||
// Report correct buffer drainage, when our buffer is empty, but jack
|
||||
// and/or the audio device still have some audio to play.
|
||||
// Assumes audio clock goes at about the same speed as the system time.
|
||||
in_jack += p->last_ok_time - now;
|
||||
}
|
||||
|
||||
if (in_jack < 0)
|
||||
in_jack = 0;
|
||||
|
||||
return (float)buffered / (float)ao->bps + in_jack;
|
||||
}
|
||||
|
||||
@@ -369,6 +384,7 @@ static int play(struct ao *ao, void **data, int samples, int flags)
|
||||
}
|
||||
|
||||
p->underrun = 0;
|
||||
p->last_chunk = flags & AOPLAY_FINAL_CHUNK;
|
||||
return ret / ao->sstride;
|
||||
}
|
||||
|
||||
|
||||
@@ -111,8 +111,8 @@ static int init(struct ao *ao)
|
||||
return -1;
|
||||
}
|
||||
|
||||
rsd_set_param(priv->rd, RSD_SAMPLERATE, &ao->samplerate);
|
||||
rsd_set_param(priv->rd, RSD_CHANNELS, &ao->channels.num);
|
||||
rsd_set_param(priv->rd, RSD_SAMPLERATE, (int[]) { ao->samplerate });
|
||||
rsd_set_param(priv->rd, RSD_CHANNELS, (int[]) { ao->channels.num });
|
||||
|
||||
ao->format = af_fmt_from_planar(ao->format);
|
||||
|
||||
|
||||
+2
-2
@@ -5,9 +5,9 @@
|
||||
from __future__ import print_function
|
||||
import os, sys, stat, hashlib, subprocess
|
||||
|
||||
WAFRELEASE = "waf-1.7.13"
|
||||
WAFRELEASE = "waf-1.7.15"
|
||||
WAFURL = "https://waf.googlecode.com/files/" + WAFRELEASE
|
||||
SHA256HASH = "03cc750049350ee01cdbc584b70924e333fcc17ba4a2d04648dab1535538a873"
|
||||
SHA256HASH = "e5ae7028f9b2d8ce1acb9fe1092e8010a90ba764d3ac065ea4e846743290b1d6"
|
||||
|
||||
if os.path.exists("waf"):
|
||||
wafver = subprocess.check_output(['./waf', '--version']).decode()
|
||||
|
||||
+14
-10
@@ -29,6 +29,19 @@
|
||||
|
||||
#include "osdep/numcores.h"
|
||||
|
||||
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size)
|
||||
{
|
||||
if (size) {
|
||||
av_free(avctx->extradata);
|
||||
avctx->extradata_size = 0;
|
||||
avctx->extradata = av_mallocz(size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!avctx->extradata)
|
||||
return -1;
|
||||
avctx->extradata_size = size;
|
||||
memcpy(avctx->extradata, ptr, size);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Copy the codec-related fields from st into avctx. This does not set the
|
||||
// codec itself, only codec related header data provided by libavformat.
|
||||
@@ -38,16 +51,7 @@
|
||||
// This is strictly for decoding only.
|
||||
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st)
|
||||
{
|
||||
if (st->extradata_size) {
|
||||
av_free(avctx->extradata);
|
||||
avctx->extradata_size = 0;
|
||||
avctx->extradata =
|
||||
av_mallocz(st->extradata_size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (avctx->extradata) {
|
||||
avctx->extradata_size = st->extradata_size;
|
||||
memcpy(avctx->extradata, st->extradata, st->extradata_size);
|
||||
}
|
||||
}
|
||||
mp_lavc_set_extradata(avctx, st->extradata, st->extradata_size);
|
||||
avctx->codec_tag = st->codec_tag;
|
||||
avctx->stream_codec_tag = st->stream_codec_tag;
|
||||
avctx->bit_rate = st->bit_rate;
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
struct mp_decoder_list;
|
||||
struct demux_packet;
|
||||
|
||||
int mp_lavc_set_extradata(AVCodecContext *avctx, void *ptr, int size);
|
||||
void mp_copy_lav_codec_headers(AVCodecContext *avctx, AVCodecContext *st);
|
||||
void mp_set_av_packet(AVPacket *dst, struct demux_packet *mpkt, AVRational *tb);
|
||||
int64_t mp_pts_to_av(double mp_pts, AVRational *tb);
|
||||
|
||||
@@ -458,6 +458,8 @@ static void handle_stream(demuxer_t *demuxer, int i)
|
||||
memcpy(sh_sub->extradata, codec->extradata, codec->extradata_size);
|
||||
sh_sub->extradata_len = codec->extradata_size;
|
||||
}
|
||||
sh_sub->w = codec->width;
|
||||
sh_sub->h = codec->height;
|
||||
|
||||
// Hack for MicroDVD: if time_base matches the ffmpeg microdvd reader's
|
||||
// default FPS (23.976), assume the MicroDVD file did not declare a
|
||||
|
||||
@@ -87,6 +87,7 @@ typedef struct sh_video {
|
||||
typedef struct sh_sub {
|
||||
unsigned char *extradata; // extra header data passed from demuxer
|
||||
int extradata_len;
|
||||
int w, h; // mp4 vobsubs
|
||||
int frame_based; // timestamps are frame-based
|
||||
bool is_utf8; // if false, subtitle packet charset is unknown
|
||||
struct ass_track *track; // loaded by libass
|
||||
|
||||
@@ -83,6 +83,10 @@
|
||||
# Play Finnish audio if available, fall back to English otherwise.
|
||||
#alang = fi,en
|
||||
|
||||
# Change subtitle encoding. For Arabic subtitles use 'cp1256'.
|
||||
# If the file seems to be valid UTF-8, prefer UTF-8.
|
||||
#subcp = utf8:cp1256
|
||||
|
||||
# Enable hardware decoding if available. Often, this requires using an certain
|
||||
# video output, otherwise no hardware decoding will be used.
|
||||
#hwdec = auto
|
||||
|
||||
+15
-1
@@ -253,7 +253,7 @@ bool mp_replace_legacy_cmd(void *t, bstr *s)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mp_input_is_abort_cmd(int cmd_id)
|
||||
static bool is_abort_cmd(int cmd_id)
|
||||
{
|
||||
switch (cmd_id) {
|
||||
case MP_CMD_QUIT:
|
||||
@@ -264,6 +264,20 @@ bool mp_input_is_abort_cmd(int cmd_id)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool mp_input_is_abort_cmd(struct mp_cmd *cmd)
|
||||
{
|
||||
if (is_abort_cmd(cmd->id))
|
||||
return true;
|
||||
if (cmd->id == MP_CMD_COMMAND_LIST) {
|
||||
for (struct mp_cmd *sub = cmd->args[0].v.p; sub; sub = sub->queue_next)
|
||||
{
|
||||
if (mp_input_is_abort_cmd(cmd))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void mp_print_cmd_list(struct mp_log *out)
|
||||
{
|
||||
for (int i = 0; mp_cmds[i].name; i++) {
|
||||
|
||||
+2
-1
@@ -107,7 +107,8 @@ enum mp_command_type {
|
||||
};
|
||||
|
||||
// Executing this command will abort playback (play something else, or quit).
|
||||
bool mp_input_is_abort_cmd(int cmd_id);
|
||||
struct mp_cmd;
|
||||
bool mp_input_is_abort_cmd(struct mp_cmd *cmd);
|
||||
|
||||
struct bstr;
|
||||
bool mp_replace_legacy_cmd(void *talloc_ctx, struct bstr *s);
|
||||
|
||||
+4
-4
@@ -237,7 +237,7 @@ static bool queue_has_abort_cmds(struct cmd_queue *queue)
|
||||
{
|
||||
bool ret = false;
|
||||
for (struct mp_cmd *cmd = queue->first; cmd; cmd = cmd->queue_next)
|
||||
if (mp_input_is_abort_cmd(cmd->id)) {
|
||||
if (mp_input_is_abort_cmd(cmd)) {
|
||||
ret = true;
|
||||
break;
|
||||
}
|
||||
@@ -544,9 +544,9 @@ static void release_down_cmd(struct input_ctx *ictx, bool drop_current)
|
||||
|
||||
static int find_key_down(struct input_ctx *ictx, int code)
|
||||
{
|
||||
code &= ~(MP_KEY_STATE_UP | MP_KEY_STATE_DOWN);
|
||||
code &= ~(MP_KEY_STATE_UP | MP_KEY_STATE_DOWN | MP_KEY_MODIFIER_MASK);
|
||||
for (int j = 0; j < ictx->num_key_down; j++) {
|
||||
if (ictx->key_down[j] == code)
|
||||
if ((ictx->key_down[j] & ~MP_KEY_MODIFIER_MASK) == code)
|
||||
return j;
|
||||
}
|
||||
return -1;
|
||||
@@ -580,7 +580,7 @@ static bool should_drop_cmd(struct input_ctx *ictx, struct mp_cmd *cmd)
|
||||
{
|
||||
struct cmd_queue *queue = &ictx->cmd_queue;
|
||||
return (queue_count_cmds(queue) >= ictx->key_fifo_size &&
|
||||
(!mp_input_is_abort_cmd(cmd->id) || queue_has_abort_cmds(queue)));
|
||||
(!mp_input_is_abort_cmd(cmd) || queue_has_abort_cmds(queue)));
|
||||
}
|
||||
|
||||
static void interpret_key(struct input_ctx *ictx, int code, double scale)
|
||||
|
||||
@@ -330,7 +330,8 @@ int cocoa_main(mpv_main_fn mpv_main, int argc, char *argv[])
|
||||
pthread_create(&playback_thread_id, NULL, playback_thread, &ctx);
|
||||
|
||||
[mpv_shared_app().input_ready lock];
|
||||
[mpv_shared_app().input_ready wait];
|
||||
while (!mpv_shared_app().inputContext)
|
||||
[mpv_shared_app().input_ready wait];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
|
||||
cocoa_run_runloop();
|
||||
@@ -388,13 +389,10 @@ void cocoa_stop_runloop(void)
|
||||
|
||||
void cocoa_set_input_context(struct input_ctx *input_context)
|
||||
{
|
||||
if (input_context) {
|
||||
[mpv_shared_app().input_ready lock];
|
||||
[mpv_shared_app().input_ready signal];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
}
|
||||
|
||||
[mpv_shared_app().input_ready lock];
|
||||
mpv_shared_app().inputContext = input_context;
|
||||
[mpv_shared_app().input_ready signal];
|
||||
[mpv_shared_app().input_ready unlock];
|
||||
}
|
||||
|
||||
void cocoa_post_fake_event(void)
|
||||
|
||||
+5
-1
@@ -59,7 +59,11 @@ char *mp_get_win_config_path(const char *filename)
|
||||
res = mp_path_join(NULL, bstr0(temp), bstr0(filename));
|
||||
if (!mp_path_exists(res) || mp_path_isdir(res)) {
|
||||
talloc_free(res);
|
||||
res = NULL;
|
||||
res = mp_path_join(NULL, bstr0(dir), bstr0(filename));
|
||||
if (!mp_path_exists(res) || mp_path_isdir(res)) {
|
||||
talloc_free(res);
|
||||
res = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -2941,7 +2941,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
}
|
||||
#endif /* HAVE_PVR */
|
||||
#if HAVE_DVBIN
|
||||
if (mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
int dir;
|
||||
int v = cmd->args[0].v.i;
|
||||
|
||||
@@ -2979,7 +2979,7 @@ void run_command(MPContext *mpctx, mp_cmd_t *cmd)
|
||||
|
||||
#if HAVE_DVBIN
|
||||
case MP_CMD_DVB_SET_CHANNEL:
|
||||
if (mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
if (mpctx->stream && mpctx->stream->type == STREAMTYPE_DVB) {
|
||||
mpctx->last_dvb_step = 1;
|
||||
|
||||
if (dvb_set_channel(mpctx->stream, cmd->args[1].v.i,
|
||||
|
||||
+6
-7
@@ -1014,7 +1014,7 @@ static bool demux_was_interrupted(struct MPContext *mpctx)
|
||||
mp_cmd_t *cmd = mp_input_get_cmd(mpctx->input, 0, 0);
|
||||
if (!cmd)
|
||||
break;
|
||||
if (mp_input_is_abort_cmd(cmd->id))
|
||||
if (mp_input_is_abort_cmd(cmd))
|
||||
run_command(mpctx, cmd);
|
||||
mp_cmd_free(cmd);
|
||||
}
|
||||
@@ -1307,14 +1307,13 @@ goto_reopen_demuxer: ;
|
||||
|
||||
// If there's a timeline force an absolute seek to initialize state
|
||||
double startpos = rel_time_to_abs(mpctx, opts->play_start, -1);
|
||||
if (startpos != -1 || mpctx->timeline) {
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, 0);
|
||||
execute_queued_seek(mpctx);
|
||||
}
|
||||
if (startpos == -1 && mpctx->resolve_result &&
|
||||
mpctx->resolve_result->start_time > 0)
|
||||
{
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, mpctx->resolve_result->start_time, 0);
|
||||
startpos = mpctx->resolve_result->start_time;
|
||||
if (startpos == -1 && mpctx->timeline)
|
||||
startpos = 0;
|
||||
if (startpos != -1) {
|
||||
queue_seek(mpctx, MPSEEK_ABSOLUTE, startpos, 0);
|
||||
execute_queued_seek(mpctx);
|
||||
}
|
||||
if (opts->chapterrange[0] > 0) {
|
||||
|
||||
@@ -1,3 +1,20 @@
|
||||
/*
|
||||
* This file is part of mpv.
|
||||
*
|
||||
* mpv is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* mpv is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with mpv. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
|
||||
+15
-10
@@ -168,14 +168,14 @@ void add_step_frame(struct MPContext *mpctx, int dir)
|
||||
}
|
||||
}
|
||||
|
||||
static void seek_reset(struct MPContext *mpctx, bool reset_ao)
|
||||
static void seek_reset(struct MPContext *mpctx, bool reset_ao, bool reset_ac)
|
||||
{
|
||||
if (mpctx->d_video) {
|
||||
video_reset_decoding(mpctx->d_video);
|
||||
vo_seek_reset(mpctx->video_out);
|
||||
}
|
||||
|
||||
if (mpctx->d_audio) {
|
||||
if (mpctx->d_audio && reset_ac) {
|
||||
audio_reset_decoding(mpctx->d_audio);
|
||||
if (reset_ao)
|
||||
clear_audio_output_buffers(mpctx);
|
||||
@@ -204,9 +204,6 @@ static void seek_reset(struct MPContext *mpctx, bool reset_ao)
|
||||
}
|
||||
|
||||
// return -1 if seek failed (non-seekable stream?), 0 otherwise
|
||||
// timeline_fallthrough: true if used to explicitly switch timeline - in this
|
||||
// case, don't drop buffered AO audio data, so that
|
||||
// timeline segment transition is seemless
|
||||
static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
bool timeline_fallthrough)
|
||||
{
|
||||
@@ -253,6 +250,9 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
seek.amount += get_current_time(mpctx);
|
||||
}
|
||||
|
||||
/* At least the liba52 decoder wants to read from the input stream
|
||||
* during initialization, so reinit must be done after the demux_seek()
|
||||
* call that clears possible stream EOF. */
|
||||
bool need_reset = false;
|
||||
double demuxer_amount = seek.amount;
|
||||
if (mpctx->timeline) {
|
||||
@@ -271,7 +271,6 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
}
|
||||
if (need_reset) {
|
||||
reinit_video_chain(mpctx);
|
||||
reinit_audio_chain(mpctx);
|
||||
reinit_subs(mpctx, 0);
|
||||
reinit_subs(mpctx, 1);
|
||||
}
|
||||
@@ -296,8 +295,10 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
demuxer_amount -= hr_seek_offset;
|
||||
int seekresult = demux_seek(mpctx->demuxer, demuxer_amount, demuxer_style);
|
||||
if (seekresult == 0) {
|
||||
if (need_reset)
|
||||
seek_reset(mpctx, !timeline_fallthrough);
|
||||
if (need_reset) {
|
||||
reinit_audio_chain(mpctx);
|
||||
seek_reset(mpctx, !timeline_fallthrough, false);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@@ -315,7 +316,11 @@ static int mp_seek(MPContext *mpctx, struct seek_params seek,
|
||||
}
|
||||
}
|
||||
|
||||
seek_reset(mpctx, !timeline_fallthrough);
|
||||
if (need_reset)
|
||||
reinit_audio_chain(mpctx);
|
||||
/* If we just reinitialized audio it doesn't need to be reset,
|
||||
* and resetting could lose audio some decoders produce during init. */
|
||||
seek_reset(mpctx, !timeline_fallthrough, !need_reset);
|
||||
|
||||
if (timeline_fallthrough) {
|
||||
// Important if video reinit happens.
|
||||
@@ -571,7 +576,7 @@ bool mp_seek_chapter(struct MPContext *mpctx, int chapter)
|
||||
if (res >= 0) {
|
||||
if (pts == -1) {
|
||||
// for DVD/BD - seek happened via stream layer
|
||||
seek_reset(mpctx, true);
|
||||
seek_reset(mpctx, true, true);
|
||||
mpctx->seek = (struct seek_params){0};
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -164,7 +164,7 @@ static void copy_chapters(struct chapter **chapters, int *num_chapters,
|
||||
double time = demuxer_chapter_time(src, n);
|
||||
if (time >= start && time <= start + len) {
|
||||
struct chapter ch = {
|
||||
.start = dest_offset + time,
|
||||
.start = dest_offset + time - start,
|
||||
.name = talloc_steal(*chapters, demuxer_chapter_name(src, n)),
|
||||
};
|
||||
MP_TARRAY_APPEND(NULL, *chapters, *num_chapters, ch);
|
||||
|
||||
@@ -175,6 +175,8 @@ void sub_init_from_sh(struct dec_sub *sub, struct sh_stream *sh)
|
||||
struct sd init_sd = sub->init_sd;
|
||||
init_sd.codec = sh->codec;
|
||||
init_sd.ass_track = sh->sub->track;
|
||||
init_sd.sub_stream_w = sh->sub->w;
|
||||
init_sd.sub_stream_h = sh->sub->h;
|
||||
|
||||
while (sub->num_sd < MAX_NUM_SD) {
|
||||
struct sd *sd = talloc(NULL, struct sd);
|
||||
|
||||
@@ -25,6 +25,9 @@ struct sd {
|
||||
// the resolution of the VO, nor does it have to be the OSD resolution.
|
||||
int sub_video_w, sub_video_h;
|
||||
|
||||
// Resolution hints stored in mp4 files.
|
||||
int sub_stream_w, sub_stream_h;
|
||||
|
||||
// Make sd_ass use an existing track
|
||||
struct ass_track *ass_track;
|
||||
|
||||
|
||||
+42
-2
@@ -21,12 +21,14 @@
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/common.h>
|
||||
#include <libavutil/intreadwrite.h>
|
||||
|
||||
#include "talloc.h"
|
||||
#include "common/msg.h"
|
||||
#include "common/av_common.h"
|
||||
#include "options/options.h"
|
||||
#include "video/mp_image.h"
|
||||
#include "video/csputils.h"
|
||||
#include "sd.h"
|
||||
#include "dec_sub.h"
|
||||
|
||||
@@ -89,9 +91,42 @@ static void get_resolution(struct sd *sd, int wh[2])
|
||||
struct sd_lavc_priv *priv = sd->priv;
|
||||
wh[0] = priv->avctx->width;
|
||||
wh[1] = priv->avctx->height;
|
||||
if (wh[0] <= 0 || wh[1] <= 0) {
|
||||
wh[0] = priv->video_params.w;
|
||||
wh[1] = priv->video_params.h;
|
||||
}
|
||||
guess_resolution(priv->avctx->codec_id, &wh[0], &wh[1]);
|
||||
}
|
||||
|
||||
static void set_mp4_vobsub_idx(AVCodecContext *avctx, char *src, int w, int h)
|
||||
{
|
||||
char pal_s[128];
|
||||
int pal_s_pos = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
unsigned int e = AV_RB32(src + i * 4);
|
||||
|
||||
// lavc doesn't accept YUV palette - "does god hate me?"
|
||||
struct mp_csp_params csp = MP_CSP_PARAMS_DEFAULTS;
|
||||
csp.int_bits_in = 8;
|
||||
csp.int_bits_out = 8;
|
||||
float cmatrix[3][4];
|
||||
mp_get_yuv2rgb_coeffs(&csp, cmatrix);
|
||||
int c[3] = {(e >> 16) & 0xff, (e >> 8) & 0xff, e & 0xff};
|
||||
mp_map_int_color(cmatrix, 8, c);
|
||||
e = (c[2] << 16) | (c[1] << 8) | c[0];
|
||||
|
||||
snprintf(pal_s + pal_s_pos, sizeof(pal_s) - pal_s_pos, "%06x%s", e,
|
||||
i != 15 ? ", " : "");
|
||||
pal_s_pos = strlen(pal_s);
|
||||
if (pal_s_pos >= sizeof(pal_s))
|
||||
break;
|
||||
}
|
||||
|
||||
char buf[256] = "";
|
||||
snprintf(buf, sizeof(buf), "size: %dx%d\npalette: %s\n", w, h, pal_s);
|
||||
mp_lavc_set_extradata(avctx, buf, strlen(buf));
|
||||
}
|
||||
|
||||
static int init(struct sd *sd)
|
||||
{
|
||||
struct sd_lavc_priv *priv = talloc_zero(NULL, struct sd_lavc_priv);
|
||||
@@ -103,8 +138,12 @@ static int init(struct sd *sd)
|
||||
ctx = avcodec_alloc_context3(sub_codec);
|
||||
if (!ctx)
|
||||
goto error;
|
||||
ctx->extradata_size = sd->extradata_len;
|
||||
ctx->extradata = sd->extradata;
|
||||
mp_lavc_set_extradata(ctx, sd->extradata, sd->extradata_len);
|
||||
if (sd->extradata_len == 64 && sd->sub_stream_w && sd->sub_stream_h &&
|
||||
cid == AV_CODEC_ID_DVD_SUBTITLE)
|
||||
{
|
||||
set_mp4_vobsub_idx(ctx, sd->extradata, sd->sub_stream_w, sd->sub_stream_h);
|
||||
}
|
||||
if (avcodec_open2(ctx, sub_codec, NULL) < 0)
|
||||
goto error;
|
||||
priv->avctx = ctx;
|
||||
@@ -264,6 +303,7 @@ static void uninit(struct sd *sd)
|
||||
|
||||
clear(priv);
|
||||
avcodec_close(priv->avctx);
|
||||
av_free(priv->avctx->extradata);
|
||||
av_free(priv->avctx);
|
||||
talloc_free(priv);
|
||||
}
|
||||
|
||||
+8
-19
@@ -318,10 +318,7 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format,
|
||||
if (bih->biSize <= sizeof(*bih))
|
||||
break;
|
||||
av_opt_set_int(avctx, "extern_huff", 1, AV_OPT_SEARCH_CHILDREN);
|
||||
avctx->extradata_size = bih->biSize - sizeof(*bih);
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
|
||||
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
|
||||
break;
|
||||
|
||||
case MP_FOURCC('R','V','1','0'):
|
||||
@@ -331,29 +328,21 @@ static void set_from_bih(AVCodecContext *avctx, uint32_t format,
|
||||
case MP_FOURCC('R','V','4','0'):
|
||||
if (bih->biSize < sizeof(*bih) + 8) {
|
||||
// only 1 packet per frame & sub_id from fourcc
|
||||
avctx->extradata_size = 8;
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
((uint32_t *)avctx->extradata)[0] = 0;
|
||||
((uint32_t *)avctx->extradata)[1] =
|
||||
format == MP_FOURCC('R','V','1','3') ?
|
||||
0x10003001 : 0x10000000;
|
||||
uint32_t extradata[2] = {
|
||||
0,
|
||||
format == MP_FOURCC('R','V','1','3') ? 0x10003001 : 0x10000000,
|
||||
};
|
||||
mp_lavc_set_extradata(avctx, &extradata, 8);
|
||||
} else {
|
||||
// has extra slice header (demux_rm or rm->avi streamcopy)
|
||||
avctx->extradata_size = bih->biSize - sizeof(*bih);
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
|
||||
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (bih->biSize <= sizeof(*bih))
|
||||
break;
|
||||
avctx->extradata_size = bih->biSize - sizeof(*bih);
|
||||
avctx->extradata = av_mallocz(avctx->extradata_size +
|
||||
FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
memcpy(avctx->extradata, bih + 1, avctx->extradata_size);
|
||||
mp_lavc_set_extradata(avctx, bih + 1, bih->biSize - sizeof(*bih));
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -126,7 +126,8 @@ static bool create_vdp_decoder(struct lavc_ctx *ctx)
|
||||
goto fail;
|
||||
}
|
||||
if (p->vid_width > maxw || p->vid_height > maxh) {
|
||||
MP_ERR(p, "Video too large.\n");
|
||||
MP_ERR(p, "Video resolution(%dx%d) is larger than the maximum size(%dx%d) supported.\n",
|
||||
p->vid_width, p->vid_height, maxw, maxh);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
+2
-2
@@ -599,11 +599,11 @@ void vf_set_dar(int *d_w, int *d_h, int w, int h, double dar)
|
||||
*d_w = w;
|
||||
*d_h = h;
|
||||
if (dar > 0.01) {
|
||||
*d_w = h * dar;
|
||||
*d_w = h * dar + 0.5;
|
||||
// we don't like horizontal downscale
|
||||
if (*d_w < w) {
|
||||
*d_w = w;
|
||||
*d_h = w / dar;
|
||||
*d_h = w / dar + 0.5;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -647,17 +647,14 @@ int vo_w32_init(struct vo *vo)
|
||||
|
||||
HINSTANCE hInstance = GetModuleHandleW(NULL);
|
||||
|
||||
HICON mplayerIcon = LoadIconW(hInstance, L"IDI_ICON1");
|
||||
|
||||
WNDCLASSEXW wcex = {
|
||||
.cbSize = sizeof wcex,
|
||||
.style = CS_OWNDC | CS_HREDRAW | CS_VREDRAW,
|
||||
.lpfnWndProc = WndProc,
|
||||
.hInstance = hInstance,
|
||||
.hIcon = mplayerIcon,
|
||||
.hIcon = LoadIconW(hInstance, L"IDI_ICON1"),
|
||||
.hCursor = LoadCursor(NULL, IDC_ARROW),
|
||||
.lpszClassName = classname,
|
||||
.hIconSm = mplayerIcon,
|
||||
};
|
||||
|
||||
if (!RegisterClassExW(&wcex)) {
|
||||
|
||||
@@ -40,6 +40,7 @@ def __add_mingw_flags__(ctx):
|
||||
|
||||
def __add_cygwin_flags__(ctx):
|
||||
ctx.env.CFLAGS += ['-mwin32']
|
||||
ctx.env.CFLAGS += ['-U__STRICT_ANSI__']
|
||||
|
||||
__compiler_map__ = {
|
||||
'__GNUC__': __add_gcc_flags__,
|
||||
|
||||
@@ -289,7 +289,7 @@ If you really mean to compile without libass support use --disable-libass."
|
||||
}, {
|
||||
'name': '--mpg123',
|
||||
'desc': 'mpg123 support',
|
||||
'func': check_pkg_config('libmpg123', '>= 1.2.0'),
|
||||
'func': check_pkg_config('libmpg123', '>= 1.14.0'),
|
||||
}, {
|
||||
'name': '--ladspa',
|
||||
'desc': 'LADSPA plugin support',
|
||||
@@ -504,6 +504,18 @@ video_output_features = [
|
||||
'name': 'gdi',
|
||||
'desc': 'GDI',
|
||||
'func': check_cc(lib='gdi32')
|
||||
} , {
|
||||
'name': 'winmm',
|
||||
'desc': 'WinMM',
|
||||
'func': check_cc(lib='winmm')
|
||||
} , {
|
||||
'name': 'ole',
|
||||
'desc': 'OLE',
|
||||
'func': check_cc(lib='ole32')
|
||||
} , {
|
||||
'name': 'uuid',
|
||||
'desc': 'UUID',
|
||||
'func': check_cc(lib='uuid')
|
||||
} , {
|
||||
'name': '--wayland',
|
||||
'desc': 'Wayland',
|
||||
@@ -570,7 +582,7 @@ video_output_features = [
|
||||
} , {
|
||||
'name': '--gl-win32',
|
||||
'desc': 'OpenGL Win32 Backend',
|
||||
'deps': [ 'gdi' ],
|
||||
'deps': [ 'gdi', 'winmm', 'ole', 'uuid' ],
|
||||
'groups': [ 'gl' ],
|
||||
'func': check_statement('windows.h', 'wglCreateContext(0)',
|
||||
lib='opengl32')
|
||||
@@ -633,7 +645,7 @@ video_output_features = [
|
||||
}, {
|
||||
'name': '--direct3d',
|
||||
'desc': 'Direct3D support',
|
||||
'deps': [ 'gdi' ],
|
||||
'deps': [ 'gdi', 'winmm', 'ole', 'uuid' ],
|
||||
'func': check_cc(header_name='d3d9.h'),
|
||||
}
|
||||
]
|
||||
|
||||
Reference in new issue
Block a user