comparison parser.c @ 4150:2205aefb22b7 libavcodec

move AVCodecParser prototypes and definitions to parser.h, and move mpegvideo parser to mpeg12.c
author bcoudurier
date Mon, 06 Nov 2006 10:43:49 +0000
parents c09e31f70a30
children b3328ed50a5e
comparison
equal deleted inserted replaced
4149:3118e8afb8a5 4150:2205aefb22b7
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */ 21 */
22 #include "avcodec.h" 22 #include "avcodec.h"
23 #include "mpegvideo.h" 23 #include "mpegvideo.h"
24 #include "mpegaudio.h" 24 #include "mpegaudio.h"
25 #include "parser.h"
25 26
26 AVCodecParser *av_first_parser = NULL; 27 AVCodecParser *av_first_parser = NULL;
27 28
28 void av_register_codec_parser(AVCodecParser *parser) 29 void av_register_codec_parser(AVCodecParser *parser)
29 { 30 {
211 av_free(s); 212 av_free(s);
212 } 213 }
213 214
214 /*****************************************************/ 215 /*****************************************************/
215 216
216 //#define END_NOT_FOUND (-100)
217
218 #define PICTURE_START_CODE 0x00000100
219 #define SEQ_START_CODE 0x000001b3
220 #define EXT_START_CODE 0x000001b5
221 #define SLICE_MIN_START_CODE 0x00000101
222 #define SLICE_MAX_START_CODE 0x000001af
223
224 typedef struct ParseContext1{
225 ParseContext pc;
226 /* XXX/FIXME PC1 vs. PC */
227 /* MPEG2 specific */
228 AVRational frame_rate;
229 int progressive_sequence;
230 int width, height;
231
232 /* XXX: suppress that, needed by MPEG4 */
233 MpegEncContext *enc;
234 int first_picture;
235 } ParseContext1;
236
237 /** 217 /**
238 * combines the (truncated) bitstream to a complete frame 218 * combines the (truncated) bitstream to a complete frame
239 * @returns -1 if no complete frame could be created 219 * @returns -1 if no complete frame could be created
240 */ 220 */
241 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size) 221 int ff_combine_frame(ParseContext *pc, int next, uint8_t **buf, int *buf_size)
294 #endif 274 #endif
295 275
296 return 0; 276 return 0;
297 } 277 }
298 278
299 #ifdef CONFIG_MPEGVIDEO_PARSER
300
301 extern const AVRational ff_frame_rate_tab[];
302
303 //FIXME move into mpeg12.c
304 static void mpegvideo_extract_headers(AVCodecParserContext *s,
305 AVCodecContext *avctx,
306 const uint8_t *buf, int buf_size)
307 {
308 ParseContext1 *pc = s->priv_data;
309 const uint8_t *buf_end;
310 uint32_t start_code;
311 int frame_rate_index, ext_type, bytes_left;
312 int frame_rate_ext_n, frame_rate_ext_d;
313 int picture_structure, top_field_first, repeat_first_field, progressive_frame;
314 int horiz_size_ext, vert_size_ext, bit_rate_ext;
315 //FIXME replace the crap with get_bits()
316 s->repeat_pict = 0;
317 buf_end = buf + buf_size;
318 while (buf < buf_end) {
319 start_code= -1;
320 buf= ff_find_start_code(buf, buf_end, &start_code);
321 bytes_left = buf_end - buf;
322 switch(start_code) {
323 case PICTURE_START_CODE:
324 if (bytes_left >= 2) {
325 s->pict_type = (buf[1] >> 3) & 7;
326 }
327 break;
328 case SEQ_START_CODE:
329 if (bytes_left >= 7) {
330 pc->width = (buf[0] << 4) | (buf[1] >> 4);
331 pc->height = ((buf[1] & 0x0f) << 8) | buf[2];
332 avcodec_set_dimensions(avctx, pc->width, pc->height);
333 frame_rate_index = buf[3] & 0xf;
334 pc->frame_rate.den = avctx->time_base.den = ff_frame_rate_tab[frame_rate_index].num;
335 pc->frame_rate.num = avctx->time_base.num = ff_frame_rate_tab[frame_rate_index].den;
336 avctx->bit_rate = ((buf[4]<<10) | (buf[5]<<2) | (buf[6]>>6))*400;
337 avctx->codec_id = CODEC_ID_MPEG1VIDEO;
338 avctx->sub_id = 1;
339 }
340 break;
341 case EXT_START_CODE:
342 if (bytes_left >= 1) {
343 ext_type = (buf[0] >> 4);
344 switch(ext_type) {
345 case 0x1: /* sequence extension */
346 if (bytes_left >= 6) {
347 horiz_size_ext = ((buf[1] & 1) << 1) | (buf[2] >> 7);
348 vert_size_ext = (buf[2] >> 5) & 3;
349 bit_rate_ext = ((buf[2] & 0x1F)<<7) | (buf[3]>>1);
350 frame_rate_ext_n = (buf[5] >> 5) & 3;
351 frame_rate_ext_d = (buf[5] & 0x1f);
352 pc->progressive_sequence = buf[1] & (1 << 3);
353 avctx->has_b_frames= !(buf[5] >> 7);
354
355 pc->width |=(horiz_size_ext << 12);
356 pc->height |=( vert_size_ext << 12);
357 avctx->bit_rate += (bit_rate_ext << 18) * 400;
358 avcodec_set_dimensions(avctx, pc->width, pc->height);
359 avctx->time_base.den = pc->frame_rate.den * (frame_rate_ext_n + 1);
360 avctx->time_base.num = pc->frame_rate.num * (frame_rate_ext_d + 1);
361 avctx->codec_id = CODEC_ID_MPEG2VIDEO;
362 avctx->sub_id = 2; /* forces MPEG2 */
363 }
364 break;
365 case 0x8: /* picture coding extension */
366 if (bytes_left >= 5) {
367 picture_structure = buf[2]&3;
368 top_field_first = buf[3] & (1 << 7);
369 repeat_first_field = buf[3] & (1 << 1);
370 progressive_frame = buf[4] & (1 << 7);
371
372 /* check if we must repeat the frame */
373 if (repeat_first_field) {
374 if (pc->progressive_sequence) {
375 if (top_field_first)
376 s->repeat_pict = 4;
377 else
378 s->repeat_pict = 2;
379 } else if (progressive_frame) {
380 s->repeat_pict = 1;
381 }
382 }
383
384 /* the packet only represents half a frame
385 XXX,FIXME maybe find a different solution */
386 if(picture_structure != 3)
387 s->repeat_pict = -1;
388 }
389 break;
390 }
391 }
392 break;
393 case -1:
394 goto the_end;
395 default:
396 /* we stop parsing when we encounter a slice. It ensures
397 that this function takes a negligible amount of time */
398 if (start_code >= SLICE_MIN_START_CODE &&
399 start_code <= SLICE_MAX_START_CODE)
400 goto the_end;
401 break;
402 }
403 }
404 the_end: ;
405 }
406
407 static int mpegvideo_parse(AVCodecParserContext *s,
408 AVCodecContext *avctx,
409 uint8_t **poutbuf, int *poutbuf_size,
410 const uint8_t *buf, int buf_size)
411 {
412 ParseContext1 *pc1 = s->priv_data;
413 ParseContext *pc= &pc1->pc;
414 int next;
415
416 if(s->flags & PARSER_FLAG_COMPLETE_FRAMES){
417 next= buf_size;
418 }else{
419 next= ff_mpeg1_find_frame_end(pc, buf, buf_size);
420
421 if (ff_combine_frame(pc, next, (uint8_t **)&buf, &buf_size) < 0) {
422 *poutbuf = NULL;
423 *poutbuf_size = 0;
424 return buf_size;
425 }
426
427 }
428 /* we have a full frame : we just parse the first few MPEG headers
429 to have the full timing information. The time take by this
430 function should be negligible for uncorrupted streams */
431 mpegvideo_extract_headers(s, avctx, buf, buf_size);
432 #if 0
433 printf("pict_type=%d frame_rate=%0.3f repeat_pict=%d\n",
434 s->pict_type, (double)avctx->time_base.den / avctx->time_base.num, s->repeat_pict);
435 #endif
436
437 *poutbuf = (uint8_t *)buf;
438 *poutbuf_size = buf_size;
439 return next;
440 }
441
442 static int mpegvideo_split(AVCodecContext *avctx,
443 const uint8_t *buf, int buf_size)
444 {
445 int i;
446 uint32_t state= -1;
447
448 for(i=0; i<buf_size; i++){
449 state= (state<<8) | buf[i];
450 if(state != 0x1B3 && state != 0x1B5 && state < 0x200 && state >= 0x100)
451 return i-3;
452 }
453 return 0;
454 }
455 #endif /* CONFIG_MPEGVIDEO_PARSER */
456
457 void ff_parse_close(AVCodecParserContext *s) 279 void ff_parse_close(AVCodecParserContext *s)
458 { 280 {
459 ParseContext *pc = s->priv_data; 281 ParseContext *pc = s->priv_data;
460 282
461 av_free(pc->buffer); 283 av_free(pc->buffer);
462 } 284 }
463 285
464 static void parse1_close(AVCodecParserContext *s) 286 void ff_parse1_close(AVCodecParserContext *s)
465 { 287 {
466 ParseContext1 *pc1 = s->priv_data; 288 ParseContext1 *pc1 = s->priv_data;
467 289
468 av_free(pc1->pc.buffer); 290 av_free(pc1->pc.buffer);
469 av_free(pc1->enc); 291 av_free(pc1->enc);
1023 } 845 }
1024 return buf_ptr - buf; 846 return buf_ptr - buf;
1025 } 847 }
1026 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */ 848 #endif /* CONFIG_AC3_PARSER || CONFIG_AAC_PARSER */
1027 849
1028 #ifdef CONFIG_MPEGVIDEO_PARSER
1029 AVCodecParser mpegvideo_parser = {
1030 { CODEC_ID_MPEG1VIDEO, CODEC_ID_MPEG2VIDEO },
1031 sizeof(ParseContext1),
1032 NULL,
1033 mpegvideo_parse,
1034 parse1_close,
1035 mpegvideo_split,
1036 };
1037 #endif
1038 #ifdef CONFIG_MPEG4VIDEO_PARSER 850 #ifdef CONFIG_MPEG4VIDEO_PARSER
1039 AVCodecParser mpeg4video_parser = { 851 AVCodecParser mpeg4video_parser = {
1040 { CODEC_ID_MPEG4 }, 852 { CODEC_ID_MPEG4 },
1041 sizeof(ParseContext1), 853 sizeof(ParseContext1),
1042 mpeg4video_parse_init, 854 mpeg4video_parse_init,
1043 mpeg4video_parse, 855 mpeg4video_parse,
1044 parse1_close, 856 ff_parse1_close,
1045 mpeg4video_split, 857 mpeg4video_split,
1046 }; 858 };
1047 #endif 859 #endif
1048 #ifdef CONFIG_CAVSVIDEO_PARSER 860 #ifdef CONFIG_CAVSVIDEO_PARSER
1049 AVCodecParser cavsvideo_parser = { 861 AVCodecParser cavsvideo_parser = {
1050 { CODEC_ID_CAVS }, 862 { CODEC_ID_CAVS },
1051 sizeof(ParseContext1), 863 sizeof(ParseContext1),
1052 NULL, 864 NULL,
1053 cavsvideo_parse, 865 cavsvideo_parse,
1054 parse1_close, 866 ff_parse1_close,
1055 mpeg4video_split, 867 mpeg4video_split,
1056 }; 868 };
1057 #endif 869 #endif
1058 #ifdef CONFIG_MPEGAUDIO_PARSER 870 #ifdef CONFIG_MPEGAUDIO_PARSER
1059 AVCodecParser mpegaudio_parser = { 871 AVCodecParser mpegaudio_parser = {