Skip to content
Permalink
master
Switch branches/tags
Go to file
 
 
Cannot retrieve contributors at this time
185 lines (148 sloc) 4.88 KB
#include <libavutil/imgutils.h>
#include <libswscale/swscale.h>
#include "dbg.h"
#include "lavfutils.h"
static int sws_flags = SWS_BICUBIC;
int load_image_into_frame(AVFrame *frame, const char *filename)
{
int retval = -1, res;
static struct SwsContext *sws_ctx;
uint8_t *image_data[4];
int linesize[4];
int source_width, source_height;
enum PixelFormat source_fmt;
res = ff_load_image(image_data, linesize, &source_width, &source_height, &source_fmt, filename, NULL);
check(res >= 0, "failed to load image");
if (source_fmt != frame->format) {
sws_ctx = sws_getContext(source_width, source_height, source_fmt,
frame->width, frame->height, frame->format,
sws_flags, NULL, NULL, NULL);
check(sws_ctx, "unable to initialize scaling context");
sws_scale(sws_ctx,
(const uint8_t * const *)image_data, linesize,
0, frame->height, frame->data, frame->linesize);
}
retval = 0;
error:
av_freep(&image_data[0]);
sws_freeContext(sws_ctx);
return retval;
}
int write_frame_to_file(FILE *file, AVFrame *frame, AVCodecContext *codec_context, AVPacket *pkt) {
int res, got_output;
av_init_packet(pkt);
pkt->data = NULL;
pkt->size = 0;
/* generate synthetic video */
frame->pts += 1;
res = avcodec_encode_video2(codec_context, pkt, frame, &got_output);
check(res >= 0, "Error encoding frame");
if (got_output) {
fwrite(pkt->data, 1, pkt->size, file);
av_free_packet(pkt);
}
return 0;
error:
return -1;
}
int write_image_to_file(FILE *file, const char *filename, int count, AVFrame *frame, AVCodecContext *codec_context, AVPacket *pkt) {
int res, i;
res = load_image_into_frame(frame, filename);
check(res >= 0, "failed to load image into frame");
for (i = 0; i < count; i++) {
res = write_frame_to_file(file, frame, codec_context, pkt);
check(res >= 0, "unable to write frame to file");
}
return 0;
error:
return -1;
}
int write_delayed_frames_to_file(FILE *file, AVFrame *frame, AVCodecContext *codec_context, AVPacket *pkt) {
int res, got_output;
for (got_output = 1; got_output;) {
res = avcodec_encode_video2(codec_context, pkt, NULL, &got_output);
check(res >= 0, "Error encoding frame");
if (got_output) {
fwrite(pkt->data, 1, pkt->size, file);
av_free_packet(pkt);
}
}
return 0;
error:
return -1;
}
AVCodecContext *get_codec_context(width, height, fps)
{
int res;
avcodec_register_all();
AVCodec *codec;
AVCodecContext *codec_context = NULL;
codec = avcodec_find_encoder(CODEC_ID_MPEG1VIDEO);
check(codec, "unable to find codec");
codec_context = avcodec_alloc_context3(codec);
check(codec_context, "unable to allocate codec");
codec_context->bit_rate = 400000;
codec_context->width = width;
codec_context->height = height;
codec_context->time_base= (AVRational){1,fps};
codec_context->gop_size = 10;
codec_context->max_b_frames=1;
codec_context->pix_fmt = PIX_FMT_YUV420P;
res = avcodec_open2(codec_context, codec, NULL);
check(res >= 0, "could not open codec");
return codec_context;
error:
return NULL;
}
AVFrame *get_av_frame(AVCodecContext *codec_context) {
int res;
AVFrame *frame;
frame = avcodec_alloc_frame();
check(frame != NULL, "unable to allocate frame");
frame->height = codec_context->height;
frame->width = codec_context->width;
frame->format = codec_context->pix_fmt;
frame->pts = 0;
res = av_image_alloc(frame->data, frame->linesize, frame->width, frame->height, frame->format, 1);
check(res >= 0, "failed to allocate memory for video frame");
return frame;
error:
return NULL;
}
int main(int argc, char **argv)
{
const char *filename = "test.mpg";
FILE *file=NULL;
int res, retval=-1;
AVCodecContext *codec_context= NULL;
AVFrame *frame=NULL;
AVPacket pkt;
uint8_t endcode[] = { 0, 0, 1, 0xb7 };
codec_context = get_codec_context(320, 240, 25);
check(codec_context != NULL, "unable to obtain encoding context");
file = fopen(filename, "wb");
check(file != NULL, "could not open destination file %s", filename);
frame = get_av_frame(codec_context);
check(frame != NULL, "unable to allocate frame");
res = write_image_to_file(file, "source/img0.jpg", 25, frame, codec_context, &pkt);
res = write_image_to_file(file, "source/img1.jpg", 50, frame, codec_context, &pkt);
res = write_image_to_file(file, "source/img2.jpg", 10, frame, codec_context, &pkt);
res = write_image_to_file(file, "source/img3.jpg", 10, frame, codec_context, &pkt);
check(res >= 0, "failed to write image to file");
res = write_delayed_frames_to_file(file, frame, codec_context, &pkt);
check(res >= 0, "failed to write delayed frames");
fwrite(endcode, 1, sizeof(endcode), file);
retval = 0;
error:
if (file)
fclose(file);
if (codec_context) {
avcodec_close(codec_context);
av_free(codec_context);
}
if (frame) {
av_freep(&frame->data[0]);
av_free(frame);
}
return retval;
}