api-example.c 16.5 KB
Newer Older
1 2 3
/*
 * copyright (c) 2001 Fabrice Bellard
 *
4
 * This file is part of Libav.
5
 *
6
 * Libav is free software; you can redistribute it and/or
7 8
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
9
 * version 2.1 of the License, or (at your option) any later version.
10
 *
11
 * Libav is distributed in the hope that it will be useful,
12 13 14 15 16
 * 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
17
 * License along with Libav; if not, write to the Free Software
18 19 20
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
 */

Michael Niedermayer's avatar
Michael Niedermayer committed
21
/**
22
 * @file
23
 * libavcodec API use example.
Fabrice Bellard's avatar
Fabrice Bellard committed
24
 *
25
 * @example libavcodec/api-example.c
Fabrice Bellard's avatar
Fabrice Bellard committed
26
 * Note that this library only handles codecs (mpeg, mpeg4, etc...),
Fabrice Bellard's avatar
Fabrice Bellard committed
27
 * not file formats (avi, vob, etc...). See library 'libavformat' for the
28
 * format handling
Fabrice Bellard's avatar
Fabrice Bellard committed
29
 */
Michael Niedermayer's avatar
Michael Niedermayer committed
30

Fabrice Bellard's avatar
Fabrice Bellard committed
31 32 33
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
34

35 36 37 38
#ifdef HAVE_AV_CONFIG_H
#undef HAVE_AV_CONFIG_H
#endif

39
#include "libavcodec/avcodec.h"
40
#include "libavutil/channel_layout.h"
41
#include "libavutil/common.h"
42
#include "libavutil/imgutils.h"
43
#include "libavutil/mathematics.h"
44
#include "libavutil/samplefmt.h"
Fabrice Bellard's avatar
Fabrice Bellard committed
45 46

#define INBUF_SIZE 4096
47 48
#define AUDIO_INBUF_SIZE 20480
#define AUDIO_REFILL_THRESH 4096
Fabrice Bellard's avatar
Fabrice Bellard committed
49

50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84
/* check that a given sample format is supported by the encoder */
static int check_sample_fmt(AVCodec *codec, enum AVSampleFormat sample_fmt)
{
    const enum AVSampleFormat *p = codec->sample_fmts;

    while (*p != AV_SAMPLE_FMT_NONE) {
        if (*p == sample_fmt)
            return 1;
        p++;
    }
    return 0;
}

/* just pick the highest supported samplerate */
static int select_sample_rate(AVCodec *codec)
{
    const int *p;
    int best_samplerate = 0;

    if (!codec->supported_samplerates)
        return 44100;

    p = codec->supported_samplerates;
    while (*p) {
        best_samplerate = FFMAX(*p, best_samplerate);
        p++;
    }
    return best_samplerate;
}

/* select layout with the highest channel count */
static int select_channel_layout(AVCodec *codec)
{
    const uint64_t *p;
    uint64_t best_ch_layout = 0;
85
    int best_nb_channels   = 0;
86 87 88 89 90 91 92 93

    if (!codec->channel_layouts)
        return AV_CH_LAYOUT_STEREO;

    p = codec->channel_layouts;
    while (*p) {
        int nb_channels = av_get_channel_layout_nb_channels(*p);

94
        if (nb_channels > best_nb_channels) {
95
            best_ch_layout    = *p;
96
            best_nb_channels = nb_channels;
97 98 99 100 101 102
        }
        p++;
    }
    return best_ch_layout;
}

Fabrice Bellard's avatar
Fabrice Bellard committed
103
/*
104
 * Audio encoding example
Fabrice Bellard's avatar
Fabrice Bellard committed
105
 */
