]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/mpc7.c
Merge remote-tracking branch 'shariman/wmall'
[ffmpeg] / libavcodec / mpc7.c
index 3418b7b4f8931cfed4e02b7a40c8975ec87f83b8..739325097142b78d6c91e6be954575f92de86e07 100644 (file)
@@ -61,6 +61,13 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
     static VLC_TYPE hdr_table[1 << MPC7_HDR_BITS][2];
     static VLC_TYPE quant_tables[7224][2];
 
+    /* Musepack SV7 is always stereo */
+    if (avctx->channels != 2) {
+        av_log_ask_for_sample(avctx, "Unsupported number of channels: %d\n",
+                              avctx->channels);
+        return AVERROR_PATCHWELCOME;
+    }
+
     if(avctx->extradata_size < 16){
         av_log(avctx, AV_LOG_ERROR, "Too small extradata size (%i)!\n", avctx->extradata_size);
         return -1;
@@ -88,7 +95,7 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
     c->frames_to_skip = 0;
 
     avctx->sample_fmt = AV_SAMPLE_FMT_S16;
-    avctx->channel_layout = (avctx->channels==2) ? AV_CH_LAYOUT_STEREO : AV_CH_LAYOUT_MONO;
+    avctx->channel_layout = AV_CH_LAYOUT_STEREO;
 
     if(vlc_initialized) return 0;
     av_log(avctx, AV_LOG_DEBUG, "Initing VLC\n");
@@ -129,6 +136,10 @@ static av_cold int mpc7_decode_init(AVCodecContext * avctx)
         }
     }
     vlc_initialized = 1;
+
+    avcodec_get_frame_defaults(&c->frame);
+    avctx->coded_frame = &c->frame;
+
     return 0;
 }
 
@@ -185,9 +196,8 @@ static int get_scale_idx(GetBitContext *gb, int ref)
     return ref + t;
 }
 
-static int mpc7_decode_frame(AVCodecContext * avctx,
-                            void *data, int *data_size,
-                            AVPacket *avpkt)
+static int mpc7_decode_frame(AVCodecContext * avctx, void *data,
+                             int *got_frame_ptr, AVPacket *avpkt)
 {
     const uint8_t *buf = avpkt->data;
     int buf_size = avpkt->size;
@@ -197,7 +207,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
     int i, ch;
     int mb = -1;
     Band *bands = c->bands;
-    int off, out_size;
+    int off, ret;
     int bits_used, bits_avail;
 
     memset(bands, 0, sizeof(*bands) * (c->maxbands + 1));
@@ -206,10 +216,11 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
         return AVERROR(EINVAL);
     }
 
-    out_size = (buf[1] ? c->lastframelen : MPC_FRAME_SIZE) * 4;
-    if (*data_size < out_size) {
-        av_log(avctx, AV_LOG_ERROR, "Output buffer is too small\n");
-        return AVERROR(EINVAL);
+    /* get output buffer */
+    c->frame.nb_samples = buf[1] ? c->lastframelen : MPC_FRAME_SIZE;
+    if ((ret = avctx->get_buffer(avctx, &c->frame)) < 0) {
+        av_log(avctx, AV_LOG_ERROR, "get_buffer() failed\n");
+        return ret;
     }
 
     bits = av_malloc(((buf_size - 1) & ~3) + FF_INPUT_BUFFER_PADDING_SIZE);
@@ -269,7 +280,7 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
         for(ch = 0; ch < 2; ch++)
             idx_to_quant(c, &gb, bands[i].res[ch], c->Q[ch] + off);
 
-    ff_mpc_dequantize_and_synth(c, mb, data, 2);
+    ff_mpc_dequantize_and_synth(c, mb, c->frame.data[0], 2);
 
     av_free(bits);
 
@@ -281,10 +292,12 @@ static int mpc7_decode_frame(AVCodecContext * avctx,
     }
     if(c->frames_to_skip){
         c->frames_to_skip--;
-        *data_size = 0;
+        *got_frame_ptr = 0;
         return buf_size;
     }
-    *data_size = out_size;
+
+    *got_frame_ptr   = 1;
+    *(AVFrame *)data = c->frame;
 
     return buf_size;
 }
@@ -305,5 +318,6 @@ AVCodec ff_mpc7_decoder = {
     .init           = mpc7_decode_init,
     .decode         = mpc7_decode_frame,
     .flush = mpc7_decode_flush,
+    .capabilities   = CODEC_CAP_DR1,
     .long_name = NULL_IF_CONFIG_SMALL("Musepack SV7"),
 };