454 |
|
|
455 |
////////////////////////////////////////////////////////////////// |
////////////////////////////////////////////////////////////////// |
456 |
|
|
457 |
|
/***************************************************************************** |
458 |
|
* MPEG-4 header parsing helper function |
459 |
|
****************************************************************************/ |
460 |
|
|
461 |
|
/* Copied from bitstream.c of xvidcore - TODO: BAD... |
462 |
|
/* Copyright (C) 2001-2003 Peter Ross <pross@xvid.org> */ |
463 |
|
|
464 |
|
static const unsigned char log2_tab_16[16] = { 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4 }; |
465 |
|
|
466 |
|
static unsigned int __inline log2bin(unsigned int value) |
467 |
|
{ |
468 |
|
int n = 0; |
469 |
|
if (value & 0xffff0000) { |
470 |
|
value >>= 16; |
471 |
|
n += 16; |
472 |
|
} |
473 |
|
if (value & 0xff00) { |
474 |
|
value >>= 8; |
475 |
|
n += 8; |
476 |
|
} |
477 |
|
if (value & 0xf0) { |
478 |
|
value >>= 4; |
479 |
|
n += 4; |
480 |
|
} |
481 |
|
return n + log2_tab_16[value]; |
482 |
|
} |
483 |
|
|
484 |
|
int |
485 |
|
Check_Video_Headers(Bitstream * bs) |
486 |
|
{ |
487 |
|
unsigned int dec_ver_id = 1, vol_ver_id, start_code; |
488 |
|
|
489 |
|
while ((BitstreamPos(bs) >> 3) + 4 <= bs->length) { |
490 |
|
BitstreamByteAlign(bs); |
491 |
|
start_code = BitstreamShowBits(bs, 32); |
492 |
|
|
493 |
|
if (start_code == VISOBJ_START_CODE) { |
494 |
|
|
495 |
|
BitstreamSkip(bs, 32); /* visual_object_start_code */ |
496 |
|
if (BitstreamGetBit(bs)) /* is_visual_object_identified */ |
497 |
|
{ |
498 |
|
dec_ver_id = BitstreamGetBits(bs, 4); /* visual_object_ver_id */ |
499 |
|
BitstreamSkip(bs, 3); /* visual_object_priority */ |
500 |
|
} else { |
501 |
|
dec_ver_id = 1; |
502 |
|
} |
503 |
|
|
504 |
|
if (BitstreamShowBits(bs, 4) != VISOBJ_TYPE_VIDEO) /* visual_object_type */ |
505 |
|
{ |
506 |
|
return -1; |
507 |
|
} |
508 |
|
BitstreamSkip(bs, 4); |
509 |
|
|
510 |
|
/* video_signal_type */ |
511 |
|
|
512 |
|
if (BitstreamGetBit(bs)) /* video_signal_type */ |
513 |
|
{ |
514 |
|
BitstreamSkip(bs, 3); /* video_format */ |
515 |
|
BitstreamSkip(bs, 1); /* video_range */ |
516 |
|
if (BitstreamGetBit(bs)) /* color_description */ |
517 |
|
{ |
518 |
|
BitstreamSkip(bs, 8); /* color_primaries */ |
519 |
|
BitstreamSkip(bs, 8); /* transfer_characteristics */ |
520 |
|
BitstreamSkip(bs, 8); /* matrix_coefficients */ |
521 |
|
} |
522 |
|
} |
523 |
|
} else if ((start_code & ~VIDOBJLAY_START_CODE_MASK) == VIDOBJLAY_START_CODE) { |
524 |
|
|
525 |
|
BitstreamSkip(bs, 32); /* video_object_layer_start_code */ |
526 |
|
BitstreamSkip(bs, 1); /* random_accessible_vol */ |
527 |
|
|
528 |
|
BitstreamSkip(bs, 8); /* video_object_type_indication */ |
529 |
|
|
530 |
|
if (BitstreamGetBit(bs)) /* is_object_layer_identifier */ |
531 |
|
{ |
532 |
|
vol_ver_id = BitstreamGetBits(bs, 4); /* video_object_layer_verid */ |
533 |
|
BitstreamSkip(bs, 3); /* video_object_layer_priority */ |
534 |
|
} else { |
535 |
|
vol_ver_id = dec_ver_id; |
536 |
|
} |
537 |
|
|
538 |
|
if (BitstreamGetBits(bs, 4) == VIDOBJLAY_AR_EXTPAR) /* aspect_ratio_info */ |
539 |
|
{ |
540 |
|
BitstreamSkip(bs, 16); /* par_width + par_height */ |
541 |
|
} |
542 |
|
|
543 |
|
if (BitstreamGetBit(bs)) /* vol_control_parameters */ |
544 |
|
{ |
545 |
|
BitstreamSkip(bs, 2); /* chroma_format */ |
546 |
|
BitstreamSkip(bs, 1); /* low_delay */ |
547 |
|
if (BitstreamGetBit(bs)) /* vbv_parameters */ |
548 |
|
{ |
549 |
|
BitstreamSkip(bs,15); /* first_half_bit_rate */ |
550 |
|
READ_MARKER(); |
551 |
|
BitstreamSkip(bs,15); /* latter_half_bit_rate */ |
552 |
|
READ_MARKER(); |
553 |
|
|
554 |
|
BitstreamSkip(bs, 15); /* first_half_vbv_buffer_size */ |
555 |
|
READ_MARKER(); |
556 |
|
BitstreamSkip(bs, 3); /* latter_half_vbv_buffer_size */ |
557 |
|
|
558 |
|
BitstreamSkip(bs, 11); /* first_half_vbv_occupancy */ |
559 |
|
READ_MARKER(); |
560 |
|
BitstreamSkip(bs, 15); /* latter_half_vbv_occupancy */ |
561 |
|
READ_MARKER(); |
562 |
|
} |
563 |
|
} |
564 |
|
|
565 |
|
if (BitstreamGetBits(bs, 2) != VIDOBJLAY_SHAPE_RECTANGULAR) /* video_object_layer_shape */ |
566 |
|
{ |
567 |
|
return -1; |
568 |
|
} |
569 |
|
|
570 |
|
READ_MARKER(); |
571 |
|
|
572 |
|
/********************** for decode B-frame time ***********************/ |
573 |
|
unsigned int time_inc_resolution = BitstreamGetBits(bs, 16); /* vop_time_increment_resolution */ |
574 |
|
|
575 |
|
unsigned time_inc_bits = 1; |
576 |
|
|
577 |
|
if (time_inc_resolution > 0) { |
578 |
|
time_inc_bits = MAX(log2bin(time_inc_resolution-1), 1); |
579 |
|
} |
580 |
|
|
581 |
|
READ_MARKER(); |
582 |
|
|
583 |
|
if (BitstreamGetBit(bs)) /* fixed_vop_rate */ |
584 |
|
{ |
585 |
|
BitstreamSkip(bs, time_inc_bits); /* fixed_vop_time_increment */ |
586 |
|
} |
587 |
|
|
588 |
|
READ_MARKER(); |
589 |
|
BitstreamSkip(bs, 13); /* video_object_layer_width */ |
590 |
|
READ_MARKER(); |
591 |
|
BitstreamSkip(bs, 13); /* video_object_layer_height */ |
592 |
|
READ_MARKER(); |
593 |
|
|
594 |
|
if (BitstreamGetBit(bs)) |
595 |
|
{ |
596 |
|
return -1; |
597 |
|
} |
598 |
|
|
599 |
|
if (!BitstreamGetBit(bs)) /* obmc_disable */ |
600 |
|
{ |
601 |
|
return -1; |
602 |
|
} |
603 |
|
|
604 |
|
if (BitstreamGetBits(bs, (vol_ver_id == 1 ? 1 : 2)) != 0) /* sprite_enable */ |
605 |
|
{ |
606 |
|
return -1; |
607 |
|
} |
608 |
|
} |
609 |
|
else /* start_code == ? */ |
610 |
|
{ |
611 |
|
BitstreamSkip(bs, 8); |
612 |
|
} |
613 |
|
} |
614 |
|
|
615 |
|
return 0; |
616 |
|
} |
617 |
|
|
618 |
|
/*****************************************************************************/ |
619 |
|
|
620 |
CUnknown * WINAPI |
CUnknown * WINAPI |
621 |
ChangeSubtypeT::CreateInstance(IUnknown *pUnk, HRESULT *phr) |
ChangeSubtypeT::CreateInstance(IUnknown *pUnk, HRESULT *phr) |
622 |
{ |
{ |
816 |
if (m_Mpeg4SequenceSize > 0) { |
if (m_Mpeg4SequenceSize > 0) { |
817 |
m_pMpeg4Sequence = (BYTE *)malloc(m_Mpeg4SequenceSize*sizeof(BYTE)); |
m_pMpeg4Sequence = (BYTE *)malloc(m_Mpeg4SequenceSize*sizeof(BYTE)); |
818 |
memcpy(m_pMpeg4Sequence, (const BYTE *)mpeg2info->dwSequenceHeader, m_Mpeg4SequenceSize); |
memcpy(m_pMpeg4Sequence, (const BYTE *)mpeg2info->dwSequenceHeader, m_Mpeg4SequenceSize); |
819 |
|
|
820 |
|
Bitstream bs; |
821 |
|
BitstreamInit(&bs, m_pMpeg4Sequence, m_Mpeg4SequenceSize); |
822 |
|
|
823 |
|
if (Check_Video_Headers(&bs) == -1) // Is upstream MPEG-4 video compatible with XVID? |
824 |
|
return VFW_E_TYPE_NOT_ACCEPTED; |
825 |
} |
} |
826 |
} |
} |
827 |
} |
} |