Changeset e987d21394a1c2a065bb1744dc84a91b29b37e06
- Timestamp:
- 10/08/06 12:31:37
(2 years ago)
- Author:
- Derk-Jan Hartman <hartman@videolan.org>
- git-committer:
- Derk-Jan Hartman <hartman@videolan.org> 1160303497 +0000
- git-parent:
[7a8c59f79b581b8e36510348f8b2d7e37aeef486]
- git-author:
- Derk-Jan Hartman <hartman@videolan.org> 1160303497 +0000
- Message:
* Skip h264 SPS/PPS in bitstream when muxing mp4
-
Files:
-
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
| r62fffad |
re987d21 |
|
| 115 | 115 | vlc_bool_t b_stco64; |
|---|
| 116 | 116 | |
|---|
| 117 | | /* for h264 */ |
|---|
| 118 | | struct |
|---|
| 119 | | { |
|---|
| 120 | | int i_profile; |
|---|
| 121 | | int i_profile_compat; |
|---|
| 122 | | int i_level; |
|---|
| 123 | | |
|---|
| 124 | | int i_sps; |
|---|
| 125 | | uint8_t *sps; |
|---|
| 126 | | int i_pps; |
|---|
| 127 | | uint8_t *pps; |
|---|
| 128 | | } avc; |
|---|
| 129 | | |
|---|
| 130 | 117 | /* for spu */ |
|---|
| 131 | 118 | int64_t i_last_dts; |
|---|
| … | … | |
| 185 | 172 | |
|---|
| 186 | 173 | static block_t *ConvertSUBT( sout_mux_t *, mp4_stream_t *, block_t *); |
|---|
| 187 | | static void ConvertAVC1( sout_mux_t *, mp4_stream_t *, block_t * ); |
|---|
| | 174 | static block_t *ConvertAVC1( sout_mux_t *, mp4_stream_t *, block_t * ); |
|---|
| 188 | 175 | |
|---|
| 189 | 176 | /***************************************************************************** |
|---|
| … | … | |
| 365 | 352 | |
|---|
| 366 | 353 | es_format_Clean( &p_stream->fmt ); |
|---|
| 367 | | if( p_stream->avc.i_sps ) free( p_stream->avc.sps ); |
|---|
| 368 | | if( p_stream->avc.i_pps ) free( p_stream->avc.pps ); |
|---|
| 369 | 354 | free( p_stream->entry ); |
|---|
| 370 | 355 | free( p_stream ); |
|---|
| … | … | |
| 441 | 426 | p_stream->i_dts_start = 0; |
|---|
| 442 | 427 | p_stream->i_duration = 0; |
|---|
| 443 | | p_stream->avc.i_profile = 77; |
|---|
| 444 | | p_stream->avc.i_profile_compat = 64; |
|---|
| 445 | | p_stream->avc.i_level = 30; |
|---|
| 446 | | p_stream->avc.i_sps = 0; |
|---|
| 447 | | p_stream->avc.sps = NULL; |
|---|
| 448 | | p_stream->avc.i_pps = 0; |
|---|
| 449 | | p_stream->avc.pps = NULL; |
|---|
| 450 | 428 | |
|---|
| 451 | 429 | p_input->p_sys = p_stream; |
|---|
| … | … | |
| 528 | 506 | p_stream = (mp4_stream_t*)p_input->p_sys; |
|---|
| 529 | 507 | |
|---|
| | 508 | again: |
|---|
| 530 | 509 | p_data = block_FifoGet( p_input->p_fifo ); |
|---|
| 531 | 510 | if( p_stream->fmt.i_codec == VLC_FOURCC( 'h', '2', '6', '4' ) ) |
|---|
| 532 | 511 | { |
|---|
| 533 | | ConvertAVC1( p_mux, p_stream, p_data ); |
|---|
| | 512 | p_data = ConvertAVC1( p_mux, p_stream, p_data ); |
|---|
| 534 | 513 | } |
|---|
| 535 | 514 | else if( p_stream->fmt.i_codec == VLC_FOURCC( 's', 'u', 'b', 't' ) ) |
|---|
| … | … | |
| 537 | 516 | p_data = ConvertSUBT( p_mux, p_stream, p_data ); |
|---|
| 538 | 517 | } |
|---|
| | 518 | if( p_data == NULL ) goto again; |
|---|
| 539 | 519 | |
|---|
| 540 | 520 | if( p_stream->fmt.i_cat != SPU_ES ) |
|---|
| … | … | |
| 683 | 663 | } |
|---|
| 684 | 664 | |
|---|
| 685 | | static void ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block ) |
|---|
| | 665 | static block_t *ConvertAVC1( sout_mux_t *p_mux, mp4_stream_t *tk, block_t *p_block ) |
|---|
| 686 | 666 | { |
|---|
| 687 | 667 | uint8_t *last = p_block->p_buffer; /* Assume it starts with 0x00000001 */ |
|---|
| … | … | |
| 717 | 697 | last[3] = ( i_size )&0xff; |
|---|
| 718 | 698 | |
|---|
| 719 | | if( (last[4]&0x1f) == 7 && tk->avc.i_sps <= 0 ) /* SPS */ |
|---|
| 720 | | { |
|---|
| 721 | | tk->avc.i_sps = i_size; |
|---|
| 722 | | tk->avc.sps = malloc( i_size ); |
|---|
| 723 | | memcpy( tk->avc.sps, &last[4], i_size ); |
|---|
| 724 | | |
|---|
| 725 | | tk->avc.i_profile = tk->avc.sps[1]; |
|---|
| 726 | | tk->avc.i_profile = tk->avc.sps[2]; |
|---|
| 727 | | tk->avc.i_level = tk->avc.sps[3]; |
|---|
| 728 | | } |
|---|
| 729 | | else if( (last[4]&0x1f) == 8 && tk->avc.i_pps <= 0 ) /* PPS */ |
|---|
| 730 | | { |
|---|
| 731 | | tk->avc.i_pps = i_size; |
|---|
| 732 | | tk->avc.pps = malloc( i_size ); |
|---|
| 733 | | memcpy( tk->avc.pps, &last[4], i_size ); |
|---|
| 734 | | } |
|---|
| | 699 | /* Skip blocks with SPS/PPS */ |
|---|
| | 700 | if( (last[4]&0x1f) == 7 || (last[4]&0x1f) == 8 ) |
|---|
| | 701 | p_block->i_buffer = 0; |
|---|
| 735 | 702 | |
|---|
| 736 | 703 | last = dat; |
|---|
| 737 | | |
|---|
| 738 | 704 | dat += 4; |
|---|
| 739 | 705 | } |
|---|
| | 706 | return p_block; |
|---|
| 740 | 707 | } |
|---|
| 741 | 708 | |
|---|
| … | … | |
| 927 | 894 | static bo_t *GetAvcCTag( mp4_stream_t *p_stream ) |
|---|
| 928 | 895 | { |
|---|
| 929 | | bo_t *avcC; |
|---|
| 930 | | |
|---|
| | 896 | bo_t *avcC = NULL; |
|---|
| | 897 | uint8_t *p_sps = NULL; |
|---|
| | 898 | uint8_t *p_pps = NULL; |
|---|
| | 899 | int i_sps_size = 0; |
|---|
| | 900 | int i_pps_size = 0; |
|---|
| | 901 | |
|---|
| | 902 | if( p_stream->fmt.i_extra > 0 ) |
|---|
| | 903 | { |
|---|
| | 904 | /* FIXME: take into account multiple sps/pps */ |
|---|
| | 905 | uint8_t *p_buffer = p_stream->fmt.p_extra; |
|---|
| | 906 | int i_buffer = p_stream->fmt.i_extra; |
|---|
| | 907 | |
|---|
| | 908 | while( i_buffer > 4 && |
|---|
| | 909 | p_buffer[0] == 0 && p_buffer[1] == 0 && |
|---|
| | 910 | p_buffer[2] == 0 && p_buffer[3] == 1 ) |
|---|
| | 911 | { |
|---|
| | 912 | const int i_nal_type = p_buffer[4]&0x1f; |
|---|
| | 913 | int i_offset = 1; |
|---|
| | 914 | int i_size = 0; |
|---|
| | 915 | int i_startcode = 0; |
|---|
| | 916 | |
|---|
| | 917 | //msg_Dbg( p_stream, "we found a startcode for NAL with TYPE:%d", i_nal_type ); |
|---|
| | 918 | |
|---|
| | 919 | for( i_offset = 1; i_offset+3 < i_buffer ; i_offset++) |
|---|
| | 920 | { |
|---|
| | 921 | if( p_buffer[i_offset] == 0 && p_buffer[i_offset+1] == 0 && |
|---|
| | 922 | p_buffer[i_offset+2] == 0 && p_buffer[i_offset+3] == 1 ) |
|---|
| | 923 | { |
|---|
| | 924 | /* we found another startcode */ |
|---|
| | 925 | i_startcode = i_offset; |
|---|
| | 926 | break; |
|---|
| | 927 | } |
|---|
| | 928 | } |
|---|
| | 929 | i_size = i_startcode ? i_startcode : i_buffer; |
|---|
| | 930 | if( i_nal_type == 7 ) |
|---|
| | 931 | { |
|---|
| | 932 | p_sps = &p_buffer[4]; |
|---|
| | 933 | i_sps_size = i_size - 4; |
|---|
| | 934 | } |
|---|
| | 935 | if( i_nal_type == 8 ) |
|---|
| | 936 | { |
|---|
| | 937 | p_pps = &p_buffer[4]; |
|---|
| | 938 | i_pps_size = i_size - 4; |
|---|
| | 939 | } |
|---|
| | 940 | i_buffer -= i_size; |
|---|
| | 941 | p_buffer += i_size; |
|---|
| | 942 | } |
|---|
| | 943 | } |
|---|
| | 944 | |
|---|
| 931 | 945 | /* FIXME use better value */ |
|---|
| 932 | 946 | avcC = box_new( "avcC" ); |
|---|
| 933 | 947 | bo_add_8( avcC, 1 ); /* configuration version */ |
|---|
| 934 | | bo_add_8( avcC, p_stream->avc.i_profile ); |
|---|
| 935 | | bo_add_8( avcC, p_stream->avc.i_profile_compat ); |
|---|
| 936 | | bo_add_8( avcC, p_stream->avc.i_level ); /* level, 5.1 */ |
|---|
| | 948 | bo_add_8( avcC, i_sps_size ? p_sps[1] : 77 ); |
|---|
| | 949 | bo_add_8( avcC, i_sps_size ? p_sps[2] : 64 ); |
|---|
| | 950 | bo_add_8( avcC, i_sps_size ? p_sps[3] : 30 ); /* level, 5.1 */ |
|---|
| 937 | 951 | bo_add_8( avcC, 0xff ); /* 0b11111100 | lengthsize = 0x11 */ |
|---|
| 938 | 952 | |
|---|
| 939 | | bo_add_8( avcC, 0xe0 | (p_stream->avc.i_sps > 0 ? 1 : 0) ); /* 0b11100000 | sps_count */ |
|---|
| 940 | | if( p_stream->avc.i_sps > 0 ) |
|---|
| 941 | | { |
|---|
| 942 | | bo_add_16be( avcC, p_stream->avc.i_sps ); |
|---|
| 943 | | bo_add_mem( avcC, p_stream->avc.i_sps, p_stream->avc.sps ); |
|---|
| 944 | | } |
|---|
| 945 | | |
|---|
| 946 | | bo_add_8( avcC, (p_stream->avc.i_pps > 0 ? 1 : 0) ); /* pps_count */ |
|---|
| 947 | | if( p_stream->avc.i_pps > 0 ) |
|---|
| 948 | | { |
|---|
| 949 | | bo_add_16be( avcC, p_stream->avc.i_pps ); |
|---|
| 950 | | bo_add_mem( avcC, p_stream->avc.i_pps, p_stream->avc.pps ); |
|---|
| | 953 | bo_add_8( avcC, 0xe0 | (i_sps_size > 0 ? 1 : 0) ); /* 0b11100000 | sps_count */ |
|---|
| | 954 | if( i_sps_size > 0 ) |
|---|
| | 955 | { |
|---|
| | 956 | bo_add_16be( avcC, i_sps_size ); |
|---|
| | 957 | bo_add_mem( avcC, i_sps_size, p_sps ); |
|---|
| | 958 | } |
|---|
| | 959 | |
|---|
| | 960 | bo_add_8( avcC, (i_pps_size > 0 ? 1 : 0) ); /* pps_count */ |
|---|
| | 961 | if( i_pps_size > 0 ) |
|---|
| | 962 | { |
|---|
| | 963 | bo_add_16be( avcC, i_pps_size ); |
|---|
| | 964 | bo_add_mem( avcC, i_pps_size, p_pps ); |
|---|
| 951 | 965 | } |
|---|
| 952 | 966 | box_fix( avcC ); |
|---|