106
static void audio_encode_example(const char *filename)
Fabrice Bellard's avatar
Fabrice Bellard committed
107 108
{
    AVCodec *codec;
Michael Niedermayer's avatar
Michael Niedermayer committed
109
    AVCodecContext *c= NULL;
110 111 112 113
    AVFrame *frame;
    AVPacket pkt;
    int i, j, k, ret, got_output;
    int buffer_size;
Fabrice Bellard's avatar
Fabrice Bellard committed
114
    FILE *f;
115
    uint16_t *samples;
Fabrice Bellard's avatar
Fabrice Bellard committed
116 117 118 119 120
    float t, tincr;

    printf("Audio encoding\n");

    /* find the MP2 encoder */
121
    codec = avcodec_find_encoder(AV_CODEC_ID_MP2);
Fabrice Bellard's avatar
Fabrice Bellard committed
122 123 124 125 126
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

127
    c = avcodec_alloc_context3(codec);
128

Fabrice Bellard's avatar
Fabrice Bellard committed
129 130
    /* put sample parameters */
    c->bit_rate = 64000;
131 132 133 134 135 136 137 138 139 140 141 142 143

    /* 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",
                av_get_sample_fmt_name(c->sample_fmt));
        exit(1);
    }

    /* select other audio parameters supported by the encoder */
    c->sample_rate    = select_sample_rate(codec);
    c->channel_layout = select_channel_layout(codec);
    c->channels       = av_get_channel_layout_nb_channels(c->channel_layout);
Fabrice Bellard's avatar
Fabrice Bellard committed
144 145

    /* open it */
146
    if (avcodec_open2(c, codec, NULL) < 0) {
Fabrice Bellard's avatar
Fabrice Bellard committed
147 148 149
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }
150

151
    f = fopen(filename, "wb");
Fabrice Bellard's avatar
Fabrice Bellard committed
152 153 154 155
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }
156

157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185
    /* frame containing input raw audio */
    frame = avcodec_alloc_frame();
    if (!frame) {
        fprintf(stderr, "could not allocate audio frame\n");
        exit(1);
    }

    frame->nb_samples     = c->frame_size;
    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);
    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);
    if (ret < 0) {
        fprintf(stderr, "could not setup audio frame\n");
        exit(1);
    }

Fabrice Bellard's avatar
Fabrice Bellard committed
186 187
    /* encode a single tone sound */
    t = 0;
188
    tincr = 2 * M_PI * 440.0 / c->sample_rate;
Fabrice Bellard's avatar
Fabrice Bellard committed
189
    for(i=0;i<200;i++) {
190 191 192 193 194
        av_init_packet(&pkt);
        pkt.data = NULL; // packet data will be allocated by the encoder
        pkt.size = 0;

        for (j = 0; j < c->frame_size; j++) {
Fabrice Bellard's avatar
Fabrice Bellard committed
195
            samples[2*j] = (int)(sin(t) * 10000);
196 197 198

            for (k = 1; k < c->channels; k++)
                samples[2*j + k] = samples[2*j];
Fabrice Bellard's avatar
Fabrice Bellard committed
199 200 201
            t += tincr;
        }
        /* encode the samples */
202 203 204 205 206 207 208 209 210
        ret = avcodec_encode_audio2(c, &pkt, frame, &got_output);
        if (ret < 0) {
            fprintf(stderr, "error encoding audio frame\n");
            exit(1);
        }
        if (got_output) {
            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
211 212 213
    }
    fclose(f);

214
    av_freep(&samples);
215
    avcodec_free_frame(&frame);
Fabrice Bellard's avatar
Fabrice Bellard committed
216
    avcodec_close(c);
217
    av_free(c);
Fabrice Bellard's avatar
Fabrice Bellard committed
218 219 220
}

/*
221
 * Audio decoding.
Fabrice Bellard's avatar
Fabrice Bellard committed
222
 */
