Mercurial > mplayer.hg
annotate av_sub.c @ 32282:606e4157cd4c
Split alloc and init of context so that parameters can be set in the context
instead of requireing being passed through function parameters. This also
makes sws work with AVOptions.
author | michael |
---|---|
date | Sun, 26 Sep 2010 19:33:57 +0000 |
parents | 8c29dfec15c2 |
children | 728bd5c2aea7 |
rev | line source |
---|---|
31599 | 1 /* |
2 * This file is part of MPlayer. | |
3 * | |
4 * MPlayer is free software; you can redistribute it and/or modify | |
5 * it under the terms of the GNU General Public License as published by | |
6 * the Free Software Foundation; either version 2 of the License, or | |
7 * (at your option) any later version. | |
8 * | |
9 * MPlayer is distributed in the hope that it will be useful, | |
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 * GNU General Public License for more details. | |
13 * | |
14 * You should have received a copy of the GNU General Public License along | |
15 * with MPlayer; if not, write to the Free Software Foundation, Inc., | |
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. | |
17 */ | |
18 | |
19 #include "libavcodec/avcodec.h" | |
20 #include "libmpdemux/stheader.h" | |
21 #include "libvo/sub.h" | |
22 #include "spudec.h" | |
23 #include "av_sub.h" | |
24 | |
25 void reset_avsub(struct sh_sub *sh) | |
26 { | |
27 if (sh->context) { | |
28 avcodec_close(sh->context); | |
29 av_freep(&sh->context); | |
30 } | |
31 } | |
32 | |
33 /** | |
34 * Decode a subtitle packet via libavcodec. | |
35 * \return < 0 on error, > 0 if further processing is needed | |
36 */ | |
32080 | 37 int decode_avsub(struct sh_sub *sh, uint8_t **data, int *size, |
38 double *pts, double *endpts) | |
31599 | 39 { |
40 AVCodecContext *ctx = sh->context; | |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
41 enum CodecID cid = CODEC_ID_NONE; |
31599 | 42 int new_type = 0; |
43 int res; | |
44 int got_sub; | |
45 AVSubtitle sub; | |
46 AVPacket pkt; | |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
47 |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
48 switch (sh->type) { |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
49 case 'b': |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
50 cid = CODEC_ID_DVB_SUBTITLE; break; |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
51 case 'p': |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
52 cid = CODEC_ID_HDMV_PGS_SUBTITLE; break; |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
53 case 'x': |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
54 cid = CODEC_ID_XSUB; break; |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
55 } |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
56 |
31599 | 57 av_init_packet(&pkt); |
58 pkt.data = *data; | |
59 pkt.size = *size; | |
60 pkt.pts = *pts * 1000; | |
61 if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE) | |
62 pkt.convergence_duration = (*endpts - *pts) * 1000; | |
63 if (!ctx) { | |
64 AVCodec *sub_codec; | |
65 avcodec_init(); | |
66 avcodec_register_all(); | |
67 ctx = avcodec_alloc_context(); | |
31628
f15df2e3081b
Add support for DVB and XSUB subtitles, not yet working properly.
reimar
parents:
31624
diff
changeset
|
68 sub_codec = avcodec_find_decoder(cid); |
31599 | 69 if (!ctx || !sub_codec || avcodec_open(ctx, sub_codec) < 0) { |
32080 | 70 mp_msg(MSGT_SUBREADER, MSGL_FATAL, |
71 "Could not open subtitle decoder\n"); | |
31599 | 72 av_freep(&ctx); |
73 return -1; | |
74 } | |
75 sh->context = ctx; | |
76 } | |
77 res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt); | |
78 if (res < 0) | |
79 return res; | |
80 if (*pts != MP_NOPTS_VALUE) { | |
81 if (sub.end_display_time > sub.start_display_time) | |
82 *endpts = *pts + sub.end_display_time / 1000.0; | |
83 *pts += sub.start_display_time / 1000.0; | |
84 } | |
85 if (got_sub && sub.num_rects > 0) { | |
86 switch (sub.rects[0]->type) { | |
87 case SUBTITLE_BITMAP: | |
88 if (!vo_spudec) | |
31924
8d7f15885b64
Pass the video dimensions specified in the subtitle to spudec.
reimar
parents:
31642
diff
changeset
|
89 vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0); |
31599 | 90 spudec_set_paletted(vo_spudec, |
91 sub.rects[0]->pict.data[0], | |
92 sub.rects[0]->pict.linesize[0], | |
93 sub.rects[0]->pict.data[1], | |
94 sub.rects[0]->x, | |
95 sub.rects[0]->y, | |
96 sub.rects[0]->w, | |
97 sub.rects[0]->h, | |
98 *pts, | |
99 *endpts); | |
100 vo_osd_changed(OSDTYPE_SPU); | |
101 break; | |
102 case SUBTITLE_TEXT: | |
103 *data = strdup(sub.rects[0]->text); | |
31642 | 104 *size = strlen(*data); |
31599 | 105 new_type = 't'; |
106 break; | |
107 case SUBTITLE_ASS: | |
108 *data = strdup(sub.rects[0]->ass); | |
31642 | 109 *size = strlen(*data); |
31599 | 110 new_type = 'a'; |
111 break; | |
112 } | |
113 } | |
114 if (got_sub) | |
31624
40c30c70ead0
Fix memory leak for subtitles decoded by libavcodec.
reimar
parents:
31599
diff
changeset
|
115 avsubtitle_free(&sub); |
31599 | 116 return new_type; |
117 } |