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

📄 sonic.c

📁 tcpmp播放器的flv插件
💻 C
📖 第 1 页 / 共 2 页
字号:
	case 44100: return 0;	case 22050: return 1;	case 11025: return 2;	case 96000: return 3;	case 48000: return 4;	case 32000: return 5;	case 24000: return 6;	case 16000: return 7;	case 8000: return 8;    }    return -1;}static int sonic_encode_init(AVCodecContext *avctx){    SonicContext *s = avctx->priv_data;    PutBitContext pb;    int i, version = 0;    if (avctx->channels > MAX_CHANNELS)    {	av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");        return -1; /* only stereo or mono for now */    }    if (avctx->channels == 2)	s->decorrelation = MID_SIDE;    if (avctx->codec->id == CODEC_ID_SONIC_LS)    {	s->lossless = 1;	s->num_taps = 32;	s->downsampling = 1;	s->quantization = 0.0;    }    else    {	s->num_taps = 128;	s->downsampling = 2;	s->quantization = 1.0;    }    // max tap 2048    if ((s->num_taps < 32) || (s->num_taps > 1024) ||	((s->num_taps>>5)<<5 != s->num_taps))    {	av_log(avctx, AV_LOG_ERROR, "Invalid number of taps\n");	return -1;    }    // generate taps    s->tap_quant = av_mallocz(4* s->num_taps);    for (i = 0; i < s->num_taps; i++)	s->tap_quant[i] = (int)(sqrt(i+1));    s->channels = avctx->channels;    s->samplerate = avctx->sample_rate;    s->block_align = (int)(2048.0*s->samplerate/44100)/s->downsampling;    s->frame_size = s->channels*s->block_align*s->downsampling;    s->tail = av_mallocz(4* s->num_taps*s->channels);    if (!s->tail)	return -1;    s->tail_size = s->num_taps*s->channels;    s->predictor_k = av_mallocz(4 * s->num_taps);    if (!s->predictor_k)	return -1;    for (i = 0; i < s->channels; i++)    {	s->coded_samples[i] = av_mallocz(4* s->block_align);	if (!s->coded_samples[i])	    return -1;    }        s->int_samples = av_mallocz(4* s->frame_size);    s->window_size = ((2*s->tail_size)+s->frame_size);    s->window = av_mallocz(4* s->window_size);    if (!s->window)	return -1;    avctx->extradata = av_mallocz(16);    if (!avctx->extradata)	return -1;    init_put_bits(&pb, avctx->extradata, 16*8);    put_bits(&pb, 2, version); // version    if (version == 1)    {	put_bits(&pb, 2, s->channels);	put_bits(&pb, 4, code_samplerate(s->samplerate));    }    put_bits(&pb, 1, s->lossless);    if (!s->lossless)	put_bits(&pb, 3, SAMPLE_SHIFT); // XXX FIXME: sample precision    put_bits(&pb, 2, s->decorrelation);    put_bits(&pb, 2, s->downsampling);    put_bits(&pb, 5, (s->num_taps >> 5)-1); // 32..1024    put_bits(&pb, 1, 0); // XXX FIXME: no custom tap quant table    flush_put_bits(&pb);    avctx->extradata_size = put_bits_count(&pb)/8;    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",	version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);    avctx->coded_frame = avcodec_alloc_frame();    if (!avctx->coded_frame)	return -ENOMEM;    avctx->coded_frame->key_frame = 1;    avctx->frame_size = s->block_align*s->downsampling;    return 0;}static int sonic_encode_close(AVCodecContext *avctx){    SonicContext *s = avctx->priv_data;    int i;    av_freep(&avctx->coded_frame);    for (i = 0; i < s->channels; i++)	av_free(s->coded_samples[i]);    av_free(s->predictor_k);    av_free(s->tail);    av_free(s->tap_quant);    av_free(s->window);    av_free(s->int_samples);    return 0;}static int sonic_encode_frame(AVCodecContext *avctx,			    uint8_t *buf, int buf_size, void *data){    SonicContext *s = avctx->priv_data;    PutBitContext pb;    int i, j, ch, quant = 0, x = 0;    short *samples = data;    init_put_bits(&pb, buf, buf_size*8);    // short -> internal    for (i = 0; i < s->frame_size; i++)	s->int_samples[i] = samples[i];    if (!s->lossless)	for (i = 0; i < s->frame_size; i++)	    s->int_samples[i] = s->int_samples[i] << SAMPLE_SHIFT;    switch(s->decorrelation)    {	case MID_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)	    {		s->int_samples[i] += s->int_samples[i+1];		s->int_samples[i+1] -= shift(s->int_samples[i], 1);	    }	    break;	case LEFT_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)		s->int_samples[i+1] -= s->int_samples[i];	    break;	case RIGHT_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)		s->int_samples[i] -= s->int_samples[i+1];	    break;    }    memset(s->window, 0, 4* s->window_size);        for (i = 0; i < s->tail_size; i++)	s->window[x++] = s->tail[i];    for (i = 0; i < s->frame_size; i++)	s->window[x++] = s->int_samples[i];        for (i = 0; i < s->tail_size; i++)	s->window[x++] = 0;    for (i = 0; i < s->tail_size; i++)	s->tail[i] = s->int_samples[s->frame_size - s->tail_size + i];    // generate taps    modified_levinson_durbin(s->window, s->window_size,		s->predictor_k, s->num_taps, s->channels, s->tap_quant);    if (intlist_write(&pb, s->predictor_k, s->num_taps, 0) < 0)	return -1;    for (ch = 0; ch < s->channels; ch++)    {	x = s->tail_size+ch;	for (i = 0; i < s->block_align; i++)	{	    int sum = 0;	    for (j = 0; j < s->downsampling; j++, x += s->channels)		sum += s->window[x];	    s->coded_samples[ch][i] = sum;	}    }        // simple rate control code        if (!s->lossless)    {	double energy1 = 0.0, energy2 = 0.0;	for (ch = 0; ch < s->channels; ch++)	{	    for (i = 0; i < s->block_align; i++)	    {		double sample = s->coded_samples[ch][i];		energy2 += sample*sample;		energy1 += fabs(sample);	    }	}		energy2 = sqrt(energy2/(s->channels*s->block_align));	energy1 = sqrt(2.0)*energy1/(s->channels*s->block_align);		// increase bitrate when samples are like a gaussian distribution	// reduce bitrate when samples are like a two-tailed exponential distribution		if (energy2 > energy1)	    energy2 += (energy2-energy1)*RATE_VARIATION;		quant = (int)(BASE_QUANT*s->quantization*energy2/SAMPLE_FACTOR);//	av_log(avctx, AV_LOG_DEBUG, "quant: %d energy: %f / %f\n", quant, energy1, energy2);	if (quant < 1)	    quant = 1;	if (quant > 65535)	    quant = 65535;		set_ue_golomb(&pb, quant);		quant *= SAMPLE_FACTOR;    }    // write out coded samples    for (ch = 0; ch < s->channels; ch++)    {	if (!s->lossless)	    for (i = 0; i < s->block_align; i++)		s->coded_samples[ch][i] = divide(s->coded_samples[ch][i], quant);	if (intlist_write(&pb, s->coded_samples[ch], s->block_align, 1) < 0)	    return -1;    }//    av_log(avctx, AV_LOG_DEBUG, "used bytes: %d\n", (put_bits_count(&pb)+7)/8);    flush_put_bits(&pb);    return (put_bits_count(&pb)+7)/8;}#endif //CONFIG_ENCODERSstatic int sonic_decode_init(AVCodecContext *avctx){    SonicContext *s = avctx->priv_data;    GetBitContext gb;    int i, version;        s->channels = avctx->channels;    s->samplerate = avctx->sample_rate;        if (!avctx->extradata)    {	av_log(avctx, AV_LOG_ERROR, "No mandatory headers present\n");	return -1;    }        init_get_bits(&gb, avctx->extradata, avctx->extradata_size);        version = get_bits(&gb, 2);    if (version > 1)    {	av_log(avctx, AV_LOG_ERROR, "Unsupported Sonic version, please report\n");	return -1;    }    if (version == 1)    {	s->channels = get_bits(&gb, 2);	s->samplerate = samplerate_table[get_bits(&gb, 4)];	av_log(avctx, AV_LOG_INFO, "Sonicv2 chans: %d samprate: %d\n",	    s->channels, s->samplerate);    }    if (s->channels > MAX_CHANNELS)    {	av_log(avctx, AV_LOG_ERROR, "Only mono and stereo streams are supported by now\n");	return -1;    }    s->lossless = get_bits1(&gb);    if (!s->lossless)	skip_bits(&gb, 3); // XXX FIXME    s->decorrelation = get_bits(&gb, 2);    s->downsampling = get_bits(&gb, 2);    s->num_taps = (get_bits(&gb, 5)+1)<<5;    if (get_bits1(&gb)) // XXX FIXME	av_log(avctx, AV_LOG_INFO, "Custom quant table\n");        s->block_align = (int)(2048.0*(s->samplerate/44100))/s->downsampling;    s->frame_size = s->channels*s->block_align*s->downsampling;//    avctx->frame_size = s->block_align;    av_log(avctx, AV_LOG_INFO, "Sonic: ver: %d ls: %d dr: %d taps: %d block: %d frame: %d downsamp: %d\n",	version, s->lossless, s->decorrelation, s->num_taps, s->block_align, s->frame_size, s->downsampling);    // generate taps    s->tap_quant = av_mallocz(4* s->num_taps);    for (i = 0; i < s->num_taps; i++)	s->tap_quant[i] = (int)(sqrt(i+1));        s->predictor_k = av_mallocz(4* s->num_taps);        for (i = 0; i < s->channels; i++)    {	s->predictor_state[i] = av_mallocz(4* s->num_taps);	if (!s->predictor_state[i])	    return -1;    }    for (i = 0; i < s->channels; i++)    {	s->coded_samples[i] = av_mallocz(4* s->block_align);	if (!s->coded_samples[i])	    return -1;    }    s->int_samples = av_mallocz(4* s->frame_size);    return 0;}static int sonic_decode_close(AVCodecContext *avctx){    SonicContext *s = avctx->priv_data;    int i;        av_free(s->int_samples);    av_free(s->tap_quant);    av_free(s->predictor_k);        for (i = 0; i < s->channels; i++)    {	av_free(s->predictor_state[i]);	av_free(s->coded_samples[i]);    }        return 0;}static int sonic_decode_frame(AVCodecContext *avctx,			    void *data, int *data_size,			    uint8_t *buf, int buf_size){    SonicContext *s = avctx->priv_data;    GetBitContext gb;    int i, quant, ch, j;    short *samples = data;    if (buf_size == 0) return 0;//    av_log(NULL, AV_LOG_INFO, "buf_size: %d\n", buf_size);        init_get_bits(&gb, buf, buf_size*8);        intlist_read(&gb, s->predictor_k, s->num_taps, 0);    // dequantize    for (i = 0; i < s->num_taps; i++)	s->predictor_k[i] *= s->tap_quant[i];    if (s->lossless)	quant = 1;    else	quant = get_ue_golomb(&gb) * SAMPLE_FACTOR;//    av_log(NULL, AV_LOG_INFO, "quant: %d\n", quant);    for (ch = 0; ch < s->channels; ch++)    {	int x = ch;	predictor_init_state(s->predictor_k, s->predictor_state[ch], s->num_taps);		intlist_read(&gb, s->coded_samples[ch], s->block_align, 1);	for (i = 0; i < s->block_align; i++)	{	    for (j = 0; j < s->downsampling - 1; j++)	    {		s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, 0);		x += s->channels;	    }	    	    s->int_samples[x] = predictor_calc_error(s->predictor_k, s->predictor_state[ch], s->num_taps, s->coded_samples[ch][i] * quant);	    x += s->channels;	}	for (i = 0; i < s->num_taps; i++)	    s->predictor_state[ch][i] = s->int_samples[s->frame_size - s->channels + ch - i*s->channels];    }        switch(s->decorrelation)    {	case MID_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)	    {		s->int_samples[i+1] += shift(s->int_samples[i], 1);		s->int_samples[i] -= s->int_samples[i+1];	    }	    break;	case LEFT_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)		s->int_samples[i+1] += s->int_samples[i];	    break;	case RIGHT_SIDE:	    for (i = 0; i < s->frame_size; i += s->channels)		s->int_samples[i] += s->int_samples[i+1];	    break;    }    if (!s->lossless)	for (i = 0; i < s->frame_size; i++)	    s->int_samples[i] = shift(s->int_samples[i], SAMPLE_SHIFT);    // internal -> short    for (i = 0; i < s->frame_size; i++)    {	if (s->int_samples[i] > 32767)	    samples[i] = 32767;	else if (s->int_samples[i] < -32768)	    samples[i] = -32768;	else	    samples[i] = s->int_samples[i];    }    align_get_bits(&gb);    *data_size = s->frame_size * 2;    return (get_bits_count(&gb)+7)/8;}#ifdef CONFIG_ENCODERSAVCodec sonic_encoder = {    "sonic",    CODEC_TYPE_AUDIO,    CODEC_ID_SONIC,    sizeof(SonicContext),    sonic_encode_init,    sonic_encode_frame,    sonic_encode_close,    NULL,};AVCodec sonic_ls_encoder = {    "sonicls",    CODEC_TYPE_AUDIO,    CODEC_ID_SONIC_LS,    sizeof(SonicContext),    sonic_encode_init,    sonic_encode_frame,    sonic_encode_close,    NULL,};#endif#ifdef CONFIG_DECODERSAVCodec sonic_decoder = {    "sonic",    CODEC_TYPE_AUDIO,    CODEC_ID_SONIC,    sizeof(SonicContext),    sonic_decode_init,    NULL,    sonic_decode_close,    sonic_decode_frame,};#endif

⌨️ 快捷键说明

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