Mercurial > mplayer.hg
annotate sub/av_sub.c @ 35833:dbfedb331095
Keep GUI history untouched upon file select "Cancel".
Currently, when "Cancel" is selected in the file select menu, the
GUI history can be modified nevertheless. Presuming that "Cancel"
shall discard changes, the history should be kept unchanged, too.
Patch by Hans-Dieter Kosch, hdkosch kabelbw de.
author | ib |
---|---|
date | Thu, 28 Feb 2013 11:19:59 +0000 |
parents | 8517826b0dbd |
children | 9b88b87f5921 |
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; | |
35715
8517826b0dbd
Replace CODEC_IDs their modern AV_-prefixed counterparts.
diego
parents:
35199
diff
changeset
|
87 enum CodecID 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 } |