1 /*
2  * Copyright (c) 2001 Fabrice Bellard
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to deal
6  * in the Software without restriction, including without limitation the rights
7  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8  * copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies or substantial portions of the Software.
13  *
14  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20  * THE SOFTWARE.
21  */
22 
23 /**
24  * @file
25  * video encoding with libavcodec API example
26  *
27  * @example encode_video.c
28  */
29 
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <string.h>
33 
34 #include <libavcodec/avcodec.h>
35 
36 #include <libavutil/opt.h>
37 #include <libavutil/imgutils.h>
38 
encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt, FILE *outfile)39 static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt,
40                    FILE *outfile)
41 {
42     int ret;
43 
44     /* send the frame to the encoder */
45     if (frame)
46         printf("Send frame %3"PRId64"\n", frame->pts);
47 
48     ret = avcodec_send_frame(enc_ctx, frame);
49     if (ret < 0) {
50         fprintf(stderr, "Error sending a frame for encoding\n");
51         exit(1);
52     }
53 
54     while (ret >= 0) {
55         ret = avcodec_receive_packet(enc_ctx, pkt);
56         if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
57             return;
58         else if (ret < 0) {
59             fprintf(stderr, "Error during encoding\n");
60             exit(1);
61         }
62 
63         printf("Write packet %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size);
64         fwrite(pkt->data, 1, pkt->size, outfile);
65         av_packet_unref(pkt);
66     }
67 }
68 
main(int argc, char **argv)69 int main(int argc, char **argv)
70 {
71     const char *filename, *codec_name;
72     const AVCodec *codec;
73     AVCodecContext *c= NULL;
74     int i, ret, x, y;
75     FILE *f;
76     AVFrame *frame;
77     AVPacket *pkt;
78     uint8_t endcode[] = { 0, 0, 1, 0xb7 };
79 
80     if (argc <= 2) {
81         fprintf(stderr, "Usage: %s <output file> <codec name>\n", argv[0]);
82         exit(0);
83     }
84     filename = argv[1];
85     codec_name = argv[2];
86 
87     /* find the mpeg1video encoder */
88     codec = avcodec_find_encoder_by_name(codec_name);
89     if (!codec) {
90         fprintf(stderr, "Codec '%s' not found\n", codec_name);
91         exit(1);
92     }
93 
94     c = avcodec_alloc_context3(codec);
95     if (!c) {
96         fprintf(stderr, "Could not allocate video codec context\n");
97         exit(1);
98     }
99 
100     pkt = av_packet_alloc();
101     if (!pkt)
102         exit(1);
103 
104     /* put sample parameters */
105     c->bit_rate = 400000;
106     /* resolution must be a multiple of two */
107     c->width = 352;
108     c->height = 288;
109     /* frames per second */
110     c->time_base = (AVRational){1, 25};
111     c->framerate = (AVRational){25, 1};
112 
113     /* emit one intra frame every ten frames
114      * check frame pict_type before passing frame
115      * to encoder, if frame->pict_type is AV_PICTURE_TYPE_I
116      * then gop_size is ignored and the output of encoder
117      * will always be I frame irrespective to gop_size
118      */
119     c->gop_size = 10;
120     c->max_b_frames = 1;
121     c->pix_fmt = AV_PIX_FMT_YUV420P;
122 
123     if (codec->id == AV_CODEC_ID_H264)
124         av_opt_set(c->priv_data, "preset", "slow", 0);
125 
126     /* open it */
127     ret = avcodec_open2(c, codec, NULL);
128     if (ret < 0) {
129         fprintf(stderr, "Could not open codec: %s\n", av_err2str(ret));
130         exit(1);
131     }
132 
133     f = fopen(filename, "wb");
134     if (!f) {
135         fprintf(stderr, "Could not open %s\n", filename);
136         exit(1);
137     }
138 
139     frame = av_frame_alloc();
140     if (!frame) {
141         fprintf(stderr, "Could not allocate video frame\n");
142         exit(1);
143     }
144     frame->format = c->pix_fmt;
145     frame->width  = c->width;
146     frame->height = c->height;
147 
148     ret = av_frame_get_buffer(frame, 0);
149     if (ret < 0) {
150         fprintf(stderr, "Could not allocate the video frame data\n");
151         exit(1);
152     }
153 
154     /* encode 1 second of video */
155     for (i = 0; i < 25; i++) {
156         fflush(stdout);
157 
158         /* Make sure the frame data is writable.
159            On the first round, the frame is fresh from av_frame_get_buffer()
160            and therefore we know it is writable.
161            But on the next rounds, encode() will have called
162            avcodec_send_frame(), and the codec may have kept a reference to
163            the frame in its internal structures, that makes the frame
164            unwritable.
165            av_frame_make_writable() checks that and allocates a new buffer
166            for the frame only if necessary.
167          */
168         ret = av_frame_make_writable(frame);
169         if (ret < 0)
170             exit(1);
171 
172         /* Prepare a dummy image.
173            In real code, this is where you would have your own logic for
174            filling the frame. FFmpeg does not care what you put in the
175            frame.
176          */
177         /* Y */
178         for (y = 0; y < c->height; y++) {
179             for (x = 0; x < c->width; x++) {
180                 frame->data[0][y * frame->linesize[0] + x] = x + y + i * 3;
181             }
182         }
183 
184         /* Cb and Cr */
185         for (y = 0; y < c->height/2; y++) {
186             for (x = 0; x < c->width/2; x++) {
187                 frame->data[1][y * frame->linesize[1] + x] = 128 + y + i * 2;
188                 frame->data[2][y * frame->linesize[2] + x] = 64 + x + i * 5;
189             }
190         }
191 
192         frame->pts = i;
193 
194         /* encode the image */
195         encode(c, frame, pkt, f);
196     }
197 
198     /* flush the encoder */
199     encode(c, NULL, pkt, f);
200 
201     /* Add sequence end code to have a real MPEG file.
202        It makes only sense because this tiny examples writes packets
203        directly. This is called "elementary stream" and only works for some
204        codecs. To create a valid file, you usually need to write packets
205        into a proper file format or protocol; see muxing.c.
206      */
207     if (codec->id == AV_CODEC_ID_MPEG1VIDEO || codec->id == AV_CODEC_ID_MPEG2VIDEO)
208         fwrite(endcode, 1, sizeof(endcode), f);
209     fclose(f);
210 
211     avcodec_free_context(&c);
212     av_frame_free(&frame);
213     av_packet_free(&pkt);
214 
215     return 0;
216 }
217