annotate dvbsub_parser.c @ 11333:e7c30cba2c7b libavcodec

Support B-frames when decoding MPEG-4 with VDPAU hardware acceleration. Based on a patch by NVIDIA.
author cehoyos
date Wed, 03 Mar 2010 00:09:57 +0000
parents c78fd9154378
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
1 /*
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
2 * DVB subtitle parser for FFmpeg
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 6977
diff changeset
3 * Copyright (c) 2005 Ian Caulfield
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
4 *
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
5 * This file is part of FFmpeg.
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
6 *
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
11 *
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
15 * Lesser General Public License for more details.
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
16 *
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
20 */
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
21 #include "avcodec.h"
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
22 #include "dsputil.h"
9428
0dce4fe6e6f3 Rename bitstream.h to get_bits.h.
stefano
parents: 8629
diff changeset
23 #include "get_bits.h"
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
24
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
25 //#define DEBUG
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
26 //#define DEBUG_PACKET_CONTENTS
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
27
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
28 /* Parser (mostly) copied from dvdsub.c */
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
29
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
30 #define PARSE_BUF_SIZE (65536)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
31
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
32
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
33 /* parser definition */
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
34 typedef struct DVBSubParseContext {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
35 uint8_t *packet_buf;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
36 int packet_start;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
37 int packet_index;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
38 int in_packet;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
39 } DVBSubParseContext;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
40
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 4931
diff changeset
41 static av_cold int dvbsub_parse_init(AVCodecParserContext *s)
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
42 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
43 DVBSubParseContext *pc = s->priv_data;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
44 pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
45
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
46 return 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
47 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
48
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
49 static int dvbsub_parse(AVCodecParserContext *s,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
50 AVCodecContext *avctx,
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4923
diff changeset
51 const uint8_t **poutbuf, int *poutbuf_size,
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
52 const uint8_t *buf, int buf_size)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
53 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
54 DVBSubParseContext *pc = s->priv_data;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
55 uint8_t *p, *p_end;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
56 int len, buf_pos = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
57
9999
c78fd9154378 Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents: 9428
diff changeset
58 dprintf(avctx, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n",
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
59 s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
60
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
61 #ifdef DEBUG_PACKET_CONTENTS
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
62 int i;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
63
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
64 for (i=0; i < buf_size; i++)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
65 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
66 av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
67 if (i % 16 == 15)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
68 av_log(avctx, AV_LOG_INFO, "\n");
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
69 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
70
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
71 if (i % 16 != 0)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
72 av_log(avctx, AV_LOG_INFO, "\n");
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
73
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
74 #endif
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
75
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
76 *poutbuf = NULL;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
77 *poutbuf_size = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
78
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
79 s->fetch_timestamp = 1;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
80
6977
de032bcdeff9 Simplify parser core.
michael
parents: 6517
diff changeset
81 if (s->last_pts != s->pts && s->pts != AV_NOPTS_VALUE) /* Start of a new packet */
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
82 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
83 if (pc->packet_index != pc->packet_start)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
84 {
9999
c78fd9154378 Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents: 9428
diff changeset
85 dprintf(avctx, "Discarding %d bytes\n",
c78fd9154378 Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents: 9428
diff changeset
86 pc->packet_index - pc->packet_start);
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
87 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
88
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
89 pc->packet_start = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
90 pc->packet_index = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
91
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
92 if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {
9999
c78fd9154378 Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents: 9428
diff changeset
93 dprintf(avctx, "Bad packet header\n");
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
94 return -1;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
95 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
96
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
97 buf_pos = 2;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
98
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
99 pc->in_packet = 1;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
100 } else {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
101 if (pc->packet_start != 0)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
102 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
103 if (pc->packet_index != pc->packet_start)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
104 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
105 memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
106 pc->packet_index - pc->packet_start);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
107
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
108 pc->packet_index -= pc->packet_start;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
109 pc->packet_start = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
110 } else {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
111 pc->packet_start = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
112 pc->packet_index = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
113 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
114 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
115 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
116
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
117 if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
118 return -1;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
119
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
120 /* if not currently in a packet, discard data */
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
121 if (pc->in_packet == 0)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
122 return buf_size;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
123
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
124 memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
125 pc->packet_index += buf_size - buf_pos;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
126
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
127 p = pc->packet_buf;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
128 p_end = pc->packet_buf + pc->packet_index;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
129
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
130 while (p < p_end)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
131 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
132 if (*p == 0x0f)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
133 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
134 if (p + 6 <= p_end)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
135 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
136 len = AV_RB16(p + 4);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
137
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
138 if (p + len + 6 <= p_end)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
139 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
140 *poutbuf_size += len + 6;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
141
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
142 p += len + 6;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
143 } else
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
144 break;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
145 } else
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
146 break;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
147 } else if (*p == 0xff) {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
148 if (p + 1 < p_end)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
149 {
9999
c78fd9154378 Change av_log() calls surrounded by '#ifdef DEBUG' into dprintf macros.
diego
parents: 9428
diff changeset
150 dprintf(avctx, "Junk at end of packet\n");
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
151 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
152 pc->packet_index = p - pc->packet_buf;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
153 pc->in_packet = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
154 break;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
155 } else {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
156 av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
157
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
158 pc->packet_index = p - pc->packet_buf;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
159 pc->in_packet = 0;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
160 break;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
161 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
162 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
163
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
164 if (*poutbuf_size > 0)
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
165 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
166 *poutbuf = pc->packet_buf;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
167 pc->packet_start = *poutbuf_size;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
168 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
169
6977
de032bcdeff9 Simplify parser core.
michael
parents: 6517
diff changeset
170 if (s->pts == AV_NOPTS_VALUE)
de032bcdeff9 Simplify parser core.
michael
parents: 6517
diff changeset
171 s->pts = s->last_pts;
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
172
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
173 return buf_size;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
174 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
175
6517
48759bfbd073 Apply 'cold' attribute to init/uninit functions in libavcodec
zuxy
parents: 4931
diff changeset
176 static av_cold void dvbsub_parse_close(AVCodecParserContext *s)
4920
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
177 {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
178 DVBSubParseContext *pc = s->priv_data;
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
179 av_freep(&pc->packet_buf);
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
180 }
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
181
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
182 AVCodecParser dvbsub_parser = {
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
183 { CODEC_ID_DVB_SUBTITLE },
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
184 sizeof(DVBSubParseContext),
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
185 dvbsub_parse_init,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
186 dvbsub_parse,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
187 dvbsub_parse_close,
6258f497d42e Move dvbsubdec parser to its own file.
diego
parents:
diff changeset
188 };