Merge commit 'a16577d9857206089fd8bce6a342b31dbd7fb9b0'
* commit 'a16577d9857206089fd8bce6a342b31dbd7fb9b0': MSN Audio support Conflicts: libavformat/riff.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
8c87658fdc
@ -22,10 +22,24 @@
|
|||||||
#define AVCODEC_GSM_H
|
#define AVCODEC_GSM_H
|
||||||
|
|
||||||
/* bytes per block */
|
/* bytes per block */
|
||||||
#define GSM_BLOCK_SIZE 33
|
#define GSM_BLOCK_SIZE 33
|
||||||
#define GSM_MS_BLOCK_SIZE 65
|
#define GSM_MS_BLOCK_SIZE 65
|
||||||
|
#define MSN_MIN_BLOCK_SIZE 41
|
||||||
|
|
||||||
/* samples per block */
|
/* samples per block */
|
||||||
#define GSM_FRAME_SIZE 160
|
#define GSM_FRAME_SIZE 160
|
||||||
|
|
||||||
|
enum GSMModes {
|
||||||
|
GSM_13000 = 0,
|
||||||
|
MSN_12400,
|
||||||
|
MSN_11800,
|
||||||
|
MSN_11200,
|
||||||
|
MSN_10600,
|
||||||
|
MSN_10000,
|
||||||
|
MSN_9400,
|
||||||
|
MSN_8800,
|
||||||
|
MSN_8200,
|
||||||
|
NUM_GSM_MODES
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* AVCODEC_GSM_H */
|
#endif /* AVCODEC_GSM_H */
|
||||||
|
@ -50,7 +50,8 @@ static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx,
|
|||||||
s->duration = GSM_FRAME_SIZE;
|
s->duration = GSM_FRAME_SIZE;
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_GSM_MS:
|
case AV_CODEC_ID_GSM_MS:
|
||||||
s->block_size = GSM_MS_BLOCK_SIZE;
|
s->block_size = avctx->block_align ? avctx->block_align
|
||||||
|
: GSM_MS_BLOCK_SIZE;
|
||||||
s->duration = GSM_FRAME_SIZE * 2;
|
s->duration = GSM_FRAME_SIZE * 2;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -55,7 +55,16 @@ static av_cold int gsm_init(AVCodecContext *avctx)
|
|||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_GSM_MS:
|
case AV_CODEC_ID_GSM_MS:
|
||||||
avctx->frame_size = 2 * GSM_FRAME_SIZE;
|
avctx->frame_size = 2 * GSM_FRAME_SIZE;
|
||||||
avctx->block_align = GSM_MS_BLOCK_SIZE;
|
if (!avctx->block_align)
|
||||||
|
avctx->block_align = GSM_MS_BLOCK_SIZE;
|
||||||
|
else
|
||||||
|
if (avctx->block_align < MSN_MIN_BLOCK_SIZE ||
|
||||||
|
avctx->block_align > GSM_MS_BLOCK_SIZE ||
|
||||||
|
(avctx->block_align - MSN_MIN_BLOCK_SIZE) % 3) {
|
||||||
|
av_log(avctx, AV_LOG_ERROR, "Invalid block alignment %d\n",
|
||||||
|
avctx->block_align);
|
||||||
|
return AVERROR_INVALIDDATA;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
@ -87,12 +96,13 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data,
|
|||||||
init_get_bits(&gb, buf, buf_size * 8);
|
init_get_bits(&gb, buf, buf_size * 8);
|
||||||
if (get_bits(&gb, 4) != 0xd)
|
if (get_bits(&gb, 4) != 0xd)
|
||||||
av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
|
av_log(avctx, AV_LOG_WARNING, "Missing GSM magic!\n");
|
||||||
res = gsm_decode_block(avctx, samples, &gb);
|
res = gsm_decode_block(avctx, samples, &gb, GSM_13000);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
break;
|
break;
|
||||||
case AV_CODEC_ID_GSM_MS:
|
case AV_CODEC_ID_GSM_MS:
|
||||||
res = ff_msgsm_decode_block(avctx, samples, buf);
|
res = ff_msgsm_decode_block(avctx, samples, buf,
|
||||||
|
(GSM_MS_BLOCK_SIZE - avctx->block_align) / 3);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
@ -92,3 +92,29 @@ const int16_t ff_gsm_dequant_tab[64][8] = {
|
|||||||
{-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879},
|
{-26879, -19199, -11520, -3840, 3840, 11520, 19199, 26879},
|
||||||
{-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671}
|
{-28671, -20479, -12288, -4096, 4096, 12288, 20479, 28671}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const int apcm_bits[11][13] = {
|
||||||
|
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1, 1 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 2, 2, 1, 1, 1, 1, 1 },
|
||||||
|
{ 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||||
|
{ 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||||
|
{ 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||||
|
{ 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||||
|
{ 3, 3, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2 },
|
||||||
|
{ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 }
|
||||||
|
};
|
||||||
|
|
||||||
|
const int* const ff_gsm_apcm_bits[][4] = {
|
||||||
|
{ apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[10] }, // 13000
|
||||||
|
{ apcm_bits[10], apcm_bits[10], apcm_bits[10], apcm_bits[ 6] }, // 12400
|
||||||
|
{ apcm_bits[10], apcm_bits[10], apcm_bits[ 7], apcm_bits[ 5] }, // 11800
|
||||||
|
{ apcm_bits[10], apcm_bits[ 8], apcm_bits[ 5], apcm_bits[ 5] }, // 11200
|
||||||
|
{ apcm_bits[ 9], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5] }, // 10600
|
||||||
|
{ apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 1] }, // 10000
|
||||||
|
{ apcm_bits[ 5], apcm_bits[ 5], apcm_bits[ 2], apcm_bits[ 0] }, // 9400
|
||||||
|
{ apcm_bits[ 5], apcm_bits[ 3], apcm_bits[ 0], apcm_bits[ 0] }, // 8800
|
||||||
|
{ apcm_bits[ 4], apcm_bits[ 0], apcm_bits[ 0], apcm_bits[ 0] }, // 8200
|
||||||
|
};
|
||||||
|
@ -40,4 +40,6 @@ typedef struct GSMContext {
|
|||||||
extern const uint16_t ff_gsm_long_term_gain_tab[4];
|
extern const uint16_t ff_gsm_long_term_gain_tab[4];
|
||||||
extern const int16_t ff_gsm_dequant_tab[64][8];
|
extern const int16_t ff_gsm_dequant_tab[64][8];
|
||||||
|
|
||||||
|
extern const int* const ff_gsm_apcm_bits[][4];
|
||||||
|
|
||||||
#endif /* AVCODEC_GSMDEC_DATA_H */
|
#endif /* AVCODEC_GSMDEC_DATA_H */
|
||||||
|
@ -28,13 +28,22 @@
|
|||||||
#include "gsm.h"
|
#include "gsm.h"
|
||||||
#include "gsmdec_data.h"
|
#include "gsmdec_data.h"
|
||||||
|
|
||||||
static void apcm_dequant_add(GetBitContext *gb, int16_t *dst)
|
static const int requant_tab[4][8] = {
|
||||||
|
{ 0 },
|
||||||
|
{ 0, 7 },
|
||||||
|
{ 0, 2, 5, 7 },
|
||||||
|
{ 0, 1, 2, 3, 4, 5, 6, 7 }
|
||||||
|
};
|
||||||
|
|
||||||
|
static void apcm_dequant_add(GetBitContext *gb, int16_t *dst, const int *frame_bits)
|
||||||
{
|
{
|
||||||
int i;
|
int i, val;
|
||||||
int maxidx = get_bits(gb, 6);
|
int maxidx = get_bits(gb, 6);
|
||||||
const int16_t *tab = ff_gsm_dequant_tab[maxidx];
|
const int16_t *tab = ff_gsm_dequant_tab[maxidx];
|
||||||
for (i = 0; i < 13; i++)
|
for (i = 0; i < 13; i++) {
|
||||||
dst[3*i] += tab[get_bits(gb, 3)];
|
val = get_bits(gb, frame_bits[i]);
|
||||||
|
dst[3*i] += tab[requant_tab[frame_bits[i]][val]];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int gsm_mult(int a, int b)
|
static inline int gsm_mult(int a, int b)
|
||||||
@ -118,7 +127,7 @@ static int postprocess(int16_t *data, int msr)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
||||||
GetBitContext *gb)
|
GetBitContext *gb, int mode)
|
||||||
{
|
{
|
||||||
GSMContext *ctx = avctx->priv_data;
|
GSMContext *ctx = avctx->priv_data;
|
||||||
int i;
|
int i;
|
||||||
@ -139,7 +148,7 @@ static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
|||||||
int offset = get_bits(gb, 2);
|
int offset = get_bits(gb, 2);
|
||||||
lag = av_clip(lag, 40, 120);
|
lag = av_clip(lag, 40, 120);
|
||||||
long_term_synth(ref_dst, lag, gain_idx);
|
long_term_synth(ref_dst, lag, gain_idx);
|
||||||
apcm_dequant_add(gb, ref_dst + offset);
|
apcm_dequant_add(gb, ref_dst + offset, ff_gsm_apcm_bits[mode][i]);
|
||||||
ref_dst += 40;
|
ref_dst += 40;
|
||||||
}
|
}
|
||||||
memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf));
|
memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf));
|
||||||
|
@ -26,13 +26,13 @@
|
|||||||
#include "gsmdec_template.c"
|
#include "gsmdec_template.c"
|
||||||
|
|
||||||
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
||||||
const uint8_t *buf)
|
const uint8_t *buf, int mode)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
GetBitContext gb;
|
GetBitContext gb;
|
||||||
init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8);
|
init_get_bits(&gb, buf, GSM_MS_BLOCK_SIZE * 8);
|
||||||
res = gsm_decode_block(avctx, samples, &gb);
|
res = gsm_decode_block(avctx, samples, &gb, mode);
|
||||||
if (res < 0)
|
if (res < 0)
|
||||||
return res;
|
return res;
|
||||||
return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb);
|
return gsm_decode_block(avctx, samples + GSM_FRAME_SIZE, &gb, mode);
|
||||||
}
|
}
|
||||||
|
@ -25,6 +25,6 @@
|
|||||||
#include "avcodec.h"
|
#include "avcodec.h"
|
||||||
|
|
||||||
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples,
|
||||||
const uint8_t *buf);
|
const uint8_t *buf, int mode);
|
||||||
|
|
||||||
#endif /* AVCODEC_MSGSMDEC_H */
|
#endif /* AVCODEC_MSGSMDEC_H */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user