📄 libmp4.c
字号:
MP4_GET2BYTES( es_descriptor.i_ES_ID ); MP4_GET1BYTE( i_flags ); es_descriptor.b_stream_dependence = ( (i_flags&0x80) != 0); es_descriptor.b_url = ( (i_flags&0x40) != 0); es_descriptor.b_OCRstream = ( (i_flags&0x20) != 0); es_descriptor.i_stream_priority = i_flags&0x1f; if( es_descriptor.b_stream_dependence ) { MP4_GET2BYTES( es_descriptor.i_depend_on_ES_ID ); } if( es_descriptor.b_url ) { unsigned int i_len; MP4_GET1BYTE( i_len ); es_descriptor.psz_URL = calloc( sizeof(char), i_len + 1 ); memcpy( es_descriptor.psz_URL, p_peek, i_len ); es_descriptor.psz_URL[i_len] = 0; p_peek += i_len; i_read -= i_len; } else { es_descriptor.psz_URL = NULL; } if( es_descriptor.b_OCRstream ) { MP4_GET2BYTES( es_descriptor.i_OCR_ES_ID ); } MP4_GET1BYTE( i_type ); /* get next type */ } if( i_type != 0x04)/* MP4DecConfigDescrTag */ { es_descriptor.p_decConfigDescr = NULL; MP4_READBOX_EXIT( 1 ); /* rest isn't interesting up to now */ } i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );#ifdef MP4_VERBOSE msg_Dbg( p_stream, "found esds MP4DecConfigDescr (%dBytes)", i_len );#endif es_descriptor.p_decConfigDescr = malloc( sizeof( MP4_descriptor_decoder_config_t )); MP4_GET1BYTE( es_descriptor.p_decConfigDescr->i_objectTypeIndication ); MP4_GET1BYTE( i_flags ); es_descriptor.p_decConfigDescr->i_streamType = i_flags >> 2; es_descriptor.p_decConfigDescr->b_upStream = ( i_flags >> 1 )&0x01; MP4_GET3BYTES( es_descriptor.p_decConfigDescr->i_buffer_sizeDB ); MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_max_bitrate ); MP4_GET4BYTES( es_descriptor.p_decConfigDescr->i_avg_bitrate ); MP4_GET1BYTE( i_type ); if( i_type != 0x05 )/* MP4DecSpecificDescrTag */ { es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = 0; es_descriptor.p_decConfigDescr->p_decoder_specific_info = NULL; MP4_READBOX_EXIT( 1 ); } i_len = MP4_ReadLengthDescriptor( &p_peek, &i_read );#ifdef MP4_VERBOSE msg_Dbg( p_stream, "found esds MP4DecSpecificDescr (%dBytes)", i_len );#endif es_descriptor.p_decConfigDescr->i_decoder_specific_info_len = i_len; es_descriptor.p_decConfigDescr->p_decoder_specific_info = malloc( i_len ); memcpy( es_descriptor.p_decConfigDescr->p_decoder_specific_info, p_peek, i_len ); MP4_READBOX_EXIT( 1 );#undef es_descriptor}static void MP4_FreeBox_esds( MP4_Box_t *p_box ){ FREE( p_box->data.p_esds->es_descriptor.psz_URL ); if( p_box->data.p_esds->es_descriptor.p_decConfigDescr ) { FREE( p_box->data.p_esds->es_descriptor.p_decConfigDescr->p_decoder_specific_info ); } FREE( p_box->data.p_esds->es_descriptor.p_decConfigDescr );}static int MP4_ReadBox_avcC( stream_t *p_stream, MP4_Box_t *p_box ){ MP4_Box_data_avcC_t *p_avcC; int i; MP4_READBOX_ENTER( MP4_Box_data_avcC_t ); p_avcC = p_box->data.p_avcC; p_avcC->i_avcC = i_read; p_avcC->p_avcC = malloc( p_avcC->i_avcC ); memcpy( p_avcC->p_avcC, p_peek, i_read ); MP4_GET1BYTE( p_avcC->i_version ); MP4_GET1BYTE( p_avcC->i_profile ); MP4_GET1BYTE( p_avcC->i_profile_compatibility ); MP4_GET1BYTE( p_avcC->i_level ); MP4_GET1BYTE( p_avcC->i_reserved1 ); p_avcC->i_length_size = (p_avcC->i_reserved1&0x03) + 1; p_avcC->i_reserved1 >>= 2; MP4_GET1BYTE( p_avcC->i_reserved2 ); p_avcC->i_sps = p_avcC->i_reserved2&0x1f; p_avcC->i_reserved2 >>= 5; if( p_avcC->i_sps > 0 ) { p_avcC->i_sps_length = malloc( p_avcC->i_sps * sizeof( uint16_t ) ); p_avcC->sps = malloc( p_avcC->i_sps * sizeof( uint8_t* ) ); for( i = 0; i < p_avcC->i_sps; i++ ) { MP4_GET2BYTES( p_avcC->i_sps_length[i] ); p_avcC->sps[i] = malloc( p_avcC->i_sps_length[i] ); memcpy( p_avcC->sps[i], p_peek, p_avcC->i_sps_length[i] ); p_peek += p_avcC->i_sps_length[i]; i_read -= p_avcC->i_sps_length[i]; } } MP4_GET1BYTE( p_avcC->i_pps ); if( p_avcC->i_pps > 0 ) { p_avcC->i_pps_length = malloc( p_avcC->i_pps * sizeof( uint16_t ) ); p_avcC->pps = malloc( p_avcC->i_pps * sizeof( uint8_t* ) ); for( i = 0; i < p_avcC->i_pps; i++ ) { MP4_GET2BYTES( p_avcC->i_pps_length[i] ); p_avcC->pps[i] = malloc( p_avcC->i_pps_length[i] ); memcpy( p_avcC->pps[i], p_peek, p_avcC->i_pps_length[i] ); p_peek += p_avcC->i_pps_length[i]; i_read -= p_avcC->i_pps_length[i]; } }#ifdef MP4_VERBOSE msg_Dbg( p_stream, "read box: \"avcC\" version=%d profile=0x%x level=0x%x lengh size=%d sps=%d pps=%d", p_avcC->i_version, p_avcC->i_profile, p_avcC->i_level, p_avcC->i_length_size, p_avcC->i_sps, p_avcC->i_pps ); for( i = 0; i < p_avcC->i_sps; i++ ) { msg_Dbg( p_stream, " - sps[%d] length=%d", i, p_avcC->i_sps_length[i] ); } for( i = 0; i < p_avcC->i_pps; i++ ) { msg_Dbg( p_stream, " - pps[%d] length=%d", i, p_avcC->i_pps_length[i] ); }#endif MP4_READBOX_EXIT( 1 );}static void MP4_FreeBox_avcC( MP4_Box_t *p_box ){ MP4_Box_data_avcC_t *p_avcC = p_box->data.p_avcC; int i; for( i = 0; i < p_avcC->i_sps; i++ ) { FREE( p_avcC->sps[i] ); } for( i = 0; i < p_avcC->i_pps; i++ ) { FREE( p_avcC->pps[i] ); } if( p_avcC->i_sps > 0 ) FREE( p_avcC->sps ); if( p_avcC->i_pps > 0 ) FREE( p_avcC->pps );}static int MP4_ReadBox_sample_soun( stream_t *p_stream, MP4_Box_t *p_box ){ unsigned int i; MP4_READBOX_ENTER( MP4_Box_data_sample_soun_t ); p_box->data.p_sample_soun->p_qt_description = NULL; /* Sanity check needed because the "wave" box does also contain an * "mp4a" box that we don't understand. */ if( i_read < 28 ) { i_read -= 30; MP4_READBOX_EXIT( 1 ); } for( i = 0; i < 6 ; i++ ) { MP4_GET1BYTE( p_box->data.p_sample_soun->i_reserved1[i] ); } MP4_GET2BYTES( p_box->data.p_sample_soun->i_data_reference_index ); /* * XXX hack -> produce a copy of the nearly complete chunk */ if( i_read > 0 ) { p_box->data.p_sample_soun->i_qt_description = i_read; p_box->data.p_sample_soun->p_qt_description = malloc( i_read ); memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read ); } else { p_box->data.p_sample_soun->i_qt_description = 0; p_box->data.p_sample_soun->p_qt_description = NULL; } MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_version ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_qt_revision_level ); MP4_GET4BYTES( p_box->data.p_sample_soun->i_qt_vendor ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_channelcount ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_samplesize ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_predefined ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_reserved3 ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratehi ); MP4_GET2BYTES( p_box->data.p_sample_soun->i_sampleratelo ); if( p_box->data.p_sample_soun->i_qt_version == 1 && i_read >= 16 ) { /* qt3+ */ MP4_GET4BYTES( p_box->data.p_sample_soun->i_sample_per_packet ); MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_packet ); MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_frame ); MP4_GET4BYTES( p_box->data.p_sample_soun->i_bytes_per_sample );#ifdef MP4_VERBOSE msg_Dbg( p_stream, "read box: \"soun\" qt3+ sample/packet=%d bytes/packet=%d " "bytes/frame=%d bytes/sample=%d", p_box->data.p_sample_soun->i_sample_per_packet, p_box->data.p_sample_soun->i_bytes_per_packet, p_box->data.p_sample_soun->i_bytes_per_frame, p_box->data.p_sample_soun->i_bytes_per_sample );#endif stream_Seek( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 44 ); } else { p_box->data.p_sample_soun->i_sample_per_packet = 0; p_box->data.p_sample_soun->i_bytes_per_packet = 0; p_box->data.p_sample_soun->i_bytes_per_frame = 0; p_box->data.p_sample_soun->i_bytes_per_sample = 0; msg_Dbg( p_stream, "read box: \"soun\" mp4 or qt1/2 (rest="I64Fd")", i_read ); stream_Seek( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 28 ); } if( p_box->i_type == FOURCC_drms ) { p_box->data.p_sample_soun->p_drms = drms_alloc( p_stream->p_vlc->psz_homedir ); if( p_box->data.p_sample_soun->p_drms == NULL ) { msg_Err( p_stream, "drms_alloc() failed" ); } } if( p_box->i_type == FOURCC_samr || p_box->i_type == FOURCC_sawb ) { /* Ignore channelcount for AMR (3gpp AMRSpecificBox) */ p_box->data.p_sample_soun->i_channelcount = 1; } if( p_box->i_type == FOURCC_alac ) { if( p_box->data.p_sample_soun->p_qt_description ) free( p_box->data.p_sample_soun->p_qt_description ); p_box->data.p_sample_soun->p_qt_description = malloc( i_read ); p_box->data.p_sample_soun->i_qt_description = i_read; memcpy( p_box->data.p_sample_soun->p_qt_description, p_peek, i_read ); } else { MP4_ReadBoxContainerRaw( p_stream, p_box ); /* esds */ }#ifdef MP4_VERBOSE msg_Dbg( p_stream, "read box: \"soun\" in stsd channel %d " "sample size %d sample rate %f", p_box->data.p_sample_soun->i_channelcount, p_box->data.p_sample_soun->i_samplesize, (float)p_box->data.p_sample_soun->i_sampleratehi + (float)p_box->data.p_sample_soun->i_sampleratelo / 65536 );#endif MP4_READBOX_EXIT( 1 );}static void MP4_FreeBox_sample_soun( MP4_Box_t *p_box ){ FREE( p_box->data.p_sample_soun->p_qt_description ); if( p_box->i_type == FOURCC_drms ) { if( p_box->data.p_sample_soun->p_drms ) { drms_free( p_box->data.p_sample_soun->p_drms ); } }}int MP4_ReadBox_sample_vide( stream_t *p_stream, MP4_Box_t *p_box ){ unsigned int i; MP4_READBOX_ENTER( MP4_Box_data_sample_vide_t ); for( i = 0; i < 6 ; i++ ) { MP4_GET1BYTE( p_box->data.p_sample_vide->i_reserved1[i] ); } MP4_GET2BYTES( p_box->data.p_sample_vide->i_data_reference_index ); /* * XXX hack -> produce a copy of the nearly complete chunk */ if( i_read > 0 ) { p_box->data.p_sample_vide->i_qt_image_description = i_read; p_box->data.p_sample_vide->p_qt_image_description = malloc( i_read ); memcpy( p_box->data.p_sample_vide->p_qt_image_description, p_peek, i_read ); } else { p_box->data.p_sample_vide->i_qt_image_description = 0; p_box->data.p_sample_vide->p_qt_image_description = NULL; } MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_version ); MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_revision_level ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_vendor ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_temporal_quality ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_spatial_quality ); MP4_GET2BYTES( p_box->data.p_sample_vide->i_width ); MP4_GET2BYTES( p_box->data.p_sample_vide->i_height ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_horizresolution ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_vertresolution ); MP4_GET4BYTES( p_box->data.p_sample_vide->i_qt_data_size ); MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_frame_count ); memcpy( &p_box->data.p_sample_vide->i_compressorname, p_peek, 32 ); p_peek += 32; i_read -= 32; MP4_GET2BYTES( p_box->data.p_sample_vide->i_depth ); MP4_GET2BYTES( p_box->data.p_sample_vide->i_qt_color_table ); stream_Seek( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 78); MP4_ReadBoxContainerRaw( p_stream, p_box );#ifdef MP4_VERBOSE msg_Dbg( p_stream, "read box: \"vide\" in stsd %dx%d depth %d", p_box->data.p_sample_vide->i_width, p_box->data.p_sample_vide->i_height, p_box->data.p_sample_vide->i_depth );#endif MP4_READBOX_EXIT( 1 );}void MP4_FreeBox_sample_vide( MP4_Box_t *p_box ){ FREE( p_box->data.p_sample_vide->p_qt_image_description );}static int MP4_ReadBox_sample_mp4s( stream_t *p_stream, MP4_Box_t *p_box ){ stream_Seek( p_stream, p_box->i_pos + MP4_BOX_HEADERSIZE( p_box ) + 8 ); MP4_ReadBoxContainerRaw( p_stream, p_box ); return 1;}static int MP4_ReadBox_sample_text( stream_t *p_stream, MP4_Box_t *p_box ){ unsigned int i; MP4_READBOX_ENTER( MP4_Box_data_sample_text_t ); for( i = 0; i < 6 ; i++ ) { MP4_GET1BYTE( p_box->data.p_sample_text->i_reserved1[i] ); } MP4_GET2BYTES( p_box->data.p_sample_text->i_data_reference_index ); MP4_GET4BYTES( p_box->data.p_sample_text->i_display_flags ); MP4_GET4BYTES( p_box->data.p_sample_text->i_justification ); MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[0] ); MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[1] ); MP4_GET2BYTES( p_box->data.p_sample_text->i_background_color[2] ); MP4_GET8BYTES( p_box->data.p_sample_text->i_text_box ); MP4_GET8BYTES( p_box->data.p_sample_text->i_reserved2 ); MP4_GET2BYTES( p_box->data.p_sample_text->i_font_number ); MP4_GET2BYTES( p_box->data.p_sample_text->i_font_face ); MP4_GET2BYTES( p_box->data.p_sample_text->i_reserved3 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -