annotate mpeg4video_parser.c @ 12530:63edd10ad4bc libavcodec tip

Try to fix crashes introduced by r25218 r25218 made assumptions about the existence of past reference frames that weren't necessarily true.
author darkshikari
date Tue, 28 Sep 2010 09:06:22 +0000
parents 20752e8b2657
children
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"
11312
20752e8b2657 Include mpeg4video.h: Needed for declaration of ff_mpeg4_decode_picture_header.
cehoyos
parents: 10641
diff changeset
25 #include "mpeg4video.h"
4957
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
26 #include "mpeg4video_parser.h"
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
27
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
28
4957
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
29 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
30 int vop_found, i;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
31 uint32_t state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
32
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
33 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
34 state= pc->state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
35
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
36 i=0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
37 if(!vop_found){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
38 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
39 state= (state<<8) | buf[i];
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
40 if(state == 0x1B6){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
41 i++;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
42 vop_found=1;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
43 break;
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
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
48 if(vop_found){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
49 /* 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
50 if (buf_size == 0)
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
51 return 0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
52 for(; i<buf_size; i++){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
53 state= (state<<8) | buf[i];
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
54 if((state&0xFFFFFF00) == 0x100){
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
55 pc->frame_start_found=0;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
56 pc->state=-1;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
57 return i-3;
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 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
61 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
62 pc->state= state;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
63 return END_NOT_FOUND;
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
64 }
3fcb2f0d9ef1 move ff_mpeg4_find_frame_end() from h263dec.c to mpeg4video_parser.c
aurel
parents: 4931
diff changeset
65
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
66 /* XXX: make it use less memory */
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
67 static int av_mpeg4_decode_header(AVCodecParserContext *s1,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
68 AVCodecContext *avctx,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
69 const uint8_t *buf, int buf_size)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
70 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
71 ParseContext1 *pc = s1->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
72 MpegEncContext *s = pc->enc;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
73 GetBitContext gb1, *gb = &gb1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
74 int ret;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
75
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
76 s->avctx = avctx;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
77 s->current_picture_ptr = &s->current_picture;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
78
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
79 if (avctx->extradata_size && pc->first_picture){
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
80 init_get_bits(gb, avctx->extradata, avctx->extradata_size*8);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
81 ret = ff_mpeg4_decode_picture_header(s, gb);
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
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
84 init_get_bits(gb, buf, 8 * buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
85 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
86 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
87 avcodec_set_dimensions(avctx, s->width, s->height);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
88 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
89 s1->pict_type= s->pict_type;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
90 pc->first_picture = 0;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
91 return ret;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
92 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
93
9007
043574c5c153 Add missing av_cold in static init/close functions.
stefano
parents: 8629
diff changeset
94 static av_cold int mpeg4video_parse_init(AVCodecParserContext *s)
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
95 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
96 ParseContext1 *pc = s->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
97
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
98 pc->enc = av_mallocz(sizeof(MpegEncContext));
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
99 if (!pc->enc)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
100 return -1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
101 pc->first_picture = 1;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
102 return 0;
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
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
105 static int mpeg4video_parse(AVCodecParserContext *s,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
106 AVCodecContext *avctx,
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
107 const uint8_t **poutbuf, int *poutbuf_size,
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
108 const uint8_t *buf, int buf_size)
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
109 {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
110 ParseContext *pc = s->priv_data;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
111 int next;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
112
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
113 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
114 next= buf_size;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
115 }else{
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
116 next= ff_mpeg4_find_frame_end(pc, buf, buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
117
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
118 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) {
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
119 *poutbuf = NULL;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
120 *poutbuf_size = 0;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
121 return buf_size;
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 }
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
124 av_mpeg4_decode_header(s, avctx, buf, buf_size);
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
125
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4912
diff changeset
126 *poutbuf = buf;
4912
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
127 *poutbuf_size = buf_size;
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
128 return next;
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
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
132 AVCodecParser mpeg4video_parser = {
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
133 { CODEC_ID_MPEG4 },
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
134 sizeof(ParseContext1),
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
135 mpeg4video_parse_init,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
136 mpeg4video_parse,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
137 ff_parse1_close,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
138 ff_mpeg4video_split,
5fc99f2a111b move mpeg4video_parser in it's own file
aurel
parents:
diff changeset
139 };