examples/decode_video: remove a stray unrelated comment
[ffmpeg.git] / doc / examples / decode_video.c
1 /*
2  * copyright (c) 2001 Fabrice Bellard
3  *
4  * This file is part of Libav.
5  *
6  * Libav is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * 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  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * 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  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
19  */
20
21 /**
22  * @file
23  * video decoding with libavcodec API example
24  *
25  * @example decode_video.c
26  */
27
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <string.h>
31
32 #include "libavcodec/avcodec.h"
33
34 #include "libavutil/common.h"
35 #include "libavutil/imgutils.h"
36 #include "libavutil/mathematics.h"
37
38 #define INBUF_SIZE 4096
39
40 static void pgm_save(unsigned char *buf, int wrap, int xsize, int ysize,
41                      char *filename)
42 {
43     FILE *f;
44     int i;
45
46     f=fopen(filename,"w");
47     fprintf(f,"P5\n%d %d\n%d\n",xsize,ysize,255);
48     for(i=0;i<ysize;i++)
49         fwrite(buf + i * wrap,1,xsize,f);
50     fclose(f);
51 }
52
53 int main(int argc, char **argv)
54 {
55     const char *filename, *outfilename;
56     const AVCodec *codec;
57     AVCodecContext *c= NULL;
58     int frame, got_picture, len;
59     FILE *f;
60     AVFrame *picture;
61     uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
62     char buf[1024];
63     AVPacket avpkt;
64
65     if (argc <= 2) {
66         fprintf(stderr, "Usage: %s <input file> <output file>\n", argv[0]);
67         exit(0);
68     }
69     filename    = argv[1];
70     outfilename = argv[2];
71
72     avcodec_register_all();
73
74     av_init_packet(&avpkt);
75
76     /* set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams) */
77     memset(inbuf + INBUF_SIZE, 0, AV_INPUT_BUFFER_PADDING_SIZE);
78
79     /* find the MPEG-1 video decoder */
80     codec = avcodec_find_decoder(AV_CODEC_ID_MPEG1VIDEO);
81     if (!codec) {
82         fprintf(stderr, "codec not found\n");
83         exit(1);
84     }
85
86     c = avcodec_alloc_context3(codec);
87     picture = av_frame_alloc();
88
89     if (codec->capabilities & AV_CODEC_CAP_TRUNCATED)
90         c->flags |= AV_CODEC_FLAG_TRUNCATED; // we do not send complete frames
91
92     /* For some codecs, such as msmpeg4 and mpeg4, width and height
93        MUST be initialized there because this information is not
94        available in the bitstream. */
95
96     /* open it */
97     if (avcodec_open2(c, codec, NULL) < 0) {
98         fprintf(stderr, "could not open codec\n");
99         exit(1);
100     }
101
102     f = fopen(filename, "rb");
103     if (!f) {
104         fprintf(stderr, "could not open %s\n", filename);
105         exit(1);
106     }
107
108     frame = 0;
109     for(;;) {
110         avpkt.size = fread(inbuf, 1, INBUF_SIZE, f);
111         if (avpkt.size == 0)
112             break;
113
114         /* NOTE1: some codecs are stream based (mpegvideo, mpegaudio)
115            and this is the only method to use them because you cannot
116            know the compressed data size before analysing it.
117
118            BUT some other codecs (msmpeg4, mpeg4) are inherently frame
119            based, so you must call them with all the data for one
120            frame exactly. You must also initialize 'width' and
121            'height' before initializing them. */
122
123         /* NOTE2: some codecs allow the raw parameters (frame size,
124            sample rate) to be changed at any frame. We handle this, so
125            you should also take care of it */
126
127         /* here, we use a stream based decoder (mpeg1video), so we
128            feed decoder and see if it could decode a frame */
129         avpkt.data = inbuf;
130         while (avpkt.size > 0) {
131             len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
132             if (len < 0) {
133                 fprintf(stderr, "Error while decoding frame %d\n", frame);
134                 exit(1);
135             }
136             if (got_picture) {
137                 printf("saving frame %3d\n", frame);
138                 fflush(stdout);
139
140                 /* the picture is allocated by the decoder. no need to
141                    free it */
142                 snprintf(buf, sizeof(buf), outfilename, frame);
143                 pgm_save(picture->data[0], picture->linesize[0],
144                          c->width, c->height, buf);
145                 frame++;
146             }
147             avpkt.size -= len;
148             avpkt.data += len;
149         }
150     }
151
152     /* Some codecs, such as MPEG, transmit the I- and P-frame with a
153        latency of one frame. You must do the following to have a
154        chance to get the last frame of the video. */
155     avpkt.data = NULL;
156     avpkt.size = 0;
157     len = avcodec_decode_video2(c, picture, &got_picture, &avpkt);
158     if (got_picture) {
159         printf("saving last frame %3d\n", frame);
160         fflush(stdout);
161
162         /* the picture is allocated by the decoder. no need to
163            free it */
164         snprintf(buf, sizeof(buf), outfilename, frame);
165         pgm_save(picture->data[0], picture->linesize[0],
166                  c->width, c->height, buf);
167         frame++;
168     }
169
170     fclose(f);
171
172     avcodec_free_context(&c);
173     av_frame_free(&picture);
174
175     return 0;
176 }