Mercurial > mplayer.hg
annotate sub/av_sub.c @ 36154:319cbb4d0967
Check return value to avoid segmentation fault.
author | ib |
---|---|
date | Wed, 08 May 2013 12:37:28 +0000 |
parents | 9b88b87f5921 |
children | 6d654ac9201e |
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" | |
34174
a93891202051
Add missing mp_msg.h #includes, remove some unnecessary ones.
diego
parents:
32564
diff
changeset
|
21 #include "mp_msg.h" |
32467 | 22 #include "sub.h" |
32464
22888a8cb312
Do not use a path for including files in the same directory.
reimar
parents:
32457
diff
changeset
|
23 #include "spudec.h" |
34528 | 24 #include "av_helpers.h" |
32464
22888a8cb312
Do not use a path for including files in the same directory.
reimar
parents:
32457
diff
changeset
|
25 #include "av_sub.h" |
31599 | 26 |
27 void reset_avsub(struct sh_sub *sh) | |
28 { | |
29 if (sh->context) { | |
35030 | 30 AVCodecContext *ctx = sh->context; |
31 ctx->extradata = NULL; | |
32 ctx->extradata_size = 0; | |
31599 | 33 avcodec_close(sh->context); |
34 av_freep(&sh->context); | |
35 } | |
36 } | |
37 | |
34784 | 38 static void avsub_to_spudec(AVSubtitleRect **rects, int num_rects, |
39 double pts, double endpts) | |
40 { | |
41 int i, xmin = INT_MAX, ymin = INT_MAX, xmax = INT_MIN, ymax = INT_MIN; | |
42 struct spu_packet_t *packet; | |
43 | |
44 if (num_rects == 1) { | |
45 spudec_set_paletted(vo_spudec, | |
46 rects[0]->pict.data[0], | |
47 rects[0]->pict.linesize[0], | |
48 rects[0]->pict.data[1], | |
49 rects[0]->x, | |
50 rects[0]->y, | |
51 rects[0]->w, | |
52 rects[0]->h, | |
53 pts, | |
54 endpts); | |
55 return; | |
56 } | |
57 for (i = 0; i < num_rects; i++) { | |
58 xmin = FFMIN(xmin, rects[i]->x); | |
59 ymin = FFMIN(ymin, rects[i]->y); | |
60 xmax = FFMAX(xmax, rects[i]->x + rects[i]->w); | |
61 ymax = FFMAX(ymax, rects[i]->y + rects[i]->h); | |
62 } | |
63 packet = spudec_packet_create(xmin, ymin, xmax - xmin, ymax - ymin); | |
64 if (!packet) | |
65 return; | |
66 spudec_packet_clear(packet); | |
67 for (i = 0; i < num_rects; i++) | |
68 spudec_packet_fill(packet, | |
69 rects[i]->pict.data[0], | |
70 rects[i]->pict.linesize[0], | |
71 rects[i]->pict.data[1], | |
72 rects[i]->x - xmin, | |
73 rects[i]->y - ymin, | |
74 rects[i]->w, | |
75 rects[i]->h); | |
76 spudec_packet_send(vo_spudec, packet, pts, endpts); | |
77 } | |
78 | |
31599 | 79 /** |
80 * Decode a subtitle packet via libavcodec. | |
81 * \return < 0 on error, > 0 if further processing is needed | |
82 */ | |
32080 | 83 int decode_avsub(struct sh_sub *sh, uint8_t **data, int *size, |
84 double *pts, double *endpts) | |
31599 | 85 { |
86 AVCodecContext *ctx = sh->context; | |
35864 | 87 enum AVCodecID cid = AV_CODEC_ID_NONE; |
31599 | 88 int new_type = 0; |
89 int res; | |
90 int got_sub; | |
91 AVSubtitle sub; | |
92 AVPacket pkt; | |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
93 |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
94 switch (sh->type) { |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
95 case 'b': |
35715
8517826b0dbd
Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents:
35199
diff
changeset
|
96 cid = AV_CODEC_ID_DVB_SUBTITLE; break; |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
97 case 'p': |
35715
8517826b0dbd
Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents:
35199
diff
changeset
|
98 cid = AV_CODEC_ID_HDMV_PGS_SUBTITLE; break; |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
99 case 'x': |
35715
8517826b0dbd
Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents:
35199
diff
changeset
|
100 cid = AV_CODEC_ID_XSUB; break; |
31631
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
101 } |
67f2fb3ff4c7
Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents:
31628
diff
changeset
|
102 |
31599 | 103 av_init_packet(&pkt); |
104 pkt.data = *data; | |
105 pkt.size = *size; | |
106 pkt.pts = *pts * 1000; | |
107 if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE) | |
108 pkt.convergence_duration = (*endpts - *pts) * 1000; | |
109 if (!ctx) { | |
110 AVCodec *sub_codec; | |
34528 | 111 init_avcodec(); |
34566
f3d53cd55376
Update deprecated avcodec_alloc_context()/avcodec_open() API calls
siretart
parents:
34528
diff
changeset
|
112 ctx = avcodec_alloc_context3(NULL); |
35199
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
113 if (!ctx) { |
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
114 mp_msg(MSGT_SUBREADER, MSGL_FATAL, |
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
115 "Could not allocate subtitle decoder context\n"); |
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
116 return -1; |
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
117 } |
35030 | 118 ctx->extradata_size = sh->extradata_len; |
119 ctx->extradata = sh->extradata; | |
31628
f15df2e3081b
Add support for DVB and XSUB subtitles, not yet working properly.
reimar
parents:
31624
diff
changeset
|
120 sub_codec = avcodec_find_decoder(cid); |
35199
9b921155e030
Move check for NULL to before the pointer is used.
reimar
parents:
35030
diff
changeset
|
121 if (!sub_codec || avcodec_open2(ctx, sub_codec, NULL) < 0) { |
32080 | 122 mp_msg(MSGT_SUBREADER, MSGL_FATAL, |
123 "Could not open subtitle decoder\n"); | |
31599 | 124 av_freep(&ctx); |
125 return -1; | |
126 } | |
127 sh->context = ctx; | |
128 } | |
129 res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt); | |
130 if (res < 0) | |
131 return res; | |
132 if (*pts != MP_NOPTS_VALUE) { | |
133 if (sub.end_display_time > sub.start_display_time) | |
134 *endpts = *pts + sub.end_display_time / 1000.0; | |
135 *pts += sub.start_display_time / 1000.0; | |
136 } | |
32564
61ac00c3c51c
Support clearing subtitles. Makes PGS subtitles disappear at the appropriate time.
reimar
parents:
32467
diff
changeset
|
137 if (got_sub && vo_spudec && sub.num_rects == 0) |
61ac00c3c51c
Support clearing subtitles. Makes PGS subtitles disappear at the appropriate time.
reimar
parents:
32467
diff
changeset
|
138 spudec_set_paletted(vo_spudec, NULL, 0, NULL, 0, 0, 0, 0, *pts, *endpts); |
31599 | 139 if (got_sub && sub.num_rects > 0) { |
140 switch (sub.rects[0]->type) { | |
141 case SUBTITLE_BITMAP: | |
142 if (!vo_spudec) | |
31924
8d7f15885b64
Pass the video dimensions specified in the subtitle to spudec.
reimar
parents:
31642
diff
changeset
|
143 vo_spudec = spudec_new_scaled(NULL, ctx->width, ctx->height, NULL, 0); |
34784 | 144 avsub_to_spudec(sub.rects, sub.num_rects, *pts, *endpts); |
31599 | 145 vo_osd_changed(OSDTYPE_SPU); |
146 break; | |
147 case SUBTITLE_TEXT: | |
148 *data = strdup(sub.rects[0]->text); | |
31642 | 149 *size = strlen(*data); |
31599 | 150 new_type = 't'; |
151 break; | |
152 case SUBTITLE_ASS: | |
153 *data = strdup(sub.rects[0]->ass); | |
31642 | 154 *size = strlen(*data); |
31599 | 155 new_type = 'a'; |
156 break; | |
157 } | |
158 } | |
159 if (got_sub) | |
31624
40c30c70ead0
Fix memory leak for subtitles decoded by libavcodec.
reimar
parents:
31599
diff
changeset
|
160 avsubtitle_free(&sub); |
31599 | 161 return new_type; |
162 } |