FFmpeg
Loading...
Searching...
No Matches
encode_video.c
Go to the documentation of this file.
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 libavcodec encoding video API usage example
25 * @example encode_video.c
26 *
27 * Generate synthetic video data and encode it to an output file.
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
39static 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);
66 }
67}
68
69int main(int argc, char **argv)
70{
71 const char *filename, *codec_name;
72 const AVCodec *codec;
74 int i, ret, x, y;
75 FILE *f;
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
95 if (!c) {
96 fprintf(stderr, "Could not allocate video codec context\n");
97 exit(1);
98 }
99
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
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 */
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 mux.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
214
215 return 0;
216}
FILE * outfile
Definition audiogen.c:96
Libavcodec external API header.
#define i(width, name, range_min, range_max)
Definition cbs_h264.c:63
#define f(width, name)
Definition cbs_vp8.c:236
#define NULL
Definition coverity.c:32
__device__ int printf(const char *,...)
static AVPacket * pkt
static AVFrame * frame
int main
Definition dovi_rpuenc.c:38
static void encode(AVCodecContext *ctx, AVFrame *frame, AVPacket *pkt, FILE *output)
int attribute_align_arg avcodec_open2(AVCodecContext *avctx, const AVCodec *codec, AVDictionary **options)
Initialize the AVCodecContext to use the given AVCodec.
Definition avcodec.c:144
AVCodecContext * avcodec_alloc_context3(const AVCodec *codec)
Allocate an AVCodecContext and set its fields to default values.
Definition options.c:149
const AVCodec * avcodec_find_encoder_by_name(const char *name)
Find a registered encoder with the specified name.
Definition allcodecs.c:1013
void avcodec_free_context(AVCodecContext **avctx)
Free the codec context and everything associated with it and write NULL to the provided pointer.
Definition options.c:164
@ AV_CODEC_ID_H264
Definition codec_id.h:77
@ AV_CODEC_ID_MPEG1VIDEO
Definition codec_id.h:51
@ AV_CODEC_ID_MPEG2VIDEO
preferred ID for MPEG-1/2 video decoding
Definition codec_id.h:52
int avcodec_receive_packet(AVCodecContext *avctx, AVPacket *avpkt)
Read encoded data from the encoder.
Definition encode.c:578
int avcodec_send_frame(AVCodecContext *avctx, const AVFrame *frame)
Supply a raw video or audio frame to the encoder.
Definition encode.c:545
void av_packet_free(AVPacket **pkt)
Free the packet, if the packet is reference counted, it will be unreferenced first.
Definition packet.c:74
void av_packet_unref(AVPacket *pkt)
Wipe the packet.
Definition packet.c:434
AVPacket * av_packet_alloc(void)
Allocate an AVPacket and set its fields to default values.
Definition packet.c:63
#define AVERROR_EOF
End of file.
Definition error.h:57
#define av_err2str(errnum)
Convenience macro, the return value should be used only directly in function arguments but never stan...
Definition error.h:122
#define AVERROR(e)
Definition error.h:45
int av_frame_get_buffer(AVFrame *frame, int align)
Allocate new buffer(s) for audio or video data.
Definition frame.c:206
void av_frame_free(AVFrame **frame)
Free the frame and any dynamically allocated objects in it, e.g.
Definition frame.c:64
AVFrame * av_frame_alloc(void)
Allocate an AVFrame and set its fields to default values.
Definition frame.c:52
int av_frame_make_writable(AVFrame *frame)
Ensure that the frame data is writable, avoiding data copy if possible.
Definition frame.c:552
int av_opt_set(void *obj, const char *name, const char *val, int search_flags)
Definition opt.c:887
misc image utilities
AVOptions.
@ AV_PIX_FMT_YUV420P
planar YUV 4:2:0, 12bpp, (1 Cr & Cb sample per 2x2 Y samples)
Definition pixfmt.h:73
main external API structure.
Definition avcodec.h:443
AVCodec.
Definition codec.h:175
enum AVCodecID id
Definition codec.h:189
This structure describes decoded (raw) audio or video data.
Definition frame.h:472
This structure stores compressed data.
Definition packet.h:580
Rational number (pair of numerator and denominator).
Definition rational.h:58
static double c[64]