Commit 3a3f06b0 authored by Ronald S. Bultje's avatar Ronald S. Bultje

dpcm: convert to bytestream2.

parent f31a68e7
...@@ -40,6 +40,7 @@ ...@@ -40,6 +40,7 @@
#include "libavutil/intreadwrite.h" #include "libavutil/intreadwrite.h"
#include "avcodec.h" #include "avcodec.h"
#include "bytestream.h" #include "bytestream.h"
#include "mathops.h"
typedef struct DPCMContext { typedef struct DPCMContext {
AVFrame frame; AVFrame frame;
...@@ -173,20 +174,18 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx) ...@@ -173,20 +174,18 @@ static av_cold int dpcm_decode_init(AVCodecContext *avctx)
static int dpcm_decode_frame(AVCodecContext *avctx, void *data, static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
int *got_frame_ptr, AVPacket *avpkt) int *got_frame_ptr, AVPacket *avpkt)
{ {
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size; int buf_size = avpkt->size;
const uint8_t *buf_end = buf + buf_size;
DPCMContext *s = avctx->priv_data; DPCMContext *s = avctx->priv_data;
int out = 0, ret; int out = 0, ret;
int predictor[2]; int predictor[2];
int ch = 0; int ch = 0;
int stereo = s->channels - 1; int stereo = s->channels - 1;
int16_t *output_samples; int16_t *output_samples, *samples_end;
GetByteContext gb;
if (stereo && (buf_size & 1)) { if (stereo && (buf_size & 1))
buf_size--; buf_size--;
buf_end--; bytestream2_init(&gb, avpkt->data, buf_size);
}
/* calculate output size */ /* calculate output size */
switch(avctx->codec->id) { switch(avctx->codec->id) {
...@@ -218,22 +217,23 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -218,22 +217,23 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
return ret; return ret;
} }
output_samples = (int16_t *)s->frame.data[0]; output_samples = (int16_t *)s->frame.data[0];
samples_end = output_samples + out;
switch(avctx->codec->id) { switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM: case CODEC_ID_ROQ_DPCM:
buf += 6; bytestream2_skipu(&gb, 6);
if (stereo) { if (stereo) {
predictor[1] = (int16_t)(bytestream_get_byte(&buf) << 8); predictor[1] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
predictor[0] = (int16_t)(bytestream_get_byte(&buf) << 8); predictor[0] = sign_extend(bytestream2_get_byteu(&gb) << 8, 16);
} else { } else {
predictor[0] = (int16_t)bytestream_get_le16(&buf); predictor[0] = sign_extend(bytestream2_get_le16u(&gb), 16);
} }
/* decode the samples */ /* decode the samples */
while (buf < buf_end) { while (output_samples < samples_end) {
predictor[ch] += s->roq_square_array[*buf++]; predictor[ch] += s->roq_square_array[bytestream2_get_byteu(&gb)];
predictor[ch] = av_clip_int16(predictor[ch]); predictor[ch] = av_clip_int16(predictor[ch]);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
...@@ -243,16 +243,16 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -243,16 +243,16 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
break; break;
case CODEC_ID_INTERPLAY_DPCM: case CODEC_ID_INTERPLAY_DPCM:
buf += 6; /* skip over the stream mask and stream length */ bytestream2_skipu(&gb, 6); /* skip over the stream mask and stream length */
for (ch = 0; ch < s->channels; ch++) { for (ch = 0; ch < s->channels; ch++) {
predictor[ch] = (int16_t)bytestream_get_le16(&buf); predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
} }
ch = 0; ch = 0;
while (buf < buf_end) { while (output_samples < samples_end) {
predictor[ch] += interplay_delta_table[*buf++]; predictor[ch] += interplay_delta_table[bytestream2_get_byteu(&gb)];
predictor[ch] = av_clip_int16(predictor[ch]); predictor[ch] = av_clip_int16(predictor[ch]);
*output_samples++ = predictor[ch]; *output_samples++ = predictor[ch];
...@@ -266,16 +266,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -266,16 +266,19 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
int shift[2] = { 4, 4 }; int shift[2] = { 4, 4 };
for (ch = 0; ch < s->channels; ch++) for (ch = 0; ch < s->channels; ch++)
predictor[ch] = (int16_t)bytestream_get_le16(&buf); predictor[ch] = sign_extend(bytestream2_get_le16u(&gb), 16);
ch = 0; ch = 0;
while (buf < buf_end) { while (output_samples < samples_end) {
uint8_t n = *buf++; int diff = bytestream2_get_byteu(&gb);
int16_t diff = (n & 0xFC) << 8; int n = diff & 3;
if ((n & 0x03) == 3)
if (n == 3)
shift[ch]++; shift[ch]++;
else else
shift[ch] -= (2 * (n & 3)); shift[ch] -= (2 * n);
diff = sign_extend((diff &~ 3) << 8, 16);
/* saturate the shifter to a lower limit of 0 */ /* saturate the shifter to a lower limit of 0 */
if (shift[ch] < 0) if (shift[ch] < 0)
shift[ch] = 0; shift[ch] = 0;
...@@ -293,9 +296,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -293,9 +296,10 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
} }
case CODEC_ID_SOL_DPCM: case CODEC_ID_SOL_DPCM:
if (avctx->codec_tag != 3) { if (avctx->codec_tag != 3) {
uint8_t *output_samples_u8 = s->frame.data[0]; uint8_t *output_samples_u8 = s->frame.data[0],
while (buf < buf_end) { *samples_end_u8 = output_samples_u8 + out;
uint8_t n = *buf++; while (output_samples_u8 < samples_end_u8) {
int n = bytestream2_get_byteu(&gb);
s->sample[0] += s->sol_table[n >> 4]; s->sample[0] += s->sol_table[n >> 4];
s->sample[0] = av_clip_uint8(s->sample[0]); s->sample[0] = av_clip_uint8(s->sample[0]);
...@@ -306,8 +310,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data, ...@@ -306,8 +310,8 @@ static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
*output_samples_u8++ = s->sample[stereo]; *output_samples_u8++ = s->sample[stereo];
} }
} else { } else {
while (buf < buf_end) { while (output_samples < samples_end) {
uint8_t n = *buf++; int n = bytestream2_get_byteu(&gb);
if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F]; if (n & 0x80) s->sample[ch] -= sol_table_16[n & 0x7F];
else s->sample[ch] += sol_table_16[n & 0x7F]; else s->sample[ch] += sol_table_16[n & 0x7F];
s->sample[ch] = av_clip_int16(s->sample[ch]); s->sample[ch] = av_clip_int16(s->sample[ch]);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment