summaryrefslogtreecommitdiffstats
path: root/av_sub.c
diff options
context:
space:
mode:
authorreimar <reimar@b3059339-0415-0410-9bf9-f77b7e298cf2>2010-07-10 13:45:09 +0000
committerUoti Urpala <uau@glyph.nonexistent.invalid>2010-11-02 04:14:43 +0200
commit96c17fe68b12104269f70b113d757fbc67b5ed1f (patch)
treeb63db7e8a5b4d090210e621ab5ad948eaf12e788 /av_sub.c
parentd6322407c503bbca1f1bb48e06e275f7b610a3a8 (diff)
downloadmpv-96c17fe68b12104269f70b113d757fbc67b5ed1f.tar.bz2
mpv-96c17fe68b12104269f70b113d757fbc67b5ed1f.tar.xz
subs: Add support for PGS subtitle decoding via libavcodec
git-svn-id: svn://svn.mplayerhq.hu/mplayer/trunk@31665 b3059339-0415-0410-9bf9-f77b7e298cf2
Diffstat (limited to 'av_sub.c')
-rw-r--r--av_sub.c103
1 files changed, 103 insertions, 0 deletions
diff --git a/av_sub.c b/av_sub.c
new file mode 100644
index 0000000000..eba46fa6d8
--- /dev/null
+++ b/av_sub.c
@@ -0,0 +1,103 @@
+/*
+ * 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 "libvo/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 *endpts)
+{
+ AVCodecContext *ctx = sh->context;
+ int new_type = 0;
+ int res;
+ int got_sub;
+ AVSubtitle sub;
+ AVPacket pkt;
+ av_init_packet(&pkt);
+ pkt.data = *data;
+ pkt.size = *size;
+ pkt.pts = *pts * 1000;
+ if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE)
+ pkt.convergence_duration = (*endpts - *pts) * 1000;
+ if (!ctx) {
+ AVCodec *sub_codec;
+ avcodec_init();
+ avcodec_register_all();
+ ctx = avcodec_alloc_context();
+ sub_codec = avcodec_find_decoder(CODEC_ID_HDMV_PGS_SUBTITLE);
+ 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)
+ *endpts = *pts + sub.end_display_time / 1000.0;
+ *pts += sub.start_display_time / 1000.0;
+ }
+ if (got_sub && sub.num_rects > 0) {
+ switch (sub.rects[0]->type) {
+ case SUBTITLE_BITMAP:
+ if (!vo_spudec)
+ vo_spudec = spudec_new(NULL);
+ 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;
+ case SUBTITLE_TEXT:
+ *data = strdup(sub.rects[0]->text);
+ new_type = 't';
+ break;
+ case SUBTITLE_ASS:
+ *data = strdup(sub.rects[0]->ass);
+ new_type = 'a';
+ break;
+ }
+ }
+ if (got_sub)
+ ; // TODO: free sub once there is a free function...
+ return new_type;
+}