lowres width/height cleanup 3rd try
[libav.git] / libavcodec / parser.c
CommitLineData
8424cf50
FB
1/*
2 * Audio and Video frame extraction
3 * Copyright (c) 2003 Fabrice Bellard.
4 * Copyright (c) 2003 Michael Niedermayer.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20#include "avcodec.h"
21#include "mpegvideo.h"
22#include "mpegaudio.h"
23
24AVCodecParser *av_first_parser = NULL;
25
26void av_register_codec_parser(AVCodecParser *parser)
27{
28 parser->next = av_first_parser;
29 av_first_parser = parser;
30}
31
32AVCodecParserContext *av_parser_init(int codec_id)
33{
34 AVCodecParserContext *s;
35 AVCodecParser *parser;
36 int ret;
37
38 for(parser = av_first_parser; parser != NULL; parser = parser->next) {
39 if (parser->codec_ids[0] == codec_id ||
40 parser->codec_ids[1] == codec_id ||
41 parser->codec_ids[2] == codec_id)
42 goto found;
43 }
44 return NULL;
45 found:
46 s = av_mallocz(sizeof(AVCodecParserContext));
47 if (!s)
48 return NULL;
49 s->parser = parser;
50 s->priv_data = av_mallocz(parser->priv_data_size);
51 if (!s->priv_data) {
52 av_free(s);
53 return NULL;
54 }
55 if (parser->parser_init) {
56 ret = parser->parser_init(s);
57 if (ret != 0) {
58 av_free(s->priv_data);
59 av_free(s);
60 return NULL;
61 }
62 }
a62aecce 63 s->fetch_timestamp=1;
8424cf50
FB
64 return s;
65}
66
6e45e928
FB
67/* NOTE: buf_size == 0 is used to signal EOF so that the last frame
68 can be returned if necessary */
8424cf50
FB
69int av_parser_parse(AVCodecParserContext *s,
70 AVCodecContext *avctx,
71 uint8_t **poutbuf, int *poutbuf_size,
b84f2a35
FB
72 const uint8_t *buf, int buf_size,
73 int64_t pts, int64_t dts)
8424cf50 74{
b84f2a35 75 int index, i, k;
6e45e928
FB
76 uint8_t dummy_buf[FF_INPUT_BUFFER_PADDING_SIZE];
77
78 if (buf_size == 0) {
79 /* padding is always necessary even if EOF, so we add it here */
80 memset(dummy_buf, 0, sizeof(dummy_buf));
81 buf = dummy_buf;
b84f2a35
FB
82 } else {
83 /* add a new packet descriptor */
84 k = (s->cur_frame_start_index + 1) & (AV_PARSER_PTS_NB - 1);
85 s->cur_frame_start_index = k;
86 s->cur_frame_offset[k] = s->cur_offset;
87 s->cur_frame_pts[k] = pts;
88 s->cur_frame_dts[k] = dts;
89
90 /* fill first PTS/DTS */
a62aecce
MN
91 if (s->fetch_timestamp){
92 s->fetch_timestamp=0;
b84f2a35
FB
93 s->last_pts = pts;
94 s->last_dts = dts;
c77a9a0e
MN
95 s->cur_frame_pts[k] =
96 s->cur_frame_dts[k] = AV_NOPTS_VALUE;
b84f2a35 97 }
6e45e928
FB
98 }
99
8424cf50
FB
100 /* WARNING: the returned index can be negative */
101 index = s->parser->parser_parse(s, avctx, poutbuf, poutbuf_size, buf, buf_size);
c77a9a0e 102//av_log(NULL, AV_LOG_DEBUG, "parser: in:%lld, %lld, out:%lld, %lld, in:%d out:%d id:%d\n", pts, dts, s->last_pts, s->last_dts, buf_size, *poutbuf_size, avctx->codec_id);
8424cf50
FB
103 /* update the file pointer */
104 if (*poutbuf_size) {
b84f2a35 105 /* fill the data for the current frame */
8424cf50 106 s->frame_offset = s->last_frame_offset;
b84f2a35
FB
107 s->pts = s->last_pts;
108 s->dts = s->last_dts;
109
110 /* offset of the next frame */
8424cf50 111 s->last_frame_offset = s->cur_offset + index;
b84f2a35
FB
112 /* find the packet in which the new frame starts. It
113 is tricky because of MPEG video start codes
114 which can begin in one packet and finish in
115 another packet. In the worst case, an MPEG
116 video start code could be in 4 different
117 packets. */
118 k = s->cur_frame_start_index;
119 for(i = 0; i < AV_PARSER_PTS_NB; i++) {
120 if (s->last_frame_offset >= s->cur_frame_offset[k])
121 break;
122 k = (k - 1) & (AV_PARSER_PTS_NB - 1);
123 }
a62aecce 124
b84f2a35
FB
125 s->last_pts = s->cur_frame_pts[k];
126 s->last_dts = s->cur_frame_dts[k];
a62aecce
MN
127
128 /* some parsers tell us the packet size even before seeing the first byte of the next packet,
129 so the next pts/dts is in the next chunk */
130 if(index == buf_size){
131 s->fetch_timestamp=1;
132 }
8424cf50
FB
133 }
134 if (index < 0)
135 index = 0;
136 s->cur_offset += index;
137 return index;
138}
139
140void av_parser_close(AVCodecParserContext *s)
141{
142 if (s->parser->parser_close)
143 s->parser->parser_close(s);
144 av_free(s->priv_data);
145 av_free(s);
146}
147
148/*****************************************************/
149
150//#define END_NOT_FOUND (-100)
151
152#define PICTURE_START_CODE 0x00000100
153#define SEQ_START_CODE 0x000001b3
154#define EXT_START_CODE 0x000001b5
155#define SLICE_MIN_START_CODE 0x00000101
156#define SLICE_MAX_START_CODE 0x000001af
157
158typedef struct ParseContext1{
e4cb187d
MN
159 ParseContext pc;
160/* XXX/FIXME PC1 vs. PC */
8424cf50
FB
161 /* MPEG2 specific */
162 int frame_rate;
163 int progressive_sequence;
164 int width, height;
c6f353ff 165
8424cf50
FB
166 /* XXX: suppress that, needed by MPEG4 */
167 MpegEncContext *enc;
c6f353ff 168 int first_picture;
8424cf50
FB
169} ParseContext1;
170
171/**
172 * combines the (truncated) bitstream to a complete frame
173 * @returns -1 if no complete frame could be created
174 */
e4cb187d 175int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
8424cf50
FB
176{
177#if 0
178 if(pc->overread){
179 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
180 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
181 }
182#endif
183
184 /* copy overreaded bytes from last frame into buffer */
185 for(; pc->overread>0; pc->overread--){
186 pc->buffer[pc->index++]= pc->buffer[pc->overread_index++];
187 }
188
189 pc->last_index= pc->index;
190
191 /* copy into buffer end return */
192 if(next == END_NOT_FOUND){
193 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, (*buf_size) + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
194
195 memcpy(&pc->buffer[pc->index], *buf, *buf_size);
196 pc->index += *buf_size;
197 return -1;
198 }
199
200 *buf_size=
201 pc->overread_index= pc->index + next;
202
203 /* append to buffer */
204 if(pc->index){
205 pc->buffer= av_fast_realloc(pc->buffer, &pc->buffer_size, next + pc->index + FF_INPUT_BUFFER_PADDING_SIZE);
206
207 memcpy(&pc->buffer[pc->index], *buf, next + FF_INPUT_BUFFER_PADDING_SIZE );
208 pc->index = 0;
209 *buf= pc->buffer;
210 }
211
212 /* store overread bytes */
213 for(;next < 0; next++){
214 pc->state = (pc->state<<8) | pc->buffer[pc->last_index + next];
215 pc->overread++;
216 }
217
218#if 0
219 if(pc->overread){
220 printf("overread %d, state:%X next:%d index:%d o_index:%d\n", pc->overread, pc->state, next, pc->index, pc->overread_index);
221 printf("%X %X %X %X\n", (*buf)[0], (*buf)[1],(*buf)[2],(*buf)[3]);
222 }
223#endif
224
225 return 0;
226}
227
8424cf50
FB
228static int find_start_code(const uint8_t **pbuf_ptr, const uint8_t *buf_end)
229{
230 const uint8_t *buf_ptr;
231 unsigned int state=0xFFFFFFFF, v;
232 int val;
233
234 buf_ptr = *pbuf_ptr;
235 while (buf_ptr < buf_end) {
236 v = *buf_ptr++;
237 if (state == 0x000001) {
238 state = ((state << 8) | v) & 0xffffff;
239 val = state;
240 goto found;
241 }
242 state = ((state << 8) | v) & 0xffffff;
243 }
244 val = -1;
245 found:
246 *pbuf_ptr = buf_ptr;
247 return val;
248}
249
250/* XXX: merge with libavcodec ? */
251#define MPEG1_FRAME_RATE_BASE 1001
252
253static const int frame_rate_tab[16] = {
254 0,
255 24000,
256 24024,
257 25025,
258 30000,
259 30030,
260 50050,
261 60000,
262 60060,
263 // Xing's 15fps: (9)
264 15015,
265 // libmpeg3's "Unofficial economy rates": (10-13)
266 5005,
267 10010,
268 12012,
269 15015,
270 // random, just to avoid segfault !never encode these
271 25025,
272 25025,
273};
274
275static void mpegvideo_extract_headers(AVCodecParserContext *s,
276 AVCodecContext *avctx,
277 const uint8_t *buf, int buf_size)
278{
279 ParseContext1 *pc = s->priv_data;
280 const uint8_t *buf_end;
281 int32_t start_code;
282 int frame_rate_index, ext_type, bytes_left;
283 int frame_rate_ext_n, frame_rate_ext_d;
8dab64b6 284 int picture_structure, top_field_first, repeat_first_field, progressive_frame;
8424cf50
FB
285 int horiz_size_ext, vert_size_ext;
286
287 s->repeat_pict = 0;
288 buf_end = buf + buf_size;
289 while (buf < buf_end) {
290 start_code = find_start_code(&buf, buf_end);
291 bytes_left = buf_end - buf;
292 switch(start_code) {
293 case PICTURE_START_CODE:
294 if (bytes_left >= 2) {
295 s->pict_type = (buf[1] >> 3) & 7;
296 }
297 break;
298 case SEQ_START_CODE:
299 if (bytes_left >= 4) {
0b2346d3
MN
300 pc->width = (buf[0] << 4) | (buf[1] >> 4);
301 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
21adafec 302 avcodec_set_dimensions(avctx, pc->width, pc->height);
8424cf50
FB
303 frame_rate_index = buf[3] & 0xf;
304 pc->frame_rate = avctx->frame_rate = frame_rate_tab[frame_rate_index];
305 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE;
3e9d718e
FB
306 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
307 avctx->sub_id = 1;
8424cf50
FB
308 }
309 break;
310 case EXT_START_CODE:
311 if (bytes_left >= 1) {
312 ext_type = (buf[0] >> 4);
313 switch(ext_type) {
314 case 0x1: /* sequence extension */
315 if (bytes_left >= 6) {
316 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
317 vert_size_ext = (buf[2] >> 5) & 3;
318 frame_rate_ext_n = (buf[5] >> 5) & 3;
319 frame_rate_ext_d = (buf[5] & 0x1f);
320 pc->progressive_sequence = buf[1] & (1 << 3);
321
0b2346d3
MN
322 pc->width |=(horiz_size_ext << 12);
323 pc->height |=( vert_size_ext << 12);
21adafec 324 avcodec_set_dimensions(avctx, pc->width, pc->height);
8424cf50
FB
325 avctx->frame_rate = pc->frame_rate * (frame_rate_ext_n + 1);
326 avctx->frame_rate_base = MPEG1_FRAME_RATE_BASE * (frame_rate_ext_d + 1);
3e9d718e 327 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
8424cf50
FB
328 avctx->sub_id = 2; /* forces MPEG2 */
329 }
330 break;
331 case 0x8: /* picture coding extension */
332 if (bytes_left >= 5) {
5bb994e2 333 picture_structure = buf[2]&3;
8424cf50
FB
334 top_field_first = buf[3] & (1 << 7);
335 repeat_first_field = buf[3] & (1 << 1);
336 progressive_frame = buf[4] & (1 << 7);
337
338 /* check if we must repeat the frame */
339 if (repeat_first_field) {
340 if (pc->progressive_sequence) {
341 if (top_field_first)
342 s->repeat_pict = 4;
343 else
344 s->repeat_pict = 2;
345 } else if (progressive_frame) {
346 s->repeat_pict = 1;
347 }
348 }
8dab64b6
MN
349
350 /* the packet only represents half a frame
351 XXX,FIXME maybe find a different solution */
352 if(picture_structure != 3)
353 s->repeat_pict = -1;
8424cf50
FB
354 }
355 break;
356 }
357 }
358 break;
359 case -1:
360 goto the_end;
361 default:
362 /* we stop parsing when we encounter a slice. It ensures
363 that this function takes a negligible amount of time */
364 if (start_code >= SLICE_MIN_START_CODE &&
365 start_code <= SLICE_MAX_START_CODE)
366 goto the_end;
367 break;
368 }
369 }
370 the_end: ;
371}
372
373static int mpegvideo_parse(AVCodecParserContext *s,
374 AVCodecContext *avctx,
375 uint8_t **poutbuf, int *poutbuf_size,
376 const uint8_t *buf, int buf_size)
377{
e4cb187d
MN
378 ParseContext1 *pc1 = s->priv_data;
379 ParseContext *pc= &pc1->pc;
8424cf50
FB
380 int next;
381
e4cb187d 382 next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
8424cf50 383
e4cb187d 384 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
8424cf50
FB
385 *poutbuf = NULL;
386 *poutbuf_size = 0;
387 return buf_size;
388 }
389 /* we have a full frame : we just parse the first few MPEG headers
390 to have the full timing information. The time take by this
391 function should be negligible for uncorrupted streams */
392 mpegvideo_extract_headers(s, avctx, buf, buf_size);
393#if 0
394 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
395 s->pict_type, (double)avctx->frame_rate / avctx->frame_rate_base, s->repeat_pict);
396#endif
397
398 *poutbuf = (uint8_t *)buf;
399 *poutbuf_size = buf_size;
400 return next;
401}
402
e4cb187d 403void ff_parse_close(AVCodecParserContext *s)
8424cf50 404{
e4cb187d 405 ParseContext *pc = s->priv_data;
8424cf50
FB
406
407 av_free(pc->buffer);
8424cf50
FB
408}
409
e4cb187d 410static void parse1_close(AVCodecParserContext *s)
8424cf50 411{
e4cb187d 412 ParseContext1 *pc1 = s->priv_data;
8424cf50 413
e4cb187d
MN
414 av_free(pc1->pc.buffer);
415 av_free(pc1->enc);
8424cf50
FB
416}
417
e4cb187d
MN
418/*************************/
419
8424cf50
FB
420/* used by parser */
421/* XXX: make it use less memory */
422static int av_mpeg4_decode_header(AVCodecParserContext *s1,
423 AVCodecContext *avctx,
424 const uint8_t *buf, int buf_size)
425{
426 ParseContext1 *pc = s1->priv_data;
427 MpegEncContext *s = pc->enc;
428 GetBitContext gb1, *gb = &gb1;
429 int ret;
430
431 s->avctx = avctx;
c6f353ff
FB
432 s->current_picture_ptr = &s->current_picture;
433
434 if (avctx->extradata_size && pc->first_picture){
435 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
436 ret = ff_mpeg4_decode_picture_header(s, gb);
437 }
438
8424cf50
FB
439 init_get_bits(gb, buf, 8 * buf_size);
440 ret = ff_mpeg4_decode_picture_header(s, gb);
441 if (s->width) {
21adafec 442 avcodec_set_dimensions(avctx, s->width, s->height);
8424cf50 443 }
c6f353ff 444 pc->first_picture = 0;
8424cf50
FB
445 return ret;
446}
447
e96682e6 448static int mpeg4video_parse_init(AVCodecParserContext *s)
8424cf50
FB
449{
450 ParseContext1 *pc = s->priv_data;
c6f353ff 451
8424cf50
FB
452 pc->enc = av_mallocz(sizeof(MpegEncContext));
453 if (!pc->enc)
454 return -1;
c6f353ff 455 pc->first_picture = 1;
8424cf50
FB
456 return 0;
457}
458
459static int mpeg4video_parse(AVCodecParserContext *s,
460 AVCodecContext *avctx,
461 uint8_t **poutbuf, int *poutbuf_size,
462 const uint8_t *buf, int buf_size)
463{
e4cb187d 464 ParseContext *pc = s->priv_data;
8424cf50
FB
465 int next;
466
e4cb187d 467 next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
8424cf50 468
e4cb187d 469 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
8424cf50
FB
470 *poutbuf = NULL;
471 *poutbuf_size = 0;
472 return buf_size;
473 }
474 av_mpeg4_decode_header(s, avctx, buf, buf_size);
475
476 *poutbuf = (uint8_t *)buf;
477 *poutbuf_size = buf_size;
478 return next;
479}
480
481/*************************/
482
8424cf50
FB
483typedef struct MpegAudioParseContext {
484 uint8_t inbuf[MPA_MAX_CODED_FRAME_SIZE]; /* input buffer */
485 uint8_t *inbuf_ptr;
486 int frame_size;
487 int free_format_frame_size;
488 int free_format_next_header;
489} MpegAudioParseContext;
490
491#define MPA_HEADER_SIZE 4
492
493/* header + layer + bitrate + freq + lsf/mpeg25 */
494#define SAME_HEADER_MASK \
495 (0xffe00000 | (3 << 17) | (0xf << 12) | (3 << 10) | (3 << 19))
496
497static int mpegaudio_parse_init(AVCodecParserContext *s1)
498{
499 MpegAudioParseContext *s = s1->priv_data;
500 s->inbuf_ptr = s->inbuf;
501 return 0;
502}
503
504static int mpegaudio_parse(AVCodecParserContext *s1,
505 AVCodecContext *avctx,
506 uint8_t **poutbuf, int *poutbuf_size,
507 const uint8_t *buf, int buf_size)
508{
509 MpegAudioParseContext *s = s1->priv_data;
510 int len, ret;
511 uint32_t header;
512 const uint8_t *buf_ptr;
513
514 *poutbuf = NULL;
515 *poutbuf_size = 0;
516 buf_ptr = buf;
517 while (buf_size > 0) {
518 len = s->inbuf_ptr - s->inbuf;
519 if (s->frame_size == 0) {
520 /* special case for next header for first frame in free
521 format case (XXX: find a simpler method) */
522 if (s->free_format_next_header != 0) {
523 s->inbuf[0] = s->free_format_next_header >> 24;
524 s->inbuf[1] = s->free_format_next_header >> 16;
525 s->inbuf[2] = s->free_format_next_header >> 8;
526 s->inbuf[3] = s->free_format_next_header;
527 s->inbuf_ptr = s->inbuf + 4;
528 s->free_format_next_header = 0;
529 goto got_header;
530 }
531 /* no header seen : find one. We need at least MPA_HEADER_SIZE
532 bytes to parse it */
533 len = MPA_HEADER_SIZE - len;
534 if (len > buf_size)
535 len = buf_size;
536 if (len > 0) {
537 memcpy(s->inbuf_ptr, buf_ptr, len);
538 buf_ptr += len;
539 buf_size -= len;
540 s->inbuf_ptr += len;
541 }
542 if ((s->inbuf_ptr - s->inbuf) >= MPA_HEADER_SIZE) {
543 got_header:
544 header = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
545 (s->inbuf[2] << 8) | s->inbuf[3];
546
547 ret = mpa_decode_header(avctx, header);
548 if (ret < 0) {
549 /* no sync found : move by one byte (inefficient, but simple!) */
550 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
551 s->inbuf_ptr--;
552 dprintf("skip %x\n", header);
553 /* reset free format frame size to give a chance
554 to get a new bitrate */
555 s->free_format_frame_size = 0;
556 } else {
557 s->frame_size = ret;
558#if 0
559 /* free format: prepare to compute frame size */
560 if (decode_header(s, header) == 1) {
561 s->frame_size = -1;
562 }
563#endif
564 }
565 }
566 } else
567#if 0
568 if (s->frame_size == -1) {
569 /* free format : find next sync to compute frame size */
570 len = MPA_MAX_CODED_FRAME_SIZE - len;
571 if (len > buf_size)
572 len = buf_size;
573 if (len == 0) {
574 /* frame too long: resync */
575 s->frame_size = 0;
576 memmove(s->inbuf, s->inbuf + 1, s->inbuf_ptr - s->inbuf - 1);
577 s->inbuf_ptr--;
578 } else {
579 uint8_t *p, *pend;
580 uint32_t header1;
581 int padding;
582
583 memcpy(s->inbuf_ptr, buf_ptr, len);
584 /* check for header */
585 p = s->inbuf_ptr - 3;
586 pend = s->inbuf_ptr + len - 4;
587 while (p <= pend) {
588 header = (p[0] << 24) | (p[1] << 16) |
589 (p[2] << 8) | p[3];
590 header1 = (s->inbuf[0] << 24) | (s->inbuf[1] << 16) |
591 (s->inbuf[2] << 8) | s->inbuf[3];
592 /* check with high probability that we have a
593 valid header */
594 if ((header & SAME_HEADER_MASK) ==
595 (header1 & SAME_HEADER_MASK)) {
596 /* header found: update pointers */
597 len = (p + 4) - s->inbuf_ptr;
598 buf_ptr += len;
599 buf_size -= len;
600 s->inbuf_ptr = p;
601 /* compute frame size */
602 s->free_format_next_header = header;
603 s->free_format_frame_size = s->inbuf_ptr - s->inbuf;
604 padding = (header1 >> 9) & 1;
605 if (s->layer == 1)
606 s->free_format_frame_size -= padding * 4;
607 else
608 s->free_format_frame_size -= padding;
609 dprintf("free frame size=%d padding=%d\n",
610 s->free_format_frame_size, padding);
611 decode_header(s, header1);
612 goto next_data;
613 }
614 p++;
615 }
616 /* not found: simply increase pointers */
617 buf_ptr += len;
618 s->inbuf_ptr += len;
619 buf_size -= len;
620 }
621 } else
622#endif
623 if (len < s->frame_size) {
624 if (s->frame_size > MPA_MAX_CODED_FRAME_SIZE)
625 s->frame_size = MPA_MAX_CODED_FRAME_SIZE;
626 len = s->frame_size - len;
627 if (len > buf_size)
628 len = buf_size;
629 memcpy(s->inbuf_ptr, buf_ptr, len);
630 buf_ptr += len;
631 s->inbuf_ptr += len;
632 buf_size -= len;
633 }
634 // next_data:
635 if (s->frame_size > 0 &&
636 (s->inbuf_ptr - s->inbuf) >= s->frame_size) {
637 *poutbuf = s->inbuf;
638 *poutbuf_size = s->inbuf_ptr - s->inbuf;
639 s->inbuf_ptr = s->inbuf;
640 s->frame_size = 0;
641 break;
642 }
643 }
644 return buf_ptr - buf;
645}
646
647#ifdef CONFIG_AC3
648extern int a52_syncinfo (const uint8_t * buf, int * flags,
649 int * sample_rate, int * bit_rate);
650
651typedef struct AC3ParseContext {
652 uint8_t inbuf[4096]; /* input buffer */
653 uint8_t *inbuf_ptr;
654 int frame_size;
655 int flags;
656} AC3ParseContext;
657
658#define AC3_HEADER_SIZE 7
659#define A52_LFE 16
660
661static int ac3_parse_init(AVCodecParserContext *s1)
662{
663 AC3ParseContext *s = s1->priv_data;
664 s->inbuf_ptr = s->inbuf;
665 return 0;
666}
667
668static int ac3_parse(AVCodecParserContext *s1,
669 AVCodecContext *avctx,
670 uint8_t **poutbuf, int *poutbuf_size,
671 const uint8_t *buf, int buf_size)
672{
673 AC3ParseContext *s = s1->priv_data;
674 const uint8_t *buf_ptr;
675 int len, sample_rate, bit_rate;
676 static const int ac3_channels[8] = {
677 2, 1, 2, 3, 3, 4, 4, 5
678 };
679
680 *poutbuf = NULL;
681 *poutbuf_size = 0;
682
683 buf_ptr = buf;
684 while (buf_size > 0) {
685 len = s->inbuf_ptr - s->inbuf;
686 if (s->frame_size == 0) {
687 /* no header seen : find one. We need at least 7 bytes to parse it */
688 len = AC3_HEADER_SIZE - len;
689 if (len > buf_size)
690 len = buf_size;
691 memcpy(s->inbuf_ptr, buf_ptr, len);
692 buf_ptr += len;
693 s->inbuf_ptr += len;
694 buf_size -= len;
695 if ((s->inbuf_ptr - s->inbuf) == AC3_HEADER_SIZE) {
696 len = a52_syncinfo(s->inbuf, &s->flags, &sample_rate, &bit_rate);
697 if (len == 0) {
698 /* no sync found : move by one byte (inefficient, but simple!) */
699 memmove(s->inbuf, s->inbuf + 1, AC3_HEADER_SIZE - 1);
700 s->inbuf_ptr--;
701 } else {
702 s->frame_size = len;
703 /* update codec info */
704 avctx->sample_rate = sample_rate;
20da3179
MN
705 /* set channels,except if the user explicitly requests 1 or 2 channels, XXX/FIXME this is a bit ugly */
706 if(avctx->channels!=1 && avctx->channels!=2){
707 avctx->channels = ac3_channels[s->flags & 7];
708 if (s->flags & A52_LFE)
709 avctx->channels++;
710 }
8424cf50
FB
711 avctx->bit_rate = bit_rate;
712 avctx->frame_size = 6 * 256;
713 }
714 }
715 } else if (len < s->frame_size) {
716 len = s->frame_size - len;
717 if (len > buf_size)
718 len = buf_size;
719
720 memcpy(s->inbuf_ptr, buf_ptr, len);
721 buf_ptr += len;
722 s->inbuf_ptr += len;
723 buf_size -= len;
724 } else {
725 *poutbuf = s->inbuf;
726 *poutbuf_size = s->frame_size;
727 s->inbuf_ptr = s->inbuf;
728 s->frame_size = 0;
729 break;
730 }
731 }
732 return buf_ptr - buf;
733}
734#endif
735
736AVCodecParser mpegvideo_parser = {
737 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
738 sizeof(ParseContext1),
739 NULL,
740 mpegvideo_parse,
e4cb187d 741 parse1_close,
8424cf50
FB
742};
743
744AVCodecParser mpeg4video_parser = {
745 { CODEC_ID_MPEG4 },
746 sizeof(ParseContext1),
747 mpeg4video_parse_init,
748 mpeg4video_parse,
e4cb187d 749 parse1_close,
8424cf50
FB
750};
751
752AVCodecParser mpegaudio_parser = {
753 { CODEC_ID_MP2, CODEC_ID_MP3 },
754 sizeof(MpegAudioParseContext),
755 mpegaudio_parse_init,
756 mpegaudio_parse,
757 NULL,
758};
759
760#ifdef CONFIG_AC3
761AVCodecParser ac3_parser = {
762 { CODEC_ID_AC3 },
763 sizeof(AC3ParseContext),
764 ac3_parse_init,
765 ac3_parse,
766 NULL,
767};
768#endif