]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/adxenc.c
Merge remote-tracking branch 'qatar/master'
[ffmpeg] / libavcodec / adxenc.c
index bc6b0f15f02962f24ca04bbc7023a8b14aa72d0a..c6e46565f6caec0eabb5f3a638f9d3d219e7b66e 100644 (file)
@@ -2,26 +2,26 @@
  * ADX ADPCM codecs
  * Copyright (c) 2001,2003 BERO
  *
- * 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 "libavutil/intreadwrite.h"
 #include "avcodec.h"
 #include "adx.h"
+#include "bytestream.h"
 #include "put_bits.h"
 
 /**
@@ -81,20 +81,32 @@ static void adx_encode(ADXContext *c, uint8_t *adx, const int16_t *wav,
     flush_put_bits(&pb);
 }
 
+#define HEADER_SIZE 36
+
 static int adx_encode_header(AVCodecContext *avctx, uint8_t *buf, int bufsize)
 {
     ADXContext *c = avctx->priv_data;
 
-    AV_WB32(buf + 0x00, 0x80000000 | 0x20);
-    AV_WB32(buf + 0x04, 0x03120400 | avctx->channels);
-    AV_WB32(buf + 0x08, avctx->sample_rate);
-    AV_WB32(buf + 0x0c, 0);
-    AV_WB16(buf + 0x10, c->cutoff);
-    AV_WB32(buf + 0x12, 0x03000000);
-    AV_WB32(buf + 0x16, 0x00000000);
-    AV_WB32(buf + 0x1a, 0x00000000);
-    memcpy (buf + 0x1e, "(c)CRI", 6);
-    return 0x20 + 4;
+    if (bufsize < HEADER_SIZE)
+        return AVERROR(EINVAL);
+
+    bytestream_put_be16(&buf, 0x8000);              /* header signature */
+    bytestream_put_be16(&buf, HEADER_SIZE - 4);     /* copyright offset */
+    bytestream_put_byte(&buf, 3);                   /* encoding */
+    bytestream_put_byte(&buf, BLOCK_SIZE);          /* block size */
+    bytestream_put_byte(&buf, 4);                   /* sample size */
+    bytestream_put_byte(&buf, avctx->channels);     /* channels */
+    bytestream_put_be32(&buf, avctx->sample_rate);  /* sample rate */
+    bytestream_put_be32(&buf, 0);                   /* total sample count */
+    bytestream_put_be16(&buf, c->cutoff);           /* cutoff frequency */
+    bytestream_put_byte(&buf, 3);                   /* version */
+    bytestream_put_byte(&buf, 0);                   /* flags */
+    bytestream_put_be32(&buf, 0);                   /* unknown */
+    bytestream_put_be32(&buf, 0);                   /* loop enabled */
+    bytestream_put_be16(&buf, 0);                   /* padding */
+    bytestream_put_buffer(&buf, "(c)CRI", 6);       /* copyright signature */
+
+    return HEADER_SIZE;
 }
 
 static av_cold int adx_encode_init(AVCodecContext *avctx)
@@ -108,6 +120,8 @@ static av_cold int adx_encode_init(AVCodecContext *avctx)
     avctx->frame_size = BLOCK_SAMPLES;
 
     avctx->coded_frame = avcodec_alloc_frame();
+    if (!avctx->coded_frame)
+        return AVERROR(ENOMEM);
 
     /* the cutoff can be adjusted, but this seems to work pretty well */
     c->cutoff = 500;
@@ -131,10 +145,19 @@ static int adx_encode_frame(AVCodecContext *avctx, uint8_t *frame,
     int ch;
 
     if (!c->header_parsed) {
-        int hdrsize = adx_encode_header(avctx, dst, buf_size);
-        dst += hdrsize;
+        int hdrsize;
+        if ((hdrsize = adx_encode_header(avctx, dst, buf_size)) < 0) {
+            av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
+            return AVERROR(EINVAL);
+        }
+        dst      += hdrsize;
+        buf_size -= hdrsize;
         c->header_parsed = 1;
     }
+    if (buf_size < BLOCK_SIZE * avctx->channels) {
+        av_log(avctx, AV_LOG_ERROR, "output buffer is too small\n");
+        return AVERROR(EINVAL);
+    }
 
     for (ch = 0; ch < avctx->channels; ch++) {
         adx_encode(c, dst, samples + ch, &c->prev[ch], avctx->channels);