~ubuntu-branches/ubuntu/jaunty/xvidcap/jaunty-proposed

« back to all changes in this revision

Viewing changes to ffmpeg/libavcodec/dvbsub_parser.c

  • Committer: Bazaar Package Importer
  • Author(s): Lionel Le Folgoc, Andrew Starr-Bochicchio, Lionel Le Folgoc
  • Date: 2008-12-26 00:10:06 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20081226001006-2040ls9680bd1blt
Tags: 1.1.7-0.2ubuntu1
[ Andrew Starr-Bochicchio ]
* Merge from debian-multimedia (LP: #298547), Ubuntu Changes:
 - For ffmpeg-related build-deps, fix versionized dependencies
   as the ubuntu versioning is different than debian-multimedia's.

[ Lionel Le Folgoc ]
* LP: #311412 is fixed since the 1.1.7~rc1-0.1 revision.
* debian/patches/03_ffmpeg.diff: updated to fix FTBFS due to libswscale API
  change (cherry-pick from Gentoo #234383).

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * DVB subtitle parser for FFmpeg
 
3
 * Copyright (c) 2005 Ian Caulfield.
 
4
 *
 
5
 * This file is part of FFmpeg.
 
6
 *
 
7
 * FFmpeg is free software; you can redistribute it and/or
 
8
 * modify it under the terms of the GNU Lesser General Public
 
9
 * License as published by the Free Software Foundation; either
 
10
 * version 2.1 of the License, or (at your option) any later version.
 
11
 *
 
12
 * FFmpeg is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
15
 * Lesser General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU Lesser General Public
 
18
 * License along with FFmpeg; if not, write to the Free Software
 
19
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 
20
 */
 
21
#include "avcodec.h"
 
22
#include "dsputil.h"
 
23
#include "bitstream.h"
 
24
 
 
25
//#define DEBUG
 
26
//#define DEBUG_PACKET_CONTENTS
 
27
 
 
28
/* Parser (mostly) copied from dvdsub.c */
 
29
 
 
30
#define PARSE_BUF_SIZE  (65536)
 
31
 
 
32
 
 
33
/* parser definition */
 
34
typedef struct DVBSubParseContext {
 
35
    uint8_t *packet_buf;
 
36
    int packet_start;
 
37
    int packet_index;
 
38
    int in_packet;
 
39
} DVBSubParseContext;
 
40
 
 
41
static av_cold int dvbsub_parse_init(AVCodecParserContext *s)
 
42
{
 
43
    DVBSubParseContext *pc = s->priv_data;
 
44
    pc->packet_buf = av_malloc(PARSE_BUF_SIZE);
 
45
 
 
46
    return 0;
 
47
}
 
48
 
 
49
static int dvbsub_parse(AVCodecParserContext *s,
 
50
                        AVCodecContext *avctx,
 
51
                        const uint8_t **poutbuf, int *poutbuf_size,
 
52
                        const uint8_t *buf, int buf_size)
 
53
{
 
54
    DVBSubParseContext *pc = s->priv_data;
 
55
    uint8_t *p, *p_end;
 
56
    int len, buf_pos = 0;
 
57
 
 
58
#ifdef DEBUG
 
59
    av_log(avctx, AV_LOG_INFO, "DVB parse packet pts=%"PRIx64", lpts=%"PRIx64", cpts=%"PRIx64":\n",
 
60
            s->pts, s->last_pts, s->cur_frame_pts[s->cur_frame_start_index]);
 
61
#endif
 
62
 
 
63
#ifdef DEBUG_PACKET_CONTENTS
 
64
    int i;
 
65
 
 
66
    for (i=0; i < buf_size; i++)
 
67
    {
 
68
        av_log(avctx, AV_LOG_INFO, "%02x ", buf[i]);
 
69
        if (i % 16 == 15)
 
70
            av_log(avctx, AV_LOG_INFO, "\n");
 
71
    }
 
72
 
 
73
    if (i % 16 != 0)
 
74
        av_log(avctx, AV_LOG_INFO, "\n");
 
75
 
 
76
#endif
 
77
 
 
78
    *poutbuf = NULL;
 
79
    *poutbuf_size = 0;
 
80
 
 
81
    s->fetch_timestamp = 1;
 
82
 
 
83
    if (s->last_pts != s->pts && s->last_pts != AV_NOPTS_VALUE) /* Start of a new packet */
 
84
    {
 
85
        if (pc->packet_index != pc->packet_start)
 
86
        {
 
87
#ifdef DEBUG
 
88
            av_log(avctx, AV_LOG_INFO, "Discarding %d bytes\n",
 
89
                pc->packet_index - pc->packet_start);
 
90
#endif
 
91
        }
 
92
 
 
93
        pc->packet_start = 0;
 
94
        pc->packet_index = 0;
 
95
 
 
96
        if (buf_size < 2 || buf[0] != 0x20 || buf[1] != 0x00) {
 
97
#ifdef DEBUG
 
98
            av_log(avctx, AV_LOG_INFO, "Bad packet header\n");
 
99
#endif
 
100
            return -1;
 
101
        }
 
102
 
 
103
        buf_pos = 2;
 
104
 
 
105
        pc->in_packet = 1;
 
106
    } else {
 
107
        if (pc->packet_start != 0)
 
108
        {
 
109
            if (pc->packet_index != pc->packet_start)
 
110
            {
 
111
                memmove(pc->packet_buf, pc->packet_buf + pc->packet_start,
 
112
                            pc->packet_index - pc->packet_start);
 
113
 
 
114
                pc->packet_index -= pc->packet_start;
 
115
                pc->packet_start = 0;
 
116
            } else {
 
117
                pc->packet_start = 0;
 
118
                pc->packet_index = 0;
 
119
            }
 
120
        }
 
121
    }
 
122
 
 
123
    if (buf_size - buf_pos + pc->packet_index > PARSE_BUF_SIZE)
 
124
        return -1;
 
125
 
 
126
/* if not currently in a packet, discard data */
 
127
    if (pc->in_packet == 0)
 
128
        return buf_size;
 
129
 
 
130
    memcpy(pc->packet_buf + pc->packet_index, buf + buf_pos, buf_size - buf_pos);
 
131
    pc->packet_index += buf_size - buf_pos;
 
132
 
 
133
    p = pc->packet_buf;
 
134
    p_end = pc->packet_buf + pc->packet_index;
 
135
 
 
136
    while (p < p_end)
 
137
    {
 
138
        if (*p == 0x0f)
 
139
        {
 
140
            if (p + 6 <= p_end)
 
141
            {
 
142
                len = AV_RB16(p + 4);
 
143
 
 
144
                if (p + len + 6 <= p_end)
 
145
                {
 
146
                    *poutbuf_size += len + 6;
 
147
 
 
148
                    p += len + 6;
 
149
                } else
 
150
                    break;
 
151
            } else
 
152
                break;
 
153
        } else if (*p == 0xff) {
 
154
            if (p + 1 < p_end)
 
155
            {
 
156
#ifdef DEBUG
 
157
                av_log(avctx, AV_LOG_INFO, "Junk at end of packet\n");
 
158
#endif
 
159
            }
 
160
            pc->packet_index = p - pc->packet_buf;
 
161
            pc->in_packet = 0;
 
162
            break;
 
163
        } else {
 
164
            av_log(avctx, AV_LOG_ERROR, "Junk in packet\n");
 
165
 
 
166
            pc->packet_index = p - pc->packet_buf;
 
167
            pc->in_packet = 0;
 
168
            break;
 
169
        }
 
170
    }
 
171
 
 
172
    if (*poutbuf_size > 0)
 
173
    {
 
174
        *poutbuf = pc->packet_buf;
 
175
        pc->packet_start = *poutbuf_size;
 
176
    }
 
177
 
 
178
    if (s->last_pts == AV_NOPTS_VALUE)
 
179
        s->last_pts = s->pts;
 
180
 
 
181
    return buf_size;
 
182
}
 
183
 
 
184
static av_cold void dvbsub_parse_close(AVCodecParserContext *s)
 
185
{
 
186
    DVBSubParseContext *pc = s->priv_data;
 
187
    av_freep(&pc->packet_buf);
 
188
}
 
189
 
 
190
AVCodecParser dvbsub_parser = {
 
191
    { CODEC_ID_DVB_SUBTITLE },
 
192
    sizeof(DVBSubParseContext),
 
193
    dvbsub_parse_init,
 
194
    dvbsub_parse,
 
195
    dvbsub_parse_close,
 
196
};