sub: add sd_spu.c to wrap spudec, cleanup mplayer.c
This unifies the subtitle rendering path. Now all subtitle rendering
goes through sd_ass.c/sd_lavc.c/sd_spu.c.
Before that commit, the spudec.h functions were used directly in
mplayer.c, which introduced many special cases. Add sd_spu.c, which is
just a small wrapper connecting the new subtitle render API with the
dusty old vobsub decoder in spudec.c.
One detail that changes is that we always pass the palette as extra
data, instead of passing the libdvdread palette as pointer to spudec
directly. This is a bit roundabout, but actually makes the code simpler
and more elegant: the difference between DVD and non-DVD dvdsubs is
reduced.
Ideally, we would just delete spudec.c and use libavcodec's DVD sub
decoder. However, DVD playback with demux_mpg produces packets
incompatible to lavc. There are incompatibilities the other way around
as well: packets from libavformat's vobsub demuxer are incompatible to
spudec.c. So we define a new subtitle codec name for demux_mpg subs,
"dvd_subtitle_mpg", which only sd_spu can decode.
There is actually code in spudec.c to "assemble" fragments into complete
packets, but using the whole spudec.c is easier than trying to move this
code into demux_mpg to fix subtitle packets.
As additional complication, Libav 9.x can't decode DVD subs correctly,
so use sd_spu in that case as well.
2013-04-28 23:13:22 +00:00
|
|
|
/*
|
|
|
|
* 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 <stdlib.h>
|
|
|
|
#include <assert.h>
|
|
|
|
|
|
|
|
#include "talloc.h"
|
|
|
|
#include "core/options.h"
|
|
|
|
#include "demux/stheader.h"
|
|
|
|
#include "sd.h"
|
|
|
|
#include "sub.h"
|
|
|
|
#include "spudec.h"
|
|
|
|
|
|
|
|
struct sd_spu_priv {
|
|
|
|
void *spudec;
|
|
|
|
};
|
|
|
|
|
2013-06-01 17:40:09 +00:00
|
|
|
static bool is_dvd_sub(const char *t)
|
|
|
|
{
|
|
|
|
return t && (strcmp(t, "dvd_subtitle") == 0 ||
|
|
|
|
strcmp(t, "dvd_subtitle_mpg") == 0);
|
|
|
|
}
|
|
|
|
|
sub: add sd_spu.c to wrap spudec, cleanup mplayer.c
This unifies the subtitle rendering path. Now all subtitle rendering
goes through sd_ass.c/sd_lavc.c/sd_spu.c.
Before that commit, the spudec.h functions were used directly in
mplayer.c, which introduced many special cases. Add sd_spu.c, which is
just a small wrapper connecting the new subtitle render API with the
dusty old vobsub decoder in spudec.c.
One detail that changes is that we always pass the palette as extra
data, instead of passing the libdvdread palette as pointer to spudec
directly. This is a bit roundabout, but actually makes the code simpler
and more elegant: the difference between DVD and non-DVD dvdsubs is
reduced.
Ideally, we would just delete spudec.c and use libavcodec's DVD sub
decoder. However, DVD playback with demux_mpg produces packets
incompatible to lavc. There are incompatibilities the other way around
as well: packets from libavformat's vobsub demuxer are incompatible to
spudec.c. So we define a new subtitle codec name for demux_mpg subs,
"dvd_subtitle_mpg", which only sd_spu can decode.
There is actually code in spudec.c to "assemble" fragments into complete
packets, but using the whole spudec.c is easier than trying to move this
code into demux_mpg to fix subtitle packets.
As additional complication, Libav 9.x can't decode DVD subs correctly,
so use sd_spu in that case as well.
2013-04-28 23:13:22 +00:00
|
|
|
static bool supports_format(const char *format)
|
|
|
|
{
|
|
|
|
return is_dvd_sub(format);
|
|
|
|
}
|
|
|
|
|
|
|
|
static int init(struct sh_sub *sh, struct osd_state *osd)
|
|
|
|
{
|
|
|
|
if (sh->initialized)
|
|
|
|
return 0;
|
|
|
|
void *spudec = spudec_new_scaled(osd->sub_video_w, osd->sub_video_h,
|
|
|
|
sh->extradata, sh->extradata_len);
|
|
|
|
if (!spudec)
|
|
|
|
return -1;
|
|
|
|
struct sd_spu_priv *priv = talloc_zero(NULL, struct sd_spu_priv);
|
|
|
|
priv->spudec = spudec;
|
|
|
|
sh->context = priv;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void decode(struct sh_sub *sh, struct osd_state *osd, void *data,
|
|
|
|
int data_len, double pts, double duration)
|
|
|
|
{
|
|
|
|
struct sd_spu_priv *priv = sh->context;
|
|
|
|
|
|
|
|
if (pts < 0 || data_len == 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
spudec_assemble(priv->spudec, data, data_len, pts * 90000);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void get_bitmaps(struct sh_sub *sh, struct osd_state *osd,
|
|
|
|
struct mp_osd_res d, double pts,
|
|
|
|
struct sub_bitmaps *res)
|
|
|
|
{
|
|
|
|
struct MPOpts *opts = sh->opts;
|
|
|
|
struct sd_spu_priv *priv = sh->context;
|
|
|
|
|
|
|
|
spudec_set_forced_subs_only(priv->spudec, opts->forced_subs_only);
|
|
|
|
spudec_heartbeat(priv->spudec, pts * 90000);
|
|
|
|
|
|
|
|
if (spudec_visible(priv->spudec))
|
|
|
|
spudec_get_indexed(priv->spudec, &d, res);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void reset(struct sh_sub *sh, struct osd_state *osd)
|
|
|
|
{
|
|
|
|
struct sd_spu_priv *priv = sh->context;
|
|
|
|
|
|
|
|
spudec_reset(priv->spudec);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void uninit(struct sh_sub *sh)
|
|
|
|
{
|
|
|
|
struct sd_spu_priv *priv = sh->context;
|
|
|
|
|
|
|
|
spudec_free(priv->spudec);
|
|
|
|
talloc_free(priv);
|
|
|
|
}
|
|
|
|
|
|
|
|
const struct sd_functions sd_spu = {
|
|
|
|
.supports_format = supports_format,
|
|
|
|
.init = init,
|
|
|
|
.decode = decode,
|
|
|
|
.get_bitmaps = get_bitmaps,
|
|
|
|
.reset = reset,
|
|
|
|
.switch_off = reset,
|
|
|
|
.uninit = uninit,
|
|
|
|
};
|