annotate mpeg4video_parser.c @ 11225:5811a86f55f1 libavcodec

Use memset to set the runs partially coded superblocks Much faster for long runs (e.g. nearly uncoded frames), slightly faster for the general case.
author conrad
date Sun, 21 Feb 2010 00:10:47 +0000
parents 9311c65558c0
children 20752e8b2657
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
1 /*
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
2 * MPEG4 Video frame extraction
8629
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 4957
diff changeset
3 * Copyright (c) 2003 Fabrice Bellard
04423b2f6e0b cosmetics: Remove pointless period after copyright statement non-sentences.
diego
parents: 4957
diff changeset
4 * Copyright (c) 2003 Michael Niedermayer
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
5 *
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
6 * This file is part of FFmpeg.
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
7 *
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
12 *
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
16 * Lesser General Public License for more details.
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
17 *
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
21 */
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
22
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
23 #include "parser.h"
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
24 #include "mpegvideo.h"
4957
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
25 #include "mpeg4video_parser.h"
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
26
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
27
4957
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
28 int ff_mpeg4_find_frame_end(ParseContext *pc, const uint8_t *buf, int buf_size){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
29 int vop_found, i;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
30 uint32_t state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
31
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
32 vop_found= pc->frame_start_found;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
33 state= pc->state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
34
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
35 i=0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
36 if(!vop_found){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
37 for(i=0; i<buf_size; i++){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
38 state= (state<<8) | buf[i];
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
39 if(state == 0x1B6){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
40 i++;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
41 vop_found=1;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
42 break;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
43 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
44 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
45 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
46
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
47 if(vop_found){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
48 /* EOF considered as end of frame */
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
49 if (buf_size == 0)
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
50 return 0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
51 for(; i<buf_size; i++){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
52 state= (state<<8) | buf[i];
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
53 if((state&0xFFFFFF00) == 0x100){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
54 pc->frame_start_found=0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
55 pc->state=-1;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
56 return i-3;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
57 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
58 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
59 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
60 pc->frame_start_found= vop_found;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
61 pc->state= state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
62 return END_NOT_FOUND;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
63 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
64
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
65 /* XXX: make it use less memory */
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
66 static int av_mpeg4_decode_header(AVCodecParserContext *s1,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
67 AVCodecContext *avctx,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
68 const uint8_t *buf, int buf_size)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
69 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
70 ParseContext1 *pc = s1->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
71 MpegEncContext *s = pc->enc;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
72 GetBitContext gb1, *gb = &gb1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
73 int ret;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
74
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
75 s->avctx = avctx;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
76 s->current_picture_ptr = &s->current_picture;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
77
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
78 if (avctx->extradata_size && pc->first_picture){
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
79 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
80 ret = ff_mpeg4_decode_picture_header(s, gb);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
81 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
82
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
83 init_get_bits(gb, buf, 8 * buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
84 ret = ff_mpeg4_decode_picture_header(s, gb);
10641
9311c65558c0 Make sure the parsers do not overwrite width/height as this can interfere
michael
parents: 9007
diff changeset
85 if (s->width && (!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height)) {
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
86 avcodec_set_dimensions(avctx, s->width, s->height);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
87 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
88 s1->pict_type= s->pict_type;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
89 pc->first_picture = 0;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
90 return ret;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
91 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
92
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8629
diff changeset
93 static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
94 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
95 ParseContext1 *pc = s->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
96
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
97 pc->enc = av_mallocz(sizeof(MpegEncContext));
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
98 if (!pc->enc)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
99 return -1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
100 pc->first_picture = 1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
101 return 0;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
102 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
103
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
104 static int mpeg4video_parse(AVCodecParserContext *s,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
105 AVCodecContext *avctx,
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
106 const uint8_t **poutbuf, int *poutbuf_size,
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
107 const uint8_t *buf, int buf_size)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
108 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
109 ParseContext *pc = s->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
110 int next;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
111
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
112 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
113 next= buf_size;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
114 }else{
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
115 next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
116
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
117 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
118 *poutbuf = NULL;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
119 *poutbuf_size = 0;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
120 return buf_size;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
121 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
122 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
123 av_mpeg4_decode_header(s, avctx, buf, buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
124
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
125 *poutbuf = buf;
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
126 *poutbuf_size = buf_size;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
127 return next;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
128 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
129
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
130
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
131 AVCodecParser mpeg4video_parser = {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
132 { CODEC_ID_MPEG4 },
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
133 sizeof(ParseContext1),
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
134 mpeg4video_parse_init,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
135 mpeg4video_parse,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
136 ff_parse1_close,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
137 ff_mpeg4video_split,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
138 };