Mercurial > libavcodec.hg
annotate mpegvideo_parser.c @ 5062:2dd00b1cc94b libavcodec
Remove mdct.o and fft.o from fft-test prerequisites list.
Both objects were added to the link command, resulting in multiple definitions
of symbols. Now linking works in the general case when mdct.o and fft.o are
compiled into libavcodec.a.
author | diego |
---|---|
date | Tue, 22 May 2007 07:08:38 +0000 |
parents | 0d1cc37d9430 |
children | 9f4f88218b78 |
rev | line source |
---|---|
4915 | 1 /* |
2 * MPEG1 / MPEG2 video parser | |
3 * Copyright (c) 2000,2001 Fabrice Bellard. | |
4 * Copyright (c) 2002-2004 Michael Niedermayer <michaelni@gmx.at> | |
5 * | |
6 * This file is part of FFmpeg. | |
7 * | |
8 * FFmpeg is free software; you can redistribute it and/or | |
9 * modify it under the terms of the GNU Lesser General Public | |
10 * License as published by the Free Software Foundation; either | |
11 * version 2.1 of the License, or (at your option) any later version. | |
12 * | |
13 * FFmpeg is distributed in the hope that it will be useful, | |
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
16 * Lesser General Public License for more details. | |
17 * | |
18 * You should have received a copy of the GNU Lesser General Public | |
19 * License along with FFmpeg; if not, write to the Free Software | |
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | |
21 */ | |
22 | |
23 #include "parser.h" | |
24 #include "mpegvideo.h" | |
25 | |
26 static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
27 AVCodecContext *avctx, | |
28 const uint8_t *buf, int buf_size) | |
29 { | |
30 ParseContext1 *pc = s->priv_data; | |
31 const uint8_t *buf_end; | |
32 uint32_t start_code; | |
33 int frame_rate_index, ext_type, bytes_left; | |
34 int frame_rate_ext_n, frame_rate_ext_d; | |
35 int picture_structure, top_field_first, repeat_first_field, progressive_frame; | |
36 int horiz_size_ext, vert_size_ext, bit_rate_ext; | |
37 //FIXME replace the crap with get_bits() | |
38 s->repeat_pict = 0; | |
39 buf_end = buf + buf_size; | |
40 while (buf < buf_end) { | |
41 start_code= -1; | |
42 buf= ff_find_start_code(buf, buf_end, &start_code); | |
43 bytes_left = buf_end - buf; | |
44 switch(start_code) { | |
45 case PICTURE_START_CODE: | |
46 if (bytes_left >= 2) { | |
47 s->pict_type = (buf[1] >> 3) & 7; | |
48 } | |
49 break; | |
50 case SEQ_START_CODE: | |
51 if (bytes_left >= 7) { | |
52 pc->width = (buf[0] << 4) | (buf[1] >> 4); | |
53 pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
54 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
55 frame_rate_index = buf[3] & 0xf; | |
56 pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num; | |
57 pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den; | |
58 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400; | |
59 avctx->codec_id = CODEC_ID_MPEG1VIDEO; | |
60 avctx->sub_id = 1; | |
61 } | |
62 break; | |
63 case EXT_START_CODE: | |
64 if (bytes_left >= 1) { | |
65 ext_type = (buf[0] >> 4); | |
66 switch(ext_type) { | |
67 case 0x1: /* sequence extension */ | |
68 if (bytes_left >= 6) { | |
69 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
70 vert_size_ext = (buf[2] >> 5) & 3; | |
71 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); | |
72 frame_rate_ext_n = (buf[5] >> 5) & 3; | |
73 frame_rate_ext_d = (buf[5] & 0x1f); | |
74 pc->progressive_sequence = buf[1] & (1 << 3); | |
75 avctx->has_b_frames= !(buf[5] >> 7); | |
76 | |
77 pc->width |=(horiz_size_ext << 12); | |
78 pc->height |=( vert_size_ext << 12); | |
79 avctx->bit_rate += (bit_rate_ext << 18) * 400; | |
80 avcodec_set_dimensions(avctx, pc->width, pc->height); | |
81 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1); | |
82 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1); | |
83 avctx->codec_id = CODEC_ID_MPEG2VIDEO; | |
84 avctx->sub_id = 2; /* forces MPEG2 */ | |
85 } | |
86 break; | |
87 case 0x8: /* picture coding extension */ | |
88 if (bytes_left >= 5) { | |
89 picture_structure = buf[2]&3; | |
90 top_field_first = buf[3] & (1 << 7); | |
91 repeat_first_field = buf[3] & (1 << 1); | |
92 progressive_frame = buf[4] & (1 << 7); | |
93 | |
94 /* check if we must repeat the frame */ | |
95 if (repeat_first_field) { | |
96 if (pc->progressive_sequence) { | |
97 if (top_field_first) | |
98 s->repeat_pict = 4; | |
99 else | |
100 s->repeat_pict = 2; | |
101 } else if (progressive_frame) { | |
102 s->repeat_pict = 1; | |
103 } | |
104 } | |
105 | |
106 /* the packet only represents half a frame | |
107 XXX,FIXME maybe find a different solution */ | |
108 if(picture_structure != 3) | |
109 s->repeat_pict = -1; | |
110 } | |
111 break; | |
112 } | |
113 } | |
114 break; | |
115 case -1: | |
116 goto the_end; | |
117 default: | |
118 /* we stop parsing when we encounter a slice. It ensures | |
119 that this function takes a negligible amount of time */ | |
120 if (start_code >= SLICE_MIN_START_CODE && | |
121 start_code <= SLICE_MAX_START_CODE) | |
122 goto the_end; | |
123 break; | |
124 } | |
125 } | |
126 the_end: ; | |
127 } | |
128 | |
129 static int mpegvideo_parse(AVCodecParserContext *s, | |
130 AVCodecContext *avctx, | |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4916
diff
changeset
|
131 const uint8_t **poutbuf, int *poutbuf_size, |
4915 | 132 const uint8_t *buf, int buf_size) |
133 { | |
134 ParseContext1 *pc1 = s->priv_data; | |
135 ParseContext *pc= &pc1->pc; | |
136 int next; | |
137 | |
138 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ | |
139 next= buf_size; | |
140 }else{ | |
4916
13ef168891b0
add a ff_ prefix to the now exported mpeg1_find_frame_end() function
aurel
parents:
4915
diff
changeset
|
141 next= ff_mpeg1_find_frame_end(pc, buf, buf_size); |
4915 | 142 |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4916
diff
changeset
|
143 if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
4915 | 144 *poutbuf = NULL; |
145 *poutbuf_size = 0; | |
146 return buf_size; | |
147 } | |
148 | |
149 } | |
150 /* we have a full frame : we just parse the first few MPEG headers | |
151 to have the full timing information. The time take by this | |
152 function should be negligible for uncorrupted streams */ | |
153 mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
154 #if 0 | |
155 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | |
156 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict); | |
157 #endif | |
158 | |
4931
0d1cc37d9430
make some parser parameters const to avoid casting const to non-const
aurel
parents:
4916
diff
changeset
|
159 *poutbuf = buf; |
4915 | 160 *poutbuf_size = buf_size; |
161 return next; | |
162 } | |
163 | |
164 static int mpegvideo_split(AVCodecContext *avctx, | |
165 const uint8_t *buf, int buf_size) | |
166 { | |
167 int i; | |
168 uint32_t state= -1; | |
169 | |
170 for(i=0; i<buf_size; i++){ | |
171 state= (state<<8) | buf[i]; | |
172 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100) | |
173 return i-3; | |
174 } | |
175 return 0; | |
176 } | |
177 | |
178 AVCodecParser mpegvideo_parser = { | |
179 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO }, | |
180 sizeof(ParseContext1), | |
181 NULL, | |
182 mpegvideo_parse, | |
183 ff_parse1_close, | |
184 mpegvideo_split, | |
185 }; |