Browse code

new audio/video parser API

Originally committed as revision 2492 to svn://svn.ffmpeg.org/ffmpeg/trunk

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