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

📄 ogg.c

📁 uclinux 下的vlc播放器源代码
💻 C
📖 第 1 页 / 共 3 页
字号:
        switch( p_stream->i_fourcc )        {        case VLC_FOURCC( 'm', 'p', 'g', 'v' ):        case VLC_FOURCC( 'm', 'p', '4', 'v' ):        case VLC_FOURCC( 'D', 'I', 'V', '3' ):        case VLC_FOURCC( 'M', 'J', 'P', 'G' ):        case VLC_FOURCC( 'W', 'M', 'V', '1' ):        case VLC_FOURCC( 'W', 'M', 'V', '2' ):        case VLC_FOURCC( 'W', 'M', 'V', '3' ):        case VLC_FOURCC( 'S', 'N', 'O', 'W' ):        case VLC_FOURCC( 'd', 'r', 'a', 'c' ):            p_stream->p_oggds_header = malloc( sizeof(oggds_header_t) );            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;            memcpy( p_stream->p_oggds_header->stream_type, "video", 5 );            if( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) )            {                memcpy( p_stream->p_oggds_header->sub_type, "XVID", 4 );            }            else if( p_stream->i_fourcc == VLC_FOURCC( 'D', 'I', 'V', '3' ) )            {                memcpy( p_stream->p_oggds_header->sub_type, "DIV3", 4 );            }            else            {                memcpy( p_stream->p_oggds_header->sub_type,                        &p_stream->i_fourcc, 4 );            }            SetDWLE( &p_stream->p_oggds_header->i_size,                     sizeof( oggds_header_t ) - 1 );            SetQWLE( &p_stream->p_oggds_header->i_time_unit,                     I64C(10000000) * p_input->p_fmt->video.i_frame_rate_base /                     (int64_t)p_input->p_fmt->video.i_frame_rate );            SetQWLE( &p_stream->p_oggds_header->i_samples_per_unit, 1 );            SetDWLE( &p_stream->p_oggds_header->i_default_len, 1 ); /* ??? */            SetDWLE( &p_stream->p_oggds_header->i_buffer_size, 1024*1024 );            SetWLE( &p_stream->p_oggds_header->i_bits_per_sample, 0 );            SetDWLE( &p_stream->p_oggds_header->header.video.i_width,                     p_input->p_fmt->video.i_width );            SetDWLE( &p_stream->p_oggds_header->header.video.i_height,                     p_input->p_fmt->video.i_height );            msg_Dbg( p_mux, "%4.4s stream", (char *)&p_stream->i_fourcc );            break;        case VLC_FOURCC( 't', 'h', 'e', 'o' ):            msg_Dbg( p_mux, "theora stream" );            break;        default:            FREE( p_input->p_sys );            return VLC_EGENERIC;        }        break;    case AUDIO_ES:        switch( p_stream->i_fourcc )        {        case VLC_FOURCC( 'v', 'o', 'r', 'b' ):            msg_Dbg( p_mux, "vorbis stream" );            break;        case VLC_FOURCC( 's', 'p', 'x', ' ' ):            msg_Dbg( p_mux, "speex stream" );            break;        case VLC_FOURCC( 'f', 'l', 'a', 'c' ):            msg_Dbg( p_mux, "flac stream" );            break;        default:            fourcc_to_wf_tag( p_stream->i_fourcc, &i_tag );            if( i_tag == WAVE_FORMAT_UNKNOWN )            {                FREE( p_input->p_sys );                return VLC_EGENERIC;            }            p_stream->p_oggds_header =                malloc( sizeof(oggds_header_t) + p_input->p_fmt->i_extra );            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;            SetDWLE( &p_stream->p_oggds_header->i_size,                     sizeof( oggds_header_t ) - 1 + p_input->p_fmt->i_extra );            if( p_input->p_fmt->i_extra )            {                memcpy( &p_stream->p_oggds_header[1],                        p_input->p_fmt->p_extra, p_input->p_fmt->i_extra );            }            memcpy( p_stream->p_oggds_header->stream_type, "audio", 5 );            memset( p_stream->p_oggds_header->sub_type, 0, 4 );            sprintf( p_stream->p_oggds_header->sub_type, "%-x", i_tag );            SetQWLE( &p_stream->p_oggds_header->i_time_unit, I64C(10000000) );            SetDWLE( &p_stream->p_oggds_header->i_default_len, 1 );            SetDWLE( &p_stream->p_oggds_header->i_buffer_size, 30*1024 );            SetQWLE( &p_stream->p_oggds_header->i_samples_per_unit,                     p_input->p_fmt->audio.i_rate );            SetWLE( &p_stream->p_oggds_header->i_bits_per_sample,                    p_input->p_fmt->audio.i_bitspersample );            SetDWLE( &p_stream->p_oggds_header->header.audio.i_channels,                     p_input->p_fmt->audio.i_channels );            SetDWLE( &p_stream->p_oggds_header->header.audio.i_block_align,                     p_input->p_fmt->audio.i_blockalign );            SetDWLE( &p_stream->p_oggds_header->header.audio.i_avgbytespersec,                     p_input->p_fmt->i_bitrate / 8);            msg_Dbg( p_mux, "%4.4s stream", (char *)&p_stream->i_fourcc );            break;        }        break;    case SPU_ES:        switch( p_stream->i_fourcc )        {        case VLC_FOURCC( 's', 'u','b', 't' ):            p_stream->p_oggds_header = malloc( sizeof(oggds_header_t) );            memset( p_stream->p_oggds_header, 0, sizeof(oggds_header_t) );            p_stream->p_oggds_header->i_packet_type = PACKET_TYPE_HEADER;            memcpy( p_stream->p_oggds_header->stream_type, "text", 4 );            msg_Dbg( p_mux, "subtitles stream" );            break;        default:            FREE( p_input->p_sys );            return VLC_EGENERIC;        }        break;    default:        FREE( p_input->p_sys );        return VLC_EGENERIC;    }    p_stream->b_new = VLC_TRUE;    p_sys->i_add_streams++;    return VLC_SUCCESS;}/***************************************************************************** * DelStream: Delete an elementary stream from the muxed stream *****************************************************************************/static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ){    sout_mux_sys_t *p_sys  = p_mux->p_sys;    ogg_stream_t   *p_stream = (ogg_stream_t*)p_input->p_sys;    block_t *p_og;    msg_Dbg( p_mux, "removing input" );    /* flush all remaining data */    if( p_input->p_sys )    {        if( !p_stream->b_new )        {            while( p_input->p_fifo->i_depth ) MuxBlock( p_mux, p_input );        }        if( !p_stream->b_new &&            ( p_og = OggStreamFlush( p_mux, &p_stream->os, 0 ) ) )        {            OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );            sout_AccessOutWrite( p_mux->p_access, p_og );        }        /* move input in delete queue */        if( !p_stream->b_new )        {            p_sys->pp_del_streams = realloc( p_sys->pp_del_streams,                                             (p_sys->i_del_streams + 1) *                                             sizeof(ogg_stream_t *) );            p_sys->pp_del_streams[p_sys->i_del_streams++] = p_stream;        }        else        {            /* wasn't already added so get rid of it */            FREE( p_stream->p_oggds_header );            FREE( p_stream );            p_sys->i_add_streams--;        }    }    p_input->p_sys = NULL;    return 0;}/***************************************************************************** * Ogg bitstream manipulation routines *****************************************************************************/static block_t *OggStreamFlush( sout_mux_t *p_mux,                                ogg_stream_state *p_os, mtime_t i_pts ){    block_t *p_og, *p_og_first = NULL;    ogg_page og;    while( ogg_stream_flush( p_os, &og ) )    {        /* Flush all data */        p_og = block_New( p_mux, og.header_len + og.body_len );        memcpy( p_og->p_buffer, og.header, og.header_len );        memcpy( p_og->p_buffer + og.header_len, og.body, og.body_len );        p_og->i_dts     = 0;        p_og->i_pts     = i_pts;        p_og->i_length  = 0;        i_pts = 0; // write it only once        block_ChainAppend( &p_og_first, p_og );    }    return p_og_first;}static block_t *OggStreamPageOut( sout_mux_t *p_mux,                                  ogg_stream_state *p_os, mtime_t i_pts ){    block_t *p_og, *p_og_first = NULL;    ogg_page og;    while( ogg_stream_pageout( p_os, &og ) )    {        /* Flush all data */        p_og = block_New( p_mux, og.header_len + og.body_len );        memcpy( p_og->p_buffer, og.header, og.header_len );        memcpy( p_og->p_buffer + og.header_len, og.body, og.body_len );        p_og->i_dts     = 0;        p_og->i_pts     = i_pts;        p_og->i_length  = 0;        i_pts = 0; // write them only once        block_ChainAppend( &p_og_first, p_og );    }    return p_og_first;}static block_t *OggCreateHeader( sout_mux_t *p_mux, mtime_t i_dts ){    block_t *p_hdr = NULL;    block_t *p_og = NULL;    ogg_packet op;    uint8_t *p_extra;    int i, i_extra;    /* Write header for each stream. All b_o_s (beginning of stream) packets     * must appear first in the ogg stream so we take care of them first. */    for( i = 0; i < p_mux->i_nb_inputs; i++ )    {        sout_input_t *p_input = p_mux->pp_inputs[i];        ogg_stream_t *p_stream = (ogg_stream_t*)p_input->p_sys;        p_stream->b_new = VLC_FALSE;        msg_Dbg( p_mux, "creating header for %4.4s",                 (char *)&p_stream->i_fourcc );        ogg_stream_init( &p_stream->os, p_stream->i_serial_no );        p_stream->i_packet_no = 0;        if( p_stream->i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) ||            p_stream->i_fourcc == VLC_FOURCC( 's', 'p', 'x', ' ' ) ||            p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )        {            /* First packet in order: vorbis/speex/theora info */            p_extra = p_input->p_fmt->p_extra;            i_extra = p_input->p_fmt->i_extra;            op.bytes = *(p_extra++) << 8;            op.bytes |= (*(p_extra++) & 0xFF);            op.packet = p_extra;            i_extra -= (op.bytes + 2);            if( i_extra < 0 )            {                msg_Err( p_mux, "header data corrupted");                op.bytes += i_extra;            }            op.b_o_s  = 1;            op.e_o_s  = 0;            op.granulepos = 0;            op.packetno = p_stream->i_packet_no++;            ogg_stream_packetin( &p_stream->os, &op );            p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );            /* Get keyframe_granule_shift for theora granulepos calculation */            if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )            {                int i_keyframe_frequency_force =                      1 << ((op.packet[40] << 6 >> 3) | (op.packet[41] >> 5));                /* granule_shift = i_log( frequency_force -1 ) */                p_stream->i_keyframe_granule_shift = 0;                i_keyframe_frequency_force--;                while( i_keyframe_frequency_force )                {                    p_stream->i_keyframe_granule_shift++;                    i_keyframe_frequency_force >>= 1;                }            }        }        else if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )        {            /* flac stream marker (yeah, only that in the 1st packet) */            op.packet = (unsigned char *)"fLaC";            op.bytes  = 4;            op.b_o_s  = 1;            op.e_o_s  = 0;            op.granulepos = 0;            op.packetno = p_stream->i_packet_no++;            ogg_stream_packetin( &p_stream->os, &op );            p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );        }        else if( p_stream->p_oggds_header )        {            /* ds header */            op.packet = (uint8_t*)p_stream->p_oggds_header;            op.bytes  = p_stream->p_oggds_header->i_size + 1;            op.b_o_s  = 1;            op.e_o_s  = 0;            op.granulepos = 0;            op.packetno = p_stream->i_packet_no++;            ogg_stream_packetin( &p_stream->os, &op );            p_og = OggStreamFlush( p_mux, &p_stream->os, 0 );        }        block_ChainAppend( &p_hdr, p_og );    }    /* Take care of the non b_o_s headers */    for( i = 0; i < p_mux->i_nb_inputs; i++ )    {

⌨️ 快捷键说明

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