Directory: | ../../../ffmpeg/ |
---|---|
File: | src/libavcodec/mpegvideo_parser.c |
Date: | 2022-07-05 19:52:29 |
Exec | Total | Coverage | |
---|---|---|---|
Lines: | 114 | 121 | 94.2% |
Branches: | 58 | 76 | 76.3% |
Line | Branch | Exec | Source |
---|---|---|---|
1 | /* | ||
2 | * MPEG-1 / MPEG-2 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 "internal.h" | ||
24 | #include "parser.h" | ||
25 | #include "mpeg12.h" | ||
26 | #include "mpeg12data.h" | ||
27 | #include "startcode.h" | ||
28 | |||
29 | struct MpvParseContext { | ||
30 | ParseContext pc; | ||
31 | AVRational frame_rate; | ||
32 | int progressive_sequence; | ||
33 | int width, height; | ||
34 | }; | ||
35 | |||
36 | #if !FF_API_FLAG_TRUNCATED | ||
37 | /** | ||
38 | * Find the end of the current frame in the bitstream. | ||
39 | * @return the position of the first byte of the next frame, or -1 | ||
40 | */ | ||
41 | static int mpeg1_find_frame_end(ParseContext *pc, const uint8_t *buf, | ||
42 | int buf_size, AVCodecParserContext *s) | ||
43 | { | ||
44 | int i; | ||
45 | uint32_t state = pc->state; | ||
46 | |||
47 | /* EOF considered as end of frame */ | ||
48 | if (buf_size == 0) | ||
49 | return 0; | ||
50 | |||
51 | /* | ||
52 | 0 frame start -> 1/4 | ||
53 | 1 first_SEQEXT -> 0/2 | ||
54 | 2 first field start -> 3/0 | ||
55 | 3 second_SEQEXT -> 2/0 | ||
56 | 4 searching end | ||
57 | */ | ||
58 | |||
59 | for (i = 0; i < buf_size; i++) { | ||
60 | av_assert1(pc->frame_start_found >= 0 && pc->frame_start_found <= 4); | ||
61 | if (pc->frame_start_found & 1) { | ||
62 | if (state == EXT_START_CODE && (buf[i] & 0xF0) != 0x80) | ||
63 | pc->frame_start_found--; | ||
64 | else if (state == EXT_START_CODE + 2) { | ||
65 | if ((buf[i] & 3) == 3) | ||
66 | pc->frame_start_found = 0; | ||
67 | else | ||
68 | pc->frame_start_found = (pc->frame_start_found + 1) & 3; | ||
69 | } | ||
70 | state++; | ||
71 | } else { | ||
72 | i = avpriv_find_start_code(buf + i, buf + buf_size, &state) - buf - 1; | ||
73 | if (pc->frame_start_found == 0 && state >= SLICE_MIN_START_CODE && state <= SLICE_MAX_START_CODE) { | ||
74 | i++; | ||
75 | pc->frame_start_found = 4; | ||
76 | } | ||
77 | if (state == SEQ_END_CODE) { | ||
78 | pc->frame_start_found = 0; | ||
79 | pc->state = -1; | ||
80 | return i + 1; | ||
81 | } | ||
82 | if (pc->frame_start_found == 2 && state == SEQ_START_CODE) | ||
83 | pc->frame_start_found = 0; | ||
84 | if (pc->frame_start_found < 4 && state == EXT_START_CODE) | ||
85 | pc->frame_start_found++; | ||
86 | if (pc->frame_start_found == 4 && (state & 0xFFFFFF00) == 0x100) { | ||
87 | if (state < SLICE_MIN_START_CODE || state > SLICE_MAX_START_CODE) { | ||
88 | pc->frame_start_found = 0; | ||
89 | pc->state = -1; | ||
90 | return i - 3; | ||
91 | } | ||
92 | } | ||
93 | if (pc->frame_start_found == 0 && s && state == PICTURE_START_CODE) { | ||
94 | ff_fetch_timestamp(s, i - 3, 1, i > 3); | ||
95 | } | ||
96 | } | ||
97 | } | ||
98 | pc->state = state; | ||
99 | return END_NOT_FOUND; | ||
100 | } | ||
101 | #endif | ||
102 | |||
103 | 9085 | static void mpegvideo_extract_headers(AVCodecParserContext *s, | |
104 | AVCodecContext *avctx, | ||
105 | const uint8_t *buf, int buf_size) | ||
106 | { | ||
107 | 9085 | struct MpvParseContext *pc = s->priv_data; | |
108 | 9085 | const uint8_t *buf_end = buf + buf_size; | |
109 | uint32_t start_code; | ||
110 | int frame_rate_index, ext_type, bytes_left; | ||
111 | int frame_rate_ext_n, frame_rate_ext_d; | ||
112 | int top_field_first, repeat_first_field, progressive_frame; | ||
113 | int horiz_size_ext, vert_size_ext, bit_rate_ext; | ||
114 | 9085 | int did_set_size=0; | |
115 | 9085 | int set_dim_ret = 0; | |
116 | 9085 | int bit_rate = 0; | |
117 | 9085 | int vbv_delay = 0; | |
118 | int chroma_format; | ||
119 | 9085 | enum AVPixelFormat pix_fmt = AV_PIX_FMT_NONE; | |
120 | //FIXME replace the crap with get_bits() | ||
121 | 9085 | s->repeat_pict = 0; | |
122 | |||
123 |
2/2✓ Branch 0 taken 32975 times.
✓ Branch 1 taken 255 times.
|
33230 | while (buf < buf_end) { |
124 | 32975 | start_code= -1; | |
125 | 32975 | buf= avpriv_find_start_code(buf, buf_end, &start_code); | |
126 | 32975 | bytes_left = buf_end - buf; | |
127 |
4/5✓ Branch 0 taken 8813 times.
✓ Branch 1 taken 1933 times.
✓ Branch 2 taken 10373 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 11856 times.
|
32975 | switch(start_code) { |
128 | 8813 | case PICTURE_START_CODE: | |
129 |
1/2✓ Branch 0 taken 8813 times.
✗ Branch 1 not taken.
|
8813 | if (bytes_left >= 2) { |
130 | 8813 | s->pict_type = (buf[1] >> 3) & 7; | |
131 |
1/2✓ Branch 0 taken 8813 times.
✗ Branch 1 not taken.
|
8813 | if (bytes_left >= 4) |
132 | 8813 | vbv_delay = ((buf[1] & 0x07) << 13) | (buf[2] << 5) | (buf[3] >> 3); | |
133 | } | ||
134 | 8813 | break; | |
135 | 1933 | case SEQ_START_CODE: | |
136 |
1/2✓ Branch 0 taken 1933 times.
✗ Branch 1 not taken.
|
1933 | if (bytes_left >= 7) { |
137 | 1933 | pc->width = (buf[0] << 4) | (buf[1] >> 4); | |
138 | 1933 | pc->height = ((buf[1] & 0x0f) << 8) | buf[2]; | |
139 |
6/8✓ Branch 0 taken 1846 times.
✓ Branch 1 taken 87 times.
✓ Branch 2 taken 1846 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1764 times.
✓ Branch 5 taken 82 times.
✗ Branch 6 not taken.
✓ Branch 7 taken 1764 times.
|
1933 | if(!avctx->width || !avctx->height || !avctx->coded_width || !avctx->coded_height){ |
140 | 169 | set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height); | |
141 | 169 | did_set_size=1; | |
142 | } | ||
143 | 1933 | pix_fmt = AV_PIX_FMT_YUV420P; | |
144 | 1933 | frame_rate_index = buf[3] & 0xf; | |
145 | 1933 | pc->frame_rate = avctx->framerate = ff_mpeg12_frame_rate_tab[frame_rate_index]; | |
146 | 1933 | bit_rate = (buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6); | |
147 | 1933 | avctx->codec_id = AV_CODEC_ID_MPEG1VIDEO; | |
148 | 1933 | avctx->ticks_per_frame = 1; | |
149 | } | ||
150 | 1933 | break; | |
151 | 10373 | case EXT_START_CODE: | |
152 |
1/2✓ Branch 0 taken 10373 times.
✗ Branch 1 not taken.
|
10373 | if (bytes_left >= 1) { |
153 |
3/3✓ Branch 0 taken 1794 times.
✓ Branch 1 taken 7941 times.
✓ Branch 2 taken 638 times.
|
10373 | ext_type = (buf[0] >> 4); |
154 | switch(ext_type) { | ||
155 | 1794 | case 0x1: /* sequence extension */ | |
156 |
1/2✓ Branch 0 taken 1794 times.
✗ Branch 1 not taken.
|
1794 | if (bytes_left >= 6) { |
157 | 1794 | horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7); | |
158 | 1794 | vert_size_ext = (buf[2] >> 5) & 3; | |
159 | 1794 | bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1); | |
160 | 1794 | frame_rate_ext_n = (buf[5] >> 5) & 3; | |
161 | 1794 | frame_rate_ext_d = (buf[5] & 0x1f); | |
162 | 1794 | pc->progressive_sequence = buf[1] & (1 << 3); | |
163 | 1794 | avctx->has_b_frames= !(buf[5] >> 7); | |
164 | |||
165 |
2/4✓ Branch 0 taken 757 times.
✓ Branch 1 taken 1037 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
|
1794 | chroma_format = (buf[1] >> 1) & 3; |
166 | switch (chroma_format) { | ||
167 | 757 | case 1: pix_fmt = AV_PIX_FMT_YUV420P; break; | |
168 | 1037 | case 2: pix_fmt = AV_PIX_FMT_YUV422P; break; | |
169 | ✗ | case 3: pix_fmt = AV_PIX_FMT_YUV444P; break; | |
170 | } | ||
171 | |||
172 | 1794 | pc->width = (pc->width & 0xFFF) | (horiz_size_ext << 12); | |
173 | 1794 | pc->height = (pc->height& 0xFFF) | ( vert_size_ext << 12); | |
174 | 1794 | bit_rate = (bit_rate&0x3FFFF) | (bit_rate_ext << 18); | |
175 |
2/2✓ Branch 0 taken 155 times.
✓ Branch 1 taken 1639 times.
|
1794 | if(did_set_size) |
176 | 155 | set_dim_ret = ff_set_dimensions(avctx, pc->width, pc->height); | |
177 | 1794 | avctx->framerate.num = pc->frame_rate.num * (frame_rate_ext_n + 1); | |
178 | 1794 | avctx->framerate.den = pc->frame_rate.den * (frame_rate_ext_d + 1); | |
179 | 1794 | avctx->codec_id = AV_CODEC_ID_MPEG2VIDEO; | |
180 | 1794 | avctx->ticks_per_frame = 2; | |
181 | } | ||
182 | 1794 | break; | |
183 | 7941 | case 0x8: /* picture coding extension */ | |
184 |
1/2✓ Branch 0 taken 7941 times.
✗ Branch 1 not taken.
|
7941 | if (bytes_left >= 5) { |
185 | 7941 | top_field_first = buf[3] & (1 << 7); | |
186 | 7941 | repeat_first_field = buf[3] & (1 << 1); | |
187 | 7941 | progressive_frame = buf[4] & (1 << 7); | |
188 | |||
189 | /* check if we must repeat the frame */ | ||
190 | 7941 | s->repeat_pict = 1; | |
191 |
2/2✓ Branch 0 taken 6 times.
✓ Branch 1 taken 7935 times.
|
7941 | if (repeat_first_field) { |
192 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 6 times.
|
6 | if (pc->progressive_sequence) { |
193 | ✗ | if (top_field_first) | |
194 | ✗ | s->repeat_pict = 5; | |
195 | else | ||
196 | ✗ | s->repeat_pict = 3; | |
197 |
1/2✓ Branch 0 taken 6 times.
✗ Branch 1 not taken.
|
6 | } else if (progressive_frame) { |
198 | 6 | s->repeat_pict = 2; | |
199 | } | ||
200 | } | ||
201 | |||
202 |
4/4✓ Branch 0 taken 4834 times.
✓ Branch 1 taken 3107 times.
✓ Branch 2 taken 4563 times.
✓ Branch 3 taken 271 times.
|
7941 | if (!pc->progressive_sequence && !progressive_frame) { |
203 |
2/2✓ Branch 0 taken 735 times.
✓ Branch 1 taken 3828 times.
|
4563 | if (top_field_first) |
204 | 735 | s->field_order = AV_FIELD_TT; | |
205 | else | ||
206 | 3828 | s->field_order = AV_FIELD_BB; | |
207 | } else | ||
208 | 3378 | s->field_order = AV_FIELD_PROGRESSIVE; | |
209 | } | ||
210 | 7941 | break; | |
211 | } | ||
212 | } | ||
213 | 10373 | break; | |
214 | ✗ | case -1: | |
215 | ✗ | goto the_end; | |
216 | 11856 | default: | |
217 | /* we stop parsing when we encounter a slice. It ensures | ||
218 | that this function takes a negligible amount of time */ | ||
219 |
1/2✓ Branch 0 taken 11856 times.
✗ Branch 1 not taken.
|
11856 | if (start_code >= SLICE_MIN_START_CODE && |
220 |
2/2✓ Branch 0 taken 8830 times.
✓ Branch 1 taken 3026 times.
|
11856 | start_code <= SLICE_MAX_START_CODE) |
221 | 8830 | goto the_end; | |
222 | 3026 | break; | |
223 | } | ||
224 | } | ||
225 | 255 | the_end: | |
226 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 9085 times.
|
9085 | if (set_dim_ret < 0) |
227 | ✗ | av_log(avctx, AV_LOG_ERROR, "Failed to set dimensions\n"); | |
228 | |||
229 |
4/4✓ Branch 0 taken 8182 times.
✓ Branch 1 taken 903 times.
✓ Branch 2 taken 1794 times.
✓ Branch 3 taken 6388 times.
|
9085 | if (avctx->codec_id == AV_CODEC_ID_MPEG2VIDEO && bit_rate) { |
230 | 1794 | avctx->rc_max_rate = 400LL*bit_rate; | |
231 | } | ||
232 |
2/2✓ Branch 0 taken 1933 times.
✓ Branch 1 taken 7152 times.
|
9085 | if (bit_rate && |
233 |
5/6✓ Branch 0 taken 139 times.
✓ Branch 1 taken 1794 times.
✓ Branch 2 taken 139 times.
✗ Branch 3 not taken.
✓ Branch 4 taken 1015 times.
✓ Branch 5 taken 918 times.
|
1933 | ((avctx->codec_id == AV_CODEC_ID_MPEG1VIDEO && bit_rate != 0x3FFFF) || vbv_delay != 0xFFFF)) { |
234 | 1015 | avctx->bit_rate = 400LL*bit_rate; | |
235 | } | ||
236 | |||
237 |
2/2✓ Branch 0 taken 1933 times.
✓ Branch 1 taken 7152 times.
|
9085 | if (pix_fmt != AV_PIX_FMT_NONE) { |
238 | 1933 | s->format = pix_fmt; | |
239 | 1933 | s->width = pc->width; | |
240 | 1933 | s->height = pc->height; | |
241 | 1933 | s->coded_width = FFALIGN(pc->width, 16); | |
242 | 1933 | s->coded_height = FFALIGN(pc->height, 16); | |
243 | } | ||
244 | |||
245 | #if FF_API_AVCTX_TIMEBASE | ||
246 |
2/2✓ Branch 0 taken 8792 times.
✓ Branch 1 taken 293 times.
|
9085 | if (avctx->framerate.num) |
247 | 8792 | avctx->time_base = av_inv_q(av_mul_q(avctx->framerate, (AVRational){avctx->ticks_per_frame, 1})); | |
248 | #endif | ||
249 | 9085 | } | |
250 | |||
251 | 47221 | static int mpegvideo_parse(AVCodecParserContext *s, | |
252 | AVCodecContext *avctx, | ||
253 | const uint8_t **poutbuf, int *poutbuf_size, | ||
254 | const uint8_t *buf, int buf_size) | ||
255 | { | ||
256 | 47221 | struct MpvParseContext *pc1 = s->priv_data; | |
257 | 47221 | ParseContext *pc= &pc1->pc; | |
258 | int next; | ||
259 | |||
260 |
2/2✓ Branch 0 taken 2787 times.
✓ Branch 1 taken 44434 times.
|
47221 | if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){ |
261 | 2787 | next= buf_size; | |
262 | }else{ | ||
263 | #if FF_API_FLAG_TRUNCATED | ||
264 | 44434 | next= ff_mpeg1_find_frame_end(pc, buf, buf_size, s); | |
265 | #else | ||
266 | next = mpeg1_find_frame_end(pc, buf, buf_size, s); | ||
267 | #endif | ||
268 | |||
269 |
2/2✓ Branch 1 taken 38136 times.
✓ Branch 2 taken 6298 times.
|
44434 | if (ff_combine_frame(pc, next, &buf, &buf_size) < 0) { |
270 | 38136 | *poutbuf = NULL; | |
271 | 38136 | *poutbuf_size = 0; | |
272 | 38136 | return buf_size; | |
273 | } | ||
274 | |||
275 | } | ||
276 | /* we have a full frame : we just parse the first few MPEG headers | ||
277 | to have the full timing information. The time take by this | ||
278 | function should be negligible for uncorrupted streams */ | ||
279 | 9085 | mpegvideo_extract_headers(s, avctx, buf, buf_size); | |
280 | ff_dlog(NULL, "pict_type=%d frame_rate=%0.3f repeat_pict=%d\n", | ||
281 | s->pict_type, av_q2d(avctx->framerate), s->repeat_pict); | ||
282 | |||
283 | 9085 | *poutbuf = buf; | |
284 | 9085 | *poutbuf_size = buf_size; | |
285 | 9085 | return next; | |
286 | } | ||
287 | |||
288 | 664 | static int mpegvideo_parse_init(AVCodecParserContext *s) | |
289 | { | ||
290 | 664 | s->pict_type = AV_PICTURE_TYPE_NONE; // first frame might be partial | |
291 | 664 | return 0; | |
292 | } | ||
293 | |||
294 | const AVCodecParser ff_mpegvideo_parser = { | ||
295 | .codec_ids = { AV_CODEC_ID_MPEG1VIDEO, AV_CODEC_ID_MPEG2VIDEO }, | ||
296 | .priv_data_size = sizeof(struct MpvParseContext), | ||
297 | .parser_init = mpegvideo_parse_init, | ||
298 | .parser_parse = mpegvideo_parse, | ||
299 | .parser_close = ff_parse_close, | ||
300 | }; | ||
301 |