Remove old dvd test code.
[dcpomatic.git] / hacks / ffmpeg / test.cc
1 #include <iostream>
2 extern "C" {
3 #include <libavcodec/avcodec.h>
4 #include <libavformat/avformat.h>
5 #include <libswscale/swscale.h>
6 }
7
8 using namespace std;
9
10 char const video[] = "./starwars.mpg";//Ghostbusters.avi";
11
12 static void
13 save_frame (AVFrame *frame, int width, int height, int N)
14 {
15         char filename[32];
16         
17         sprintf (filename, "frame%d.ppm", N);
18         FILE* file = fopen (filename, "wb");
19         if (file == NULL) {
20                 return;
21         }
22
23         fprintf (file, "P6\n%d %d\n255\n", width, height);
24
25         for (int y = 0; y < height; y++) {
26                 fwrite (frame->data[0] + y * frame->linesize[0], 1, width * 3, file);
27         }
28
29         fclose (file);
30 }
31
32 int
33 main (int argc, char* argv[])
34 {
35         av_register_all ();
36
37         AVFormatContext* format_context = NULL;
38         if (avformat_open_input (&format_context, video, NULL, NULL) != 0) {
39                 fprintf (stderr, "avformat_open_input failed.\n");
40                 return -1;
41         }
42
43         if (avformat_find_stream_info (format_context, NULL) < 0) {
44                 fprintf (stderr, "av_find_stream_info failed.\n");
45                 return -1;
46         }
47
48         av_dump_format (format_context, 0, video, 0);
49
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) {
53                         video_stream = i;
54                         break;
55                 }
56         }
57
58         AVCodecContext* decoder_context = format_context->streams[video_stream]->codec;
59
60         AVCodec* decoder = avcodec_find_decoder (decoder_context->codec_id);
61         if (decoder == NULL) {
62                 fprintf (stderr, "avcodec_find_decoder failed.\n");
63                 return -1;
64         }
65
66         if (avcodec_open2 (decoder_context, decoder, NULL) < 0) {
67                 fprintf (stderr, "avcodec_open failed.\n");
68                 return -1;
69         }
70
71         /* XXX */
72         if (decoder_context->time_base.num > 1000 && decoder_context->time_base.den == 1) {
73                 decoder_context->time_base.den = 1000;
74         }
75
76         AVCodec* encoder = avcodec_find_encoder (CODEC_ID_JPEG2000);
77         if (encoder == NULL) {
78                 cerr << "avcodec_find_encoder failed.\n";
79                 return -1;
80         }
81
82         AVCodecContext* encoder_context = avcodec_alloc_context3 (encoder);
83
84         cout << decoder_context->width << " x " << decoder_context->height << "\n";
85         encoder_context->width = decoder_context->width;
86         encoder_context->height = decoder_context->height;
87         /* XXX */
88         encoder_context->time_base = (AVRational) {1, 25};
89         encoder_context->pix_fmt = PIX_FMT_YUV420P;
90         encoder_context->compression_level = 0;
91
92         if (avcodec_open2 (encoder_context, encoder, NULL) < 0) {
93                 cerr << "avcodec_open failed.\n";
94                 return -1;
95         }
96         
97         AVFrame* frame = avcodec_alloc_frame ();
98
99         AVFrame* frame_RGB = avcodec_alloc_frame ();
100         if (frame_RGB == NULL) {
101                 fprintf (stderr, "avcodec_alloc_frame failed.\n");
102                 return -1;
103         }
104
105         FILE* outfile = fopen ("output", "wb");
106
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);
109
110         avpicture_fill ((AVPicture *) frame_RGB, buffer, PIX_FMT_RGB24, decoder_context->width, decoder_context->height);
111
112         /* alloc image and output buffer */
113         int outbuf_size = 100000;
114         uint8_t* outbuf = (uint8_t *) malloc (outbuf_size);
115         int out_size = 0;
116         
117         AVPacket packet;
118         int i = 0;
119         while (av_read_frame (format_context, &packet) >= 0) {
120
121                 int frame_finished;
122
123                 if (packet.stream_index == video_stream) {
124                         avcodec_decode_video2 (decoder_context, frame, &frame_finished, &packet);
125
126                         if (frame_finished) {
127                                 static struct SwsContext *img_convert_context;
128
129                                 if (img_convert_context == NULL) {
130                                         int w = decoder_context->width;
131                                         int h = decoder_context->height;
132                                         
133                                         img_convert_context = sws_getContext (
134                                                 w, h, 
135                                                 decoder_context->pix_fmt, 
136                                                 w, h, PIX_FMT_RGB24, SWS_BICUBIC,
137                                                 NULL, NULL, NULL
138                                                 );
139                                         
140                                         if (img_convert_context == NULL) {
141                                                 fprintf (stderr, "sws_getContext failed.\n");
142                                                 return -1;
143                                         }
144                                 }
145                                 
146                                 sws_scale (
147                                         img_convert_context, frame->data, frame->linesize, 0, 
148                                         decoder_context->height, frame_RGB->data, frame_RGB->linesize
149                                         );
150
151                                 out_size = avcodec_encode_video (encoder_context, outbuf, outbuf_size, frame);
152                                 ++i;
153                                 if (i == 200) {
154                                         fwrite (outbuf, 1, out_size, outfile);
155                                 }
156                         }
157                 }
158
159                 av_free_packet (&packet);
160         }
161
162         while (out_size) {
163                 out_size = avcodec_encode_video (encoder_context, outbuf, outbuf_size, NULL);
164                 fwrite (outbuf, 1, out_size, outfile);
165         }
166
167         fclose (outfile);
168         free (buffer);
169         av_free (frame_RGB);
170         av_free (frame);
171         avcodec_close (decoder_context);
172         avcodec_close (encoder_context);
173         avformat_close_input (&format_context);
174         
175         return 0;       
176 }