* Assorted DPCM codecs
* Copyright (c) 2003 The ffmpeg Project
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * FFmpeg is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
- * Libav is distributed in the hope that it will be useful,
+ * FFmpeg is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include "bytestream.h"
typedef struct DPCMContext {
+ AVFrame frame;
int channels;
int16_t roq_square_array[256];
int sample[2]; ///< previous sample (for SOL_DPCM)
else
avctx->sample_fmt = AV_SAMPLE_FMT_S16;
+ avcodec_get_frame_defaults(&s->frame);
+ avctx->coded_frame = &s->frame;
+
return 0;
}
-static int dpcm_decode_frame(AVCodecContext *avctx, void *data, int *data_size,
- AVPacket *avpkt)
+static int dpcm_decode_frame(AVCodecContext *avctx, void *data,
+ int *got_frame_ptr, AVPacket *avpkt)
{
const uint8_t *buf = avpkt->data;
int buf_size = avpkt->size;
const uint8_t *buf_end = buf + buf_size;
DPCMContext *s = avctx->priv_data;
- int out = 0;
+ int out = 0, ret;
int predictor[2];
int ch = 0;
int stereo = s->channels - 1;
- int16_t *output_samples = data;
+ int16_t *output_samples;
/* calculate output size */
switch(avctx->codec->id) {
out = buf_size;
break;
}
- out *= av_get_bytes_per_sample(avctx->sample_fmt);
- if (out < 0) {
+ if (out <= 0) {
av_log(avctx, AV_LOG_ERROR, "packet is too small\n");
return AVERROR(EINVAL);
}
- if (*data_size < out) {
- av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
- return AVERROR(EINVAL);
+ if (out % s->channels) {
+ av_log(avctx, AV_LOG_WARNING, "channels have differing number of samples\n");
}
+ /* get output buffer */
+ s->frame.nb_samples = (out + s->channels - 1) / s->channels;
+ if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+ av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+ return ret;
+ }
+ output_samples = (int16_t *)s->frame.data[0];
+
switch(avctx->codec->id) {
case CODEC_ID_ROQ_DPCM:
}
case CODEC_ID_SOL_DPCM:
if (avctx->codec_tag != 3) {
- uint8_t *output_samples_u8 = data;
+ uint8_t *output_samples_u8 = s->frame.data[0];
while (buf < buf_end) {
uint8_t n = *buf++;
break;
}
- *data_size = out;
+ *got_frame_ptr = 1;
+ *(AVFrame *)data = s->frame;
+
return buf_size;
}
.priv_data_size = sizeof(DPCMContext), \
.init = dpcm_decode_init, \
.decode = dpcm_decode_frame, \
+ .capabilities = CODEC_CAP_DR1, \
.long_name = NULL_IF_CONFIG_SMALL(long_name_), \
}