223
static void audio_decode_example(const char *outfilename, const char *filename)
Fabrice Bellard's avatar
Fabrice Bellard committed
224 225
{
    AVCodec *codec;
Michael Niedermayer's avatar
Michael Niedermayer committed
226
    AVCodecContext *c= NULL;
227
    int len;
Fabrice Bellard's avatar
Fabrice Bellard committed
228
    FILE *f, *outfile;
229
    uint8_t inbuf[AUDIO_INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
230
    AVPacket avpkt;
231
    AVFrame *decoded_frame = NULL;
232 233

    av_init_packet(&avpkt);
Fabrice Bellard's avatar
Fabrice Bellard committed
234 235

    printf("Audio decoding\n");
236

Fabrice Bellard's avatar
Fabrice Bellard committed
237
    /* find the mpeg audio decoder */
238
    codec = avcodec_find_decoder(AV_CODEC_ID_MP2);
Fabrice Bellard's avatar
Fabrice Bellard committed
239 240 241 242 243
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

244
    c = avcodec_alloc_context3(codec);
Fabrice Bellard's avatar
Fabrice Bellard committed
245 246

    /* open it */
247
    if (avcodec_open2(c, codec, NULL) < 0) {
Fabrice Bellard's avatar
Fabrice Bellard committed
248 249 250
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }
251

252
    f = fopen(filename, "rb");
Fabrice Bellard's avatar
Fabrice Bellard committed
253 254 255 256
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }
257
    outfile = fopen(outfilename, "wb");
Fabrice Bellard's avatar
Fabrice Bellard committed
258
    if (!outfile) {
259
        av_free(c);
Fabrice Bellard's avatar
Fabrice Bellard committed
260 261
        exit(1);
    }
262

Fabrice Bellard's avatar
Fabrice Bellard committed
263
    /* decode until eof */
264
    avpkt.data = inbuf;
265 266 267
    avpkt.size = fread(inbuf, 1, AUDIO_INBUF_SIZE, f);

    while (avpkt.size > 0) {
268 269 270 271 272 273 274 275 276 277 278
        int got_frame = 0;

        if (!decoded_frame) {
            if (!(decoded_frame = avcodec_alloc_frame())) {
                fprintf(stderr, "out of memory\n");
                exit(1);
            }
        } else
            avcodec_get_frame_defaults(decoded_frame);

        len = avcodec_decode_audio4(c, decoded_frame, &got_frame, &avpkt);
279 280 281
        if (len < 0) {
            fprintf(stderr, "Error while decoding\n");
            exit(1);
Fabrice Bellard's avatar
Fabrice Bellard committed
282
        }
283
        if (got_frame) {
284
            /* if a frame has been decoded, output it */
285 286 287 288
            int data_size = av_samples_get_buffer_size(NULL, c->channels,
                                                       decoded_frame->nb_samples,
                                                       c->sample_fmt, 1);
            fwrite(decoded_frame->data[0], 1, data_size, outfile);
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304
        }
        avpkt.size -= len;
        avpkt.data += len;
        if (avpkt.size < AUDIO_REFILL_THRESH) {
            /* Refill the input buffer, to avoid trying to decode
             * incomplete frames. Instead of this, one could also use
             * a parser, or use a proper container format through
             * libavformat. */
            memmove(inbuf, avpkt.data, avpkt.size);
            avpkt.data = inbuf;
            len = fread(avpkt.data + avpkt.size, 1,
                        AUDIO_INBUF_SIZE - avpkt.size, f);
            if (len > 0)
                avpkt.size += len;
        }
    }
Fabrice Bellard's avatar
Fabrice Bellard committed
305 306 307 308 309

    fclose(outfile);
    fclose(f);

    avcodec_close(c);
310
    av_free(c);
311
    avcodec_free_frame(&decoded_frame);
Fabrice Bellard's avatar
Fabrice Bellard committed
312 313 314
}

/*
315
 * Video encoding example
Fabrice Bellard's avatar
Fabrice Bellard committed
316
 */
