annotate parser.c @ 1795:920e6381e1fe libavcodec

2 byte shorter userdata for mpeg4 in the past it was startcode,string,00,7F,startcode now it is startcode,string,stratcode both are mpeg4 compliant, as according to the standard the userdata lasts until the next 00 00 01 (startcode prefix) but some very primitive decoders which simply skip until the first 00 byte and then expect the next valid startcode might fail with the old variant, just a theory though (didnt test if quicktime can decode it now)
author michael
date Sun, 08 Feb 2004 22:52:35 +0000
parents f5af91b8be17
children d9e067853051
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
1 /*
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
2 * Audio and Video frame extraction
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
4 * Copyright (c) 2003 Michael Niedermayer.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
5 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
6 * This library is free software; you can redistribute it and/or
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
7 * modify it under the terms of the GNU Lesser General Public
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
8 * License as published by the Free Software Foundation; either
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
9 * version 2 of the License, or (at your option) any later version.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
10 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
11 * This library is distributed in the hope that it will be useful,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
14 * Lesser General Public License for more details.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
15 *
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
16 * You should have received a copy of the GNU Lesser General Public
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
17 * License along with this library; if not, write to the Free Software
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
19 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
20 #include "avcodec.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
21 #include "mpegvideo.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
22 #include "mpegaudio.h"
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
23
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
24 AVCodecParser *av_first_parser = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
25
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
26 void av_register_codec_parser(AVCodecParser *parser)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
27 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
28 parser->next = av_first_parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
29 av_first_parser = parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
30 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
31
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
32 AVCodecParserContext *av_parser_init(int codec_id)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
33 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
34 AVCodecParserContext *s;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
35 AVCodecParser *parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
36 int ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
37
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
38 for(parser = av_first_parser; parser != NULL; parser = parser->next) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
39 if (parser->codec_ids[0] == codec_id ||
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
40 parser->codec_ids[1] == codec_id ||
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
41 parser->codec_ids[2] == codec_id)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
42 goto found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
43 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
44 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
45 found:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
46 s = av_mallocz(sizeof(AVCodecParserContext));
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
47 if (!s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
48 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
49 s->parser = parser;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
50 s->priv_data = av_mallocz(parser->priv_data_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
51 if (!s->priv_data) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
52 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
53 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
54 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
55 if (parser->parser_init) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
56 ret = parser->parser_init(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
57 if (ret != 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
58 av_free(s->priv_data);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
59 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
60 return NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
61 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
62 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
63 return s;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
64 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
65
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
66 /* NOTE: buf_size == 0 is used to signal EOF so that the last frame
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
67 can be returned if necessary */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
68 int av_parser_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
69 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
70 uint8_t **poutbuf, int *poutbuf_size,
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
71 const uint8_t *buf, int buf_size,
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
72 int64_t pts, int64_t dts)
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
73 {
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
74 int index, i, k;
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
75 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
76
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
77 if (buf_size == 0) {
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
78 /* padding is always necessary even if EOF, so we add it here */
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
79 memset(dummy_buf, 0, sizeof(dummy_buf));
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
80 buf = dummy_buf;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
81 } else {
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
82 /* add a new packet descriptor */
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
83 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
84 s->cur_frame_start_index = k;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
85 s->cur_frame_offset[k] = s->cur_offset;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
86 s->cur_frame_pts[k] = pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
87 s->cur_frame_dts[k] = dts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
88
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
89 /* fill first PTS/DTS */
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
90 if (s->cur_offset == 0) {
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
91 s->last_pts = pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
92 s->last_dts = dts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
93 }
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
94 }
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
95
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
96 /* WARNING: the returned index can be negative */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
97 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
98 /* update the file pointer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
99 if (*poutbuf_size) {
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
100 /* fill the data for the current frame */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
101 s->frame_offset = s->last_frame_offset;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
102 s->pts = s->last_pts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
103 s->dts = s->last_dts;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
104
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
105 /* offset of the next frame */
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
106 s->last_frame_offset = s->cur_offset + index;
1696
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
107 /* find the packet in which the new frame starts. It
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
108 is tricky because of MPEG video start codes
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
109 which can begin in one packet and finish in
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
110 another packet. In the worst case, an MPEG
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
111 video start code could be in 4 different
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
112 packets. */
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
113 k = s->cur_frame_start_index;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
114 for(i = 0; i < AV_PARSER_PTS_NB; i++) {
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
115 if (s->last_frame_offset >= s->cur_frame_offset[k])
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
116 break;
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
117 k = (k - 1) & (AV_PARSER_PTS_NB - 1);
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
118 }
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
119 s->last_pts = s->cur_frame_pts[k];
f5af91b8be17 pts and dts support in parser API
bellard
parents: 1694
diff changeset
120 s->last_dts = s->cur_frame_dts[k];
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
121 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
122 if (index < 0)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
123 index = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
124 s->cur_offset += index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
125 return index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
126 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
127
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
128 void av_parser_close(AVCodecParserContext *s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
129 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
130 if (s->parser->parser_close)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
131 s->parser->parser_close(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
132 av_free(s->priv_data);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
133 av_free(s);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
134 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
135
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
136 /*****************************************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
137
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
138 //#define END_NOT_FOUND (-100)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
139
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
140 #define PICTURE_START_CODE 0x00000100
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
141 #define SEQ_START_CODE 0x000001b3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
142 #define EXT_START_CODE 0x000001b5
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
143 #define SLICE_MIN_START_CODE 0x00000101
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
144 #define SLICE_MAX_START_CODE 0x000001af
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
145
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
146 typedef struct ParseContext1{
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
147 uint8_t *buffer;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
148 int index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
149 int last_index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
150 int buffer_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
151 uint32_t state; ///< contains the last few bytes in MSB order
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
152 int frame_start_found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
153 int overread; ///< the number of bytes which where irreversibly read from the next frame
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
154 int overread_index; ///< the index into ParseContext1.buffer of the overreaded bytes
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
155
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
156 /* MPEG2 specific */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
157 int frame_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
158 int progressive_sequence;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
159 int width, height;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
160
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
161 /* XXX: suppress that, needed by MPEG4 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
162 MpegEncContext *enc;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
163 int first_picture;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
164 } ParseContext1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
165
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
166 /**
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
167 * combines the (truncated) bitstream to a complete frame
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
168 * @returns -1 if no complete frame could be created
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
169 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
170 static int ff_combine_frame1(ParseContext1 *pc, int next, uint8_t **buf, int *buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
171 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
172 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
173 if(pc->overread){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
174 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
175 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
176 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
177 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
178
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
179 /* copy overreaded bytes from last frame into buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
180 for(; pc->overread>0; pc->overread--){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
181 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
182 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
183
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
184 pc->last_index= pc->index;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
185
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
186 /* copy into buffer end return */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
187 if(next == END_NOT_FOUND){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
188 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
189
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
190 memcpy(&pc->buffer[pc->index], *buf, *buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
191 pc->index += *buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
192 return -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
193 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
194
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
195 *buf_size=
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
196 pc->overread_index= pc->index + next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
197
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
198 /* append to buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
199 if(pc->index){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
200 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
201
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
202 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
203 pc->index = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
204 *buf= pc->buffer;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
205 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
206
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
207 /* store overread bytes */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
208 for(;next < 0; next++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
209 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
210 pc->overread++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
211 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
212
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
213 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
214 if(pc->overread){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
215 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
216 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
217 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
218 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
219
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
220 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
221 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
222
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
223 /**
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
224 * finds the end of the current frame in the bitstream.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
225 * @return the position of the first byte of the next frame, or -1
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
226 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
227 static int mpeg1_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
228 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
229 int i;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
230 uint32_t state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
231
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
232 state= pc->state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
233
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
234 i=0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
235 if(!pc->frame_start_found){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
236 for(i=0; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
237 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
238 if(state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
239 i++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
240 pc->frame_start_found=1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
241 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
242 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
243 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
244 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
245
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
246 if(pc->frame_start_found){
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
247 /* EOF considered as end of frame */
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
248 if (buf_size == 0)
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
249 return 0;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
250 for(; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
251 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
252 if((state&0xFFFFFF00) == 0x100){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
253 if(state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
254 pc->frame_start_found=0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
255 pc->state=-1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
256 return i-3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
257 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
258 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
259 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
260 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
261 pc->state= state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
262 return END_NOT_FOUND;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
263 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
264
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
265 static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
266 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
267 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
268 unsigned int state=0xFFFFFFFF, v;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
269 int val;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
270
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
271 buf_ptr = *pbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
272 while (buf_ptr < buf_end) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
273 v = *buf_ptr++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
274 if (state == 0x000001) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
275 state = ((state << 8) | v) & 0xffffff;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
276 val = state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
277 goto found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
278 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
279 state = ((state << 8) | v) & 0xffffff;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
280 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
281 val = -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
282 found:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
283 *pbuf_ptr = buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
284 return val;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
285 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
286
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
287 /* XXX: merge with libavcodec ? */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
288 #define MPEG1_FRAME_RATE_BASE 1001
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
289
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
290 static const int frame_rate_tab[16] = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
291 0,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
292 24000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
293 24024,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
294 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
295 30000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
296 30030,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
297 50050,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
298 60000,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
299 60060,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
300 // Xing's 15fps: (9)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
301 15015,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
302 // libmpeg3's "Unofficial economy rates": (10-13)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
303 5005,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
304 10010,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
305 12012,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
306 15015,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
307 // random, just to avoid segfault !never encode these
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
308 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
309 25025,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
310 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
311
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
312 static void mpegvideo_extract_headers(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
313 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
314 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
315 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
316 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
317 const uint8_t *buf_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
318 int32_t start_code;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
319 int frame_rate_index, ext_type, bytes_left;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
320 int frame_rate_ext_n, frame_rate_ext_d;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
321 int top_field_first, repeat_first_field, progressive_frame;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
322 int horiz_size_ext, vert_size_ext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
323
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
324 s->repeat_pict = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
325 buf_end = buf + buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
326 while (buf < buf_end) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
327 start_code = find_start_code(&buf, buf_end);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
328 bytes_left = buf_end - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
329 switch(start_code) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
330 case PICTURE_START_CODE:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
331 if (bytes_left >= 2) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
332 s->pict_type = (buf[1] >> 3) & 7;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
333 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
334 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
335 case SEQ_START_CODE:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
336 if (bytes_left >= 4) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
337 pc->width = avctx->width = (buf[0] << 4) | (buf[1] >> 4);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
338 pc->height = avctx->height = ((buf[1] & 0x0f) << 8) | buf[2];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
339 frame_rate_index = buf[3] & 0xf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
340 pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
341 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE;
1681
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
342 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
343 avctx->sub_id = 1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
344 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
345 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
346 case EXT_START_CODE:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
347 if (bytes_left >= 1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
348 ext_type = (buf[0] >> 4);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
349 switch(ext_type) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
350 case 0x1: /* sequence extension */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
351 if (bytes_left >= 6) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
352 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
353 vert_size_ext = (buf[2] >> 5) & 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
354 frame_rate_ext_n = (buf[5] >> 5) & 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
355 frame_rate_ext_d = (buf[5] & 0x1f);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
356 pc->progressive_sequence = buf[1] & (1 << 3);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
357
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
358 avctx->width = pc->width | (horiz_size_ext << 12);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
359 avctx->height = pc->height | (vert_size_ext << 12);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
360 avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
361 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
1681
27a272442d6b fill codec info
bellard
parents: 1614
diff changeset
362 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
363 avctx->sub_id = 2; /* forces MPEG2 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
364 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
365 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
366 case 0x8: /* picture coding extension */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
367 if (bytes_left >= 5) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
368 top_field_first = buf[3] & (1 << 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
369 repeat_first_field = buf[3] & (1 << 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
370 progressive_frame = buf[4] & (1 << 7);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
371
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
372 /* check if we must repeat the frame */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
373 if (repeat_first_field) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
374 if (pc->progressive_sequence) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
375 if (top_field_first)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
376 s->repeat_pict = 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
377 else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
378 s->repeat_pict = 2;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
379 } else if (progressive_frame) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
380 s->repeat_pict = 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
381 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
382 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
383 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
384 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
385 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
386 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
387 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
388 case -1:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
389 goto the_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
390 default:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
391 /* we stop parsing when we encounter a slice. It ensures
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
392 that this function takes a negligible amount of time */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
393 if (start_code >= SLICE_MIN_START_CODE &&
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
394 start_code <= SLICE_MAX_START_CODE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
395 goto the_end;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
396 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
397 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
398 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
399 the_end: ;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
400 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
401
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
402 static int mpegvideo_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
403 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
404 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
405 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
406 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
407 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
408 int next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
409
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
410 next= mpeg1_find_frame_end(pc, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
411
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
412 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
413 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
414 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
415 return buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
416 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
417 /* we have a full frame : we just parse the first few MPEG headers
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
418 to have the full timing information. The time take by this
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
419 function should be negligible for uncorrupted streams */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
420 mpegvideo_extract_headers(s, avctx, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
421 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
422 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
423 s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
424 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
425
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
426 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
427 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
428 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
429 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
430
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
431 static void mpegvideo_parse_close(AVCodecParserContext *s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
432 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
433 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
434
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
435 av_free(pc->buffer);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
436 av_free(pc->enc);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
437 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
438
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
439 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
440
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
441 /**
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
442 * finds the end of the current frame in the bitstream.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
443 * @return the position of the first byte of the next frame, or -1
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
444 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
445 static int mpeg4_find_frame_end(ParseContext1 *pc,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
446 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
447 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
448 int vop_found, i;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
449 uint32_t state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
450
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
451 vop_found= pc->frame_start_found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
452 state= pc->state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
453
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
454 i=0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
455 if(!vop_found){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
456 for(i=0; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
457 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
458 if(state == 0x1B6){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
459 i++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
460 vop_found=1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
461 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
462 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
463 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
464 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
465
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
466 if(vop_found){
1694
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
467 /* EOF considered as end of frame */
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
468 if (buf_size == 0)
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
469 return 0;
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
470 for(; i<buf_size; i++){
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
471 state= (state<<8) | buf[i];
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
472 if((state&0xFFFFFF00) == 0x100){
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
473 pc->frame_start_found=0;
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
474 pc->state=-1;
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
475 return i-3;
13169235c306 added End Of File handling to return last picture for MPEG1/2/4
bellard
parents: 1681
diff changeset
476 }
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
477 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
478 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
479 pc->frame_start_found= vop_found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
480 pc->state= state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
481 return END_NOT_FOUND;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
482 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
483
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
484 /* used by parser */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
485 /* XXX: make it use less memory */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
486 static int av_mpeg4_decode_header(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
487 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
488 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
489 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
490 ParseContext1 *pc = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
491 MpegEncContext *s = pc->enc;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
492 GetBitContext gb1, *gb = &gb1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
493 int ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
494
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
495 s->avctx = avctx;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
496 s->current_picture_ptr = &s->current_picture;
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
497
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
498 if (avctx->extradata_size && pc->first_picture){
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
499 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
500 ret = ff_mpeg4_decode_picture_header(s, gb);
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
501 }
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
502
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
503 init_get_bits(gb, buf, 8 * buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
504 ret = ff_mpeg4_decode_picture_header(s, gb);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
505 if (s->width) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
506 avctx->width = s->width;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
507 avctx->height = s->height;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
508 }
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
509 pc->first_picture = 0;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
510 return ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
511 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
512
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
513 int mpeg4video_parse_init(AVCodecParserContext *s)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
514 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
515 ParseContext1 *pc = s->priv_data;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
516
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
517 pc->enc = av_mallocz(sizeof(MpegEncContext));
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
518 if (!pc->enc)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
519 return -1;
1614
6c82ef97d3e6 also parse extradata for MPEG4
bellard
parents: 1613
diff changeset
520 pc->first_picture = 1;
1613
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
521 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
522 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
523
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
524 static int mpeg4video_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
525 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
526 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
527 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
528 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
529 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
530 int next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
531
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
532 next= mpeg4_find_frame_end(pc, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
533
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
534 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
535 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
536 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
537 return buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
538 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
539 av_mpeg4_decode_header(s, avctx, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
540
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
541 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
542 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
543 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
544 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
545
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
546 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
547
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
548 static int h263_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
549 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
550 int vop_found, i;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
551 uint32_t state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
552
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
553 vop_found= pc->frame_start_found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
554 state= pc->state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
555
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
556 i=0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
557 if(!vop_found){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
558 for(i=0; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
559 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
560 if(state>>(32-22) == 0x20){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
561 i++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
562 vop_found=1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
563 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
564 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
565 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
566 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
567
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
568 if(vop_found){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
569 for(; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
570 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
571 if(state>>(32-22) == 0x20){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
572 pc->frame_start_found=0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
573 pc->state=-1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
574 return i-3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
575 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
576 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
577 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
578 pc->frame_start_found= vop_found;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
579 pc->state= state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
580
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
581 return END_NOT_FOUND;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
582 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
583
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
584 static int h263_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
585 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
586 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
587 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
588 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
589 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
590 int next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
591
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
592 next= h263_find_frame_end(pc, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
593
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
594 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
595 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
596 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
597 return buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
598 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
599
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
600 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
601 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
602 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
603 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
604
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
605 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
606
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
607 /**
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
608 * finds the end of the current frame in the bitstream.
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
609 * @return the position of the first byte of the next frame, or -1
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
610 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
611 static int h264_find_frame_end(ParseContext1 *pc, const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
612 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
613 int i;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
614 uint32_t state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
615 //printf("first %02X%02X%02X%02X\n", buf[0], buf[1],buf[2],buf[3]);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
616 // mb_addr= pc->mb_addr - 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
617 state= pc->state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
618 //FIXME this will fail with slices
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
619 for(i=0; i<buf_size; i++){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
620 state= (state<<8) | buf[i];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
621 if((state&0xFFFFFF1F) == 0x101 || (state&0xFFFFFF1F) == 0x102 || (state&0xFFFFFF1F) == 0x105){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
622 if(pc->frame_start_found){
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
623 pc->state=-1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
624 pc->frame_start_found= 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
625 return i-3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
626 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
627 pc->frame_start_found= 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
628 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
629 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
630
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
631 pc->state= state;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
632 return END_NOT_FOUND;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
633 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
634
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
635 static int h264_parse(AVCodecParserContext *s,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
636 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
637 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
638 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
639 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
640 ParseContext1 *pc = s->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
641 int next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
642
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
643 next= h264_find_frame_end(pc, buf, buf_size);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
644
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
645 if (ff_combine_frame1(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
646 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
647 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
648 return buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
649 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
650
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
651 *poutbuf = (uint8_t *)buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
652 *poutbuf_size = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
653 return next;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
654 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
655
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
656 /*************************/
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
657
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
658 typedef struct MpegAudioParseContext {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
659 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
660 uint8_t *inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
661 int frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
662 int free_format_frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
663 int free_format_next_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
664 } MpegAudioParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
665
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
666 #define MPA_HEADER_SIZE 4
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
667
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
668 /* header + layer + bitrate + freq + lsf/mpeg25 */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
669 #define SAME_HEADER_MASK \
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
670 (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
671
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
672 static int mpegaudio_parse_init(AVCodecParserContext *s1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
673 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
674 MpegAudioParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
675 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
676 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
677 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
678
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
679 static int mpegaudio_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
680 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
681 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
682 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
683 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
684 MpegAudioParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
685 int len, ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
686 uint32_t header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
687 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
688
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
689 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
690 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
691 buf_ptr = buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
692 while (buf_size > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
693 len = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
694 if (s->frame_size == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
695 /* special case for next header for first frame in free
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
696 format case (XXX: find a simpler method) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
697 if (s->free_format_next_header != 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
698 s->inbuf[0] = s->free_format_next_header >> 24;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
699 s->inbuf[1] = s->free_format_next_header >> 16;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
700 s->inbuf[2] = s->free_format_next_header >> 8;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
701 s->inbuf[3] = s->free_format_next_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
702 s->inbuf_ptr = s->inbuf + 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
703 s->free_format_next_header = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
704 goto got_header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
705 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
706 /* no header seen : find one. We need at least MPA_HEADER_SIZE
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
707 bytes to parse it */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
708 len = MPA_HEADER_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
709 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
710 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
711 if (len > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
712 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
713 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
714 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
715 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
716 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
717 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
718 got_header:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
719 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
720 (s->inbuf[2] << 8) | s->inbuf[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
721
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
722 ret = mpa_decode_header(avctx, header);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
723 if (ret < 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
724 /* no sync found : move by one byte (inefficient, but simple!) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
725 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
726 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
727 dprintf("skip %x\n", header);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
728 /* reset free format frame size to give a chance
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
729 to get a new bitrate */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
730 s->free_format_frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
731 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
732 s->frame_size = ret;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
733 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
734 /* free format: prepare to compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
735 if (decode_header(s, header) == 1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
736 s->frame_size = -1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
737 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
738 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
739 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
740 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
741 } else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
742 #if 0
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
743 if (s->frame_size == -1) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
744 /* free format : find next sync to compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
745 len = MPA_MAX_CODED_FRAME_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
746 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
747 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
748 if (len == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
749 /* frame too long: resync */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
750 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
751 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
752 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
753 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
754 uint8_t *p, *pend;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
755 uint32_t header1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
756 int padding;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
757
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
758 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
759 /* check for header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
760 p = s->inbuf_ptr - 3;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
761 pend = s->inbuf_ptr + len - 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
762 while (p <= pend) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
763 header = (p[0] << 24) | (p[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
764 (p[2] << 8) | p[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
765 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
766 (s->inbuf[2] << 8) | s->inbuf[3];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
767 /* check with high probability that we have a
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
768 valid header */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
769 if ((header & SAME_HEADER_MASK) ==
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
770 (header1 & SAME_HEADER_MASK)) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
771 /* header found: update pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
772 len = (p + 4) - s->inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
773 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
774 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
775 s->inbuf_ptr = p;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
776 /* compute frame size */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
777 s->free_format_next_header = header;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
778 s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
779 padding = (header1 >> 9) & 1;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
780 if (s->layer == 1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
781 s->free_format_frame_size -= padding * 4;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
782 else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
783 s->free_format_frame_size -= padding;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
784 dprintf("free frame size=%d padding=%d\n",
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
785 s->free_format_frame_size, padding);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
786 decode_header(s, header1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
787 goto next_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
788 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
789 p++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
790 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
791 /* not found: simply increase pointers */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
792 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
793 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
794 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
795 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
796 } else
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
797 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
798 if (len < s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
799 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
800 s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
801 len = s->frame_size - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
802 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
803 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
804 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
805 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
806 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
807 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
808 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
809 // next_data:
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
810 if (s->frame_size > 0 &&
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
811 (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
812 *poutbuf = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
813 *poutbuf_size = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
814 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
815 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
816 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
817 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
818 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
819 return buf_ptr - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
820 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
821
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
822 #ifdef CONFIG_AC3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
823 extern int a52_syncinfo (const uint8_t * buf, int * flags,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
824 int * sample_rate, int * bit_rate);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
825
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
826 typedef struct AC3ParseContext {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
827 uint8_t inbuf[4096]; /* input buffer */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
828 uint8_t *inbuf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
829 int frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
830 int flags;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
831 } AC3ParseContext;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
832
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
833 #define AC3_HEADER_SIZE 7
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
834 #define A52_LFE 16
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
835
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
836 static int ac3_parse_init(AVCodecParserContext *s1)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
837 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
838 AC3ParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
839 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
840 return 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
841 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
842
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
843 static int ac3_parse(AVCodecParserContext *s1,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
844 AVCodecContext *avctx,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
845 uint8_t **poutbuf, int *poutbuf_size,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
846 const uint8_t *buf, int buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
847 {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
848 AC3ParseContext *s = s1->priv_data;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
849 const uint8_t *buf_ptr;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
850 int len, sample_rate, bit_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
851 static const int ac3_channels[8] = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
852 2, 1, 2, 3, 3, 4, 4, 5
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
853 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
854
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
855 *poutbuf = NULL;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
856 *poutbuf_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
857
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
858 buf_ptr = buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
859 while (buf_size > 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
860 len = s->inbuf_ptr - s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
861 if (s->frame_size == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
862 /* no header seen : find one. We need at least 7 bytes to parse it */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
863 len = AC3_HEADER_SIZE - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
864 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
865 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
866 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
867 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
868 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
869 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
870 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
871 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
872 if (len == 0) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
873 /* no sync found : move by one byte (inefficient, but simple!) */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
874 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
875 s->inbuf_ptr--;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
876 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
877 s->frame_size = len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
878 /* update codec info */
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
879 avctx->sample_rate = sample_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
880 avctx->channels = ac3_channels[s->flags & 7];
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
881 if (s->flags & A52_LFE)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
882 avctx->channels++;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
883 avctx->bit_rate = bit_rate;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
884 avctx->frame_size = 6 * 256;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
885 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
886 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
887 } else if (len < s->frame_size) {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
888 len = s->frame_size - len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
889 if (len > buf_size)
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
890 len = buf_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
891
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
892 memcpy(s->inbuf_ptr, buf_ptr, len);
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
893 buf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
894 s->inbuf_ptr += len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
895 buf_size -= len;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
896 } else {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
897 *poutbuf = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
898 *poutbuf_size = s->frame_size;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
899 s->inbuf_ptr = s->inbuf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
900 s->frame_size = 0;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
901 break;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
902 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
903 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
904 return buf_ptr - buf;
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
905 }
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
906 #endif
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
907
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
908 AVCodecParser mpegvideo_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
909 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
910 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
911 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
912 mpegvideo_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
913 mpegvideo_parse_close,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
914 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
915
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
916 AVCodecParser mpeg4video_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
917 { CODEC_ID_MPEG4 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
918 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
919 mpeg4video_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
920 mpeg4video_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
921 mpegvideo_parse_close,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
922 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
923
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
924 AVCodecParser h263_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
925 { CODEC_ID_H263 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
926 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
927 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
928 h263_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
929 mpegvideo_parse_close,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
930 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
931
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
932 AVCodecParser h264_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
933 { CODEC_ID_H264 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
934 sizeof(ParseContext1),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
935 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
936 h264_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
937 mpegvideo_parse_close,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
938 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
939
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
940 AVCodecParser mpegaudio_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
941 { CODEC_ID_MP2, CODEC_ID_MP3 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
942 sizeof(MpegAudioParseContext),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
943 mpegaudio_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
944 mpegaudio_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
945 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
946 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
947
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
948 #ifdef CONFIG_AC3
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
949 AVCodecParser ac3_parser = {
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
950 { CODEC_ID_AC3 },
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
951 sizeof(AC3ParseContext),
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
952 ac3_parse_init,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
953 ac3_parse,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
954 NULL,
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
955 };
0279c6c61f11 new audio/video parser API
bellard
parents:
diff changeset
956 #endif