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

📄 faad.c

📁 VLC Player Source Code
💻 C
📖 第 1 页 / 共 2 页
字号:
    }    if( p_dec->fmt_out.audio.i_rate == 0 && p_dec->fmt_in.i_extra > 0 )    {        /* We have a decoder config so init the handle */        unsigned long i_rate;        unsigned char i_channels;        if( faacDecInit2( p_sys->hfaad, p_dec->fmt_in.p_extra,                          p_dec->fmt_in.i_extra,                          &i_rate, &i_channels ) >= 0 )        {            p_dec->fmt_out.audio.i_rate = i_rate;            p_dec->fmt_out.audio.i_channels = i_channels;            p_dec->fmt_out.audio.i_physical_channels                = p_dec->fmt_out.audio.i_original_channels                = pi_channels_guessed[i_channels];            aout_DateInit( &p_sys->date, i_rate );        }    }    if( p_dec->fmt_out.audio.i_rate == 0 && p_sys->i_buffer )    {        unsigned long i_rate;        unsigned char i_channels;        /* Init faad with the first frame */        if( faacDecInit( p_sys->hfaad,                         p_sys->p_buffer, p_sys->i_buffer,                         &i_rate, &i_channels ) < 0 )        {            block_Release( p_block );            return NULL;        }        p_dec->fmt_out.audio.i_rate = i_rate;        p_dec->fmt_out.audio.i_channels = i_channels;        p_dec->fmt_out.audio.i_physical_channels            = p_dec->fmt_out.audio.i_original_channels            = pi_channels_guessed[i_channels];        aout_DateInit( &p_sys->date, i_rate );    }    if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )    {        aout_DateSet( &p_sys->date, p_block->i_pts );    }    else if( !aout_DateGet( &p_sys->date ) )    {        /* We've just started the stream, wait for the first PTS. */        block_Release( p_block );        p_sys->i_buffer = 0;        return NULL;    }    /* Decode all data */    if( p_sys->i_buffer )    {        void *samples;        faacDecFrameInfo frame;        aout_buffer_t *p_out;        int i, j;        samples = faacDecDecode( p_sys->hfaad, &frame,                                 p_sys->p_buffer, p_sys->i_buffer );        if( frame.error > 0 )        {            msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );            /* Flush the buffer */            p_sys->i_buffer = 0;            block_Release( p_block );            return NULL;        }        if( frame.channels <= 0 || frame.channels > 8 || frame.channels == 7 )        {            msg_Warn( p_dec, "invalid channels count: %i", frame.channels );            /* Flush the buffer */            p_sys->i_buffer -= frame.bytesconsumed;            if( p_sys->i_buffer > 0 )            {                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],                         p_sys->i_buffer );            }            block_Release( p_block );            return NULL;        }        if( frame.samples <= 0 )        {            msg_Warn( p_dec, "decoded zero sample" );            /* Flush the buffer */            p_sys->i_buffer -= frame.bytesconsumed;            if( p_sys->i_buffer > 0 )            {                memmove( p_sys->p_buffer,&p_sys->p_buffer[frame.bytesconsumed],                         p_sys->i_buffer );            }            block_Release( p_block );            return NULL;        }        /* We decoded a valid frame */        if( p_dec->fmt_out.audio.i_rate != frame.samplerate )        {            aout_DateInit( &p_sys->date, frame.samplerate );            aout_DateSet( &p_sys->date, p_block->i_pts );        }        p_block->i_pts = 0;  /* PTS is valid only once */        p_dec->fmt_out.audio.i_rate = frame.samplerate;        p_dec->fmt_out.audio.i_channels = frame.channels;        p_dec->fmt_out.audio.i_physical_channels            = p_dec->fmt_out.audio.i_original_channels            = pi_channels_guessed[frame.channels];        /* Adjust stream info when dealing with SBR/PS */        if( (p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps) &&            p_dec->p_parent->i_object_type == VLC_OBJECT_INPUT )        {            input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;            char *psz_cat;            const char *psz_ext = (frame.sbr && frame.ps) ? "SBR+PS" :                                    frame.sbr ? "SBR" : "PS";            msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)",                    psz_ext, frame.channels, frame.samplerate );            if( asprintf( &psz_cat, _("Stream %d"), p_dec->fmt_in.i_id ) != -1 )            {                input_Control( p_input, INPUT_ADD_INFO, psz_cat,                            _("AAC extension"), "%s", psz_ext );                input_Control( p_input, INPUT_ADD_INFO, psz_cat,                            _("Channels"), "%d", frame.channels );                input_Control( p_input, INPUT_ADD_INFO, psz_cat,                            _("Sample rate"), _("%d Hz"), frame.samplerate );                free( psz_cat );            }            p_sys->b_sbr = frame.sbr; p_sys->b_ps = frame.ps;        }        /* Convert frame.channel_position to our own channel values */        p_dec->fmt_out.audio.i_physical_channels = 0;        for( i = 0; i < frame.channels; i++ )        {            /* Find the channel code */            for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ )            {                if( frame.channel_position[i] == pi_channels_in[j] )                    break;            }            if( j >= MAX_CHANNEL_POSITIONS )            {                msg_Warn( p_dec, "unknown channel ordering" );                /* Invent something */                j = i;            }            /* */            p_sys->pi_channel_positions[i] = pi_channels_out[j];            if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] )                frame.channels--; /* We loose a duplicated channel */            else                p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j];        }        p_dec->fmt_out.audio.i_original_channels =            p_dec->fmt_out.audio.i_physical_channels;        p_out = p_dec->pf_aout_buffer_new(p_dec, frame.samples/frame.channels);        if( p_out == NULL )        {            p_sys->i_buffer = 0;            block_Release( p_block );            return NULL;        }        p_out->start_date = aout_DateGet( &p_sys->date );        p_out->end_date = aout_DateIncrement( &p_sys->date,            (frame.samples / frame.channels) * p_sys->i_input_rate / INPUT_RATE_DEFAULT );        DoReordering( (uint32_t *)p_out->p_buffer, samples,                      frame.samples / frame.channels, frame.channels,                      p_sys->pi_channel_positions );        p_sys->i_buffer -= frame.bytesconsumed;        if( p_sys->i_buffer > 0 )        {            memmove( p_sys->p_buffer, &p_sys->p_buffer[frame.bytesconsumed],                     p_sys->i_buffer );        }        return p_out;    }    block_Release( p_block );    return NULL;}/***************************************************************************** * Close: *****************************************************************************/static void Close( vlc_object_t *p_this ){    decoder_t *p_dec = (decoder_t *)p_this;    decoder_sys_t *p_sys = p_dec->p_sys;    faacDecClose( p_sys->hfaad );    free( p_sys->p_buffer );    free( p_sys );}/***************************************************************************** * DoReordering: do some channel re-ordering (the ac3 channel order is *   different from the aac one). *****************************************************************************/static void DoReordering( uint32_t *p_out, uint32_t *p_in, int i_samples,                          int i_nb_channels, uint32_t *pi_chan_positions ){    int pi_chan_table[MAX_CHANNEL_POSITIONS];    int i, j, k;    /* Find the channels mapping */    for( i = 0, j = 0; i < MAX_CHANNEL_POSITIONS; i++ )    {        for( k = 0; k < i_nb_channels; k++ )        {            if( pi_channels_ordered[i] == pi_chan_positions[k] )            {                pi_chan_table[k] = j++;                break;            }        }    }    /* Do the actual reordering */    if( vlc_CPU() & CPU_CAPABILITY_FPU )        for( i = 0; i < i_samples; i++ )            for( j = 0; j < i_nb_channels; j++ )                p_out[i * i_nb_channels + pi_chan_table[j]] =                    p_in[i * i_nb_channels + j];    else        for( i = 0; i < i_samples; i++ )            for( j = 0; j < i_nb_channels; j++ )                ((uint16_t *)p_out)[i * i_nb_channels + pi_chan_table[j]] =                    ((uint16_t *)p_in)[i * i_nb_channels + j];}

⌨️ 快捷键说明

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