mirror of
https://git.ffmpeg.org/ffmpeg.git
synced 2024-12-17 13:04:50 +00:00
Move run level decode functionality to ff_wma_run_level_decode
so that it can be reused for wmapro Originally committed as revision 19171 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
e8c7f81cf2
commit
c0e9b2e84f
@ -424,3 +424,64 @@ int ff_wma_end(AVCodecContext *avctx)
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Decode run level compressed coefficients.
|
||||||
|
* @param avctx codec context
|
||||||
|
* @param gb bitstream reader context
|
||||||
|
* @param vlc vlc table for get_vlc2
|
||||||
|
* @param level_table level codes
|
||||||
|
* @param run_table run codes
|
||||||
|
* @param version 0 for wma1,2 1 for wmapro
|
||||||
|
* @param ptr output buffer
|
||||||
|
* @param offset offset in the output buffer
|
||||||
|
* @param num_coefs number of input coefficents
|
||||||
|
* @param block_len input buffer length (2^n)
|
||||||
|
* @param frame_len_bits number of bits for escaped run codes
|
||||||
|
* @param coef_nb_bits number of bits for escaped level codes
|
||||||
|
* @return 0 on success, -1 otherwise
|
||||||
|
*/
|
||||||
|
int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
|
||||||
|
VLC *vlc,
|
||||||
|
const uint16_t *level_table, const uint16_t *run_table,
|
||||||
|
int version, int16_t *ptr, int offset,
|
||||||
|
int num_coefs, int block_len, int frame_len_bits,
|
||||||
|
int coef_nb_bits)
|
||||||
|
{
|
||||||
|
int code, run, level, sign;
|
||||||
|
int16_t* eptr = ptr + num_coefs;
|
||||||
|
for(;;) {
|
||||||
|
code = get_vlc2(gb, vlc->table, VLCBITS, VLCMAX);
|
||||||
|
if (code < 0)
|
||||||
|
return -1;
|
||||||
|
if (code == 1) {
|
||||||
|
/* EOB */
|
||||||
|
break;
|
||||||
|
} else if (code == 0) {
|
||||||
|
/* escape */
|
||||||
|
level = get_bits(gb, coef_nb_bits);
|
||||||
|
/* NOTE: this is rather suboptimal. reading
|
||||||
|
block_len_bits would be better */
|
||||||
|
run = get_bits(gb, frame_len_bits);
|
||||||
|
} else {
|
||||||
|
/* normal code */
|
||||||
|
run = run_table[code];
|
||||||
|
level = level_table[code];
|
||||||
|
}
|
||||||
|
sign = get_bits1(gb);
|
||||||
|
if (!sign)
|
||||||
|
level = -level;
|
||||||
|
ptr += run;
|
||||||
|
if (ptr >= eptr)
|
||||||
|
{
|
||||||
|
av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
*ptr++ = level;
|
||||||
|
/* NOTE: EOB can be omitted */
|
||||||
|
if (ptr >= eptr)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -148,5 +148,11 @@ int av_cold ff_wma_get_frame_len_bits(int sample_rate, int version,
|
|||||||
int ff_wma_init(AVCodecContext * avctx, int flags2);
|
int ff_wma_init(AVCodecContext * avctx, int flags2);
|
||||||
int ff_wma_total_gain_to_bits(int total_gain);
|
int ff_wma_total_gain_to_bits(int total_gain);
|
||||||
int ff_wma_end(AVCodecContext *avctx);
|
int ff_wma_end(AVCodecContext *avctx);
|
||||||
|
int ff_wma_run_level_decode(AVCodecContext* avctx, GetBitContext* gb,
|
||||||
|
VLC *vlc,
|
||||||
|
const uint16_t *level_table, const uint16_t *run_table,
|
||||||
|
int version, int16_t *ptr, int offset,
|
||||||
|
int num_coefs, int block_len, int frame_len_bits,
|
||||||
|
int coef_nb_bits);
|
||||||
|
|
||||||
#endif /* AVCODEC_WMA_H */
|
#endif /* AVCODEC_WMA_H */
|
||||||
|
@ -349,7 +349,7 @@ static void wma_window(WMACodecContext *s, float *out)
|
|||||||
*/
|
*/
|
||||||
static int wma_decode_block(WMACodecContext *s)
|
static int wma_decode_block(WMACodecContext *s)
|
||||||
{
|
{
|
||||||
int n, v, a, ch, code, bsize;
|
int n, v, a, ch, bsize;
|
||||||
int coef_nb_bits, total_gain;
|
int coef_nb_bits, total_gain;
|
||||||
int nb_coefs[MAX_CHANNELS];
|
int nb_coefs[MAX_CHANNELS];
|
||||||
float mdct_norm;
|
float mdct_norm;
|
||||||
@ -485,53 +485,17 @@ static int wma_decode_block(WMACodecContext *s)
|
|||||||
/* parse spectral coefficients : just RLE encoding */
|
/* parse spectral coefficients : just RLE encoding */
|
||||||
for(ch = 0; ch < s->nb_channels; ch++) {
|
for(ch = 0; ch < s->nb_channels; ch++) {
|
||||||
if (s->channel_coded[ch]) {
|
if (s->channel_coded[ch]) {
|
||||||
VLC *coef_vlc;
|
int tindex;
|
||||||
int level, run, sign, tindex;
|
int16_t* ptr = &s->coefs1[ch][0];
|
||||||
int16_t *ptr, *eptr;
|
|
||||||
const uint16_t *level_table, *run_table;
|
|
||||||
|
|
||||||
/* special VLC tables are used for ms stereo because
|
/* special VLC tables are used for ms stereo because
|
||||||
there is potentially less energy there */
|
there is potentially less energy there */
|
||||||
tindex = (ch == 1 && s->ms_stereo);
|
tindex = (ch == 1 && s->ms_stereo);
|
||||||
coef_vlc = &s->coef_vlc[tindex];
|
|
||||||
run_table = s->run_table[tindex];
|
|
||||||
level_table = s->level_table[tindex];
|
|
||||||
/* XXX: optimize */
|
|
||||||
ptr = &s->coefs1[ch][0];
|
|
||||||
eptr = ptr + nb_coefs[ch];
|
|
||||||
memset(ptr, 0, s->block_len * sizeof(int16_t));
|
memset(ptr, 0, s->block_len * sizeof(int16_t));
|
||||||
for(;;) {
|
ff_wma_run_level_decode(s->avctx, &s->gb, &s->coef_vlc[tindex],
|
||||||
code = get_vlc2(&s->gb, coef_vlc->table, VLCBITS, VLCMAX);
|
s->level_table[tindex], s->run_table[tindex],
|
||||||
if (code < 0)
|
0, ptr, 0, nb_coefs[ch],
|
||||||
return -1;
|
s->block_len, s->frame_len_bits, coef_nb_bits);
|
||||||
if (code == 1) {
|
|
||||||
/* EOB */
|
|
||||||
break;
|
|
||||||
} else if (code == 0) {
|
|
||||||
/* escape */
|
|
||||||
level = get_bits(&s->gb, coef_nb_bits);
|
|
||||||
/* NOTE: this is rather suboptimal. reading
|
|
||||||
block_len_bits would be better */
|
|
||||||
run = get_bits(&s->gb, s->frame_len_bits);
|
|
||||||
} else {
|
|
||||||
/* normal code */
|
|
||||||
run = run_table[code];
|
|
||||||
level = level_table[code];
|
|
||||||
}
|
|
||||||
sign = get_bits1(&s->gb);
|
|
||||||
if (!sign)
|
|
||||||
level = -level;
|
|
||||||
ptr += run;
|
|
||||||
if (ptr >= eptr)
|
|
||||||
{
|
|
||||||
av_log(NULL, AV_LOG_ERROR, "overflow in spectral RLE, ignoring\n");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
*ptr++ = level;
|
|
||||||
/* NOTE: EOB can be omitted */
|
|
||||||
if (ptr >= eptr)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if (s->version == 1 && s->nb_channels >= 2) {
|
if (s->version == 1 && s->nb_channels >= 2) {
|
||||||
align_get_bits(&s->gb);
|
align_get_bits(&s->gb);
|
||||||
|
Loading…
Reference in New Issue
Block a user