3 #include <libavcodec/avcodec.h>
4 #include <libavformat/avformat.h>
5 #include <libswscale/swscale.h>
10 char const video[] = "./starwars.mpg";//Ghostbusters.avi";
13 save_frame (AVFrame *frame, int width, int height, int N)
17 sprintf (filename, "frame%d.ppm", N);
18 FILE* file = fopen (filename, "wb");
23 fprintf (file, "P6\n%d %d\n255\n", width, height);
25 for (int y = 0; y < height; y++) {
26 fwrite (frame->data[0] + y * frame->linesize[0], 1, width * 3, file);
33 main (int argc, char* argv[])
37 AVFormatContext* format_context = NULL;
38 if (avformat_open_input (&format_context, video, NULL, NULL) != 0) {
39 fprintf (stderr, "avformat_open_input failed.\n");
43 if (avformat_find_stream_info (format_context, NULL) < 0) {
44 fprintf (stderr, "av_find_stream_info failed.\n");
48 av_dump_format (format_context, 0, video, 0);
50 int video_stream = -1;
51 for (uint32_t i = 0; i < format_context->nb_streams; ++i) {
52 if (format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
58 AVCodecContext* decoder_context = format_context->streams[video_stream]->codec;
60 AVCodec* decoder = avcodec_find_decoder (decoder_context->codec_id);
61 if (decoder == NULL) {
62 fprintf (stderr, "avcodec_find_decoder failed.\n");
66 if (avcodec_open2 (decoder_context, decoder, NULL) < 0) {
67 fprintf (stderr, "avcodec_open failed.\n");
72 if (decoder_context->time_base.num > 1000 && decoder_context->time_base.den == 1) {
73 decoder_context->time_base.den = 1000;
76 AVCodec* encoder = avcodec_find_encoder (CODEC_ID_JPEG2000);
77 if (encoder == NULL) {
78 cerr << "avcodec_find_encoder failed.\n";
82 AVCodecContext* encoder_context = avcodec_alloc_context3 (encoder);
84 cout << decoder_context->width << " x " << decoder_context->height << "\n";
85 encoder_context->width = decoder_context->width;
86 encoder_context->height = decoder_context->height;
88 encoder_context->time_base = (AVRational) {1, 25};
89 encoder_context->pix_fmt = PIX_FMT_YUV420P;
90 encoder_context->compression_level = 0;
92 if (avcodec_open2 (encoder_context, encoder, NULL) < 0) {
93 cerr << "avcodec_open failed.\n";
97 AVFrame* frame = avcodec_alloc_frame ();
99 AVFrame* frame_RGB = avcodec_alloc_frame ();
100 if (frame_RGB == NULL) {
101 fprintf (stderr, "avcodec_alloc_frame failed.\n");
105 FILE* outfile = fopen ("output", "wb");
107 int num_bytes = avpicture_get_size (PIX_FMT_RGB24, decoder_context->width, decoder_context->height);
108 uint8_t* buffer = (uint8_t *) malloc (num_bytes);
110 avpicture_fill ((AVPicture *) frame_RGB, buffer, PIX_FMT_RGB24, decoder_context->width, decoder_context->height);
112 /* alloc image and output buffer */
113 int outbuf_size = 100000;
114 uint8_t* outbuf = (uint8_t *) malloc (outbuf_size);
119 while (av_read_frame (format_context, &packet) >= 0) {
123 if (packet.stream_index == video_stream) {
124 avcodec_decode_video2 (decoder_context, frame, &frame_finished, &packet);
126 if (frame_finished) {
127 static struct SwsContext *img_convert_context;
129 if (img_convert_context == NULL) {
130 int w = decoder_context->width;
131 int h = decoder_context->height;
133 img_convert_context = sws_getContext (
135 decoder_context->pix_fmt,
136 w, h, PIX_FMT_RGB24, SWS_BICUBIC,
140 if (img_convert_context == NULL) {
141 fprintf (stderr, "sws_getContext failed.\n");
147 img_convert_context, frame->data, frame->linesize, 0,
148 decoder_context->height, frame_RGB->data, frame_RGB->linesize
151 out_size = avcodec_encode_video (encoder_context, outbuf, outbuf_size, frame);
154 fwrite (outbuf, 1, out_size, outfile);
159 av_free_packet (&packet);
163 out_size = avcodec_encode_video (encoder_context, outbuf, outbuf_size, NULL);
164 fwrite (outbuf, 1, out_size, outfile);
171 avcodec_close (decoder_context);
172 avcodec_close (encoder_context);
173 avformat_close_input (&format_context);