317
static void video_encode_example(const char *filename)
Fabrice Bellard's avatar
Fabrice Bellard committed
318 319
{
    AVCodec *codec;
Michael Niedermayer's avatar
Michael Niedermayer committed
320
    AVCodecContext *c= NULL;
321
    int i, ret, x, y, got_output;
Fabrice Bellard's avatar
Fabrice Bellard committed
322
    FILE *f;
323
    AVFrame *picture;
324 325
    AVPacket pkt;
    uint8_t endcode[] = { 0, 0, 1, 0xb7 };
Fabrice Bellard's avatar
Fabrice Bellard committed
326 327 328 329

    printf("Video encoding\n");

    /* find the mpeg1 video encoder */
330
    codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO);
Fabrice Bellard's avatar
Fabrice Bellard committed
331 332 333 334 335
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

336
    c = avcodec_alloc_context3(codec);
337
    picture= avcodec_alloc_frame();
338

Fabrice Bellard's avatar
Fabrice Bellard committed
339 340 341
    /* put sample parameters */
    c->bit_rate = 400000;
    /* resolution must be a multiple of two */
342
    c->width = 352;
Fabrice Bellard's avatar
Fabrice Bellard committed
343 344
    c->height = 288;
    /* frames per second */
345
    c->time_base= (AVRational){1,25};
Fabrice Bellard's avatar
Fabrice Bellard committed
346
    c->gop_size = 10; /* emit one intra frame every ten frames */
347
    c->max_b_frames=1;
348
    c->pix_fmt = AV_PIX_FMT_YUV420P;
Fabrice Bellard's avatar
Fabrice Bellard committed
349 350

    /* open it */
351
    if (avcodec_open2(c, codec, NULL) < 0) {
Fabrice Bellard's avatar
Fabrice Bellard committed
352 353 354
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }
355

356
    f = fopen(filename, "wb");
Fabrice Bellard's avatar
Fabrice Bellard committed
357 358 359 360
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }
361

362 363 364 365 366 367 368 369 370
    ret = av_image_alloc(picture->data, picture->linesize, c->width, c->height,
                         c->pix_fmt, 32);
    if (ret < 0) {
        fprintf(stderr, "could not alloc raw picture buffer\n");
        exit(1);
    }
    picture->format = c->pix_fmt;
    picture->width  = c->width;
    picture->height = c->height;
Fabrice Bellard's avatar
Fabrice Bellard committed
371 372 373

    /* encode 1 second of video */
    for(i=0;i<25;i++) {
374 375 376 377
        av_init_packet(&pkt);
        pkt.data = NULL;    // packet data will be allocated by the encoder
        pkt.size = 0;

Fabrice Bellard's avatar
Fabrice Bellard committed
378 379 380 381 382
        fflush(stdout);
        /* prepare a dummy image */
        /* Y */
        for(y=0;y<c->height;y++) {
            for(x=0;x<c->width;x++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
383
                picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3;
Fabrice Bellard's avatar
Fabrice Bellard committed
384 385 386 387 388 389
            }
        }

        /* Cb and Cr */
        for(y=0;y<c->height/2;y++) {
            for(x=0;x<c->width/2;x++) {
Michael Niedermayer's avatar
Michael Niedermayer committed
390 391
                picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2;
                picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5;
Fabrice Bellard's avatar
Fabrice Bellard committed
392 393 394
            }
        }

395 396
        picture->pts = i;

Fabrice Bellard's avatar
Fabrice Bellard committed
397
        /* encode the image */
398 399 400 401 402 403 404 405 406 407 408
        ret = avcodec_encode_video2(c, &pkt, picture, &got_output);
        if (ret < 0) {
            fprintf(stderr, "error encoding frame\n");
            exit(1);
        }

        if (got_output) {
            printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        }
409 410 411
    }

    /* get the delayed frames */
