Use C++ compiler.
[dcpomatic.git] / ffmpeg / test.cc
1 extern "C" {
2 #include <libavcodec/avcodec.h>
3 #include <libavformat/avformat.h>
4 #include <libswscale/swscale.h>
5 }
6
7 char const video[] = "/home/carl/Films/A town called panic.divx";//Ghostbusters.avi";
8
9 static void
10 save_frame (AVFrame *frame, int width, int height, int N)
11 {
12         char filename[32];
13         
14         sprintf (filename, "frame%d.ppm", N);
15         FILE* file = fopen (filename, "wb");
16         if (file == NULL) {
17                 return;
18         }
19
20         fprintf (file, "P6\n%d %d\n255\n", width, height);
21
22         for (int y = 0; y < height; y++) {
23                 fwrite (frame->data[0] + y * frame->linesize[0], 1, width * 3, file);
24         }
25
26         fclose (file);
27 }
28
29 int
30 main (int argc, char* argv[])
31 {
32         av_register_all ();
33
34         AVFormatContext* format_context = NULL;
35         if (avformat_open_input (&format_context, video, NULL, NULL) != 0) {
36                 fprintf (stderr, "avformat_open_input failed.\n");
37                 return -1;
38         }
39
40         if (avformat_find_stream_info (format_context, NULL) < 0) {
41                 fprintf (stderr, "av_find_stream_info failed.\n");
42                 return -1;
43         }
44
45         av_dump_format (format_context, 0, video, 0);
46
47         int video_stream = -1;
48         for (uint32_t i = 0; i < format_context->nb_streams; ++i) {
49                 if (format_context->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
50                         video_stream = i;
51                         break;
52                 }
53         }
54
55         AVCodecContext* codec_context = format_context->streams[video_stream]->codec;
56
57         AVCodec* codec = avcodec_find_decoder (codec_context->codec_id);
58         if (codec == NULL) {
59                 fprintf (stderr, "avcodec_find_decoder failed.\n");
60                 return -1;
61         }
62
63         if (avcodec_open2 (codec_context, codec, NULL) < 0) {
64                 fprintf (stderr, "avcodec_open failed.\n");
65                 return -1;
66         }
67
68         if (codec_context->time_base.num > 1000 && codec_context->time_base.den == 1) {
69                 codec_context->time_base.den = 1000;
70         }
71                 
72         AVFrame* frame = avcodec_alloc_frame ();
73
74         AVFrame* frame_RGB = avcodec_alloc_frame ();
75         if (frame_RGB == NULL) {
76                 fprintf (stderr, "avcodec_alloc_frame failed.\n");
77                 return -1;
78         }
79
80         int num_bytes = avpicture_get_size (PIX_FMT_RGB24, codec_context->width, codec_context->height);
81         uint8_t* buffer = (uint8_t *) malloc (num_bytes);
82
83         avpicture_fill ((AVPicture *) frame_RGB, buffer, PIX_FMT_RGB24, codec_context->width, codec_context->height);
84
85         int i = 0;
86         AVPacket packet;
87         while (av_read_frame (format_context, &packet) >= 0) {
88
89                 int frame_finished;
90
91                 if (packet.stream_index == video_stream) {
92                         avcodec_decode_video2 (codec_context, frame, &frame_finished, &packet);
93
94                         if (frame_finished) {
95                                 static struct SwsContext *img_convert_context;
96
97                                 if (img_convert_context == NULL) {
98                                         int w = codec_context->width;
99                                         int h = codec_context->height;
100                                         
101                                         img_convert_context = sws_getContext (
102                                                 w, h, 
103                                                 codec_context->pix_fmt, 
104                                                 w, h, PIX_FMT_RGB24, SWS_BICUBIC,
105                                                 NULL, NULL, NULL
106                                                 );
107                                         
108                                         if (img_convert_context == NULL) {
109                                                 fprintf (stderr, "sws_getContext failed.\n");
110                                                 return -1;
111                                         }
112                                 }
113                                 
114                                 sws_scale (
115                                         img_convert_context, frame->data, frame->linesize, 0, 
116                                         codec_context->height, frame_RGB->data, frame_RGB->linesize
117                                         );
118
119                                 ++i;
120                                 if (i > 100 && i < 150) {
121                                         save_frame (frame_RGB, codec_context->width, codec_context->height, i);
122                                 }
123                         }
124                 }
125
126                 av_free_packet (&packet);
127         }
128         
129         free (buffer);
130         av_free (frame_RGB);
131         av_free (frame);
132         avcodec_close(codec_context);
133         avformat_close_input (&format_context);
134         
135         return 0;       
136 }