annotate sub/av_sub.c @ 35253:48db1b241757

Try to do something sensible when malloc fails instead of continuing which is sure to crash.
author reimar
date Mon, 05 Nov 2012 20:45:40 +0000
parents 9b921155e030
children 8517826b0dbd
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
1 /*
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
2 * This file is part of MPlayer.
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
3 *
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
4 * MPlayer is free software; you can redistribute it and/or modify
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
5 * it under the terms of the GNU General Public License as published by
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
6 * the Free Software Foundation; either version 2 of the License, or
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
7 * (at your option) any later version.
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
8 *
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
9 * MPlayer is distributed in the hope that it will be useful,
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
12 * GNU General Public License for more details.
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
13 *
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
14 * You should have received a copy of the GNU General Public License along
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
15 * with MPlayer; if not, write to the Free Software Foundation, Inc.,
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
17 */
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
18
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
19 #include "libavcodec/avcodec.h"
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
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
fbe5c829c69b Move libvo/sub.[ch] from libvo to sub.
cigaes
parents: 32464
diff changeset
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
cd1c0283e645 Reuse init_avcodec function.
reimar
parents: 34174
diff changeset
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
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
26
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
27 void reset_avsub(struct sh_sub *sh)
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
28 {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
29 if (sh->context) {
35030
97470e8b352f Pass extradata to libavcodec subtitle decoder.
reimar
parents: 34784
diff changeset
30 AVCodecContext *ctx = sh->context;
97470e8b352f Pass extradata to libavcodec subtitle decoder.
reimar
parents: 34784
diff changeset
31 ctx->extradata = NULL;
97470e8b352f Pass extradata to libavcodec subtitle decoder.
reimar
parents: 34784
diff changeset
32 ctx->extradata_size = 0;
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
33 avcodec_close(sh->context);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
34 av_freep(&sh->context);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
35 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
36 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
37
34784
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
38 static void avsub_to_spudec(AVSubtitleRect **rects, int num_rects,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
39 double pts, double endpts)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
40 {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
41 int i, xmin = INT_MAX, ymin = INT_MAX, xmax = INT_MIN, ymax = INT_MIN;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
42 struct spu_packet_t *packet;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
43
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
44 if (num_rects == 1) {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
45 spudec_set_paletted(vo_spudec,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
46 rects[0]->pict.data[0],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
47 rects[0]->pict.linesize[0],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
48 rects[0]->pict.data[1],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
49 rects[0]->x,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
50 rects[0]->y,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
51 rects[0]->w,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
52 rects[0]->h,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
53 pts,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
54 endpts);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
55 return;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
56 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
57 for (i = 0; i < num_rects; i++) {
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
58 xmin = FFMIN(xmin, rects[i]->x);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
59 ymin = FFMIN(ymin, rects[i]->y);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
60 xmax = FFMAX(xmax, rects[i]->x + rects[i]->w);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
61 ymax = FFMAX(ymax, rects[i]->y + rects[i]->h);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
62 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
63 packet = spudec_packet_create(xmin, ymin, xmax - xmin, ymax - ymin);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
64 if (!packet)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
65 return;
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
66 spudec_packet_clear(packet);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
67 for (i = 0; i < num_rects; i++)
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
68 spudec_packet_fill(packet,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
69 rects[i]->pict.data[0],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
70 rects[i]->pict.linesize[0],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
71 rects[i]->pict.data[1],
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
72 rects[i]->x - xmin,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
73 rects[i]->y - ymin,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
74 rects[i]->w,
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
75 rects[i]->h);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
76 spudec_packet_send(vo_spudec, packet, pts, endpts);
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
77 }
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
78
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
79 /**
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
80 * Decode a subtitle packet via libavcodec.
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
81 * \return < 0 on error, > 0 if further processing is needed
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
82 */
32080
8c29dfec15c2 cosmetics: Break some long lines.
diego
parents: 31924
diff changeset
83 int decode_avsub(struct sh_sub *sh, uint8_t **data, int *size,
8c29dfec15c2 cosmetics: Break some long lines.
diego
parents: 31924
diff changeset
84 double *pts, double *endpts)
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
85 {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
86 AVCodecContext *ctx = sh->context;
31631
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
87 enum CodecID cid = CODEC_ID_NONE;
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
88 int new_type = 0;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
89 int res;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
90 int got_sub;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
91 AVSubtitle sub;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
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':
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
96 cid = CODEC_ID_DVB_SUBTITLE; break;
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
97 case 'p':
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
98 cid = CODEC_ID_HDMV_PGS_SUBTITLE; break;
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
99 case 'x':
67f2fb3ff4c7 Try to get subtitle scaling somewhat right with libavcodec decoded
reimar
parents: 31628
diff changeset
100 cid = CODEC_ID_XSUB; break;
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
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
103 av_init_packet(&pkt);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
104 pkt.data = *data;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
105 pkt.size = *size;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
106 pkt.pts = *pts * 1000;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
107 if (*pts != MP_NOPTS_VALUE && *endpts != MP_NOPTS_VALUE)
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
108 pkt.convergence_duration = (*endpts - *pts) * 1000;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
109 if (!ctx) {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
110 AVCodec *sub_codec;
34528
cd1c0283e645 Reuse init_avcodec function.
reimar
parents: 34174
diff changeset
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
97470e8b352f Pass extradata to libavcodec subtitle decoder.
reimar
parents: 34784
diff changeset
118 ctx->extradata_size = sh->extradata_len;
97470e8b352f Pass extradata to libavcodec subtitle decoder.
reimar
parents: 34784
diff changeset
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
8c29dfec15c2 cosmetics: Break some long lines.
diego
parents: 31924
diff changeset
122 mp_msg(MSGT_SUBREADER, MSGL_FATAL,
8c29dfec15c2 cosmetics: Break some long lines.
diego
parents: 31924
diff changeset
123 "Could not open subtitle decoder\n");
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
124 av_freep(&ctx);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
125 return -1;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
126 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
127 sh->context = ctx;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
128 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
129 res = avcodec_decode_subtitle2(ctx, &sub, &got_sub, &pkt);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
130 if (res < 0)
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
131 return res;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
132 if (*pts != MP_NOPTS_VALUE) {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
133 if (sub.end_display_time > sub.start_display_time)
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
134 *endpts = *pts + sub.end_display_time / 1000.0;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
135 *pts += sub.start_display_time / 1000.0;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
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
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
139 if (got_sub && sub.num_rects > 0) {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
140 switch (sub.rects[0]->type) {
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
141 case SUBTITLE_BITMAP:
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
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
d180a74b1a89 av_sub: support multiple rectangles.
cigaes
parents: 34566
diff changeset
144 avsub_to_spudec(sub.rects, sub.num_rects, *pts, *endpts);
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
145 vo_osd_changed(OSDTYPE_SPU);
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
146 break;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
147 case SUBTITLE_TEXT:
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
148 *data = strdup(sub.rects[0]->text);
31642
af4d89e131b4 Set size correctly for decoded text subs.
reimar
parents: 31631
diff changeset
149 *size = strlen(*data);
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
150 new_type = 't';
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
151 break;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
152 case SUBTITLE_ASS:
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
153 *data = strdup(sub.rects[0]->ass);
31642
af4d89e131b4 Set size correctly for decoded text subs.
reimar
parents: 31631
diff changeset
154 *size = strlen(*data);
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
155 new_type = 'a';
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
156 break;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
157 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
158 }
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
159 if (got_sub)
31624
40c30c70ead0 Fix memory leak for subtitles decoded by libavcodec.
reimar
parents: 31599
diff changeset
160 avsubtitle_free(&sub);
31599
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
161 return new_type;
cafeb7863de8 Add support for PGS subtitle decoding via libavcodec.
reimar
parents:
diff changeset
162 }