412
    for (got_output = 1; got_output; i++) {
413
        fflush(stdout);
414

415 416 417 418 419 420 421 422 423 424 425
        ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);
        if (ret < 0) {
            fprintf(stderr, "error encoding frame\n");
            exit(1);
        }

        if (got_output) {
            printf("encoding frame %3d (size=%5d)\n", i, pkt.size);
            fwrite(pkt.data, 1, pkt.size, f);
            av_free_packet(&pkt);
        }
Fabrice Bellard's avatar
Fabrice Bellard committed
426 427 428
    }

    /* add sequence end code to have a real mpeg file */
429
    fwrite(endcode, 1, sizeof(endcode), f);
Fabrice Bellard's avatar
Fabrice Bellard committed
430 431 432
    fclose(f);

    avcodec_close(c);
433
    av_free(c);
434
    av_freep(&picture->data[0]);
435
    avcodec_free_frame(&picture);
Fabrice Bellard's avatar
Fabrice Bellard committed
436 437 438 439
    printf("\n");
}

/*
440
 * Video decoding example
Fabrice Bellard's avatar
Fabrice Bellard committed
441 442
 */

443 444
static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
                     char *filename)
Fabrice Bellard's avatar
Fabrice Bellard committed
445 446 447 448 449 450 451 452 453 454 455
{
    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);
    fclose(f);
}

