mirror of
https://github.com/mpv-player/mpv
synced 2025-03-31 15:59:34 +00:00
Merge remote-tracking branch 'origin/master' into my_master
This commit is contained in:
commit
f341b21a90
10
Makefile
10
Makefile
@ -60,13 +60,8 @@ SRCS_COMMON-$(DVDREAD_INTERNAL) += libdvdread4/bitreader.c \
|
||||
SRCS_COMMON-$(FAAD) += libmpcodecs/ad_faad.c
|
||||
SRCS_COMMON-$(FASTMEMCPY) += libvo/aclib.c
|
||||
|
||||
# Requires a new enough libavutil that installs eval.h
|
||||
SRCS_COMMON-$(FFMPEG_EVAL_API) += libmpcodecs/vf_geq.c \
|
||||
libmpcodecs/vf_qp.c \
|
||||
|
||||
# These filters use private headers and do not work with shared libavcodec.
|
||||
SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_fspp.c \
|
||||
libmpcodecs/vf_mcdeint.c \
|
||||
SRCS_COMMON-$(FFMPEG_INTERNALS) += libmpcodecs/vf_mcdeint.c \
|
||||
libmpcodecs/vf_spp.c \
|
||||
|
||||
SRCS_COMMON-$(FREETYPE) += sub/font_load_ft.c
|
||||
@ -316,6 +311,8 @@ SRCS_COMMON = asxparser.c \
|
||||
libmpcodecs/vf_flip.c \
|
||||
libmpcodecs/vf_format.c \
|
||||
libmpcodecs/vf_framestep.c \
|
||||
libmpcodecs/vf_fspp.c \
|
||||
libmpcodecs/vf_geq.c \
|
||||
libmpcodecs/vf_gradfun.c \
|
||||
libmpcodecs/vf_halfpack.c \
|
||||
libmpcodecs/vf_harddup.c \
|
||||
@ -337,6 +334,7 @@ SRCS_COMMON = asxparser.c \
|
||||
libmpcodecs/vf_pp.c \
|
||||
libmpcodecs/vf_pp7.c \
|
||||
libmpcodecs/vf_pullup.c \
|
||||
libmpcodecs/vf_qp.c \
|
||||
libmpcodecs/vf_rectangle.c \
|
||||
libmpcodecs/vf_remove_logo.c \
|
||||
libmpcodecs/vf_rgbtest.c \
|
||||
|
@ -1,30 +0,0 @@
|
||||
/*
|
||||
* This file is part of MPlayer.
|
||||
*
|
||||
* MPlayer 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.
|
||||
*
|
||||
* MPlayer 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 MPlayer; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*/
|
||||
|
||||
#ifndef MPLAYER_ACCESS_MPCONTEXT_H
|
||||
#define MPLAYER_ACCESS_MPCONTEXT_H
|
||||
|
||||
struct MPContext;
|
||||
void *mpctx_get_video_out(struct MPContext *mpctx);
|
||||
void *mpctx_get_demuxer(struct MPContext *mpctx);
|
||||
void *mpctx_get_playtree_iter(struct MPContext *mpctx);
|
||||
void *mpctx_get_mixer(struct MPContext *mpctx);
|
||||
int mpctx_get_global_sub_size(struct MPContext *mpctx);
|
||||
int mpctx_get_osd_function(struct MPContext *mpctx);
|
||||
|
||||
#endif /* MPLAYER_ACCESS_MPCONTEXT_H */
|
@ -680,10 +680,8 @@ static int mp_property_pause(m_option_t *prop, int action, void *arg,
|
||||
case M_PROPERTY_STEP_DOWN:
|
||||
if (mpctx->paused) {
|
||||
unpause_player(mpctx);
|
||||
mpctx->osd_function = OSD_PLAY;
|
||||
} else {
|
||||
pause_player(mpctx);
|
||||
mpctx->osd_function = OSD_PAUSE;
|
||||
}
|
||||
return M_PROPERTY_OK;
|
||||
default:
|
||||
|
16
configure
vendored
16
configure
vendored
@ -6003,27 +6003,21 @@ echores "$_live"
|
||||
|
||||
|
||||
|
||||
all_libav_libs="libavutil libavcodec libavformat libswscale libpostproc"
|
||||
all_libav_libs="libavutil >= 51.7.0:libavcodec >= 53.5.0:libavformat >= 53.2.0:libswscale >= 2.0.0:libpostproc >= 52.0.0"
|
||||
echocheck "Libav ($all_libav_libs)"
|
||||
if test "$ffmpeg" = auto ; then
|
||||
IFS=":" # shell should not be used for programming
|
||||
if $_pkg_config --exists --print-errors $all_libav_libs ; then
|
||||
inc_ffmpeg=$($_pkg_config --cflags $all_libav_libs)
|
||||
_ld_tmp=$($_pkg_config --libs $all_libav_libs)
|
||||
extra_ldflags="$extra_ldflags $_ld_tmp"
|
||||
extra_cflags="$extra_cflags $inc_ffmpeg"
|
||||
elif header_check libavutil/avutil.h -lpostproc -lswscale -lavformat -lavcodec -lavutil $_ld_lm ; then
|
||||
extra_ldflags="$extra_ldflags -lpostproc -lswscale -lavformat -lavcodec -lavutil"
|
||||
unset IFS
|
||||
else
|
||||
die "Unable to find development files for some of the required Libav libraries above. Aborting."
|
||||
fi
|
||||
fi
|
||||
|
||||
ffmpeg_eval_api=no
|
||||
def_ffmpeg_eval_api="#undef CONFIG_FFMPEG_EVAL_API"
|
||||
if $_pkg_config --atleast-version=50.33.0 libavutil ; then
|
||||
ffmpeg_eval_api=yes
|
||||
def_ffmpeg_eval_api="#define CONFIG_FFMPEG_EVAL_API 1"
|
||||
fi
|
||||
echores "yes"
|
||||
|
||||
def_ffmpeg_internals="#undef CONFIG_FFMPEG_INTERNALS"
|
||||
if ! test -z "$_ffmpeg_source" ; then
|
||||
@ -6790,7 +6784,6 @@ XVR100 = $_xvr100
|
||||
YUV4MPEG = $_yuv4mpeg
|
||||
|
||||
# FFmpeg
|
||||
FFMPEG_EVAL_API = $ffmpeg_eval_api
|
||||
FFMPEG_INTERNALS = $ffmpeg_internals
|
||||
FFMPEG_SOURCE_PATH = $_ffmpeg_source
|
||||
|
||||
@ -7143,7 +7136,6 @@ $def_yuv4mpeg
|
||||
|
||||
|
||||
/* FFmpeg */
|
||||
$def_ffmpeg_eval_api
|
||||
$def_ffmpeg_internals
|
||||
|
||||
$def_arpa_inet_h
|
||||
|
@ -181,9 +181,7 @@ const struct mp_AVCodecTag mp_ff_codec_bmp_tags[] = {
|
||||
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'U', 'V', '9') },
|
||||
{ CODEC_ID_RAWVIDEO, MKTAG('Y', 'V', 'U', '9') },
|
||||
{ CODEC_ID_FRWU, MKTAG('F', 'R', 'W', 'U') },
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 89, 0)
|
||||
{ CODEC_ID_R10K, MKTAG('R', '1', '0', 'k') },
|
||||
#endif
|
||||
{ CODEC_ID_R210, MKTAG('r', '2', '1', '0') },
|
||||
{ CODEC_ID_V210, MKTAG('v', '2', '1', '0') },
|
||||
{ CODEC_ID_INDEO3, MKTAG('I', 'V', '3', '1') },
|
||||
@ -260,9 +258,7 @@ const struct mp_AVCodecTag mp_ff_codec_bmp_tags[] = {
|
||||
{ CODEC_ID_AURA2, MKTAG('A', 'U', 'R', '2') },
|
||||
{ CODEC_ID_DPX, MKTAG('d', 'p', 'x', ' ') },
|
||||
{ CODEC_ID_KGV1, MKTAG('K', 'G', 'V', '1') },
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 108, 0)
|
||||
{ CODEC_ID_LAGARITH, MKTAG('L', 'A', 'G', 'S') },
|
||||
#endif
|
||||
{ CODEC_ID_NONE, 0 }
|
||||
};
|
||||
|
||||
@ -299,15 +295,11 @@ const struct mp_AVCodecTag mp_ff_codec_wav_tags[] = {
|
||||
{ CODEC_ID_WMALOSSLESS, 0x0163 },
|
||||
{ CODEC_ID_ADPCM_CT, 0x0200 },
|
||||
{ CODEC_ID_ATRAC3, 0x0270 },
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 88, 0)
|
||||
{ CODEC_ID_ADPCM_G722, 0x028F },
|
||||
#endif
|
||||
{ CODEC_ID_IMC, 0x0401 },
|
||||
{ CODEC_ID_GSM_MS, 0x1500 },
|
||||
{ CODEC_ID_TRUESPEECH, 0x1501 },
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 94, 0)
|
||||
{ CODEC_ID_AAC_LATM, 0x1602 },
|
||||
#endif
|
||||
{ CODEC_ID_AC3, 0x2000 },
|
||||
{ CODEC_ID_DTS, 0x2001 },
|
||||
{ CODEC_ID_SONIC, 0x2048 },
|
||||
|
@ -75,20 +75,16 @@ static const struct {
|
||||
|
||||
{IMGFMT_420P16_LE, PIX_FMT_YUV420P16LE},
|
||||
{IMGFMT_420P16_BE, PIX_FMT_YUV420P16BE},
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 2, 0)
|
||||
{IMGFMT_420P9_LE, PIX_FMT_YUV420P9LE},
|
||||
{IMGFMT_420P9_BE, PIX_FMT_YUV420P9BE},
|
||||
{IMGFMT_420P10_LE, PIX_FMT_YUV420P10LE},
|
||||
{IMGFMT_420P10_BE, PIX_FMT_YUV420P10BE},
|
||||
{IMGFMT_422P10_LE, PIX_FMT_YUV422P10LE},
|
||||
{IMGFMT_422P10_BE, PIX_FMT_YUV422P10BE},
|
||||
#endif
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 7, 0)
|
||||
{IMGFMT_444P9_BE , PIX_FMT_YUV444P9BE},
|
||||
{IMGFMT_444P9_LE , PIX_FMT_YUV444P9LE},
|
||||
{IMGFMT_444P10_BE, PIX_FMT_YUV444P10BE},
|
||||
{IMGFMT_444P10_LE, PIX_FMT_YUV444P10LE},
|
||||
#endif
|
||||
{IMGFMT_422P16_LE, PIX_FMT_YUV422P16LE},
|
||||
{IMGFMT_422P16_BE, PIX_FMT_YUV422P16BE},
|
||||
{IMGFMT_444P16_LE, PIX_FMT_YUV444P16LE},
|
||||
@ -134,13 +130,9 @@ int pixfmt2imgfmt(enum PixelFormat pix_fmt)
|
||||
break;
|
||||
int fmt = conversion_map[i].fmt;
|
||||
if (!fmt) {
|
||||
#if LIBAVUTIL_VERSION_INT >= AV_VERSION_INT(51, 2, 0)
|
||||
const char *fmtname = av_get_pix_fmt_name(pix_fmt);
|
||||
mp_msg(MSGT_GLOBAL, MSGL_ERR, "Unsupported PixelFormat %s (%d)\n",
|
||||
fmtname ? fmtname : "INVALID", pix_fmt);
|
||||
#else
|
||||
mp_msg(MSGT_GLOBAL, MSGL_ERR, "Unsupported PixelFormat %i\n", pix_fmt);
|
||||
#endif
|
||||
}
|
||||
return fmt;
|
||||
}
|
||||
|
@ -142,7 +142,6 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
|
||||
{
|
||||
af_data_t* c = data; // Current working data
|
||||
af_volume_t* s = (af_volume_t*)af->setup; // Setup for this instance
|
||||
int ch = 0; // Channel counter
|
||||
register int nch = c->nch; // Number of channels
|
||||
register int i = 0;
|
||||
|
||||
@ -150,9 +149,9 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
|
||||
if(af->data->format == (AF_FORMAT_S16_NE)){
|
||||
int16_t* a = (int16_t*)c->audio; // Audio data
|
||||
int len = c->len/2; // Number of samples
|
||||
for(ch = 0; ch < nch ; ch++){
|
||||
if(s->enable[ch]){
|
||||
register int vol = (int)(255.0 * s->level[ch]);
|
||||
for (int ch = 0; ch < nch; ch++) {
|
||||
int vol = 256.0 * s->level[ch];
|
||||
if (s->enable[ch] && vol != 256) {
|
||||
for(i=ch;i<len;i+=nch){
|
||||
register int x = (a[i] * vol) >> 8;
|
||||
a[i]=clamp(x,SHRT_MIN,SHRT_MAX);
|
||||
@ -164,7 +163,7 @@ static af_data_t* play(struct af_instance_s* af, af_data_t* data)
|
||||
else if(af->data->format == (AF_FORMAT_FLOAT_NE)){
|
||||
float* a = (float*)c->audio; // Audio data
|
||||
int len = c->len/4; // Number of samples
|
||||
for(ch = 0; ch < nch ; ch++){
|
||||
for (int ch = 0; ch < nch; ch++) {
|
||||
// Volume control (fader)
|
||||
if(s->enable[ch]){
|
||||
float t = 1.0 - s->time;
|
||||
|
@ -74,12 +74,15 @@ static const struct ao_driver * const audio_out_drivers[] = {
|
||||
#ifdef CONFIG_COREAUDIO
|
||||
&audio_out_coreaudio,
|
||||
#endif
|
||||
#ifdef CONFIG_OSS_AUDIO
|
||||
&audio_out_oss,
|
||||
#ifdef CONFIG_PULSE
|
||||
&audio_out_pulse,
|
||||
#endif
|
||||
#ifdef CONFIG_ALSA
|
||||
&audio_out_alsa,
|
||||
#endif
|
||||
#ifdef CONFIG_OSS_AUDIO
|
||||
&audio_out_oss,
|
||||
#endif
|
||||
#ifdef CONFIG_ALSA5
|
||||
&audio_out_alsa5,
|
||||
#endif
|
||||
@ -96,20 +99,17 @@ static const struct ao_driver * const audio_out_drivers[] = {
|
||||
#ifdef CONFIG_ESD
|
||||
&audio_out_esd,
|
||||
#endif
|
||||
#ifdef CONFIG_PULSE
|
||||
&audio_out_pulse,
|
||||
#endif
|
||||
#ifdef CONFIG_JACK
|
||||
&audio_out_jack,
|
||||
#endif
|
||||
#ifdef CONFIG_NAS
|
||||
&audio_out_nas,
|
||||
#endif
|
||||
#ifdef CONFIG_SDL
|
||||
&audio_out_sdl,
|
||||
#endif
|
||||
#ifdef CONFIG_OPENAL
|
||||
&audio_out_openal,
|
||||
#endif
|
||||
#ifdef CONFIG_SDL
|
||||
&audio_out_sdl,
|
||||
#endif
|
||||
&audio_out_mpegpes,
|
||||
#ifdef CONFIG_IVTV
|
||||
|
@ -20,6 +20,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <stdbool.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
@ -47,7 +48,7 @@ LIBAD_EXTERN(ffmpeg)
|
||||
|
||||
struct priv {
|
||||
AVCodecContext *avctx;
|
||||
bool old_packet;
|
||||
int previous_data_left;
|
||||
};
|
||||
|
||||
static int preinit(sh_audio_t *sh)
|
||||
@ -230,7 +231,7 @@ static int control(sh_audio_t *sh, int cmd, void *arg, ...)
|
||||
case ADCTRL_RESYNC_STREAM:
|
||||
avcodec_flush_buffers(ctx->avctx);
|
||||
ds_clear_parser(sh->ds);
|
||||
ctx->old_packet = false;
|
||||
ctx->previous_data_left = 0;
|
||||
return CONTROL_TRUE;
|
||||
}
|
||||
return CONTROL_UNKNOWN;
|
||||
@ -247,23 +248,37 @@ static int decode_audio(sh_audio_t *sh_audio, unsigned char *buf, int minlen,
|
||||
while (len < minlen) {
|
||||
AVPacket pkt;
|
||||
int len2 = maxlen;
|
||||
double pts;
|
||||
int x = ds_get_packet_pts(sh_audio->ds, &start, &pts);
|
||||
if (x <= 0) {
|
||||
double pts = MP_NOPTS_VALUE;
|
||||
int x;
|
||||
bool packet_already_used = ctx->previous_data_left;
|
||||
struct demux_packet *mpkt = ds_get_packet2(sh_audio->ds,
|
||||
ctx->previous_data_left);
|
||||
if (!mpkt) {
|
||||
assert(!ctx->previous_data_left);
|
||||
start = NULL;
|
||||
x = 0;
|
||||
ds_parse(sh_audio->ds, &start, &x, MP_NOPTS_VALUE, 0);
|
||||
ds_parse(sh_audio->ds, &start, &x, pts, 0);
|
||||
if (x <= 0)
|
||||
break; // error
|
||||
} else {
|
||||
int in_size = x;
|
||||
assert(mpkt->len >= ctx->previous_data_left);
|
||||
if (!ctx->previous_data_left) {
|
||||
ctx->previous_data_left = mpkt->len;
|
||||
pts = mpkt->pts;
|
||||
}
|
||||
x = ctx->previous_data_left;
|
||||
start = mpkt->buffer + mpkt->len - ctx->previous_data_left;
|
||||
int consumed = ds_parse(sh_audio->ds, &start, &x, pts, 0);
|
||||
sh_audio->ds->buffer_pos -= in_size - consumed;
|
||||
ctx->previous_data_left -= consumed;
|
||||
}
|
||||
av_init_packet(&pkt);
|
||||
pkt.data = start;
|
||||
pkt.size = x;
|
||||
if (pts != MP_NOPTS_VALUE && !ctx->old_packet) {
|
||||
if (mpkt && mpkt->avpacket) {
|
||||
pkt.side_data = mpkt->avpacket->side_data;
|
||||
pkt.side_data_elems = mpkt->avpacket->side_data_elems;
|
||||
}
|
||||
if (pts != MP_NOPTS_VALUE && !packet_already_used) {
|
||||
sh_audio->pts = pts;
|
||||
sh_audio->pts_bytes = 0;
|
||||
}
|
||||
@ -275,14 +290,11 @@ static int decode_audio(sh_audio_t *sh_audio, unsigned char *buf, int minlen,
|
||||
mp_msg(MSGT_DECAUDIO, MSGL_V, "lavc_audio: error\n");
|
||||
break;
|
||||
}
|
||||
if (!sh_audio->parser && y < x) {
|
||||
sh_audio->ds->buffer_pos += y - x; // put back data (HACK!)
|
||||
ctx->old_packet = true;
|
||||
}
|
||||
if (!sh_audio->parser)
|
||||
ctx->previous_data_left += x - y;
|
||||
if (len2 > 0) {
|
||||
if (avctx->channels >= 5) {
|
||||
int samplesize = av_get_bits_per_sample_format(
|
||||
avctx->sample_fmt) / 8;
|
||||
int samplesize = av_get_bytes_per_sample(avctx->sample_fmt);
|
||||
reorder_channel_nch(buf, AF_CHANNEL_LAYOUT_LAVC_DEFAULT,
|
||||
AF_CHANNEL_LAYOUT_MPLAYER_DEFAULT,
|
||||
avctx->channels,
|
||||
|
@ -147,10 +147,7 @@ static int init(sh_video_t *sh)
|
||||
&& lavc_codec->id != CODEC_ID_H264
|
||||
&& lavc_codec->id != CODEC_ID_INTERPLAY_VIDEO
|
||||
&& lavc_codec->id != CODEC_ID_ROQ && lavc_codec->id != CODEC_ID_VP8
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 108, 0)
|
||||
&& lavc_codec->id != CODEC_ID_LAGARITH
|
||||
#endif
|
||||
)
|
||||
&& lavc_codec->id != CODEC_ID_LAGARITH)
|
||||
ctx->do_dr1 = 1;
|
||||
ctx->b_age = ctx->ip_age[0] = ctx->ip_age[1] = 256 * 256 * 256 * 64;
|
||||
ctx->ip_count = ctx->b_count = 0;
|
||||
@ -314,27 +311,12 @@ static int init(sh_video_t *sh)
|
||||
memcpy(avctx->extradata, sh->bih + 1, avctx->extradata_size);
|
||||
break;
|
||||
}
|
||||
/* Pass palette to codec */
|
||||
if (sh->bih && (sh->bih->biBitCount <= 8)) {
|
||||
avctx->palctrl = calloc(1, sizeof(AVPaletteControl));
|
||||
avctx->palctrl->palette_changed = 1;
|
||||
if (sh->bih->biSize - sizeof(*sh->bih))
|
||||
/* Palette size in biSize */
|
||||
memcpy(avctx->palctrl->palette, sh->bih + 1,
|
||||
FFMIN(sh->bih->biSize - sizeof(*sh->bih), AVPALETTE_SIZE));
|
||||
else
|
||||
/* Palette size in biClrUsed */
|
||||
memcpy(avctx->palctrl->palette, sh->bih + 1,
|
||||
FFMIN(sh->bih->biClrUsed * 4, AVPALETTE_SIZE));
|
||||
}
|
||||
|
||||
if (sh->bih)
|
||||
avctx->bits_per_coded_sample = sh->bih->biBitCount;
|
||||
|
||||
if (lavc_param->threads > 1) {
|
||||
avctx->thread_count = lavc_param->threads;
|
||||
avcodec_thread_init(avctx, lavc_param->threads);
|
||||
}
|
||||
|
||||
/* open it */
|
||||
if (avcodec_open(avctx, lavc_codec) < 0) {
|
||||
mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not open codec.\n");
|
||||
@ -365,7 +347,6 @@ static void uninit(sh_video_t *sh)
|
||||
mp_tmsg(MSGT_DECVIDEO, MSGL_ERR, "Could not close codec.\n");
|
||||
|
||||
av_freep(&avctx->extradata);
|
||||
free(avctx->palctrl);
|
||||
av_freep(&avctx->slice_offset);
|
||||
}
|
||||
|
||||
@ -663,12 +644,10 @@ static struct mp_image *decode(struct sh_video *sh, struct demux_packet *packet,
|
||||
pkt.size = len;
|
||||
// HACK: make PNGs decode normally instead of as CorePNG delta frames
|
||||
pkt.flags = AV_PKT_FLAG_KEY;
|
||||
#if LIBAVCODEC_VERSION_MAJOR >= 53
|
||||
if (packet && packet->avpacket) {
|
||||
pkt.side_data = packet->avpacket->side_data;
|
||||
pkt.side_data_elems = packet->avpacket->side_data_elems;
|
||||
}
|
||||
#endif
|
||||
// The avcodec opaque field stupidly supports only int64_t type
|
||||
union pts { int64_t i; double d; };
|
||||
avctx->reordered_opaque = (union pts){.d = *reordered_pts}.i;
|
||||
|
@ -138,6 +138,7 @@ static const vf_info_t *const filter_list[] = {
|
||||
&vf_info_lavc,
|
||||
&vf_info_lavcdeint,
|
||||
&vf_info_screenshot,
|
||||
&vf_info_fspp,
|
||||
&vf_info_uspp,
|
||||
|
||||
&vf_info_dvbscale,
|
||||
@ -182,13 +183,10 @@ static const vf_info_t *const filter_list[] = {
|
||||
&vf_info_hue,
|
||||
#ifdef CONFIG_FFMPEG_INTERNALS
|
||||
&vf_info_spp,
|
||||
&vf_info_fspp,
|
||||
&vf_info_mcdeint,
|
||||
#endif
|
||||
#ifdef CONFIG_FFMPEG_EVAL_API
|
||||
&vf_info_geq,
|
||||
&vf_info_qp,
|
||||
#endif
|
||||
&vf_info_yuvcsp,
|
||||
&vf_info_kerndeint,
|
||||
&vf_info_rgbtest,
|
||||
|
@ -38,6 +38,10 @@
|
||||
#include <inttypes.h>
|
||||
#include <math.h>
|
||||
|
||||
#include <libavutil/intreadwrite.h>
|
||||
#include <libavutil/mem.h>
|
||||
#include <libavcodec/avcodec.h>
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "mp_msg.h"
|
||||
@ -46,15 +50,9 @@
|
||||
#include "mp_image.h"
|
||||
#include "vf.h"
|
||||
#include "libvo/fastmemcpy.h"
|
||||
#include "mangle.h"
|
||||
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
#include "libavutil/mem.h"
|
||||
#include "libavcodec/avcodec.h"
|
||||
#include "libavcodec/dsputil.h"
|
||||
|
||||
#undef free
|
||||
#undef malloc
|
||||
typedef short DCTELEM;
|
||||
|
||||
//===========================================================================//
|
||||
#define BLOCKSZ 12
|
||||
|
@ -65,7 +65,7 @@ const m_option_t lavfdopts_conf[] = {
|
||||
typedef struct lavf_priv {
|
||||
AVInputFormat *avif;
|
||||
AVFormatContext *avfc;
|
||||
ByteIOContext *pb;
|
||||
AVIOContext *pb;
|
||||
uint8_t buffer[BIO_BUFFER_SIZE];
|
||||
int audio_streams;
|
||||
int video_streams;
|
||||
@ -242,12 +242,6 @@ static const char * const preferred_internal[] = {
|
||||
/* lavf Matroska demuxer doesn't support ordered chapters and fails
|
||||
* for more files */
|
||||
"matroska",
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 99, 0)
|
||||
/* Seeking doesn't work with lavf FLAC demuxer in FFmpeg versions
|
||||
* without a FLAC parser. In principle this could use a runtime check to
|
||||
* switch if a shared library is updated. */
|
||||
"flac",
|
||||
#endif
|
||||
/* lavf gives neither pts nor dts for some video frames in .rm */
|
||||
"rm",
|
||||
NULL
|
||||
@ -292,8 +286,8 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
AVCodecContext *codec = st->codec;
|
||||
char *stream_type = NULL;
|
||||
int stream_id;
|
||||
AVMetadataTag *lang = av_metadata_get(st->metadata, "language", NULL, 0);
|
||||
AVMetadataTag *title = av_metadata_get(st->metadata, "title", NULL, 0);
|
||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
AVDictionaryEntry *title = av_dict_get(st->metadata, "title", NULL, 0);
|
||||
// Don't use native MPEG codec tag values with our generic tag tables.
|
||||
// May contain for example value 3 for MP3, which we'd map to PCM audio.
|
||||
if (matches_avinputformat_name(priv, "mpeg") ||
|
||||
@ -506,7 +500,7 @@ static void handle_stream(demuxer_t *demuxer, AVFormatContext *avfc, int i)
|
||||
break;
|
||||
}
|
||||
case AVMEDIA_TYPE_ATTACHMENT: {
|
||||
AVMetadataTag *ftag = av_metadata_get(st->metadata, "filename",
|
||||
AVDictionaryEntry *ftag = av_dict_get(st->metadata, "filename",
|
||||
NULL, 0);
|
||||
char *filename = ftag ? ftag->value : NULL;
|
||||
if (st->codec->codec_id == CODEC_ID_TTF)
|
||||
@ -540,15 +534,12 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
struct MPOpts *opts = demuxer->opts;
|
||||
struct lavfdopts *lavfdopts = &opts->lavfdopts;
|
||||
AVFormatContext *avfc;
|
||||
AVFormatParameters ap;
|
||||
const AVOption *opt;
|
||||
AVMetadataTag *t = NULL;
|
||||
AVDictionaryEntry *t = NULL;
|
||||
lavf_priv_t *priv = demuxer->priv;
|
||||
int i;
|
||||
char mp_filename[256] = "mp:";
|
||||
|
||||
memset(&ap, 0, sizeof(AVFormatParameters));
|
||||
|
||||
stream_seek(demuxer->stream, 0);
|
||||
|
||||
avfc = avformat_alloc_context();
|
||||
@ -567,7 +558,6 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
if (index_mode == 0)
|
||||
avfc->flags |= AVFMT_FLAG_IGNIDX;
|
||||
|
||||
ap.prealloced_context = 1;
|
||||
if (lavfdopts->probesize) {
|
||||
opt = av_set_int(avfc, "probesize", lavfdopts->probesize);
|
||||
if (!opt)
|
||||
@ -602,17 +592,18 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
av_strlcat(mp_filename, "foobar.dummy", sizeof(mp_filename));
|
||||
|
||||
if (!(priv->avif->flags & AVFMT_NOFILE)) {
|
||||
priv->pb = av_alloc_put_byte(priv->buffer, BIO_BUFFER_SIZE, 0,
|
||||
priv->pb = avio_alloc_context(priv->buffer, BIO_BUFFER_SIZE, 0,
|
||||
demuxer, mp_read, NULL, mp_seek);
|
||||
priv->pb->read_seek = mp_read_seek;
|
||||
priv->pb->is_streamed = !demuxer->stream->end_pos ||
|
||||
(demuxer->stream->flags & MP_STREAM_SEEK) != MP_STREAM_SEEK;
|
||||
priv->pb->seekable = demuxer->stream->end_pos
|
||||
&& (demuxer->stream->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK
|
||||
? AVIO_SEEKABLE_NORMAL : 0;
|
||||
avfc->pb = priv->pb;
|
||||
}
|
||||
|
||||
if (av_open_input_stream(&avfc, priv->pb, mp_filename, priv->avif,
|
||||
&ap) < 0) {
|
||||
if (avformat_open_input(&avfc, mp_filename, priv->avif, NULL) < 0) {
|
||||
mp_msg(MSGT_HEADER, MSGL_ERR,
|
||||
"LAVF_header: av_open_input_stream() failed\n");
|
||||
"LAVF_header: avformat_open_input() failed\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -625,8 +616,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
}
|
||||
|
||||
/* Add metadata. */
|
||||
av_metadata_conv(avfc, NULL, avfc->iformat->metadata_conv);
|
||||
while ((t = av_metadata_get(avfc->metadata, "", t,
|
||||
while ((t = av_dict_get(avfc->metadata, "", t,
|
||||
AV_METADATA_IGNORE_SUFFIX)))
|
||||
demux_info_add(demuxer, t->key, t->value);
|
||||
|
||||
@ -636,7 +626,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
(AVRational){1, 1000000000});
|
||||
uint64_t end = av_rescale_q(c->end, c->time_base,
|
||||
(AVRational){1, 1000000000});
|
||||
t = av_metadata_get(c->metadata, "title", NULL, 0);
|
||||
t = av_dict_get(c->metadata, "title", NULL, 0);
|
||||
demuxer_add_chapter(demuxer, t ? bstr(t->value) : bstr(NULL),
|
||||
start, end);
|
||||
}
|
||||
@ -649,7 +639,7 @@ static demuxer_t *demux_open_lavf(demuxer_t *demuxer)
|
||||
int p;
|
||||
for (p = 0; p < avfc->nb_programs; p++) {
|
||||
AVProgram *program = avfc->programs[p];
|
||||
t = av_metadata_get(program->metadata, "title", NULL, 0);
|
||||
t = av_dict_get(program->metadata, "title", NULL, 0);
|
||||
mp_msg(MSGT_HEADER, MSGL_INFO, "LAVF: Program %d %s\n",
|
||||
program->id, t ? t->value : "");
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_V, "PROGRAM_ID=%d\n", program->id);
|
||||
@ -712,28 +702,12 @@ static void check_internet_radio_hack(struct demuxer *demuxer)
|
||||
if (!priv->internet_radio_hack) {
|
||||
mp_msg(MSGT_DEMUX, MSGL_V,
|
||||
"[lavf] enabling internet ogg radio hack\n");
|
||||
#if LIBAVFORMAT_VERSION_MAJOR < 53
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[lavf] This looks like an "
|
||||
"internet radio ogg stream with track changes.\n"
|
||||
"Playback will likely fail after %d track changes "
|
||||
"due to libavformat limitations.\n"
|
||||
"You may be able to work around that limitation by "
|
||||
"using -demuxer ogg.\n", MAX_STREAMS);
|
||||
#endif
|
||||
}
|
||||
#if LIBAVFORMAT_VERSION_MAJOR < 53
|
||||
if (avfc->nb_streams == MAX_STREAMS) {
|
||||
mp_tmsg(MSGT_DEMUX, MSGL_WARN, "[lavf] This is the %dth "
|
||||
"track.\nPlayback will likely fail at the next change.\n"
|
||||
"You may be able to work around this limitation by "
|
||||
"using -demuxer ogg.\n", MAX_STREAMS);
|
||||
}
|
||||
#endif
|
||||
priv->internet_radio_hack = true;
|
||||
// use new per-track metadata as global metadata
|
||||
AVMetadataTag *t = NULL;
|
||||
AVDictionaryEntry *t = NULL;
|
||||
AVStream *stream = avfc->streams[avfc->nb_streams - 1];
|
||||
while ((t = av_metadata_get(stream->metadata, "", t,
|
||||
while ((t = av_dict_get(stream->metadata, "", t,
|
||||
AV_METADATA_IGNORE_SUFFIX)))
|
||||
demux_info_add(demuxer, t->key, t->value);
|
||||
} else {
|
||||
@ -1021,7 +995,7 @@ static void demux_close_lavf(demuxer_t *demuxer)
|
||||
if (priv) {
|
||||
if (priv->avfc) {
|
||||
av_freep(&priv->avfc->key);
|
||||
av_close_input_stream(priv->avfc);
|
||||
av_close_input_file(priv->avfc);
|
||||
}
|
||||
av_freep(&priv->pb);
|
||||
free(priv);
|
||||
|
@ -501,11 +501,9 @@ static void allocate_parser(AVCodecContext **avctx, AVCodecParserContext **parse
|
||||
enum CodecID codec_id = CODEC_ID_NONE;
|
||||
|
||||
switch (format) {
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 94, 0)
|
||||
case MKTAG('M', 'P', '4', 'L'):
|
||||
codec_id = CODEC_ID_AAC_LATM;
|
||||
break;
|
||||
#endif
|
||||
case 0x2000:
|
||||
case 0x332D6361:
|
||||
case 0x332D4341:
|
||||
@ -833,10 +831,11 @@ int ds_get_packet_sub(demux_stream_t *ds, unsigned char **start)
|
||||
return len;
|
||||
}
|
||||
|
||||
struct demux_packet *ds_get_packet2(struct demux_stream *ds)
|
||||
struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last)
|
||||
{
|
||||
// This shouldn't get used together with partial reads
|
||||
assert(ds->buffer_pos >= ds->buffer_size);
|
||||
assert(ds->buffer_pos == 0 || ds->buffer_pos >= ds->buffer_size);
|
||||
if (!repeat_last)
|
||||
ds_fill_buffer(ds);
|
||||
ds->buffer_pos = ds->buffer_size;
|
||||
return ds->current;
|
||||
|
@ -346,7 +346,7 @@ int ds_get_packet(struct demux_stream *ds, unsigned char **start);
|
||||
int ds_get_packet_pts(struct demux_stream *ds, unsigned char **start,
|
||||
double *pts);
|
||||
int ds_get_packet_sub(struct demux_stream *ds, unsigned char **start);
|
||||
struct demux_packet *ds_get_packet2(struct demux_stream *ds);
|
||||
struct demux_packet *ds_get_packet2(struct demux_stream *ds, bool repeat_last);
|
||||
double ds_get_next_pts(struct demux_stream *ds);
|
||||
int ds_parse(struct demux_stream *sh, uint8_t **buffer, int *len, double pts,
|
||||
off_t pos);
|
||||
|
@ -44,9 +44,7 @@ static const struct mp_AVCodecTag mp_wav_tags[] = {
|
||||
{ CODEC_ID_MUSEPACK7, MKTAG('M', 'P', 'C', ' ')},
|
||||
{ CODEC_ID_MUSEPACK8, MKTAG('M', 'P', 'C', '8')},
|
||||
{ CODEC_ID_NELLYMOSER, MKTAG('N', 'E', 'L', 'L')},
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 92, 0)
|
||||
{ CODEC_ID_PCM_LXF, MKTAG('P', 'L', 'X', 'F')},
|
||||
#endif
|
||||
{ CODEC_ID_QCELP, MKTAG('Q', 'c', 'l', 'p')},
|
||||
{ CODEC_ID_QDM2, MKTAG('Q', 'D', 'M', '2')},
|
||||
{ CODEC_ID_RA_144, MKTAG('1', '4', '_', '4')},
|
||||
@ -66,9 +64,7 @@ const struct mp_AVCodecTag * const mp_wav_taglists[] = {mp_ff_codec_wav_tags, mp
|
||||
|
||||
static const struct mp_AVCodecTag mp_codecid_override_tags[] = {
|
||||
{ CODEC_ID_AAC, MKTAG('M', 'P', '4', 'A')},
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 94, 0)
|
||||
{ CODEC_ID_AAC_LATM, MKTAG('M', 'P', '4', 'L')},
|
||||
#endif
|
||||
{ CODEC_ID_AC3, 0x2000},
|
||||
{ CODEC_ID_ADPCM_IMA_AMV, MKTAG('A', 'M', 'V', 'A')},
|
||||
{ CODEC_ID_BINKAUDIO_DCT, MKTAG('B', 'A', 'U', '1')},
|
||||
@ -109,9 +105,7 @@ static const struct mp_AVCodecTag mp_bmp_tags[] = {
|
||||
{ CODEC_ID_FLIC, MKTAG('F', 'L', 'I', 'C')},
|
||||
{ CODEC_ID_IDCIN, MKTAG('I', 'D', 'C', 'I')},
|
||||
{ CODEC_ID_INTERPLAY_VIDEO, MKTAG('I', 'N', 'P', 'V')},
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 114, 0)
|
||||
{ CODEC_ID_JV, MKTAG('F', 'F', 'J', 'V')},
|
||||
#endif
|
||||
{ CODEC_ID_MDEC, MKTAG('M', 'D', 'E', 'C')},
|
||||
{ CODEC_ID_MOTIONPIXELS, MKTAG('M', 'V', 'I', '1')},
|
||||
{ CODEC_ID_NUV, MKTAG('N', 'U', 'V', '1')},
|
||||
|
@ -478,8 +478,12 @@ static int win_x11_init_vdpau_procs(struct vo *vo)
|
||||
vdp_st = vdp_device_create_x11(x11->display, x11->screen, &vc->vdp_device,
|
||||
&vc->vdp_get_proc_address);
|
||||
if (vdp_st != VDP_STATUS_OK) {
|
||||
if (vc->is_preempted)
|
||||
mp_msg(MSGT_VO, MSGL_DBG2, "[vdpau] Error calling "
|
||||
"vdp_device_create_x11 while preempted: %d\n", vdp_st);
|
||||
else
|
||||
mp_msg(MSGT_VO, MSGL_ERR, "[vdpau] Error when calling "
|
||||
"vdp_device_create_x11: %i\n", vdp_st);
|
||||
"vdp_device_create_x11: %d\n", vdp_st);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1026,9 +1030,6 @@ static void draw_eosd(struct vo *vo)
|
||||
VdpOutputSurface output_surface = vc->output_surfaces[vc->surface_num];
|
||||
int i;
|
||||
|
||||
if (handle_preemption(vo) < 0)
|
||||
return;
|
||||
|
||||
VdpOutputSurfaceRenderBlendState blend_state = {
|
||||
.struct_version = VDP_OUTPUT_SURFACE_RENDER_BLEND_STATE_VERSION,
|
||||
.blend_factor_source_color =
|
||||
@ -1440,28 +1441,23 @@ static void draw_image(struct vo *vo, mp_image_t *mpi, double pts)
|
||||
struct mp_image *reserved_mpi = NULL;
|
||||
struct vdpau_render_state *rndr;
|
||||
|
||||
if (vc->is_preempted) {
|
||||
vo->frame_loaded = true;
|
||||
return;
|
||||
}
|
||||
|
||||
if (IMGFMT_IS_VDPAU(vc->image_format)) {
|
||||
rndr = mpi->priv;
|
||||
reserved_mpi = mpi;
|
||||
} else if (!(mpi->flags & MP_IMGFLAG_DRAW_CALLBACK)) {
|
||||
VdpStatus vdp_st;
|
||||
void *destdata[3] = {mpi->planes[0], mpi->planes[2], mpi->planes[1]};
|
||||
rndr = get_surface(vo, vc->deint_counter);
|
||||
vc->deint_counter = WRAP_ADD(vc->deint_counter, 1, NUM_BUFFERED_VIDEO);
|
||||
if (handle_preemption(vo) >= 0) {
|
||||
VdpStatus vdp_st;
|
||||
const void *destdata[3] = {mpi->planes[0], mpi->planes[2],
|
||||
mpi->planes[1]};
|
||||
if (vc->image_format == IMGFMT_NV12)
|
||||
destdata[1] = destdata[2];
|
||||
vdp_st =
|
||||
vdp->video_surface_put_bits_y_cb_cr(rndr->surface,
|
||||
vc->vdp_pixel_format,
|
||||
(const void *const*)destdata,
|
||||
mpi->stride); // pitch
|
||||
vdp_st = vdp->video_surface_put_bits_y_cb_cr(rndr->surface,
|
||||
vc->vdp_pixel_format, destdata, mpi->stride);
|
||||
CHECK_ST_WARNING("Error when calling "
|
||||
"vdp_video_surface_put_bits_y_cb_cr");
|
||||
}
|
||||
} else
|
||||
// We don't support slice callbacks so this shouldn't occur -
|
||||
// I think the flags test above in pointless, but I'm adding
|
||||
@ -1830,8 +1826,10 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
case VOCTRL_DRAW_EOSD:
|
||||
if (!data)
|
||||
return VO_FALSE;
|
||||
if (status_ok(vo)) {
|
||||
generate_eosd(vo, data);
|
||||
draw_eosd(vo);
|
||||
}
|
||||
return VO_TRUE;
|
||||
case VOCTRL_GET_EOSD_RES: {
|
||||
struct mp_eosd_res *r = data;
|
||||
@ -1843,18 +1841,22 @@ static int control(struct vo *vo, uint32_t request, void *data)
|
||||
}
|
||||
case VOCTRL_NEWFRAME:
|
||||
vc->deint_queue_pos = next_deint_queue_pos(vo, true);
|
||||
if (status_ok(vo))
|
||||
video_to_output_surface(vo);
|
||||
return true;
|
||||
case VOCTRL_SKIPFRAME:
|
||||
vc->deint_queue_pos = next_deint_queue_pos(vo, true);
|
||||
return true;
|
||||
case VOCTRL_REDRAW_FRAME:
|
||||
if (status_ok(vo))
|
||||
video_to_output_surface(vo);
|
||||
return true;
|
||||
case VOCTRL_RESET:
|
||||
forget_frames(vo);
|
||||
return true;
|
||||
case VOCTRL_SCREENSHOT: {
|
||||
if (!status_ok(vo))
|
||||
return false;
|
||||
struct voctrl_screenshot_args *args = data;
|
||||
if (args->full_window)
|
||||
args->out_image = get_window_screenshot(vo);
|
||||
|
@ -212,6 +212,9 @@ typedef struct MPContext {
|
||||
// step this many frames, then pause
|
||||
int step_frames;
|
||||
|
||||
bool status_printed;
|
||||
int paused_cache_fill;
|
||||
|
||||
// Set after showing warning about decoding being too slow for realtime
|
||||
// playback rate. Used to avoid showing it multiple times.
|
||||
bool drop_message_shown;
|
||||
|
122
mplayer.c
122
mplayer.c
@ -62,7 +62,6 @@
|
||||
#include "m_option.h"
|
||||
#include "m_config.h"
|
||||
#include "mplayer.h"
|
||||
#include "access_mpcontext.h"
|
||||
#include "m_property.h"
|
||||
|
||||
#include "libavutil/avstring.h"
|
||||
@ -348,36 +347,6 @@ int use_filename_title;
|
||||
|
||||
#include "metadata.h"
|
||||
|
||||
void *mpctx_get_video_out(MPContext *mpctx)
|
||||
{
|
||||
return mpctx->video_out;
|
||||
}
|
||||
|
||||
void *mpctx_get_demuxer(MPContext *mpctx)
|
||||
{
|
||||
return mpctx->demuxer;
|
||||
}
|
||||
|
||||
void *mpctx_get_playtree_iter(MPContext *mpctx)
|
||||
{
|
||||
return mpctx->playtree_iter;
|
||||
}
|
||||
|
||||
void *mpctx_get_mixer(MPContext *mpctx)
|
||||
{
|
||||
return &mpctx->mixer;
|
||||
}
|
||||
|
||||
int mpctx_get_global_sub_size(MPContext *mpctx)
|
||||
{
|
||||
return mpctx->global_sub_size;
|
||||
}
|
||||
|
||||
int mpctx_get_osd_function(MPContext *mpctx)
|
||||
{
|
||||
return mpctx->osd_function;
|
||||
}
|
||||
|
||||
static float get_relative_time(struct MPContext *mpctx)
|
||||
{
|
||||
unsigned int new_time = GetTimer();
|
||||
@ -1367,6 +1336,8 @@ static void print_status(struct MPContext *mpctx, double a_pos, bool at_frame)
|
||||
mp_msg(MSGT_STATUSLINE, MSGL_STATUS, "%s\r", line);
|
||||
}
|
||||
free(line);
|
||||
|
||||
mpctx->status_printed = true;
|
||||
}
|
||||
|
||||
struct stream_dump_progress {
|
||||
@ -2936,7 +2907,7 @@ static double update_video(struct MPContext *mpctx)
|
||||
int in_size = 0;
|
||||
unsigned char *buf = NULL;
|
||||
pts = MP_NOPTS_VALUE;
|
||||
struct demux_packet *pkt = ds_get_packet2(mpctx->d_video);
|
||||
struct demux_packet *pkt = ds_get_packet2(mpctx->d_video, false);
|
||||
if (pkt) {
|
||||
in_size = pkt->len;
|
||||
buf = pkt->buffer;
|
||||
@ -3004,6 +2975,48 @@ static double update_video(struct MPContext *mpctx)
|
||||
return frame_time;
|
||||
}
|
||||
|
||||
static int get_cache_fill(struct MPContext *mpctx)
|
||||
{
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
if (stream_cache_size > 0)
|
||||
return cache_fill_status(mpctx->stream);
|
||||
#endif
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void update_pause_message(struct MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
|
||||
if (opts->quiet)
|
||||
return;
|
||||
|
||||
int cache_fill = get_cache_fill(mpctx);
|
||||
bool cache_changed = cache_fill != mpctx->paused_cache_fill;
|
||||
|
||||
if (!mpctx->status_printed && !cache_changed)
|
||||
return;
|
||||
|
||||
char *msg = mp_gtext(" ===== PAUSE =====");
|
||||
char *tmpmem = NULL;
|
||||
if (cache_fill >= 0)
|
||||
msg = tmpmem = talloc_asprintf(NULL, "%s %d%%", msg, cache_fill);
|
||||
|
||||
if (opts->term_osd && !mpctx->sh_video) {
|
||||
set_osd_msg(OSD_MSG_PAUSE, 1, 0, "%s", msg);
|
||||
update_osd_msg(mpctx);
|
||||
} else {
|
||||
if (mpctx->status_printed)
|
||||
mp_msg(MSGT_CPLAYER, MSGL_STATUS, "\n");
|
||||
mp_msg(MSGT_CPLAYER, MSGL_STATUS, "%s\r", msg);
|
||||
}
|
||||
|
||||
mpctx->paused_cache_fill = cache_fill;
|
||||
mpctx->status_printed = false;
|
||||
|
||||
talloc_free(tmpmem);
|
||||
}
|
||||
|
||||
void pause_player(struct MPContext *mpctx)
|
||||
{
|
||||
if (mpctx->paused)
|
||||
@ -3011,12 +3024,20 @@ void pause_player(struct MPContext *mpctx)
|
||||
mpctx->paused = 1;
|
||||
mpctx->step_frames = 0;
|
||||
mpctx->time_frame -= get_relative_time(mpctx);
|
||||
mpctx->osd_function = OSD_PAUSE;
|
||||
|
||||
if (mpctx->video_out && mpctx->sh_video && mpctx->video_out->config_ok)
|
||||
vo_control(mpctx->video_out, VOCTRL_PAUSE, NULL);
|
||||
|
||||
if (mpctx->ao && mpctx->sh_audio)
|
||||
ao_pause(mpctx->ao); // pause audio, keep data if possible
|
||||
|
||||
mpctx->paused_cache_fill = get_cache_fill(mpctx);
|
||||
mpctx->status_printed = true;
|
||||
update_pause_message(mpctx);
|
||||
|
||||
if (!mpctx->opts.quiet)
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_PAUSED\n");
|
||||
}
|
||||
|
||||
void unpause_player(struct MPContext *mpctx)
|
||||
@ -3024,6 +3045,8 @@ void unpause_player(struct MPContext *mpctx)
|
||||
if (!mpctx->paused)
|
||||
return;
|
||||
mpctx->paused = 0;
|
||||
if (!mpctx->step_frames)
|
||||
mpctx->osd_function = OSD_PLAY;
|
||||
|
||||
if (mpctx->ao && mpctx->sh_audio)
|
||||
ao_resume(mpctx->ao);
|
||||
@ -3059,21 +3082,9 @@ void add_step_frame(struct MPContext *mpctx)
|
||||
|
||||
static void pause_loop(struct MPContext *mpctx)
|
||||
{
|
||||
struct MPOpts *opts = &mpctx->opts;
|
||||
mp_cmd_t *cmd;
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
int old_cache_fill = stream_cache_size > 0 ?
|
||||
cache_fill_status(mpctx->stream) : 0;
|
||||
#endif
|
||||
if (!opts->quiet) {
|
||||
if (opts->term_osd && !mpctx->sh_video) {
|
||||
set_osd_tmsg(OSD_MSG_PAUSE, 1, 0, " ===== PAUSE =====");
|
||||
update_osd_msg(mpctx);
|
||||
} else
|
||||
mp_msg(MSGT_CPLAYER, MSGL_STATUS, "\n%s\r",
|
||||
mp_gtext(" ===== PAUSE ====="));
|
||||
mp_msg(MSGT_IDENTIFY, MSGL_INFO, "ID_PAUSED\n");
|
||||
}
|
||||
|
||||
update_pause_message(mpctx);
|
||||
|
||||
while ((cmd = mp_input_get_cmd(mpctx->input, 20, 1)) == NULL
|
||||
|| cmd->id == MP_CMD_SET_MOUSE_POS || cmd->pausing == 4) {
|
||||
@ -3090,23 +3101,7 @@ static void pause_loop(struct MPContext *mpctx)
|
||||
vo_osd_changed(hack);
|
||||
if (hack || mpctx->sh_video && mpctx->video_out->want_redraw)
|
||||
break;
|
||||
#ifdef CONFIG_STREAM_CACHE
|
||||
if (!opts->quiet && stream_cache_size > 0) {
|
||||
int new_cache_fill = cache_fill_status(mpctx->stream);
|
||||
if (new_cache_fill != old_cache_fill) {
|
||||
if (opts->term_osd && !mpctx->sh_video) {
|
||||
set_osd_tmsg(OSD_MSG_PAUSE, 1, 0, "%s %d%%",
|
||||
mp_gtext(" ===== PAUSE ====="),
|
||||
new_cache_fill);
|
||||
update_osd_msg(mpctx);
|
||||
} else
|
||||
mp_msg(MSGT_CPLAYER, MSGL_STATUS, "%s %d%%\r",
|
||||
mp_gtext(" ===== PAUSE ====="),
|
||||
new_cache_fill);
|
||||
old_cache_fill = new_cache_fill;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
update_pause_message(mpctx);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3991,6 +3986,7 @@ int main(int argc, char *argv[])
|
||||
.set_of_sub_pos = -1,
|
||||
.file_format = DEMUXER_TYPE_UNKNOWN,
|
||||
.last_dvb_step = 1,
|
||||
.paused_cache_fill = -1,
|
||||
};
|
||||
|
||||
InitTimer();
|
||||
|
@ -44,9 +44,6 @@
|
||||
#include "libavutil/base64.h"
|
||||
|
||||
#include <libavutil/avutil.h>
|
||||
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(50, 17, 0)
|
||||
#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
|
||||
#endif
|
||||
|
||||
extern int stream_cache_size;
|
||||
extern int network_bandwidth;
|
||||
|
@ -42,9 +42,6 @@
|
||||
#include "libavutil/base64.h"
|
||||
|
||||
#include <libavutil/avutil.h>
|
||||
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(50, 17, 0)
|
||||
#define AV_BASE64_SIZE(x) (((x)+2) / 3 * 4 + 1)
|
||||
#endif
|
||||
|
||||
#include "stream/http.h"
|
||||
#include "mp_msg.h"
|
||||
|
@ -28,21 +28,26 @@
|
||||
|
||||
static int fill_buffer(stream_t *s, char *buffer, int max_len)
|
||||
{
|
||||
int r = url_read_complete(s->priv, buffer, max_len);
|
||||
AVIOContext *avio = s->priv;
|
||||
int r = avio_read(avio, buffer, max_len);
|
||||
return (r <= 0) ? -1 : r;
|
||||
}
|
||||
|
||||
static int write_buffer(stream_t *s, char *buffer, int len)
|
||||
{
|
||||
/* url_write retries internally on short writes and EAGAIN */
|
||||
int r = url_write(s->priv, buffer, len);
|
||||
return (r <= 0) ? -1 : r;
|
||||
AVIOContext *avio = s->priv;
|
||||
avio_write(avio, buffer, len);
|
||||
avio_flush(avio);
|
||||
if (avio->error)
|
||||
return -1;
|
||||
return len;
|
||||
}
|
||||
|
||||
static int seek(stream_t *s, off_t newpos)
|
||||
{
|
||||
AVIOContext *avio = s->priv;
|
||||
s->pos = newpos;
|
||||
if (url_seek(s->priv, s->pos, SEEK_SET) < 0) {
|
||||
if (avio_seek(avio, s->pos, SEEK_SET) < 0) {
|
||||
s->eof = 1;
|
||||
return 0;
|
||||
}
|
||||
@ -51,11 +56,12 @@ static int seek(stream_t *s, off_t newpos)
|
||||
|
||||
static int control(stream_t *s, int cmd, void *arg)
|
||||
{
|
||||
AVIOContext *avio = avio;
|
||||
int64_t size, ts;
|
||||
double pts;
|
||||
switch(cmd) {
|
||||
case STREAM_CTRL_GET_SIZE:
|
||||
size = url_filesize(s->priv);
|
||||
size = avio_size(avio);
|
||||
if(size >= 0) {
|
||||
*(off_t *)arg = size;
|
||||
return 1;
|
||||
@ -64,7 +70,7 @@ static int control(stream_t *s, int cmd, void *arg)
|
||||
case STREAM_CTRL_SEEK_TO_TIME:
|
||||
pts = *(double *)arg;
|
||||
ts = pts * AV_TIME_BASE;
|
||||
ts = av_url_read_seek(s->priv, -1, ts, 0);
|
||||
ts = avio_seek_time(avio, -1, ts, 0);
|
||||
if (ts >= 0)
|
||||
return 1;
|
||||
break;
|
||||
@ -74,7 +80,13 @@ static int control(stream_t *s, int cmd, void *arg)
|
||||
|
||||
static void close_f(stream_t *stream)
|
||||
{
|
||||
url_close(stream->priv);
|
||||
AVIOContext *avio = stream->priv;
|
||||
/* NOTE: As of 2011 write streams must be manually flushed before close.
|
||||
* Currently write_buffer() always flushes them after writing.
|
||||
* avio_close() could return an error, but we have no way to return that
|
||||
* with the current stream API.
|
||||
*/
|
||||
avio_close(avio);
|
||||
}
|
||||
|
||||
static const char prefix[] = "ffmpeg://";
|
||||
@ -83,7 +95,7 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
|
||||
{
|
||||
int flags = 0;
|
||||
const char *filename;
|
||||
URLContext *ctx = NULL;
|
||||
AVIOContext *avio = NULL;
|
||||
int res = STREAM_ERROR;
|
||||
int64_t size;
|
||||
int dummy;
|
||||
@ -109,22 +121,22 @@ static int open_f(stream_t *stream, int mode, void *opts, int *file_format)
|
||||
dummy = !strncmp(filename, "rtsp:", 5);
|
||||
mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] Opening %s\n", filename);
|
||||
|
||||
if (!dummy && url_open(&ctx, filename, flags) < 0)
|
||||
if (!dummy && avio_open(&avio, filename, flags) < 0)
|
||||
goto out;
|
||||
|
||||
mp_msg(MSGT_OPEN, MSGL_V, "[ffmpeg] libavformat URL type: %s\n",
|
||||
ctx->prot->name);
|
||||
if (!strncmp("rtmp", ctx->prot->name, 4)) {
|
||||
char *rtmp[] = {"rtmp:", "rtmpt:", "rtmpe:", "rtmpte:", "rtmps:"};
|
||||
for (int i = 0; i < FF_ARRAY_ELEMS(rtmp); i++)
|
||||
if (!strncmp(filename, rtmp[i], strlen(rtmp[i]))) {
|
||||
*file_format = DEMUXER_TYPE_LAVF;
|
||||
stream->lavf_type = "flv";
|
||||
}
|
||||
stream->priv = ctx;
|
||||
size = dummy ? 0 : url_filesize(ctx);
|
||||
stream->priv = avio;
|
||||
size = dummy ? 0 : avio_size(avio);
|
||||
if (size >= 0)
|
||||
stream->end_pos = size;
|
||||
stream->type = STREAMTYPE_FILE;
|
||||
stream->seek = seek;
|
||||
if (dummy || ctx->is_streamed) {
|
||||
if (dummy || !avio->seekable) {
|
||||
stream->type = STREAMTYPE_STREAM;
|
||||
stream->seek = NULL;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@
|
||||
#endif
|
||||
#include <errno.h>
|
||||
|
||||
#include "talloc.h"
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__DragonFly__) || defined(__NetBSD__) || defined(__OpenBSD__)
|
||||
#include "vcd_read_fbsd.h"
|
||||
#elif defined(__APPLE__)
|
||||
@ -157,9 +159,9 @@ static int open_s(stream_t *stream,int mode, void* opts, int* file_format) {
|
||||
|
||||
if (!p->device) {
|
||||
if(cdrom_device)
|
||||
p->device = strdup(cdrom_device);
|
||||
p->device = talloc_strdup(NULL, cdrom_device);
|
||||
else
|
||||
p->device = strdup(DEFAULT_CDROM_DEVICE);
|
||||
p->device = talloc_strdup(NULL, DEFAULT_CDROM_DEVICE);
|
||||
}
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
|
@ -110,9 +110,7 @@ int decode_avsub(struct sh_sub *sh, uint8_t *data, int size,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 82, 0)
|
||||
if (got_sub)
|
||||
avsubtitle_free(&sub);
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user