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

📄 ogg.c

📁 video linux conference
💻 C
📖 第 1 页 / 共 3 页
字号:
        sout_input_t *p_input = p_mux->pp_inputs[i];        ogg_stream_t *p_stream = (ogg_stream_t*)p_input->p_sys;        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' ) )        {            /* Special case, headers are already there in the incoming stream.             * We need to gather them an mark them as headers. */            int j = 2;            if( p_stream->i_fourcc == VLC_FOURCC( 's', 'p', 'x', ' ' ) ) j = 1;            p_extra = p_input->p_fmt->p_extra;            i_extra = p_input->p_fmt->i_extra;            /* Skip 1 header */            op.bytes = *(p_extra++) << 8;            op.bytes |= (*(p_extra++) & 0xFF);            op.packet = p_extra;            p_extra += op.bytes;            i_extra -= (op.bytes + 2);            while( j-- )            {                op.bytes = *(p_extra++) << 8;                op.bytes |= (*(p_extra++) & 0xFF);                op.packet = p_extra;                p_extra += op.bytes;                i_extra -= (op.bytes + 2);                if( i_extra < 0 )                {                    msg_Err( p_mux, "header data corrupted");                    op.bytes += i_extra;                }                op.b_o_s  = 0;                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 );            }        }        else if( p_stream->i_fourcc != VLC_FOURCC( 'f', 'l', 'a', 'c' ) )        {            uint8_t com[128];            int     i_com;            /* comment */            com[0] = PACKET_TYPE_COMMENT;            i_com = snprintf( &com[1], 128, PACKAGE_VERSION" stream output" )                     + 1;            op.packet = com;            op.bytes  = i_com;            op.b_o_s  = 0;            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 );        }        /* Special case for mp4v and flac */        if( ( p_stream->i_fourcc == VLC_FOURCC( 'm', 'p', '4', 'v' ) ||              p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ) &&            p_input->p_fmt->i_extra )        {            /* Send a packet with the VOL data for mp4v             * or STREAMINFO for flac */            msg_Dbg( p_mux, "writing extra data" );            op.bytes  = p_input->p_fmt->i_extra;            op.packet = p_input->p_fmt->p_extra;            if( p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) )            {                /* Skip the flac stream marker */                op.bytes -= 4;                op.packet+= 4;            }            op.b_o_s  = 0;            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 );        }    }    /* set HEADER flag */    for( p_og = p_hdr; p_og != NULL; p_og = p_og->p_next )    {        p_og->i_flags |= BLOCK_FLAG_HEADER;    }    return p_hdr;}static block_t *OggCreateFooter( sout_mux_t *p_mux, mtime_t i_dts ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    block_t *p_hdr = NULL;    block_t *p_og;    ogg_packet    op;    int i;    /* flush all remaining data */    for( i = 0; i < p_mux->i_nb_inputs; i++ )    {        ogg_stream_t *p_stream = p_mux->pp_inputs[i]->p_sys;        /* skip newly added streams */        if( p_stream->b_new ) continue;        if( ( 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 );        }    }    /* Write eos packets for each stream. */    for( i = 0; i < p_mux->i_nb_inputs; i++ )    {        ogg_stream_t *p_stream = p_mux->pp_inputs[i]->p_sys;        /* skip newly added streams */        if( p_stream->b_new ) continue;        op.packet = NULL;        op.bytes  = 0;        op.b_o_s  = 0;        op.e_o_s  = 1;        op.granulepos = -1;        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 );        ogg_stream_clear( &p_stream->os );    }    for( i = 0; i < p_sys->i_del_streams; i++ )    {        op.packet = NULL;        op.bytes  = 0;        op.b_o_s  = 0;        op.e_o_s  = 1;        op.granulepos = -1;        op.packetno = p_sys->pp_del_streams[i]->i_packet_no++;        ogg_stream_packetin( &p_sys->pp_del_streams[i]->os, &op );        p_og = OggStreamFlush( p_mux, &p_sys->pp_del_streams[i]->os, 0 );        block_ChainAppend( &p_hdr, p_og );        ogg_stream_clear( &p_sys->pp_del_streams[i]->os );    }    return p_hdr;}static void OggSetDate( block_t *p_og, mtime_t i_dts, mtime_t i_length ){    int i_count;    block_t *p_tmp;    mtime_t i_delta;    for( p_tmp = p_og, i_count = 0; p_tmp != NULL; p_tmp = p_tmp->p_next )    {        i_count++;    }    i_delta = i_length / i_count;    for( p_tmp = p_og; p_tmp != NULL; p_tmp = p_tmp->p_next )    {        p_tmp->i_dts    = i_dts;        p_tmp->i_length = i_delta;        i_dts += i_delta;    }}/***************************************************************************** * Mux: multiplex available data in input fifos into the Ogg bitstream *****************************************************************************/static int Mux( sout_mux_t *p_mux ){    sout_mux_sys_t *p_sys = p_mux->p_sys;    block_t        *p_og = NULL;    int            i_stream;    mtime_t        i_dts;    if( p_sys->i_add_streams || p_sys->i_del_streams )    {        /* Open new ogg stream */        if( MuxGetStream( p_mux, &i_stream, &i_dts) < 0 )        {            msg_Dbg( p_mux, "waiting for data..." );            return VLC_SUCCESS;        }        if( p_sys->i_streams )        {            /* Close current ogg stream */            int i;            msg_Dbg( p_mux, "writing footer" );            block_ChainAppend( &p_og, OggCreateFooter( p_mux, 0 ) );            /* Remove deleted logical streams */            for( i = 0; i < p_sys->i_del_streams; i++ )            {                FREE( p_sys->pp_del_streams[i]->p_oggds_header );                FREE( p_sys->pp_del_streams[i] );            }            FREE( p_sys->pp_del_streams );            p_sys->i_streams = 0;        }        msg_Dbg( p_mux, "writing header" );        p_sys->i_start_dts = i_dts;        p_sys->i_streams = p_mux->i_nb_inputs;        p_sys->i_del_streams = 0;        p_sys->i_add_streams = 0;        block_ChainAppend( &p_og, OggCreateHeader( p_mux, i_dts ) );        /* Write header and/or footer */        OggSetDate( p_og, i_dts, 0 );        sout_AccessOutWrite( p_mux->p_access, p_og );        p_og = NULL;    }    for( ;; )    {        if( MuxGetStream( p_mux, &i_stream, 0 ) < 0 ) return VLC_SUCCESS;        MuxBlock( p_mux, p_mux->pp_inputs[i_stream] );    }    return VLC_SUCCESS;}static int MuxBlock( 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_data = block_FifoGet( p_input->p_fifo );    block_t *p_og = NULL;    ogg_packet op;    if( p_stream->i_fourcc != VLC_FOURCC( 'v', 'o', 'r', 'b' ) &&        p_stream->i_fourcc != VLC_FOURCC( 'f', 'l', 'a', 'c' ) &&        p_stream->i_fourcc != VLC_FOURCC( 's', 'p', 'x', ' ' ) &&        p_stream->i_fourcc != VLC_FOURCC( 't', 'h', 'e', 'o' ) )    {        p_data = block_Realloc( p_data, 1, p_data->i_buffer );        p_data->p_buffer[0] = PACKET_IS_SYNCPOINT;      // FIXME    }    op.packet   = p_data->p_buffer;    op.bytes    = p_data->i_buffer;    op.b_o_s    = 0;    op.e_o_s    = 0;    op.packetno = p_stream->i_packet_no++;    if( p_stream->i_cat == AUDIO_ES )    {        if( p_stream->i_fourcc == VLC_FOURCC( 'v', 'o', 'r', 'b' ) ||            p_stream->i_fourcc == VLC_FOURCC( 'f', 'l', 'a', 'c' ) ||            p_stream->i_fourcc == VLC_FOURCC( 's', 'p', 'x', ' ' ) )        {            /* number of sample from begining + current packet */            op.granulepos =                ( p_data->i_dts - p_sys->i_start_dts + p_data->i_length ) *                (mtime_t)p_input->p_fmt->audio.i_rate / I64C(1000000);        }        else if( p_stream->p_oggds_header )        {            /* number of sample from begining */            op.granulepos = ( p_data->i_dts - p_sys->i_start_dts ) *                p_stream->p_oggds_header->i_samples_per_unit / I64C(1000000);        }    }    else if( p_stream->i_cat == VIDEO_ES )    {        if( p_stream->i_fourcc == VLC_FOURCC( 't', 'h', 'e', 'o' ) )        {            /* FIXME, we assume only keyframes */            op.granulepos = ( ( p_data->i_dts - p_sys->i_start_dts ) *                p_input->p_fmt->video.i_frame_rate /                p_input->p_fmt->video.i_frame_rate_base /                I64C(1000000) ) << p_stream->i_keyframe_granule_shift;        }        else if( p_stream->p_oggds_header )            op.granulepos = ( p_data->i_dts - p_sys->i_start_dts ) * I64C(10) /                p_stream->p_oggds_header->i_time_unit;    }    else if( p_stream->i_cat == SPU_ES )    {        /* granulepos is in milisec */        op.granulepos = ( p_data->i_dts - p_sys->i_start_dts ) / 1000;    }    ogg_stream_packetin( &p_stream->os, &op );    if( p_stream->i_cat == SPU_ES ||        p_stream->i_fourcc == VLC_FOURCC( 's', 'p', 'x', ' ' ) )    {        /* Subtitles or Speex packets are quite small so they          * need to be flushed to be sent on time */        p_og = OggStreamFlush( p_mux, &p_stream->os, p_data->i_dts );    }    else    {        p_og = OggStreamPageOut( p_mux, &p_stream->os, p_data->i_dts );    }    if( p_og )    {        OggSetDate( p_og, p_stream->i_dts, p_stream->i_length );        p_stream->i_dts = -1;        p_stream->i_length = 0;        sout_AccessOutWrite( p_mux->p_access, p_og );    }    else    {        if( p_stream->i_dts < 0 )        {            p_stream->i_dts = p_data->i_dts;        }        p_stream->i_length += p_data->i_length;    }    block_Release( p_data );    return VLC_SUCCESS;}

⌨️ 快捷键说明

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