diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/creator.c | 143 | ||||
-rw-r--r-- | src/creator.h | 53 |
2 files changed, 196 insertions, 0 deletions
diff --git a/src/creator.c b/src/creator.c new file mode 100644 index 0000000..71a981f --- /dev/null +++ b/src/creator.c @@ -0,0 +1,143 @@ +#include <creator.h> +#include <render.h> + +static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt, + FILE *outfile) +{ + int ret; + /* send the frame to the encoder */ + ret = avcodec_send_frame(enc_ctx, frame); + if (ret < 0) { + fprintf(stderr, "error sending a frame for encoding\n"); + exit(1); + } + while (ret >= 0) { + ret = avcodec_receive_packet(enc_ctx, pkt); + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + return; + else if (ret < 0) { + fprintf(stderr, "error during encoding\n"); + exit(1); + } + printf("encoded frame %3"PRId64" (size=%5d)\n", pkt->pts, pkt->size); + fwrite(pkt->data, 1, pkt->size, outfile); + av_packet_unref(pkt); + } +} +int generateVideo(filename, int width, int height, int fps, int bitRate, Config *config, u32 (*sfunc) (long double, long double, u32)) +{ + const char *filename; + const AVCodec *codec; + AVCodecContext *c= NULL; + int i, ret, x, y; + FILE *f; + AVFrame *picture; + AVPacket *pkt; + uint8_t endcode[] = { 0, 0, 1, 0xb7 }; + if (argc <= 1) { + fprintf(stderr, "Usage: %s <output file>\n", argv[0]); + exit(0); + } + filename = argv[1]; + avcodec_register_all(); + /* find the mpeg1video encoder */ + codec = avcodec_find_encoder(AV_CODEC_ID_MPEG1VIDEO); + if (!codec) { + fprintf(stderr, "codec not found\n"); + exit(1); + } + c = avcodec_alloc_context3(codec); + picture = av_frame_alloc(); + pkt = av_packet_alloc(); + if (!pkt) + exit(1); + + /* put sample parameters */ + c->bit_rate = bitRate; + + /* resolution must be a multiple of two */ + if ((width*height)%2) + exit(1); + c->width = width; + c->height = height; + + /* frames per second */ + c->time_base = (AVRational){1, fps}; + c->framerate = (AVRational){fps, 1}; + + /* emit one intra frame every ten frames */ + c->gop_size = 10; + c->max_b_frames=1; + c->pix_fmt = AV_PIX_FMT_RGBA; + /* open it */ + + if (avcodec_open2(c, codec, NULL) < 0) { + fprintf(stderr, "could not open codec\n"); + exit(1); + } + f = fopen(filename, "wb"); + if (!f) { + fprintf(stderr, "could not open %s\n", filename); + exit(1); + } + picture->format = c->pix_fmt; + picture->width = c->width; + picture->height = c->height; + ret = av_frame_get_buffer(picture, 32); + if (ret < 0) { + fprintf(stderr, "could not alloc the frame data\n"); + exit(1); + } + + + /* encode 1 second of video */ + x_min_s = -2.0; + x_max_s = 1.0; + y_min_s= -1.0; + y_max_s = 1.0; + x_min = x_min_s; + x_max = x_max_s; + y_min = y_min_s; + y_max = y_max_s; + _config = config; + _sfunc = sfunc; + for(i=0;i<25;i++) { + fflush(stdout); + /* make sure the frame data is writable */ + ret = av_frame_make_writable(picture); + if (ret < 0) + exit(1); + + + s_arr = (u32 *) malloc((_config->width) * (_config->height) * sizeof(u32)); + calculate(x_min, y_min, x_max, y_max, _sfunc, s_arr); + picture->data[0] = s_arr; + + /* prepare a dummy image */ + /* Y */ + /*for(y=0;y<c->height;y++) { + for(x=0;x<c->width;x++) { + picture->data[0][y * picture->linesize[0] + x] = x + y + i * 3; + } + } YCbCr colorCode + /* Cb and Cr * + for(y=0;y<c->height/2;y++) { + for(x=0;x<c->width/2;x++) { + picture->data[1][y * picture->linesize[1] + x] = 128 + y + i * 2; + picture->data[2][y * picture->linesize[2] + x] = 64 + x + i * 5; + } + } */ + picture->pts = i; + /* encode the image */ + encode(c, picture, pkt, f); + } + /* flush the encoder */ + encode(c, NULL, pkt, f); + /* add sequence end code to have a real MPEG file */ + fwrite(endcode, 1, sizeof(endcode), f); + fclose(f); + avcodec_free_context(&c); + av_frame_free(&picture); + av_packet_free(&pkt); + return 0; +} diff --git a/src/creator.h b/src/creator.h new file mode 100644 index 0000000..7606d4e --- /dev/null +++ b/src/creator.h @@ -0,0 +1,53 @@ +/* + * render.h + * + * Created on: 26.01.2018 + * Author: rigtopa + * + */ + +#ifndef CREATOR_H_ +#define CREATOR_H_ + +#define COORDS(x, y, width) ((y)*(width)+(x)) + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <libavcodec/avcodec.h> +#include <libavutil/frame.h> +#include <libavutil/imgutils.h> + +typedef struct config { + u32 iterations; + u8 threads; + u32 colorFrom; + u32 colorTo; + long double to_x; + long double to_y; + long double speed; + u8 video; + u8 filetype; + u16 width; + u16 height; + u8 renderFPS; + u8 videoFPS; + u32 bitrate; + const char *path; + // TODO: key mapping als option in die struct +} Config; + +Config *_config; +u32 (*_sfunc) (long double, long double, u32); +u32 *s_arr; +long double x_min, x_max, y_min, y_max; +long double x_min_s, x_max_s, y_min_s, y_max_s; +int delta; +long double dt, ft; + +static void encode(AVCodecContext *enc_ctx, AVFrame *frame, AVPacket *pkt, FILE *outfile); + +int generateVideo(filename, int width, int height, int fps, int bitRate, Config *config, u32 (*sfunc) (long double, long double, u32)); + + +#endif /* RENDER_H_ */ |