diff options
author | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2011-01-26 19:40:52 +0200 |
---|---|---|
committer | Uoti Urpala <uau@glyph.nonexistent.invalid> | 2011-01-26 20:39:05 +0200 |
commit | c9026cb3210205b07e2e068467a18ee40f9259a3 (patch) | |
tree | ea9657ad306899c6fbedae4abd088e9ac44fa61f /sub/av_sub.c | |
parent | ebd2058d033416274f2e4b40f5ad907d86f8aad5 (diff) | |
download | mpv-c9026cb3210205b07e2e068467a18ee40f9259a3.tar.bz2 mpv-c9026cb3210205b07e2e068467a18ee40f9259a3.tar.xz |
sub/OSD: move some related files to sub/
Diffstat (limited to 'sub/av_sub.c')
-rw-r--r-- | sub/av_sub.c | 119 |
1 files changed, 119 insertions, 0 deletions
diff --git a/sub/av_sub.c b/sub/av_sub.c new file mode 100644 index 0000000000..a68fbce083 --- /dev/null +++ b/sub/av_sub.c @@ -0,0 +1,119 @@ +/* + * 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. + */ + +#include <libavcodec/avcodec.h> + +#include "libmpdemux/stheader.h" +#include "sub.h" +#include "spudec.h" +#include "av_sub.h" + +void reset_avsub(struct sh_sub *sh) +{ + if (sh->context) { + avcodec_close(sh->context); + av_freep(&sh->context); + } +} + +/** + * Decode a subtitle packet via libavcodec. + * \return < 0 on error, > 0 if further processing is needed + */ +int decode_avsub(struct sh_sub *sh, uint8_t *data, int size, + double pts, double duration) +{ + AVCodecContext *ctx = sh->context; + enum CodecID cid = CODEC_ID_NONE; + int res; + int got_sub; + AVSubtitle sub; + AVPacket pkt; + + switch (sh->type) { + case 'b': + cid = CODEC_ID_DVB_SUBTITLE; break; + case 'p': + cid = CODEC_ID_HDMV_PGS_SUBTITLE; break; + case 'x': + cid = CODEC_ID_XSUB; break; + } + + av_init_packet(&pkt); + pkt.data = data; + pkt.size = size; + pkt.pts = pts * 1000; + if (duration >= 0) + pkt.convergence_duration = duration * 1000; + if (!ctx) { + AVCodec *sub_codec; + avcodec_init(); + avcodec_register_all(); + ctx = avcodec_alloc_context(); + sub_codec = avcodec_find_decoder(cid); + if (!ctx || !sub_codec || avcodec_open(ctx, sub_codec) < 0) { + mp_msg(MSGT_SUBREADER, MSGL_FATAL, + "Could not open subtitle decoder\n"); + av_freep(&ctx); + return -1; + } + sh->context = ctx; + } + res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt); + if (res < 0) + return res; + if (pts != MP_NOPTS_VALUE) { + if (sub.end_display_time > sub.start_display_time) + duration = (sub.end_display_time - sub.start_display_time) / 1000.0; + pts += sub.start_display_time / 1000.0; + } + double endpts = MP_NOPTS_VALUE; + if (pts != MP_NOPTS_VALUE && duration >= 0) + endpts = pts + duration; + if (got_sub && vo_spudec && sub.num_rects == 0) + spudec_set_paletted(vo_spudec, NULL, 0, NULL, 0, 0, 0, 0, pts, endpts); + if (got_sub && sub.num_rects > 0) { + switch (sub.rects[0]->type) { + case SUBTITLE_BITMAP: + if (!vo_spudec) + vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0); + spudec_set_paletted(vo_spudec, + sub.rects[0]->pict.data[0], + sub.rects[0]->pict.linesize[0], + sub.rects[0]->pict.data[1], + sub.rects[0]->x, + sub.rects[0]->y, + sub.rects[0]->w, + sub.rects[0]->h, + pts, + endpts); + vo_osd_changed(OSDTYPE_SPU); + break; + default: + mp_msg(MSGT_SUBREADER, MSGL_ERR, "sd_avsub: unsupported subtitle " + "type from libavcodec\n"); + res = -1; + break; + } + } +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 82, 0) + if (got_sub) + avsubtitle_free(&sub); +#endif + return res; +} |