summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMike Melanson <mike@multimedia.cx>2004-02-03 04:27:16 +0000
committerMike Melanson <mike@multimedia.cx>2004-02-03 04:27:16 +0000
commit2abfd77ce354f0d369c86393e4b9a2f0f984db2c (patch)
tree6ff95b38a2dcc1cf87bc81151338fc9ef844980f
parentd0e05a83c949fe5d0ad638b1450497f5fbbf65b5 (diff)
downloadxine-lib-2abfd77ce354f0d369c86393e4b9a2f0f984db2c.tar.gz
xine-lib-2abfd77ce354f0d369c86393e4b9a2f0f984db2c.tar.bz2
ported SMJPEG IMA and EA ADPCM decoders to ffmpeg
CVS patchset: 6109 CVS date: 2004/02/03 04:27:16
-rw-r--r--src/libffmpeg/audio_decoder.c6
-rw-r--r--src/libffmpeg/libavcodec/adpcm.c87
-rw-r--r--src/libffmpeg/libavcodec/avcodec.h4
-rw-r--r--src/libffmpeg/xine_decoder.c4
4 files changed, 99 insertions, 2 deletions
diff --git a/src/libffmpeg/audio_decoder.c b/src/libffmpeg/audio_decoder.c
index fc1b2dac1..14be0c0f7 100644
--- a/src/libffmpeg/audio_decoder.c
+++ b/src/libffmpeg/audio_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: audio_decoder.c,v 1.2 2004/02/01 06:00:56 tmmm Exp $
+ * $Id: audio_decoder.c,v 1.3 2004/02/03 04:27:18 tmmm Exp $
*
* xine audio decoder plugin using ffmpeg
*
@@ -88,8 +88,10 @@ static const ff_codec_t ff_audio_lookup[] = {
{BUF_AUDIO_DK3ADPCM, CODEC_ID_ADPCM_IMA_DK3, "Duck DK3 ADPCM (ffmpeg)"},
{BUF_AUDIO_DK4ADPCM, CODEC_ID_ADPCM_IMA_DK4, "Duck DK4 ADPCM (ffmpeg)"},
{BUF_AUDIO_VQA_IMA, CODEC_ID_ADPCM_IMA_WS, "Westwood Studios IMA (ffmpeg)"},
+ {BUF_AUDIO_SMJPEG_IMA, CODEC_ID_ADPCM_IMA_SMJPEG, "SMJPEG IMA (ffmpeg)"},
{BUF_AUDIO_XA_ADPCM, CODEC_ID_ADPCM_XA, "CD-ROM/XA ADPCM (ffmpeg)"},
{BUF_AUDIO_4X_ADPCM, CODEC_ID_ADPCM_4XM, "4X ADPCM (ffmpeg)"},
+ {BUF_AUDIO_EA_ADPCM, CODEC_ID_ADPCM_EA, "Electronic Arts ADPCM (ffmpeg)"},
{BUF_AUDIO_MULAW, CODEC_ID_PCM_MULAW, "mu-law logarithmic PCM (ffmpeg)"},
{BUF_AUDIO_ALAW, CODEC_ID_PCM_ALAW, "A-law logarithmic PCM (ffmpeg)"},
{BUF_AUDIO_ROQ, CODEC_ID_ROQ_DPCM, "RoQ DPCM (ffmpeg)"},
@@ -367,6 +369,8 @@ static uint32_t supported_audio_types[] = {
BUF_AUDIO_MAC6,
BUF_AUDIO_XAN_DPCM,
BUF_AUDIO_VMD,
+ BUF_AUDIO_EA_ADPCM,
+ BUF_AUDIO_SMJPEG_IMA,
/* BUF_AUDIO_MPEG, */
0
};
diff --git a/src/libffmpeg/libavcodec/adpcm.c b/src/libffmpeg/libavcodec/adpcm.c
index bced66f19..7aee84f65 100644
--- a/src/libffmpeg/libavcodec/adpcm.c
+++ b/src/libffmpeg/libavcodec/adpcm.c
@@ -25,6 +25,7 @@
* Fringe ADPCM codecs (e.g., DK3, DK4, Westwood)
* by Mike Melanson (melanson@pcisys.net)
* CD-ROM XA ADPCM codec by BERO
+ * EA ADPCM decoder by Robin Kay (komadori@myrealbox.com)
*
* Features and limitations:
*
@@ -44,6 +45,13 @@
#define BLKSIZE 1024
+#define BE_16(x) ((((uint8_t*)(x))[0] << 8) | ((uint8_t*)(x))[1])
+#define LE_16(x) ((((uint8_t*)(x))[1] << 8) | ((uint8_t*)(x))[0])
+#define LE_32(x) ((((uint8_t*)(x))[3] << 24) | \
+ (((uint8_t*)(x))[2] << 16) | \
+ (((uint8_t*)(x))[1] << 8) | \
+ ((uint8_t*)(x))[0])
+
#define CLAMP_TO_SHORT(value) \
if (value > 32767) \
value = 32767; \
@@ -97,6 +105,11 @@ static const int xa_adpcm_table[5][2] = {
{ 122, -60 }
};
+static int ea_adpcm_table[] = {
+ 0, 240, 460, 392, 0, 0, -208, -220, 0, 1,
+ 3, 4, 7, 8, 10, 11, 0, -1, -3, -4
+};
+
/* end of tables */
typedef struct ADPCMChannelStatus {
@@ -444,6 +457,15 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
int decode_top_nibble_next = 0;
int diff_channel;
+ /* EA ADPCM state variables */
+ uint32_t samples_in_chunk;
+ int32_t previous_left_sample, previous_right_sample;
+ int32_t current_left_sample, current_right_sample;
+ int32_t next_left_sample, next_right_sample;
+ int32_t coeff1l, coeff2l, coeff1r, coeff2r;
+ uint8_t shift_left, shift_right;
+ int count1, count2;
+
if (!buf_size)
return 0;
@@ -715,6 +737,69 @@ static int adpcm_decode_frame(AVCodecContext *avctx,
buf_size -= 128;
}
break;
+ case CODEC_ID_ADPCM_EA:
+ samples_in_chunk = LE_32(src);
+ if (samples_in_chunk >= ((buf_size - 12) * 2)) {
+ src += buf_size;
+ break;
+ }
+ src += 4;
+ current_left_sample = (int16_t)LE_16(src);
+ src += 2;
+ previous_left_sample = (int16_t)LE_16(src);
+ src += 2;
+ current_right_sample = (int16_t)LE_16(src);
+ src += 2;
+ previous_right_sample = (int16_t)LE_16(src);
+ src += 2;
+
+ for (count1 = 0; count1 < samples_in_chunk/28;count1++) {
+ coeff1l = ea_adpcm_table[(*src >> 4) & 0x0F];
+ coeff2l = ea_adpcm_table[((*src >> 4) & 0x0F) + 4];
+ coeff1r = ea_adpcm_table[*src & 0x0F];
+ coeff2r = ea_adpcm_table[(*src & 0x0F) + 4];
+ src++;
+
+ shift_left = ((*src >> 4) & 0x0F) + 8;
+ shift_right = (*src & 0x0F) + 8;
+ src++;
+
+ for (count2 = 0; count2 < 28; count2++) {
+ next_left_sample = (((*src & 0xF0) << 24) >> shift_left);
+ next_right_sample = (((*src & 0x0F) << 28) >> shift_right);
+ src++;
+
+ next_left_sample = (next_left_sample +
+ (current_left_sample * coeff1l) +
+ (previous_left_sample * coeff2l) + 0x80) >> 8;
+ next_right_sample = (next_right_sample +
+ (current_right_sample * coeff1r) +
+ (previous_right_sample * coeff2r) + 0x80) >> 8;
+ CLAMP_TO_SHORT(next_left_sample);
+ CLAMP_TO_SHORT(next_right_sample);
+
+ previous_left_sample = current_left_sample;
+ current_left_sample = next_left_sample;
+ previous_right_sample = current_right_sample;
+ current_right_sample = next_right_sample;
+ *samples++ = (unsigned short)current_left_sample;
+ *samples++ = (unsigned short)current_right_sample;
+ }
+ }
+ break;
+ case CODEC_ID_ADPCM_IMA_SMJPEG:
+ c->status[0].predictor = *src;
+ src += 2;
+ c->status[0].step_index = *src++;
+ src++; /* skip another byte before getting to the meat */
+ while (src < buf + buf_size) {
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0],
+ *src & 0x0F, 3);
+ *samples++ = adpcm_ima_expand_nibble(&c->status[0],
+ (*src >> 4) & 0x0F, 3);
+ src++;
+ }
+ break;
default:
*data_size = 0;
return -1;
@@ -765,9 +850,11 @@ ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
ADPCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
+ADPCM_CODEC(CODEC_ID_ADPCM_IMA_SMJPEG, adpcm_ima_smjpeg);
ADPCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
ADPCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
ADPCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
ADPCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
+ADPCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea);
#undef ADPCM_CODEC
diff --git a/src/libffmpeg/libavcodec/avcodec.h b/src/libffmpeg/libavcodec/avcodec.h
index 6f26b0685..2e884e834 100644
--- a/src/libffmpeg/libavcodec/avcodec.h
+++ b/src/libffmpeg/libavcodec/avcodec.h
@@ -117,10 +117,12 @@ enum CodecID {
CODEC_ID_ADPCM_IMA_DK3,
CODEC_ID_ADPCM_IMA_DK4,
CODEC_ID_ADPCM_IMA_WS,
+ CODEC_ID_ADPCM_IMA_SMJPEG,
CODEC_ID_ADPCM_MS,
CODEC_ID_ADPCM_4XM,
CODEC_ID_ADPCM_XA,
CODEC_ID_ADPCM_ADX,
+ CODEC_ID_ADPCM_EA,
/* AMR */
CODEC_ID_AMR_NB,
@@ -1727,10 +1729,12 @@ PCM_CODEC(CODEC_ID_ADPCM_IMA_WAV, adpcm_ima_wav);
PCM_CODEC(CODEC_ID_ADPCM_IMA_DK3, adpcm_ima_dk3);
PCM_CODEC(CODEC_ID_ADPCM_IMA_DK4, adpcm_ima_dk4);
PCM_CODEC(CODEC_ID_ADPCM_IMA_WS, adpcm_ima_ws);
+PCM_CODEC(CODEC_ID_ADPCM_SMJPEG, adpcm_ima_smjpeg);
PCM_CODEC(CODEC_ID_ADPCM_MS, adpcm_ms);
PCM_CODEC(CODEC_ID_ADPCM_4XM, adpcm_4xm);
PCM_CODEC(CODEC_ID_ADPCM_XA, adpcm_xa);
PCM_CODEC(CODEC_ID_ADPCM_ADX, adpcm_adx);
+PCM_CODEC(CODEC_ID_ADPCM_EA, adpcm_ea);
#undef PCM_CODEC
diff --git a/src/libffmpeg/xine_decoder.c b/src/libffmpeg/xine_decoder.c
index b45a25eb7..d5d10d0fe 100644
--- a/src/libffmpeg/xine_decoder.c
+++ b/src/libffmpeg/xine_decoder.c
@@ -17,7 +17,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*
- * $Id: xine_decoder.c,v 1.156 2004/02/01 22:45:18 jstembridge Exp $
+ * $Id: xine_decoder.c,v 1.157 2004/02/03 04:27:18 tmmm Exp $
*
* xine decoder plugin using ffmpeg
*
@@ -83,8 +83,10 @@ void avcodec_register_all(void)
register_avcodec(&adpcm_ima_dk3_decoder);
register_avcodec(&adpcm_ima_dk4_decoder);
register_avcodec(&adpcm_ima_ws_decoder);
+ register_avcodec(&adpcm_ima_smjpeg_decoder);
register_avcodec(&adpcm_xa_decoder);
register_avcodec(&adpcm_4xm_decoder);
+ register_avcodec(&adpcm_ea_decoder);
register_avcodec(&pcm_alaw_decoder);
register_avcodec(&pcm_mulaw_decoder);
register_avcodec(&roq_dpcm_decoder);