annotate vc1_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 7dd2a45249a9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
1 /*
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
2 * VC-1 and WMV3 parser
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
3 * Copyright (c) 2006-2007 Konstantin Shishkov
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
4 * Partly based on vc9.c (c) 2005 Anonymous, Alex Beregszaszi, Michael Niedermayer
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
5 *
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
6 * This file is part of FFmpeg.
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
7 *
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
8 * FFmpeg is free software; you can redistribute it and/or
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
9 * modify it under the terms of the GNU Lesser General Public
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
10 * License as published by the Free Software Foundation; either
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
11 * version 2.1 of the License, or (at your option) any later version.
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
12 *
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
13 * FFmpeg is distributed in the hope that it will be useful,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
16 * Lesser General Public License for more details.
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
17 *
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
18 * You should have received a copy of the GNU Lesser General Public
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
19 * License along with FFmpeg; if not, write to the Free Software
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
21 */
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
22
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
23 /**
11644
7dd2a45249a9 Remove explicit filename from Doxygen @file commands.
diego
parents: 9732
diff changeset
24 * @file
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
25 * VC-1 and WMV3 parser
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
26 */
4919
983533ccc393 Remove superfluous #includes, parser.h now includes its prerequisites.
diego
parents: 4904
diff changeset
27
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
28 #include "parser.h"
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
29 #include "vc1.h"
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
30 #include "get_bits.h"
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
31
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
32 typedef struct {
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
33 ParseContext pc;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
34 VC1Context v;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
35 } VC1ParseContext;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
36
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
37 static void vc1_extract_headers(AVCodecParserContext *s, AVCodecContext *avctx,
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
38 const uint8_t *buf, int buf_size)
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
39 {
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
40 VC1ParseContext *vpc = s->priv_data;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
41 GetBitContext gb;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
42 const uint8_t *start, *end, *next;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
43 uint8_t *buf2 = av_mallocz(buf_size + FF_INPUT_BUFFER_PADDING_SIZE);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
44
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
45 vpc->v.s.avctx = avctx;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
46 vpc->v.parse_only = 1;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
47 next = buf;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
48
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
49 for(start = buf, end = buf + buf_size; next < end; start = next){
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
50 int buf2_size, size;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
51
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
52 next = find_next_marker(start + 4, end);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
53 size = next - start - 4;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
54 buf2_size = vc1_unescape_buffer(start + 4, size, buf2);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
55 init_get_bits(&gb, buf2, buf2_size * 8);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
56 if(size <= 0) continue;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
57 switch(AV_RB32(start)){
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
58 case VC1_CODE_SEQHDR:
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
59 vc1_decode_sequence_header(avctx, &vpc->v, &gb);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
60 break;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
61 case VC1_CODE_ENTRYPOINT:
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
62 vc1_decode_entry_point(avctx, &vpc->v, &gb);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
63 break;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
64 case VC1_CODE_FRAME:
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
65 if(vpc->v.profile < PROFILE_ADVANCED)
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
66 vc1_parse_frame_header (&vpc->v, &gb);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
67 else
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
68 vc1_parse_frame_header_adv(&vpc->v, &gb);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
69
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
70 /* keep FF_BI_TYPE internal to VC1 */
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
71 if (vpc->v.s.pict_type == FF_BI_TYPE)
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
72 s->pict_type = FF_B_TYPE;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
73 else
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
74 s->pict_type = vpc->v.s.pict_type;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
75
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
76 break;
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
77 }
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
78 }
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
79
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
80 av_free(buf2);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
81 }
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
82
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
83 /**
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
84 * finds the end of the current frame in the bitstream.
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
85 * @return the position of the first byte of the next frame, or -1
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
86 */
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
87 static int vc1_find_frame_end(ParseContext *pc, const uint8_t *buf,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
88 int buf_size) {
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
89 int pic_found, i;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
90 uint32_t state;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
91
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
92 pic_found= pc->frame_start_found;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
93 state= pc->state;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
94
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
95 i=0;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
96 if(!pic_found){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
97 for(i=0; i<buf_size; i++){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
98 state= (state<<8) | buf[i];
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
99 if(state == VC1_CODE_FRAME || state == VC1_CODE_FIELD){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
100 i++;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
101 pic_found=1;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
102 break;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
103 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
104 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
105 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
106
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
107 if(pic_found){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
108 /* EOF considered as end of frame */
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
109 if (buf_size == 0)
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
110 return 0;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
111 for(; i<buf_size; i++){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
112 state= (state<<8) | buf[i];
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
113 if(IS_MARKER(state) && state != VC1_CODE_FIELD && state != VC1_CODE_SLICE){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
114 pc->frame_start_found=0;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
115 pc->state=-1;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
116 return i-3;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
117 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
118 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
119 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
120 pc->frame_start_found= pic_found;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
121 pc->state= state;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
122 return END_NOT_FOUND;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
123 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
124
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
125 static int vc1_parse(AVCodecParserContext *s,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
126 AVCodecContext *avctx,
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4927
diff changeset
127 const uint8_t **poutbuf, int *poutbuf_size,
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
128 const uint8_t *buf, int buf_size)
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
129 {
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
130 VC1ParseContext *vpc = s->priv_data;
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
131 int next;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
132
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
133 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
134 next= buf_size;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
135 }else{
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
136 next= vc1_find_frame_end(&vpc->pc, buf, buf_size);
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
137
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
138 if (ff_combine_frame(&vpc->pc, next, &buf, &buf_size) < 0) {
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
139 *poutbuf = NULL;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
140 *poutbuf_size = 0;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
141 return buf_size;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
142 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
143 }
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
144
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
145 vc1_extract_headers(s, avctx, buf, buf_size);
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
146
4931
0d1cc37d9430 make some parser parameters const to avoid casting const to non-const
aurel
parents: 4927
diff changeset
147 *poutbuf = buf;
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
148 *poutbuf_size = buf_size;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
149 return next;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
150 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
151
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
152 static int vc1_split(AVCodecContext *avctx,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
153 const uint8_t *buf, int buf_size)
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
154 {
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
155 int i;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
156 uint32_t state= -1;
9009
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
157 int charged=0;
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
158
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
159 for(i=0; i<buf_size; i++){
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
160 state= (state<<8) | buf[i];
9009
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
161 if(IS_MARKER(state)){
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
162 if(state == VC1_CODE_SEQHDR || state == VC1_CODE_ENTRYPOINT){
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
163 charged=1;
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
164 }else if(charged){
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
165 return i-3;
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
166 }
9a642761d734 Fix vc1 split().
michael
parents: 8718
diff changeset
167 }
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
168 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
169 return 0;
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
170 }
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
171
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
172 AVCodecParser vc1_parser = {
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
173 { CODEC_ID_VC1 },
9732
c25359a56edf set pict_type in VC-1 parser, fix some timestamps problems
bcoudurier
parents: 9009
diff changeset
174 sizeof(VC1ParseContext),
4900
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
175 NULL,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
176 vc1_parse,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
177 ff_parse1_close,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
178 vc1_split,
36051a4c182a Move VC1 parser to its own file.
diego
parents:
diff changeset
179 };