456
static void video_decode_example(const char *outfilename, const char *filename)
Fabrice Bellard's avatar
Fabrice Bellard committed
457 458
{
    AVCodec *codec;
Michael Niedermayer's avatar
Michael Niedermayer committed
459
    AVCodecContext *c= NULL;
460
    int frame, got_picture, len;
Fabrice Bellard's avatar
Fabrice Bellard committed
461
    FILE *f;
462
    AVFrame *picture;
463
    uint8_t inbuf[INBUF_SIZE + FF_INPUT_BUFFER_PADDING_SIZE];
Fabrice Bellard's avatar
Fabrice Bellard committed
464
    char buf[1024];
465 466 467
    AVPacket avpkt;

    av_init_packet(&avpkt);
Fabrice Bellard's avatar
Fabrice Bellard committed
468

469 470 471
    /* set end of buffer to 0 (this ensures that no overreading happens for damaged mpeg streams) */
    memset(inbuf + INBUF_SIZE, 0, FF_INPUT_BUFFER_PADDING_SIZE);

Fabrice Bellard's avatar
Fabrice Bellard committed
472 473 474
    printf("Video decoding\n");

    /* find the mpeg1 video decoder */
475
    codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
Fabrice Bellard's avatar
Fabrice Bellard committed
476 477 478 479 480
    if (!codec) {
        fprintf(stderr, "codec not found\n");
        exit(1);
    }

481
    c = avcodec_alloc_context3(codec);
482
    picture= avcodec_alloc_frame();
Fabrice Bellard's avatar
Fabrice Bellard committed
483

484
    if(codec->capabilities&CODEC_CAP_TRUNCATED)
Diego Biurrun's avatar
Diego Biurrun committed
485
        c->flags|= CODEC_FLAG_TRUNCATED; /* we do not send complete frames */
486

Diego Biurrun's avatar
Diego Biurrun committed
487 488 489
    /* For some codecs, such as msmpeg4 and mpeg4, width and height
       MUST be initialized there because this information is not
       available in the bitstream. */
Fabrice Bellard's avatar
Fabrice Bellard committed
490 491

    /* open it */
492
    if (avcodec_open2(c, codec, NULL) < 0) {
Fabrice Bellard's avatar
Fabrice Bellard committed
493 494 495
        fprintf(stderr, "could not open codec\n");
        exit(1);
    }
496

Fabrice Bellard's avatar
Fabrice Bellard committed
497 498
    /* the codec gives us the frame size, in samples */

499
    f = fopen(filename, "rb");
Fabrice Bellard's avatar
Fabrice Bellard committed
500 501 502 503
    if (!f) {
        fprintf(stderr, "could not open %s\n", filename);
        exit(1);
    }
504

Fabrice Bellard's avatar
Fabrice Bellard committed
505 506
    frame = 0;
    for(;;) {
507 508
        avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
        if (avpkt.size == 0)
Fabrice Bellard's avatar
Fabrice Bellard committed
509 510 511 512
            break;

        /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
           and this is the only method to use them because you cannot
513
           know the compressed data size before analysing it.
Fabrice Bellard's avatar
Fabrice Bellard committed
514

515 516 517
           BUT some other codecs (msmpeg4, mpeg4) are inherently frame
           based, so you must call them with all the data for one
           frame exactly. You must also initialize 'width' and
Fabrice Bellard's avatar
Fabrice Bellard committed
518 519 520 521 522 523 524 525
           'height' before initializing them. */

        /* NOTE2: some codecs allow the raw parameters (frame size,
           sample rate) to be changed at any frame. We handle this, so
           you should also take care of it */

        /* here, we use a stream based decoder (mpeg1video), so we
           feed decoder and see if it could decode a frame */
526 527 528
        avpkt.data = inbuf;
        while (avpkt.size > 0) {
            len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
Fabrice Bellard's avatar
Fabrice Bellard committed
529 530 531 532 533
            if (len < 0) {
                fprintf(stderr, "Error while decoding frame %d\n", frame);
                exit(1);
            }
            if (got_picture) {
534
                printf("saving frame %3d\n", frame);
Fabrice Bellard's avatar
Fabrice Bellard committed
535 536 537 538 539
                fflush(stdout);

                /* the picture is allocated by the decoder. no need to
                   free it */
                snprintf(buf, sizeof(buf), outfilename, frame);
540
                pgm_save(picture->data[0], picture->linesize[0],
Fabrice Bellard's avatar
Fabrice Bellard committed
541 542 543
                         c->width, c->height, buf);
                frame++;
            }
544 545
            avpkt.size -= len;
            avpkt.data += len;
Fabrice Bellard's avatar
Fabrice Bellard committed
546 547 548 549 550 551
        }
    }

    /* some codecs, such as MPEG, transmit the I and P frame with a
       latency of one frame. You must do the following to have a
       chance to get the last frame of the video */
552 553 554
    avpkt.data = NULL;
    avpkt.size = 0;
    len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
Fabrice Bellard's avatar
Fabrice Bellard committed
555
    if (got_picture) {
556
        printf("saving last frame %3d\n", frame);
Fabrice Bellard's avatar
Fabrice Bellard committed
557
        fflush(stdout);
558

Fabrice Bellard's avatar
Fabrice Bellard committed
559 560 561
        /* the picture is allocated by the decoder. no need to
           free it */
        snprintf(buf, sizeof(buf), outfilename, frame);
562
        pgm_save(picture->data[0], picture->linesize[0],
Fabrice Bellard's avatar
Fabrice Bellard committed
563 564 565
                 c->width, c->height, buf);
        frame++;
    }
566

Fabrice Bellard's avatar
Fabrice Bellard committed
567 568 569
    fclose(f);

    avcodec_close(c);
570
    av_free(c);
571
    avcodec_free_frame(&picture);
Fabrice Bellard's avatar
Fabrice Bellard committed
572 573 574 575 576 577 578
    printf("\n");
}

int main(int argc, char **argv)
{
    const char *filename;

579
    /* register all the codecs */
Fabrice Bellard's avatar
Fabrice Bellard committed
580
    avcodec_register_all();
581

Fabrice Bellard's avatar
Fabrice Bellard committed
582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
    if (argc <= 1) {
        audio_encode_example("/tmp/test.mp2");
        audio_decode_example("/tmp/test.sw", "/tmp/test.mp2");

        video_encode_example("/tmp/test.mpg");
        filename = "/tmp/test.mpg";
    } else {
        filename = argv[1];
    }

    //    audio_decode_example("/tmp/test.sw", filename);
    video_decode_example("/tmp/test%d.pgm", filename);

    return 0;
}