00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "avcodec.h"
00025 #include "bytestream.h"
00026
00027 #define ROQ_FIRST_FRAME_SIZE (735*8)
00028 #define ROQ_FRAME_SIZE 735
00029
00030
00031 #define MAX_DPCM (127*127)
00032 static unsigned char dpcmValues[MAX_DPCM];
00033
00034
00035 typedef struct
00036 {
00037 short lastSample[2];
00038 } ROQDPCMContext;
00039
00040 static av_cold void roq_dpcm_table_init(void)
00041 {
00042 int i;
00043
00044
00045 for (i=0; i<MAX_DPCM; i++) {
00046 int s= ff_sqrt(i);
00047 int mid= s*s + s;
00048 dpcmValues[i]= s + (i>mid);
00049 }
00050 }
00051
00052 static av_cold int roq_dpcm_encode_init(AVCodecContext *avctx)
00053 {
00054 ROQDPCMContext *context = avctx->priv_data;
00055
00056 if (avctx->channels > 2) {
00057 av_log(avctx, AV_LOG_ERROR, "Audio must be mono or stereo\n");
00058 return -1;
00059 }
00060 if (avctx->sample_rate != 22050) {
00061 av_log(avctx, AV_LOG_ERROR, "Audio must be 22050 Hz\n");
00062 return -1;
00063 }
00064 if (avctx->sample_fmt != SAMPLE_FMT_S16) {
00065 av_log(avctx, AV_LOG_ERROR, "Audio must be signed 16-bit\n");
00066 return -1;
00067 }
00068
00069 roq_dpcm_table_init();
00070
00071 avctx->frame_size = ROQ_FIRST_FRAME_SIZE;
00072
00073 context->lastSample[0] = context->lastSample[1] = 0;
00074
00075 avctx->coded_frame= avcodec_alloc_frame();
00076 avctx->coded_frame->key_frame= 1;
00077
00078 return 0;
00079 }
00080
00081 static unsigned char dpcm_predict(short *previous, short current)
00082 {
00083 int diff;
00084 int negative;
00085 int result;
00086 int predicted;
00087
00088 diff = current - *previous;
00089
00090 negative = diff<0;
00091 diff = FFABS(diff);
00092
00093 if (diff >= MAX_DPCM)
00094 result = 127;
00095 else
00096 result = dpcmValues[diff];
00097
00098
00099 retry:
00100 diff = result*result;
00101 if (negative)
00102 diff = -diff;
00103 predicted = *previous + diff;
00104
00105
00106 if (predicted > 32767 || predicted < -32768) {
00107 result--;
00108 goto retry;
00109 }
00110
00111
00112 result |= negative << 7;
00113
00114 *previous = predicted;
00115
00116 return result;
00117 }
00118
00119 static int roq_dpcm_encode_frame(AVCodecContext *avctx,
00120 unsigned char *frame, int buf_size, void *data)
00121 {
00122 int i, samples, stereo, ch;
00123 short *in;
00124 unsigned char *out;
00125
00126 ROQDPCMContext *context = avctx->priv_data;
00127
00128 stereo = (avctx->channels == 2);
00129
00130 if (stereo) {
00131 context->lastSample[0] &= 0xFF00;
00132 context->lastSample[1] &= 0xFF00;
00133 }
00134
00135 out = frame;
00136 in = data;
00137
00138 bytestream_put_byte(&out, stereo ? 0x21 : 0x20);
00139 bytestream_put_byte(&out, 0x10);
00140 bytestream_put_le32(&out, avctx->frame_size*avctx->channels);
00141
00142 if (stereo) {
00143 bytestream_put_byte(&out, (context->lastSample[1])>>8);
00144 bytestream_put_byte(&out, (context->lastSample[0])>>8);
00145 } else
00146 bytestream_put_le16(&out, context->lastSample[0]);
00147
00148
00149 samples = avctx->frame_size;
00150 for (i=0; i<samples; i++)
00151 for (ch=0; ch<avctx->channels; ch++)
00152 *out++ = dpcm_predict(&context->lastSample[ch], *in++);
00153
00154
00155 avctx->frame_size = ROQ_FRAME_SIZE;
00156
00157
00158 return out - frame;
00159 }
00160
00161 static av_cold int roq_dpcm_encode_close(AVCodecContext *avctx)
00162 {
00163 av_freep(&avctx->coded_frame);
00164
00165 return 0;
00166 }
00167
00168 AVCodec roq_dpcm_encoder = {
00169 "roq_dpcm",
00170 CODEC_TYPE_AUDIO,
00171 CODEC_ID_ROQ_DPCM,
00172 sizeof(ROQDPCMContext),
00173 roq_dpcm_encode_init,
00174 roq_dpcm_encode_frame,
00175 roq_dpcm_encode_close,
00176 NULL,
00177 .sample_fmts = (enum SampleFormat[]){SAMPLE_FMT_S16,SAMPLE_FMT_NONE},
00178 .long_name = NULL_IF_CONFIG_SMALL("id RoQ DPCM"),
00179 };