1
0
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:
wm4 2012-01-18 04:18:41 +01:00
commit f341b21a90
24 changed files with 205 additions and 303 deletions

View File

@ -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 \

View File

@ -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 */

View File

@ -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
View File

@ -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

View File

@ -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 },

View File

@ -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;
}

View File

@ -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;

View File

@ -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

View File

@ -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,

View File

@ -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;

View File

@ -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,

View File

@ -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

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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')},

View File

@ -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);

View File

@ -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
View File

@ -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();

View File

@ -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;

View File

@ -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"

View File

@ -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;
}

View File

@ -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__)

View File

@ -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;
}