Merge commit 'fee0f1de2c6a9924acb74013436dbea8f2bd1ecb'
authorClément Bœsch <cboesch@gopro.com>
Tue, 4 Apr 2017 09:40:34 +0000 (11:40 +0200)
committerClément Bœsch <cboesch@gopro.com>
Tue, 4 Apr 2017 09:40:34 +0000 (11:40 +0200)
* commit 'fee0f1de2c6a9924acb74013436dbea8f2bd1ecb':
  examples/decode_audio: flush the decoder

Merged-by: Clément Bœsch <cboesch@gopro.com>
1  2 
doc/examples/decode_audio.c

@@@ -1,23 -1,21 +1,23 @@@
  /*
 - * copyright (c) 2001 Fabrice Bellard
 + * Copyright (c) 2001 Fabrice Bellard
   *
 - * This file is part of Libav.
 + * Permission is hereby granted, free of charge, to any person obtaining a copy
 + * of this software and associated documentation files (the "Software"), to deal
 + * in the Software without restriction, including without limitation the rights
 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 + * copies of the Software, and to permit persons to whom the Software is
 + * furnished to do so, subject to the following conditions:
   *
 - * Libav 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.
 + * The above copyright notice and this permission notice shall be included in
 + * all copies or substantial portions of the Software.
   *
 - * Libav 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
 - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 + * THE SOFTWARE.
   */
  
  /**
  #include <stdlib.h>
  #include <string.h>
  
 -#include "libavutil/channel_layout.h"
 -#include "libavutil/frame.h"
 -#include "libavutil/mem.h"
 +#include <libavutil/frame.h>
 +#include <libavutil/mem.h>
  
 -#include "libavcodec/avcodec.h"
 +#include <libavcodec/avcodec.h>
  
  #define AUDIO_INBUF_SIZE 20480
  #define AUDIO_REFILL_THRESH 4096
@@@ -42,8 -41,8 +42,8 @@@
  static void decode(AVCodecContext *dec_ctx, AVPacket *pkt, AVFrame *frame,
                     FILE *outfile)
  {
 -    int16_t *interleave_buf;
 -    int ret, data_size, i;
 +    int i, ch;
 +    int ret, data_size;
  
      /* send the packet with the compressed data to the decoder */
      ret = avcodec_send_packet(dec_ctx, pkt);
              fprintf(stderr, "Error during decoding\n");
              exit(1);
          }
 -
 -        /* the stream parameters may change at any time, check that they are
 -         * what we expect */
 -        if (av_get_channel_layout_nb_channels(frame->channel_layout) != 2 ||
 -            frame->format != AV_SAMPLE_FMT_S16P) {
 -            fprintf(stderr, "Unsupported frame parameters\n");
 -            exit(1);
 -        }
 -
 -        /* The decoded data is signed 16-bit planar -- each channel in its own
 -         * buffer. We interleave the two channels manually here, but using
 -         * libavresample is recommended instead. */
 -        data_size = sizeof(*interleave_buf) * 2 * frame->nb_samples;
 -        interleave_buf = av_malloc(data_size);
 -        if (!interleave_buf)
 +        data_size = av_get_bytes_per_sample(dec_ctx->sample_fmt);
 +        if (data_size < 0) {
 +            /* This should not occur, checking just for paranoia */
 +            fprintf(stderr, "Failed to calculate data size\n");
              exit(1);
 -
 -        for (i = 0; i < frame->nb_samples; i++) {
 -            interleave_buf[2 * i]     = ((int16_t*)frame->data[0])[i];
 -            interleave_buf[2 * i + 1] = ((int16_t*)frame->data[1])[i];
          }
 -        fwrite(interleave_buf, 1, data_size, outfile);
 -        av_freep(&interleave_buf);
 +        for (i = 0; i < frame->nb_samples; i++)
 +            for (ch = 0; ch < dec_ctx->channels; ch++)
 +                fwrite(frame->data[ch] + data_size*i, 1, data_size, outfile);
      }
  }
  
@@@ -102,31 -115,27 +102,31 @@@ int main(int argc, char **argv
      /* find the MPEG audio decoder */
      codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
      if (!codec) {
 -        fprintf(stderr, "codec not found\n");
 +        fprintf(stderr, "Codec not found\n");
          exit(1);
      }
  
      parser = av_parser_init(codec->id);
      if (!parser) {
 -        fprintf(stderr, "parser not found\n");
 +        fprintf(stderr, "Parser not found\n");
          exit(1);
      }
  
      c = avcodec_alloc_context3(codec);
 +    if (!c) {
 +        fprintf(stderr, "Could not allocate audio codec context\n");
 +        exit(1);
 +    }
  
      /* open it */
      if (avcodec_open2(c, codec, NULL) < 0) {
 -        fprintf(stderr, "could not open codec\n");
 +        fprintf(stderr, "Could not open codec\n");
          exit(1);
      }
  
      f = fopen(filename, "rb");
      if (!f) {
 -        fprintf(stderr, "could not open %s\n", filename);
 +        fprintf(stderr, "Could not open %s\n", filename);
          exit(1);
      }
      outfile = fopen(outfilename, "wb");
      while (data_size > 0) {
          if (!decoded_frame) {
              if (!(decoded_frame = av_frame_alloc())) {
 -                fprintf(stderr, "out of memory\n");
 +                fprintf(stderr, "Could not allocate audio frame\n");
                  exit(1);
              }
          }
          }
      }
  
+     /* flush the decoder */
+     pkt->data = NULL;
+     pkt->size = 0;
+     decode(c, pkt, decoded_frame, outfile);
      fclose(outfile);
      fclose(f);