Mercurial > audlegacy
annotate Plugins/Input/wma/libffwma/parser.c @ 142:5ce1d36e9ff5 trunk
[svn] Don't build wma by default, it's not working.
author | nenolod |
---|---|
date | Thu, 10 Nov 2005 15:56:32 -0800 |
parents | b8d4c1faa6d7 |
children | 12004b385a96 |
rev | line source |
---|---|
137 | 1 /* |
2 * Audio and Video frame extraction | |
3 * Copyright (c) 2003 Fabrice Bellard. | |
4 * Copyright (c) 2003 Michael Niedermayer. | |
5 * | |
6 * This library is free software; you can redistribute it and/or | |
7 * modify it under the terms of the GNU Lesser General Public | |
8 * License as published by the Free Software Foundation; either | |
9 * version 2 of the License, or (at your option) any later version. | |
10 * | |
11 * This library is distributed in the hope that it will be useful, | |
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
14 * Lesser General Public License for more details. | |
15 * | |
16 * You should have received a copy of the GNU Lesser General Public | |
17 * License along with this library; if not, write to the Free Software | |
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
19 */ | |
20 #include "avcodec.h" | |
21 | |
22 AVCodecParser *av_first_parser = NULL; | |
23 | |
24 void av_register_codec_parser(AVCodecParser *parser) | |
25 { | |
26 parser->next = av_first_parser; | |
27 av_first_parser = parser; | |
28 } | |
29 | |
30 AVCodecParserContext *av_parser_init(int codec_id) | |
31 { | |
32 AVCodecParserContext *s; | |
33 AVCodecParser *parser; | |
34 int ret; | |
35 | |
36 for(parser = av_first_parser; parser != NULL; parser = parser->next) { | |
37 if (parser->codec_ids[0] == codec_id || | |
38 parser->codec_ids[1] == codec_id || | |
39 parser->codec_ids[2] == codec_id) | |
40 goto found; | |
41 } | |
42 return NULL; | |
43 found: | |
142
5ce1d36e9ff5
[svn] Don't build wma by default, it's not working.
nenolod
parents:
137
diff
changeset
|
44 s = malloc(sizeof(AVCodecParserContext)); |
137 | 45 if (!s) |
46 return NULL; | |
47 s->parser = parser; | |
142
5ce1d36e9ff5
[svn] Don't build wma by default, it's not working.
nenolod
parents:
137
diff
changeset
|
48 s->priv_data = malloc(parser->priv_data_size); |
137 | 49 if (!s->priv_data) { |
50 free(s); | |
51 return NULL; | |
52 } | |
53 if (parser->parser_init) { | |
54 ret = parser->parser_init(s); | |
55 if (ret != 0) { | |
56 free(s->priv_data); | |
57 free(s); | |
58 return NULL; | |
59 } | |
60 } | |
61 return s; | |
62 } | |
63 | |
64 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame | |
65 can be returned if necessary */ | |
66 int av_parser_parse(AVCodecParserContext *s, | |
67 AVCodecContext *avctx, | |
68 uint8_t **poutbuf, int *poutbuf_size, | |
69 const uint8_t *buf, int buf_size, | |
70 int64_t pts, int64_t dts) | |
71 { | |
72 int index, i, k; | |
73 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE]; | |
74 | |
75 if (buf_size == 0) { | |
76 /* padding is always necessary even if EOF, so we add it here */ | |
77 memset(dummy_buf, 0, sizeof(dummy_buf)); | |
78 buf = dummy_buf; | |
79 } else { | |
80 /* add a new packet descriptor */ | |
81 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1); | |
82 s->cur_frame_start_index = k; | |
83 s->cur_frame_offset[k] = s->cur_offset; | |
84 s->cur_frame_pts[k] = pts; | |
85 s->cur_frame_dts[k] = dts; | |
86 | |
87 /* fill first PTS/DTS */ | |
88 if (s->cur_offset == 0) { | |
89 s->last_pts = pts; | |
90 s->last_dts = dts; | |
91 } | |
92 } | |
93 | |
94 /* WARNING: the returned index can be negative */ | |
95 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size); | |
96 /* update the file pointer */ | |
97 if (*poutbuf_size) { | |
98 /* fill the data for the current frame */ | |
99 s->frame_offset = s->last_frame_offset; | |
100 s->pts = s->last_pts; | |
101 s->dts = s->last_dts; | |
102 | |
103 /* offset of the next frame */ | |
104 s->last_frame_offset = s->cur_offset + index; | |
105 /* find the packet in which the new frame starts. It | |
106 is tricky because of MPEG video start codes | |
107 which can begin in one packet and finish in | |
108 another packet. In the worst case, an MPEG | |
109 video start code could be in 4 different | |
110 packets. */ | |
111 k = s->cur_frame_start_index; | |
112 for(i = 0; i < AV_PARSER_PTS_NB; i++) { | |
113 if (s->last_frame_offset >= s->cur_frame_offset[k]) | |
114 break; | |
115 k = (k - 1) & (AV_PARSER_PTS_NB - 1); | |
116 } | |
117 s->last_pts = s->cur_frame_pts[k]; | |
118 s->last_dts = s->cur_frame_dts[k]; | |
119 } | |
120 if (index < 0) | |
121 index = 0; | |
122 s->cur_offset += index; | |
123 return index; | |
124 } | |
125 | |
126 void av_parser_close(AVCodecParserContext *s) | |
127 { | |
128 if (s->parser->parser_close) | |
129 s->parser->parser_close(s); | |
130 | |
131 free(s->priv_data); | |
132 free(s); | |
133 } | |
134 |