]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/wavpack.c
h264: fix bit depth changes with frame threading
[ffmpeg] / libavcodec / wavpack.c
index 1098873d7cefdeb531de2d0b60e97521c4e41a57..37e87686ca14c51e06fa2e4ffd1254754cc03c54 100644 (file)
 
 #define BITSTREAM_READER_LE
 
-#include "libavutil/audioconvert.h"
+#include "libavutil/channel_layout.h"
 #include "avcodec.h"
 #include "get_bits.h"
+#include "internal.h"
 #include "unary.h"
 
 /**
@@ -126,7 +127,6 @@ typedef struct WavpackFrameContext {
 
 typedef struct WavpackContext {
     AVCodecContext *avctx;
-    AVFrame frame;
 
     WavpackFrameContext *fdec[WV_MAX_FRAME_DECODERS];
     int fdec_num;
@@ -428,7 +428,7 @@ static float wv_get_value_float(WavpackFrameContext *s, uint32_t *crc, int S)
         uint32_t u;
     } value;
 
-    int sign;
+    unsigned int sign;
     int exp = s->float_max_exp;
 
     if (s->got_extra_bits) {
@@ -500,6 +500,21 @@ static void wv_reset_saved_context(WavpackFrameContext *s)
     s->sc.crc = s->extra_sc.crc = 0xFFFFFFFF;
 }
 
+static inline int wv_check_crc(WavpackFrameContext *s, uint32_t crc,
+                               uint32_t crc_extra_bits)
+{
+    if (crc != s->CRC) {
+        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
+        return AVERROR_INVALIDDATA;
+    }
+    if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
+        av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
+        return AVERROR_INVALIDDATA;
+    }
+
+    return 0;
+}
+
 static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
                                    void *dst, const int type)
 {
@@ -610,14 +625,9 @@ static inline int wv_unpack_stereo(WavpackFrameContext *s, GetBitContext *gb,
     } while (!last && count < s->samples);
 
     wv_reset_saved_context(s);
-    if (crc != s->CRC) {
-        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
-        return -1;
-    }
-    if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
-        av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
-        return -1;
-    }
+    if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
+        wv_check_crc(s, crc, crc_extra_bits))
+        return AVERROR_INVALIDDATA;
 
     return count * 2;
 }
@@ -680,14 +690,9 @@ static inline int wv_unpack_mono(WavpackFrameContext *s, GetBitContext *gb,
     } while (!last && count < s->samples);
 
     wv_reset_saved_context(s);
-    if (crc != s->CRC) {
-        av_log(s->avctx, AV_LOG_ERROR, "CRC error\n");
-        return -1;
-    }
-    if (s->got_extra_bits && crc_extra_bits != s->crc_extra_bits) {
-        av_log(s->avctx, AV_LOG_ERROR, "Extra bits CRC error\n");
-        return -1;
-    }
+    if ((s->avctx->err_recognition & AV_EF_CRCCHECK) &&
+        wv_check_crc(s, crc, crc_extra_bits))
+        return AVERROR_INVALIDDATA;
 
     return count;
 }
@@ -733,9 +738,6 @@ static av_cold int wavpack_decode_init(AVCodecContext *avctx)
 
     s->fdec_num = 0;
 
-    avcodec_get_frame_defaults(&s->frame);
-    avctx->coded_frame = &s->frame;
-
     return 0;
 }
 
@@ -808,8 +810,8 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
     s->hybrid         =   s->frame_flags & WV_HYBRID_MODE;
     s->hybrid_bitrate =   s->frame_flags & WV_HYBRID_BITRATE;
     s->post_shift     = bpp * 8 - orig_bpp + ((s->frame_flags >> 13) & 0x1f);
-    s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1) >> s->post_shift;
-    s->hybrid_minclip = ((-1LL << (orig_bpp - 1)))     >> s->post_shift;
+    s->hybrid_maxclip = (( 1LL << (orig_bpp - 1)) - 1);
+    s->hybrid_minclip = ((-1LL << (orig_bpp - 1)));
     s->CRC            = AV_RL32(buf); buf += 4;
     if (wc->mkv_mode)
         buf += 4; //skip block size;
@@ -906,8 +908,9 @@ static int wavpack_decode_block(AVCodecContext *avctx, int block_no,
                 } else {
                     for (j = 0; j < s->decorr[i].value; j++) {
                         s->decorr[i].samplesA[j] = wp_exp2(AV_RL16(buf)); buf += 2;
-                        if (s->stereo_in)
+                        if (s->stereo_in) {
                             s->decorr[i].samplesB[j] = wp_exp2(AV_RL16(buf)); buf += 2;
+                        }
                     }
                     t += s->decorr[i].value * 2 * (s->stereo_in + 1);
                 }
@@ -1165,6 +1168,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
     WavpackContext *s  = avctx->priv_data;
     const uint8_t *buf = avpkt->data;
     int buf_size       = avpkt->size;
+    AVFrame *frame     = data;
     int frame_size, ret, frame_flags;
     int samplecount = 0;
 
@@ -1196,11 +1200,12 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
         avctx->sample_fmt = AV_SAMPLE_FMT_S16;
     } else {
         avctx->sample_fmt = AV_SAMPLE_FMT_S32;
+        avctx->bits_per_raw_sample = ((frame_flags & 0x03) + 1) << 3;
     }
 
     /* get output buffer */
-    s->frame.nb_samples = s->samples;
-    if ((ret = avctx->get_buffer(avctx, &s->frame)) < 0) {
+    frame->nb_samples = s->samples;
+    if ((ret = ff_get_buffer(avctx, frame, 0)) < 0) {
         av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
         return ret;
     }
@@ -1224,7 +1229,7 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
             return -1;
         }
         if ((samplecount = wavpack_decode_block(avctx, s->block,
-                                                s->frame.data[0], got_frame_ptr,
+                                                frame->data[0], got_frame_ptr,
                                                 buf, frame_size)) < 0) {
             wavpack_decode_flush(avctx);
             return -1;
@@ -1233,16 +1238,13 @@ static int wavpack_decode_frame(AVCodecContext *avctx, void *data,
         buf += frame_size; buf_size -= frame_size;
     }
 
-    if (*got_frame_ptr)
-        *(AVFrame *)data = s->frame;
-
     return avpkt->size;
 }
 
 AVCodec ff_wavpack_decoder = {
     .name           = "wavpack",
     .type           = AVMEDIA_TYPE_AUDIO,
-    .id             = CODEC_ID_WAVPACK,
+    .id             = AV_CODEC_ID_WAVPACK,
     .priv_data_size = sizeof(WavpackContext),
     .init           = wavpack_decode_init,
     .close          = wavpack_decode_end,