You've already forked FFmpeg
							
							
				mirror of
				https://github.com/FFmpeg/FFmpeg.git
				synced 2025-10-30 23:18:11 +02:00 
			
		
		
		
	Merge commit 'a16577d9857206089fd8bce6a342b31dbd7fb9b0'
* commit 'a16577d9857206089fd8bce6a342b31dbd7fb9b0': MSN Audio support Conflicts: libavformat/riff.c Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
		| @@ -22,10 +22,24 @@ | ||||
| #define AVCODEC_GSM_H | ||||
|  | ||||
| /* bytes per block */ | ||||
| #define GSM_BLOCK_SIZE    33 | ||||
| #define GSM_MS_BLOCK_SIZE 65 | ||||
| #define GSM_BLOCK_SIZE     33 | ||||
| #define GSM_MS_BLOCK_SIZE  65 | ||||
| #define MSN_MIN_BLOCK_SIZE 41 | ||||
|  | ||||
| /* samples per block */ | ||||
| #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 */ | ||||
|   | ||||
| @@ -50,7 +50,8 @@ static int gsm_parse(AVCodecParserContext *s1, AVCodecContext *avctx, | ||||
|             s->duration   = GSM_FRAME_SIZE; | ||||
|             break; | ||||
|         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; | ||||
|             break; | ||||
|         default: | ||||
|   | ||||
| @@ -55,7 +55,16 @@ static av_cold int gsm_init(AVCodecContext *avctx) | ||||
|         break; | ||||
|     case AV_CODEC_ID_GSM_MS: | ||||
|         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; | ||||
| @@ -87,12 +96,13 @@ static int gsm_decode_frame(AVCodecContext *avctx, void *data, | ||||
|         init_get_bits(&gb, buf, buf_size * 8); | ||||
|         if (get_bits(&gb, 4) != 0xd) | ||||
|             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) | ||||
|             return res; | ||||
|         break; | ||||
|     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) | ||||
|             return res; | ||||
|     } | ||||
|   | ||||
| @@ -92,3 +92,29 @@ const int16_t ff_gsm_dequant_tab[64][8] = { | ||||
|     {-26879, -19199, -11520,  -3840,   3840,  11520,  19199,  26879}, | ||||
|     {-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 int16_t ff_gsm_dequant_tab[64][8]; | ||||
|  | ||||
| extern const int* const ff_gsm_apcm_bits[][4]; | ||||
|  | ||||
| #endif /* AVCODEC_GSMDEC_DATA_H */ | ||||
|   | ||||
| @@ -28,13 +28,22 @@ | ||||
| #include "gsm.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); | ||||
|     const int16_t *tab = ff_gsm_dequant_tab[maxidx]; | ||||
|     for (i = 0; i < 13; i++) | ||||
|         dst[3*i] += tab[get_bits(gb, 3)]; | ||||
|     for (i = 0; i < 13; i++) { | ||||
|         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) | ||||
| @@ -118,7 +127,7 @@ static int postprocess(int16_t *data, int msr) | ||||
| } | ||||
|  | ||||
| static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, | ||||
|                             GetBitContext *gb) | ||||
|                             GetBitContext *gb, int mode) | ||||
| { | ||||
|     GSMContext *ctx = avctx->priv_data; | ||||
|     int i; | ||||
| @@ -139,7 +148,7 @@ static int gsm_decode_block(AVCodecContext *avctx, int16_t *samples, | ||||
|         int offset   = get_bits(gb, 2); | ||||
|         lag = av_clip(lag, 40, 120); | ||||
|         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; | ||||
|     } | ||||
|     memcpy(ctx->ref_buf, ctx->ref_buf + 160, 120 * sizeof(*ctx->ref_buf)); | ||||
|   | ||||
| @@ -26,13 +26,13 @@ | ||||
| #include "gsmdec_template.c" | ||||
|  | ||||
| int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, | ||||
|                           const uint8_t *buf) | ||||
|                           const uint8_t *buf, int mode) | ||||
| { | ||||
|     int res; | ||||
|     GetBitContext gb; | ||||
|     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) | ||||
|         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" | ||||
|  | ||||
| int ff_msgsm_decode_block(AVCodecContext *avctx, int16_t *samples, | ||||
|                           const uint8_t *buf); | ||||
|                           const uint8_t *buf, int mode); | ||||
|  | ||||
| #endif /* AVCODEC_MSGSMDEC_H */ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user