Merge commit '8191f960a669819db4de33a2439ded1630b8a73e'
authorClément Bœsch <u@pkh.me>
Wed, 29 Mar 2017 12:22:32 +0000 (14:22 +0200)
committerClément Bœsch <u@pkh.me>
Wed, 29 Mar 2017 12:22:32 +0000 (14:22 +0200)
* commit '8191f960a669819db4de33a2439ded1630b8a73e':
  examples/decode_video: constify the AVCodec instance

Merged-by: Clément Bœsch <u@pkh.me>
1  2 
doc/examples/decode_video.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 "libavcodec/avcodec.h"
 -
 -#include "libavutil/common.h"
 -#include "libavutil/imgutils.h"
 -#include "libavutil/mathematics.h"
 +#include <libavcodec/avcodec.h>
  
  #define INBUF_SIZE 4096
  
@@@ -41,50 -43,23 +41,50 @@@ static void pgm_save(unsigned char *buf
      FILE *f;
      int i;
  
 -    f=fopen(filename,"w");
 -    fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
 -    for(i=0;i<ysize;i++)
 -        fwrite(buf + i * wrap,1,xsize,f);
 +    f = fopen(filename,"w");
 +    fprintf(f, "P5\n%d %d\n%d\n", xsize, ysize, 255);
 +    for (i = 0; i < ysize; i++)
 +        fwrite(buf + i * wrap, 1, xsize, f);
      fclose(f);
  }
  
 +static int decode_write_frame(const char *outfilename, AVCodecContext *avctx,
 +                              AVFrame *frame, int *frame_count, AVPacket *pkt, int last)
 +{
 +    int len, got_frame;
 +    char buf[1024];
 +
 +    len = avcodec_decode_video2(avctx, frame, &got_frame, pkt);
 +    if (len < 0) {
 +        fprintf(stderr, "Error while decoding frame %d\n", *frame_count);
 +        return len;
 +    }
 +    if (got_frame) {
 +        printf("Saving %sframe %3d\n", last ? "last " : "", *frame_count);
 +        fflush(stdout);
 +
 +        /* the picture is allocated by the decoder, no need to free it */
 +        snprintf(buf, sizeof(buf), outfilename, *frame_count);
 +        pgm_save(frame->data[0], frame->linesize[0],
 +                 frame->width, frame->height, buf);
 +        (*frame_count)++;
 +    }
 +    if (pkt->data) {
 +        pkt->size -= len;
 +        pkt->data += len;
 +    }
 +    return 0;
 +}
 +
  int main(int argc, char **argv)
  {
      const char *filename, *outfilename;
-     AVCodec *codec;
+     const AVCodec *codec;
      AVCodecContext *c= NULL;
 -    int frame, got_picture, len;
 +    int frame_count;
      FILE *f;
 -    AVFrame *picture;
 +    AVFrame *frame;
      uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
 -    char buf[1024];
      AVPacket avpkt;
  
      if (argc <= 2) {
      /* find the MPEG-1 video decoder */
      codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
      if (!codec) {
 -        fprintf(stderr, "codec not found\n");
 +        fprintf(stderr, "Codec not found\n");
          exit(1);
      }
  
      c = avcodec_alloc_context3(codec);
 -    picture = av_frame_alloc();
 +    if (!c) {
 +        fprintf(stderr, "Could not allocate video codec context\n");
 +        exit(1);
 +    }
  
      if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
          c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
  
      /* 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);
      }
  
 -    /* the codec gives us the frame size, in samples */
 -
      f = fopen(filename, "rb");
      if (!f) {
 -        fprintf(stderr, "could not open %s\n", filename);
 +        fprintf(stderr, "Could not open %s\n", filename);
          exit(1);
      }
  
 -    frame = 0;
 -    for(;;) {
 +    frame = av_frame_alloc();
 +    if (!frame) {
 +        fprintf(stderr, "Could not allocate video frame\n");
 +        exit(1);
 +    }
 +
 +    frame_count = 0;
 +    for (;;) {
          avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
          if (avpkt.size == 0)
              break;
          /* here, we use a stream based decoder (mpeg1video), so we
             feed decoder and see if it could decode a frame */
          avpkt.data = inbuf;
 -        while (avpkt.size > 0) {
 -            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
 -            if (len < 0) {
 -                fprintf(stderr, "Error while decoding frame %d\n", frame);
 +        while (avpkt.size > 0)
 +            if (decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 0) < 0)
                  exit(1);
 -            }
 -            if (got_picture) {
 -                printf("saving frame %3d\n", frame);
 -                fflush(stdout);
 -
 -                /* the picture is allocated by the decoder. no need to
 -                   free it */
 -                snprintf(buf, sizeof(buf), outfilename, frame);
 -                pgm_save(picture->data[0], picture->linesize[0],
 -                         c->width, c->height, buf);
 -                frame++;
 -            }
 -            avpkt.size -= len;
 -            avpkt.data += len;
 -        }
      }
  
      /* Some codecs, such as MPEG, transmit the I- and P-frame with a
         chance to get the last frame of the video. */
      avpkt.data = NULL;
      avpkt.size = 0;
 -    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
 -    if (got_picture) {
 -        printf("saving last frame %3d\n", frame);
 -        fflush(stdout);
 -
 -        /* the picture is allocated by the decoder. no need to
 -           free it */
 -        snprintf(buf, sizeof(buf), outfilename, frame);
 -        pgm_save(picture->data[0], picture->linesize[0],
 -                 c->width, c->height, buf);
 -        frame++;
 -    }
 +    decode_write_frame(outfilename, c, frame, &frame_count, &avpkt, 1);
  
      fclose(f);
  
      avcodec_free_context(&c);
 -    av_frame_free(&picture);
 +    av_frame_free(&frame);
  
      return 0;
  }