Merge commit 'f76698e759a08e8d3b629c06edb0439f474e7fee'
authorClément Bœsch <u@pkh.me>
Wed, 29 Mar 2017 11:31:44 +0000 (13:31 +0200)
committerClément Bœsch <u@pkh.me>
Wed, 29 Mar 2017 11:31:44 +0000 (13:31 +0200)
* commit 'f76698e759a08e8d3b629c06edb0439f474e7fee':
  examples/encode_audio: use the AVFrame API for allocating the data

Merged-by: Clément Bœsch <u@pkh.me>
1  2 
doc/examples/encode_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.
   */
  
  /**
@@@ -99,7 -97,6 +99,6 @@@ int main(int argc, char **argv
      AVFrame *frame;
      AVPacket pkt;
      int i, j, k, ret, got_output;
-     int buffer_size;
      FILE *f;
      uint16_t *samples;
      float t, tincr;
      /* find the MP2 encoder */
      codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
      if (!codec) {
 -        fprintf(stderr, "codec not found\n");
 +        fprintf(stderr, "Codec not found\n");
          exit(1);
      }
  
      c = avcodec_alloc_context3(codec);
 +    if (!c) {
 +        fprintf(stderr, "Could not allocate audio codec context\n");
 +        exit(1);
 +    }
  
      /* put sample parameters */
      c->bit_rate = 64000;
      /* check that the encoder supports s16 pcm input */
      c->sample_fmt = AV_SAMPLE_FMT_S16;
      if (!check_sample_fmt(codec, c->sample_fmt)) {
 -        fprintf(stderr, "encoder does not support %s",
 +        fprintf(stderr, "Encoder does not support sample format %s",
                  av_get_sample_fmt_name(c->sample_fmt));
          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, "wb");
      if (!f) {
 -        fprintf(stderr, "could not open %s\n", filename);
 +        fprintf(stderr, "Could not open %s\n", filename);
          exit(1);
      }
  
      /* frame containing input raw audio */
      frame = av_frame_alloc();
      if (!frame) {
 -        fprintf(stderr, "could not allocate audio frame\n");
 +        fprintf(stderr, "Could not allocate audio frame\n");
          exit(1);
      }
  
      frame->format         = c->sample_fmt;
      frame->channel_layout = c->channel_layout;
  
-     /* the codec gives us the frame size, in samples,
-      * we calculate the size of the samples buffer in bytes */
-     buffer_size = av_samples_get_buffer_size(NULL, c->channels, c->frame_size,
-                                              c->sample_fmt, 0);
-     if (buffer_size < 0) {
-         fprintf(stderr, "Could not get sample buffer size\n");
-         exit(1);
-     }
-     samples = av_malloc(buffer_size);
-     if (!samples) {
-         fprintf(stderr, "Could not allocate %d bytes for samples buffer\n",
-                 buffer_size);
-         exit(1);
-     }
-     /* setup the data pointers in the AVFrame */
-     ret = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
-                                    (const uint8_t*)samples, buffer_size, 0);
+     /* allocate the data buffers */
+     ret = av_frame_get_buffer(frame, 0);
      if (ret < 0) {
-         fprintf(stderr, "Could not setup audio frame\n");
 -        fprintf(stderr, "could not allocate audio data buffers\n");
++        fprintf(stderr, "Could not allocate audio data buffers\n");
          exit(1);
      }
  
      /* encode a single tone sound */
      t = 0;
      tincr = 2 * M_PI * 440.0 / c->sample_rate;
 -    for(i=0;i<200;i++) {
 +    for (i = 0; i < 200; i++) {
          av_init_packet(&pkt);
          pkt.data = NULL; // packet data will be allocated by the encoder
          pkt.size = 0;
  
+         /* make sure the frame is writable -- makes a copy if the encoder
+          * kept a reference internally */
+         ret = av_frame_make_writable(frame);
+         if (ret < 0)
+             exit(1);
+         samples = (uint16_t*)frame->data[0];
          for (j = 0; j < c->frame_size; j++) {
              samples[2*j] = (int)(sin(t) * 10000);
  
          /* encode the samples */
          ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
          if (ret < 0) {
 -            fprintf(stderr, "error encoding audio frame\n");
 +            fprintf(stderr, "Error encoding audio frame\n");
              exit(1);
          }
          if (got_output) {
              av_packet_unref(&pkt);
          }
      }
 +
 +    /* get the delayed frames */
 +    for (got_output = 1; got_output; i++) {
 +        ret = avcodec_encode_audio2(c, &pkt, NULL, &got_output);
 +        if (ret < 0) {
 +            fprintf(stderr, "Error encoding frame\n");
 +            exit(1);
 +        }
 +
 +        if (got_output) {
 +            fwrite(pkt.data, 1, pkt.size, f);
 +            av_packet_unref(&pkt);
 +        }
 +    }
      fclose(f);
  
-     av_freep(&samples);
      av_frame_free(&frame);
      avcodec_free_context(&c);
  }