⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 asf.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
{0x33000890, 0xE5B1, 0x11CF, {0x89, 0xF4, 0x00, 0xA0, 0xC9, 0x03, 0x49, 0xCB}};static const guid_t asf_object_metadata_guid ={0xC5F8CBEA, 0x5BAF, 0x4877, {0x84, 0x67, 0xAA, 0x8C, 0x44, 0xFA, 0x4C, 0xCA}};/**************************************************************************** * Misc ****************************************************************************/static void asf_chunk_add( bo_t *bo,                           int i_type, int i_len, int i_flags, int i_seq ){    bo_addle_u16( bo, i_type );    bo_addle_u16( bo, i_len + 8 );    bo_addle_u32( bo, i_seq );    bo_addle_u16( bo, i_flags );    bo_addle_u16( bo, i_len + 8 );}static block_t *asf_header_create( sout_mux_t *p_mux, vlc_bool_t b_broadcast ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    asf_track_t    *tk;    mtime_t i_duration = 0;    int i_size, i_header_ext_size, i;    int i_ci_size, i_cm_size = 0, i_cd_size = 0;    block_t *out;    bo_t bo;    msg_Dbg( p_mux, "Asf muxer creating header" );    if( p_sys->i_dts_first > 0 )    {        i_duration = p_sys->i_dts_last - p_sys->i_dts_first;        if( i_duration < 0 ) i_duration = 0;    }    /* calculate header size */    i_size = 30 + 104;    i_ci_size = 44;    for( i = 0; i < p_sys->i_track; i++ )    {        i_size += 78 + p_sys->track[i].i_extra;        i_ci_size += 8 + 2 * strlen( p_sys->track[i].psz_name );        if( p_sys->track[i].i_cat == AUDIO_ES ) i_ci_size += 4;        else if( p_sys->track[i].i_cat == VIDEO_ES ) i_ci_size += 6;        /* Error correction data field */        if( p_sys->track[i].b_audio_correction ) i_size += 8;    }    /* size of the content description object */    if( *p_sys->psz_title || *p_sys->psz_author || *p_sys->psz_copyright ||        *p_sys->psz_comment || *p_sys->psz_rating )    {        i_cd_size = 34 + 2 * ( strlen( p_sys->psz_title ) + 1 +                             strlen( p_sys->psz_author ) + 1 +                             strlen( p_sys->psz_copyright ) + 1 +                             strlen( p_sys->psz_comment ) + 1 +                             strlen( p_sys->psz_rating ) + 1 );    }    /* size of the metadata object */    for( i = 0; i < p_sys->i_track; i++ )    {        if( p_sys->track[i].i_cat == VIDEO_ES )        {            i_cm_size = 26 + 2 * (16 + 2 * sizeof("AspectRatio?"));            break;        }    }    i_header_ext_size = i_cm_size ? i_cm_size + 46 : 0;    i_size += i_ci_size + i_cd_size + i_header_ext_size ;    if( p_sys->b_asf_http )    {        out = block_New( p_mux, i_size + 50 + 12 );        bo_init( &bo, out->p_buffer, i_size + 50 + 12 );        asf_chunk_add( &bo, 0x4824, i_size + 50, 0xc00, p_sys->i_seq++ );    }    else    {        out = block_New( p_mux, i_size + 50 );        bo_init( &bo, out->p_buffer, i_size + 50 );    }    /* header object */    bo_add_guid ( &bo, &asf_object_header_guid );    bo_addle_u64( &bo, i_size );    bo_addle_u32( &bo, 2 + p_sys->i_track +                  (i_cd_size ? 1 : 0) + (i_cm_size ? 1 : 0) );    bo_add_u8   ( &bo, 1 );    bo_add_u8   ( &bo, 2 );    /* sub object */    /* file properties */    bo_add_guid ( &bo, &asf_object_file_properties_guid );    bo_addle_u64( &bo, 104 );    bo_add_guid ( &bo, &p_sys->fid );    bo_addle_u64( &bo, i_size + 50 + p_sys->i_packet_count *                                p_sys->i_packet_size ); /* file size */    bo_addle_u64( &bo, 0 );                 /* creation date */    bo_addle_u64( &bo, b_broadcast ? 0xffffffffLL : p_sys->i_packet_count );    bo_addle_u64( &bo, i_duration * 10 );   /* play duration (100ns) */    bo_addle_u64( &bo, i_duration * 10 );   /* send duration (100ns) */    bo_addle_u64( &bo, p_sys->i_preroll_time ); /* preroll duration (ms) */    bo_addle_u32( &bo, b_broadcast ? 0x01 : 0x02 /* seekable */ ); /* flags */    bo_addle_u32( &bo, p_sys->i_packet_size );  /* packet size min */    bo_addle_u32( &bo, p_sys->i_packet_size );  /* packet size max */    bo_addle_u32( &bo, p_sys->i_bitrate );      /* maxbitrate */    /* header extention */    if( i_header_ext_size )    {        bo_add_guid ( &bo, &asf_object_header_extention_guid );        bo_addle_u64( &bo, i_header_ext_size );        bo_add_guid ( &bo, &asf_guid_reserved_1 );        bo_addle_u16( &bo, 6 );        bo_addle_u32( &bo, i_header_ext_size - 46 );    }    /* metadata object (part of header extension) */    if( i_cm_size )    {        int64_t i_num, i_den;        int i_dst_num, i_dst_den;        for( i = 0; i < p_sys->i_track; i++ )            if( p_sys->track[i].i_cat == VIDEO_ES ) break;        i_num = p_sys->track[i].fmt.video.i_aspect *            (int64_t)p_sys->track[i].fmt.video.i_height;        i_den = VOUT_ASPECT_FACTOR * p_sys->track[i].fmt.video.i_width;        vlc_reduce( &i_dst_num, &i_dst_den, i_num, i_den, 0 );        msg_Dbg( p_mux, "pixel aspect-ratio: %i/%i", i_dst_num, i_dst_den );        bo_add_guid ( &bo, &asf_object_metadata_guid );        bo_addle_u64( &bo, i_cm_size );        bo_addle_u16( &bo, 2 ); /* description records count */        /* 1st description record */        bo_addle_u16( &bo, 0 ); /* reserved */        bo_addle_u16( &bo, i + 1 ); /* stream number (0 for the whole file) */        bo_addle_u16( &bo, 2 * sizeof("AspectRatioX") ); /* name length */        bo_addle_u16( &bo, 0x3 /* DWORD */ ); /* data type */        bo_addle_u32( &bo, 4 ); /* data length */        bo_addle_str16_nosize( &bo, "AspectRatioX" );        bo_addle_u32( &bo, i_dst_num ); /* data */        /* 2nd description record */        bo_addle_u16( &bo, 0 ); /* reserved */        bo_addle_u16( &bo, i + 1 ); /* stream number (0 for the whole file) */        bo_addle_u16( &bo, 2 * sizeof("AspectRatioY") ); /* name length */        bo_addle_u16( &bo, 0x3 /* DWORD */ ); /* data type */        bo_addle_u32( &bo, 4 ); /* data length */        bo_addle_str16_nosize( &bo, "AspectRatioY" );        bo_addle_u32( &bo, i_dst_den ); /* data */    }    /* content description header */    if( i_cd_size > 0 )    {        bo_add_guid ( &bo, &asf_object_content_description_guid );        bo_addle_u64( &bo, i_cd_size );        bo_addle_u16( &bo, 2 * strlen( p_sys->psz_title ) + 2 );        bo_addle_u16( &bo, 2 * strlen( p_sys->psz_author ) + 2 );        bo_addle_u16( &bo, 2 * strlen( p_sys->psz_copyright ) + 2 );        bo_addle_u16( &bo, 2 * strlen( p_sys->psz_comment ) + 2 );        bo_addle_u16( &bo, 2 * strlen( p_sys->psz_rating ) + 2 );        bo_addle_str16_nosize( &bo, p_sys->psz_title );        bo_addle_str16_nosize( &bo, p_sys->psz_author );        bo_addle_str16_nosize( &bo, p_sys->psz_copyright );        bo_addle_str16_nosize( &bo, p_sys->psz_comment );        bo_addle_str16_nosize( &bo, p_sys->psz_rating );    }    /* stream properties */    for( i = 0; i < p_sys->i_track; i++ )    {        tk = &p_sys->track[i];        bo_add_guid ( &bo, &asf_object_stream_properties_guid );        bo_addle_u64( &bo, 78 + tk->i_extra + (tk->b_audio_correction ? 8:0) );        if( tk->i_cat == AUDIO_ES )        {            bo_add_guid( &bo, &asf_object_stream_type_audio );            if( tk->b_audio_correction )                bo_add_guid( &bo, &asf_guid_audio_conceal_spread );            else                bo_add_guid( &bo, &asf_guid_audio_conceal_none );        }        else if( tk->i_cat == VIDEO_ES )        {            bo_add_guid( &bo, &asf_object_stream_type_video );            bo_add_guid( &bo, &asf_guid_video_conceal_none );        }        bo_addle_u64( &bo, 0 );         /* time offset */        bo_addle_u32( &bo, tk->i_extra );        /* correction data length */        bo_addle_u32( &bo, tk->b_audio_correction ? 8 : 0 );        bo_addle_u16( &bo, tk->i_id );  /* stream number */        bo_addle_u32( &bo, 0 );        bo_add_mem  ( &bo, tk->p_extra, tk->i_extra );        /* Error correction data field */        if( tk->b_audio_correction )        {            bo_add_u8( &bo, 0x1 ); /* span */            bo_addle_u16( &bo, tk->i_blockalign );  /* virtual packet length */            bo_addle_u16( &bo, tk->i_blockalign );  /* virtual chunck length */            bo_addle_u16( &bo, 1 );  /* silence length */            bo_add_u8( &bo, 0x0 ); /* data */        }    }    /* Codec Infos */    bo_add_guid ( &bo, &asf_object_codec_list_guid );    bo_addle_u64( &bo, i_ci_size );    bo_add_guid ( &bo, &asf_object_codec_list_reserved_guid );    bo_addle_u32( &bo, p_sys->i_track );    for( i = 0; i < p_sys->i_track; i++ )    {        tk = &p_sys->track[i];        if( tk->i_cat == VIDEO_ES ) bo_addle_u16( &bo, 1 /* video */ );        else if( tk->i_cat == AUDIO_ES ) bo_addle_u16( &bo, 2 /* audio */ );        else bo_addle_u16( &bo, 0xFFFF /* unknown */ );        bo_addle_str16( &bo, tk->psz_name );        bo_addle_u16( &bo, 0 );        if( tk->i_cat == AUDIO_ES )        {            bo_addle_u16( &bo, 2 );            bo_addle_u16( &bo, tk->i_tag );        }        else if( tk->i_cat == VIDEO_ES )        {            bo_addle_u16( &bo, 4 );            bo_add_mem  ( &bo, (uint8_t*)&tk->i_fourcc, 4 );        }    }    /* data object */    bo_add_guid ( &bo, &asf_object_data_guid );    bo_addle_u64( &bo, 50 + p_sys->i_packet_count * p_sys->i_packet_size );    bo_add_guid ( &bo, &p_sys->fid );    bo_addle_u64( &bo, p_sys->i_packet_count );    bo_addle_u16( &bo, 0x101 );    return out;}/**************************************************************************** * ****************************************************************************/static block_t *asf_packet_flush( sout_mux_t *p_mux ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    int i_pad, i_preheader = p_sys->b_asf_http ? 12 : 0;    block_t *pk;    bo_t bo;    if( !p_sys->pk ) return 0;    i_pad = p_sys->i_packet_size - p_sys->i_pk_used;    memset( p_sys->pk->p_buffer + p_sys->i_pk_used, 0, i_pad );    bo_init( &bo, p_sys->pk->p_buffer, 14 + i_preheader );    if( p_sys->b_asf_http )        asf_chunk_add( &bo, 0x4424, p_sys->i_packet_size, 0x0, p_sys->i_seq++);    bo_add_u8   ( &bo, 0x82 );    bo_addle_u16( &bo, 0 );    bo_add_u8( &bo, 0x11 );    bo_add_u8( &bo, 0x5d );    bo_addle_u16( &bo, i_pad );    bo_addle_u32( &bo, (p_sys->i_pk_dts - p_sys->i_dts_first) / 1000 +                  p_sys->i_preroll_time );    bo_addle_u16( &bo, 0 /* data->i_length */ );    bo_add_u8( &bo, 0x80 | p_sys->i_pk_frame );    pk = p_sys->pk;    p_sys->pk = NULL;    p_sys->i_packet_count++;    return pk;}static block_t *asf_packet_create( sout_mux_t *p_mux,                                   asf_track_t *tk, block_t *data ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    int     i_data = data->i_buffer;    int     i_pos  = 0;    uint8_t *p_data= data->p_buffer;    block_t *first = NULL, **last = &first;    int     i_preheader = p_sys->b_asf_http ? 12 : 0;    while( i_pos < i_data )    {        bo_t bo;        int i_payload;        if( p_sys->pk == NULL )        {            p_sys->pk = block_New( p_mux, p_sys->i_packet_size + i_preheader );            /* reserve 14 bytes for the packet header */            p_sys->i_pk_used = 14 + i_preheader;            p_sys->i_pk_frame = 0;            p_sys->i_pk_dts = data->i_dts;        }        bo_init( &bo, &p_sys->pk->p_buffer[p_sys->i_pk_used],                 p_sys->i_packet_size - p_sys->i_pk_used );        /* add payload (header size = 17) */        i_payload = __MIN( i_data - i_pos,                           p_sys->i_packet_size - p_sys->i_pk_used - 17 );        if( tk->b_audio_correction && p_sys->i_pk_frame && i_payload < i_data )        {            /* Don't know why yet but WMP doesn't like splitted WMA packets */            *last = asf_packet_flush( p_mux );            last  = &(*last)->p_next;            continue;        }        bo_add_u8   ( &bo, !(data->i_flags & BLOCK_FLAG_TYPE_P ||                      data->i_flags & BLOCK_FLAG_TYPE_B) ?                      0x80 | tk->i_id : tk->i_id );        bo_add_u8   ( &bo, tk->i_sequence );        bo_addle_u32( &bo, i_pos );        bo_add_u8   ( &bo, 0x08 );  /* flags */        bo_addle_u32( &bo, i_data );        bo_addle_u32( &bo, (data->i_dts - p_sys->i_dts_first) / 1000 +                      p_sys->i_preroll_time );        bo_addle_u16( &bo, i_payload );        bo_add_mem  ( &bo, &p_data[i_pos], i_payload );        i_pos += i_payload;        p_sys->i_pk_used += 17 + i_payload;        p_sys->i_pk_frame++;        if( p_sys->i_pk_used + 17 >= p_sys->i_packet_size )        {            /* Not enough data for another payload, flush the packet */            *last = asf_packet_flush( p_mux );            last  = &(*last)->p_next;        }    }    tk->i_sequence++;    block_Release( data );    return first;}static block_t *asf_stream_end_create( sout_mux_t *p_mux ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    block_t *out = NULL;    bo_t bo;    if( p_sys->b_asf_http )    {        out = block_New( p_mux, 12 );        bo_init( &bo, out->p_buffer, 12 );        asf_chunk_add( &bo, 0x4524, 0, 0x00, p_sys->i_seq++ );    }    else    {        /* Create index */        out = block_New( p_mux, 56 );        bo_init( &bo, out->p_buffer, 56 );        bo_add_guid ( &bo, &asf_object_index_guid );        bo_addle_u64( &bo, 56 );        bo_add_guid ( &bo, &p_sys->fid );        bo_addle_u64( &bo, 10000000 );        bo_addle_u32( &bo, 5 );        bo_addle_u32( &bo, 0 );    }    return out;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -