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

📄 ts.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 5 页
字号:
                            if ( ( i_spu_delay >= INT64_C(100000000) ) ||                                 ( i_spu_delay < INT64_C(10000) ) )                            {                                BufferChainClean( &p_stream->chain_pes );                                p_stream->i_pes_dts = 0;                                p_stream->i_pes_used = 0;                                p_stream->i_pes_length = 0;                                continue;                            }                        }                    }                    b_ok = false;                    if( p_stream == p_pcr_stream || p_sys->b_data_alignment                         || p_input->p_fmt->i_codec !=                             VLC_FOURCC('m', 'p', 'g', 'a') )                    {                        p_data = block_FifoGet( p_input->p_fifo );                        if( p_input->p_fmt->i_codec ==                                VLC_FOURCC('m', 'p', '4', 'a' ) )                            p_data = Add_ADTS( p_data, p_input->p_fmt );                    }                    else                        p_data = FixPES( p_mux, p_input->p_fifo );                    if( block_FifoCount( p_input->p_fifo ) > 0 &&                        p_input->p_fmt->i_cat != SPU_ES )                    {                        block_t *p_next = block_FifoShow( p_input->p_fifo );                        p_data->i_length = p_next->i_dts - p_data->i_dts;                    }                    else if( p_input->p_fmt->i_codec !=                               VLC_FOURCC('s', 'u', 'b', 't' ) )                        p_data->i_length = 1000;                    if( ( p_pcr_stream->i_pes_dts > 0 &&                          p_data->i_dts - 10000000 > p_pcr_stream->i_pes_dts +                          p_pcr_stream->i_pes_length ) ||                        p_data->i_dts < p_stream->i_pes_dts ||                        ( p_stream->i_pes_dts > 0 &&                          p_input->p_fmt->i_cat != SPU_ES &&                          p_data->i_dts - 10000000 > p_stream->i_pes_dts +                          p_stream->i_pes_length ) )                    {                        msg_Warn( p_mux, "packet with too strange dts "                                  "(dts=%"PRId64",old=%"PRId64",pcr=%"PRId64")",                                  p_data->i_dts, p_stream->i_pes_dts,                                  p_pcr_stream->i_pes_dts );                        block_Release( p_data );                        BufferChainClean( &p_stream->chain_pes );                        p_stream->i_pes_dts = 0;                        p_stream->i_pes_used = 0;                        p_stream->i_pes_length = 0;                        if( p_input->p_fmt->i_cat != SPU_ES )                        {                            BufferChainClean( &p_pcr_stream->chain_pes );                            p_pcr_stream->i_pes_dts = 0;                            p_pcr_stream->i_pes_used = 0;                            p_pcr_stream->i_pes_length = 0;                        }                    }                    else                    {                        int i_header_size = 0;                        int b_data_alignment = 0;                        if( p_input->p_fmt->i_cat == SPU_ES )                        {                            if( p_input->p_fmt->i_codec ==                                VLC_FOURCC('s','u','b','t') )                            {                                /* Prepend header */                                p_data = block_Realloc( p_data, 2,                                                        p_data->i_buffer );                                p_data->p_buffer[0] =                                    ( (p_data->i_buffer - 2) >> 8) & 0xff;                                p_data->p_buffer[1] =                                    ( (p_data->i_buffer - 2)     ) & 0xff;                                /* remove trailling \0 if any */                                if( p_data->i_buffer > 2 &&                                    p_data->p_buffer[p_data->i_buffer -1] ==                                    '\0' )                                    p_data->i_buffer--;                                /* Append a empty sub (sub text only) */                                if( p_data->i_length > 0 &&                                    !( p_data->i_buffer == 1 &&                                       *p_data->p_buffer == ' ' ) )                                {                                    block_t *p_spu = block_New( p_mux, 3 );                                    p_spu->i_dts = p_spu->i_pts =                                        p_data->i_dts + p_data->i_length;                                    p_spu->i_length = 1000;                                    p_spu->p_buffer[0] = 0;                                    p_spu->p_buffer[1] = 1;                                    p_spu->p_buffer[2] = ' ';                                    EStoPES( p_mux->p_sout, &p_spu, p_spu,                                                 p_input->p_fmt,                                                 p_stream->i_stream_id, 1,                                                 0, 0, 0 );                                    p_data->p_next = p_spu;                                }                            }                            else if( p_input->p_fmt->i_codec ==                                       VLC_FOURCC('t','e','l','x') )                            {                                /* EN 300 472 */                                i_header_size = 0x24;                                b_data_alignment = 1;                            }                            else if( p_input->p_fmt->i_codec ==                                       VLC_FOURCC('d','v','b','s') )                            {                                /* EN 300 743 */                                b_data_alignment = 1;                            }                        }                        else if( p_data->i_length < 0 ||                                 p_data->i_length > 2000000 )                        {                            /* FIXME choose a better value, but anyway we                             * should never have to do that */                            p_data->i_length = 1000;                        }                        p_stream->i_pes_length += p_data->i_length;                        if( p_stream->i_pes_dts == 0 )                        {                            p_stream->i_pes_dts = p_data->i_dts;                        }                        /* Convert to pes */                        if( p_stream->i_stream_id == 0xa0 &&                            p_data->i_pts <= 0 )                        {                            /* XXX yes I know, it's awful, but it's needed,                             * so don't remove it ... */                            p_data->i_pts = p_data->i_dts;                        }                         EStoPES ( p_mux->p_sout, &p_data, p_data,                                       p_input->p_fmt, p_stream->i_stream_id,                                       1, b_data_alignment, i_header_size, 0 );                        BufferChainAppend( &p_stream->chain_pes, p_data );                        if( p_sys->b_use_key_frames && p_stream == p_pcr_stream                            && (p_data->i_flags & BLOCK_FLAG_TYPE_I)                            && !(p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME)                            && (p_stream->i_pes_length > 400000) )                        {                            i_shaping_delay = p_stream->i_pes_length;                            p_stream->b_key_frame = 1;                        }                    }                }            }            if( b_ok )            {                break;            }        }        /* save */        i_pcr_dts      = p_pcr_stream->i_pes_dts;        i_pcr_length   = p_pcr_stream->i_pes_length;        p_pcr_stream->b_key_frame = 0;        /* msg_Dbg( p_mux, "starting muxing %lldms", i_pcr_length / 1000 ); */        /* 2: calculate non accurate total size of muxed ts */        i_packet_count = 0;        for( i = 0; i < p_mux->i_nb_inputs; i++ )        {            ts_stream_t *p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;            block_t *p_pes;            /* False for pcr stream but it will be enough to do PCR algo */            for( p_pes = p_stream->chain_pes.p_first; p_pes != NULL;                 p_pes = p_pes->p_next )            {                int i_size = p_pes->i_buffer;                if( p_pes->i_dts + p_pes->i_length >                    p_pcr_stream->i_pes_dts + p_pcr_stream->i_pes_length )                {                    mtime_t i_frag = p_pcr_stream->i_pes_dts +                        p_pcr_stream->i_pes_length - p_pes->i_dts;                    if( i_frag < 0 )                    {                        /* Next stream */                        break;                    }                    i_size = p_pes->i_buffer * i_frag / p_pes->i_length;                }                i_packet_count += ( i_size + 183 ) / 184;            }        }        /* add overhead for PCR (not really exact) */        i_packet_count += (8 * i_pcr_length / p_sys->i_pcr_delay + 175) / 176;        /* 3: mux PES into TS */        BufferChainInit( &chain_ts );        /* append PAT/PMT  -> FIXME with big pcr delay it won't have enough pat/pmt */        GetPAT( p_mux, &chain_ts );        GetPMT( p_mux, &chain_ts );        i_packet_pos = 0;        i_packet_count += chain_ts.i_depth;        /* msg_Dbg( p_mux, "estimated pck=%d", i_packet_count ); */        for( ;; )        {            int          i_stream;            mtime_t      i_dts;            ts_stream_t  *p_stream;            sout_input_t *p_input;            block_t      *p_ts;            bool         b_pcr;            /* Select stream (lowest dts) */            for( i = 0, i_stream = -1, i_dts = 0; i < p_mux->i_nb_inputs; i++ )            {                p_stream = (ts_stream_t*)p_mux->pp_inputs[i]->p_sys;                if( p_stream->i_pes_dts == 0 )                {                    continue;                }                if( i_stream == -1 ||                    p_stream->i_pes_dts < i_dts )                {                    i_stream = i;                    i_dts = p_stream->i_pes_dts;                }            }            if( i_stream == -1 || i_dts > i_pcr_dts + i_pcr_length )            {                break;            }            p_stream = (ts_stream_t*)p_mux->pp_inputs[i_stream]->p_sys;            p_input = p_mux->pp_inputs[i_stream];            /* do we need to issue pcr */            b_pcr = false;            if( p_stream == p_pcr_stream &&                i_pcr_dts + i_packet_pos * i_pcr_length / i_packet_count >=                p_sys->i_pcr + p_sys->i_pcr_delay )            {                b_pcr = true;                p_sys->i_pcr = i_pcr_dts + i_packet_pos *                    i_pcr_length / i_packet_count;            }            /* Build the TS packet */            p_ts = TSNew( p_mux, p_stream, b_pcr );            if( p_sys->csa != NULL &&                 (p_input->p_fmt->i_cat != AUDIO_ES || p_sys->b_crypt_audio) &&                 (p_input->p_fmt->i_cat != VIDEO_ES || p_sys->b_crypt_video) )            {                p_ts->i_flags |= BLOCK_FLAG_SCRAMBLED;            }            i_packet_pos++;            /* */            BufferChainAppend( &chain_ts, p_ts );        }        /* 4: date and send */        TSSchedule( p_mux, &chain_ts, i_pcr_length, i_pcr_dts );    }}#define STD_PES_PAYLOAD 170static block_t *FixPES( sout_mux_t *p_mux, block_fifo_t *p_fifo ){    block_t *p_data;    size_t i_size;    p_data = block_FifoShow( p_fifo );    i_size = p_data->i_buffer;    if( i_size == STD_PES_PAYLOAD )    {        return block_FifoGet( p_fifo );    }    else if( i_size > STD_PES_PAYLOAD )    {        block_t *p_new = block_New( p_mux, STD_PES_PAYLOAD );        vlc_memcpy( p_new->p_buffer, p_data->p_buffer, STD_PES_PAYLOAD );        p_new->i_pts = p_data->i_pts;        p_new->i_dts = p_data->i_dts;        p_new->i_length = p_data->i_length * STD_PES_PAYLOAD                            / p_data->i_buffer;        p_data->i_buffer -= STD_PES_PAYLOAD;        p_data->p_buffer += STD_PES_PAYLOAD;        p_data->i_pts += p_new->i_length;        p_data->i_dts += p_new->i_length;        p_data->i_length -= p_new->i_length;        p_data->i_flags |= BLOCK_FLAG_NO_KEYFRAME;        return p_new;    }    else    {        block_t *p_next;        int i_copy;        p_data = block_FifoGet( p_fifo );        p_data = block_Realloc( p_data, 0, STD_PES_PAYLOAD );        p_next = block_FifoShow( p_fifo );        if ( p_data->i_flags & BLOCK_FLAG_NO_KEYFRAME )        {            p_data->i_flags &= ~BLOCK_FLAG_NO_KEYFRAME;            p_data->i_pts = p_next->i_pts;            p_data->i_dts = p_next->i_dts;        }        i_copy = __MIN( STD_PES_PAYLOAD - i_size, p_next->i_buffer );        vlc_memcpy( &p_data->p_buffer[i_size], p_next->p_buffer, i_copy );        p_next->i_pts += p_next->i_length * i_copy / p_next->i_buffer;        p_next->i_dts += p_next->i_length * i_copy / p_next->i_buffer;        p_next->i_length -= p_next->i_length * i_copy / p_next->i_buffer;        p_next->i_buffer -= i_copy;        p_next->p_buffer += i_copy;        p_next->i_flags |= BLOCK_FLAG_NO_KEYFRAME;        if( !p_next->i_buffer )        {            p_next = block_FifoGet( p_fifo );            block_Release( p_next );        }        return p_data;    }}static block_t *Add_ADTS( block_t *p_data, es_format_t *p_fmt ){    uint8_t *p_extra = p_fmt->p_extra;    if( !p_data || p_fmt->i_extra < 2 || !p_extra )        return p_data; /* no data to construct the headers */    int i_index = ( (p_extra[0] << 1) | (p_extra[1] >> 7) ) & 0x0f;    int i_profile = (p_extra[0] >> 3) - 1; /* i_profile < 4 */    if( i_index == 0x0f && p_fmt->i_extra < 5 )        return p_data; /* not enough data */    int i_channels = (p_extra[i_index == 0x0f ? 4 : 1] >> 3) & 0x0f;#define ADTS_HEADER_SIZE 7 /* CRC needs 2 more bytes */    /* keep a copy in case block_Realloc() fails */    block_t *p_bak_block = block_Duplicate( p_data );    if( !p_bak_block ) /* OOM, block_Realloc() is likely to lose our block */        return p_data; /* the frame isn't correct but that's the best we have */    block_t *p_new_block = block_Realloc( p_data, ADTS_HEADER_SIZE,                                            p_data->i_buffer );    if( !p_new_block )        return p_bak_bl

⌨️ 快捷键说明

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