source: libpipi/trunk/examples/makemovie.c @ 3516

Last change on this file since 3516 was 3516, checked in by Sam Hocevar, 11 years ago

Fix the FFmpeg headers location in example programs.

  • Property svn:keywords set to Id
File size: 5.2 KB
Line 
1/*
2 *  makemovie     read image names from stdin and create a movie
3 *  Copyright (c) 2009 Sam Hocevar <sam@zoy.org>
4 *                All Rights Reserved
5 *
6 *  $Id: makemovie.c 3516 2009-05-25 00:16:20Z sam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#include <stdlib.h>
18#include <stdio.h>
19#include <string.h>
20
21#include <libavformat/avformat.h>
22#include <libswscale/swscale.h>
23
24#include <pipi.h>
25
26/* These values define a 720x576 anamorphic widescreen image that gets
27 * scaled to 1024x576 (16:9). */
28#define WIDTH 720
29#define HEIGHT 576
30#define PAR_NUM 64
31#define PAR_DEN 45
32#define FPS 25
33#define BITRATE 8000000
34
35int main(int argc, char *argv[])
36{
37    char file[1024];
38    AVPacket packet;
39    AVFormatContext *fmt;
40    AVCodecContext *ctx;
41    AVStream *stream;
42    AVCodec *codec;
43    AVFrame *frame;
44    struct SwsContext *sws = NULL;
45    pipi_image_t *image;
46    pipi_pixels_t *p;
47    uint8_t *buffer, *tmp;
48    int f, len;
49
50    if(argc < 2)
51        return EXIT_FAILURE;
52
53    av_register_all();
54    fmt = avformat_alloc_context();
55    if(!fmt)
56        return EXIT_FAILURE;
57    snprintf(fmt->filename, sizeof(fmt->filename), "%s", argv[1]);
58
59    fmt->oformat = guess_format(NULL, argv[1], NULL);
60    if(!fmt->oformat)
61        fmt->oformat = guess_format("mpeg", NULL, NULL);
62    if(!fmt->oformat)
63        return EXIT_FAILURE;
64
65    stream = av_new_stream(fmt, 0);
66    if(!stream)
67        return EXIT_FAILURE;
68    stream->sample_aspect_ratio.num = PAR_NUM;
69    stream->sample_aspect_ratio.den = PAR_DEN;
70
71    ctx = stream->codec;
72    ctx->width = WIDTH;
73    ctx->height = HEIGHT;
74    ctx->sample_aspect_ratio.num = PAR_NUM;
75    ctx->sample_aspect_ratio.den = PAR_DEN;
76    //ctx->codec_id = fmt->oformat->video_codec;
77    //ctx->codec_id = CODEC_ID_FFV1;
78    //ctx->codec_id = CODEC_ID_THEORA;
79    //ctx->codec_id = CODEC_ID_SNOW;
80    //ctx->strict_std_compliance = FF_COMPLIANCE_EXPERIMENTAL; /* Snow */
81    ctx->codec_id = CODEC_ID_MJPEG;
82    ctx->codec_type = CODEC_TYPE_VIDEO;
83    ctx->bit_rate = BITRATE;
84    ctx->time_base.num = 1;
85    ctx->time_base.den = FPS; /* 25 fps */
86    ctx->gop_size = FPS / 2;
87    ctx->pix_fmt = PIX_FMT_YUV420P; /* send YUV 420 */
88    if(ctx->codec_id == CODEC_ID_MPEG2VIDEO)
89        ctx->max_b_frames = 2;
90    if(ctx->codec_id == CODEC_ID_MPEG1VIDEO)
91        ctx->mb_decision = 2;
92    if(fmt->oformat->flags & AVFMT_GLOBALHEADER)
93        ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
94
95    if(av_set_parameters(fmt, NULL) < 0)
96        return EXIT_FAILURE;
97
98    codec = avcodec_find_encoder(ctx->codec_id);
99    if(!codec)
100        return EXIT_FAILURE;
101    if(avcodec_open(ctx, codec) < 0)
102        return EXIT_FAILURE;
103
104    frame = avcodec_alloc_frame();
105    if(!frame)
106        return EXIT_FAILURE;
107    tmp = av_malloc(avpicture_get_size(ctx->pix_fmt, ctx->width, ctx->height));
108    if(!tmp)
109        return EXIT_FAILURE;
110    avpicture_fill((AVPicture *)frame, tmp, ctx->pix_fmt,
111                   ctx->width, ctx->height);
112
113    if(!(fmt->flags & AVFMT_NOFILE))
114        if(url_fopen(&fmt->pb, argv[1], URL_WRONLY) < 0)
115            return EXIT_FAILURE;
116
117    len = 64 * 1024 * 1024;
118    buffer = av_malloc(len);
119
120    av_write_header(fmt);
121
122    for(f = 0; ; f++)
123    {
124        uint8_t *start;
125        int w = 0, h = 0, bytes, pitch;
126
127        if(!fgets(file, sizeof(file), stdin))
128            break;
129        file[strlen(file) - 1] = '\0';
130
131        image = pipi_load(file);
132        if(!image)
133            return EXIT_FAILURE;
134        p = pipi_get_pixels(image, PIPI_PIXELS_RGBA_U8);
135        start = (uint8_t *)p->pixels;
136        pitch = p->w * 4;
137
138        if(w != p->w || h != p->h)
139        {
140            w = p->w;
141            h = p->h;
142            if(sws)
143                sws_freeContext(sws);
144            sws = NULL;
145        }
146
147        if(!sws)
148            sws = sws_getContext(w, h, PIX_FMT_RGB32, ctx->width, ctx->height,
149                                 ctx->pix_fmt, SWS_BICUBIC, NULL, NULL, NULL);
150
151        sws_scale(sws, &start, &pitch, 0, h, frame->data, frame->linesize);
152
153        pipi_free(image);
154
155        bytes = avcodec_encode_video(ctx, buffer, len, frame);
156        if(bytes <= 0)
157            continue;
158
159        av_init_packet(&packet);
160        if(ctx->coded_frame->pts != (int64_t)AV_NOPTS_VALUE)
161            packet.pts = av_rescale_q(ctx->coded_frame->pts,
162                                      ctx->time_base, stream->time_base);
163        if(ctx->coded_frame->key_frame)
164            packet.flags |= PKT_FLAG_KEY;
165        packet.stream_index = 0;
166        packet.data = buffer;
167        packet.size = bytes;
168        if(av_interleaved_write_frame(fmt, &packet) < 0)
169            return EXIT_FAILURE;
170
171        fprintf(stderr, "frame %d\r", f);
172    }
173
174    fprintf(stderr, "\n");
175
176    av_write_trailer(fmt);
177
178    avcodec_close(stream->codec);
179    av_free(frame->data[0]);
180    av_free(frame);
181    av_free(buffer);
182    av_freep(&fmt->streams[0]->codec);
183    av_freep(&fmt->streams[0]);
184
185    if(sws)
186        sws_freeContext(sws);
187    if(!(fmt->flags & AVFMT_NOFILE))
188        url_fclose(fmt->pb);
189
190    av_free(fmt);
191
192    return EXIT_SUCCESS;
193}
194
Note: See TracBrowser for help on using the repository browser.