2 #if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
10 #include "../config.h"
12 #include "../muxers.h"
13 #include "x264_gtk_encode_private.h"
16 #define DATA_MAX 3000000
17 uint8_t data[DATA_MAX];
19 int64_t x264_mdate (void);
22 int (*p_open_infile)( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
23 int (*p_get_frame_total)( hnd_t handle );
24 int (*p_read_frame)( x264_picture_t *p_pic, hnd_t handle, int i_frame );
25 int (*p_close_infile)( hnd_t handle );
27 /* output interface */
28 static int (*p_open_outfile) (char *filename, void **handle);
29 static int (*p_set_outfile_param) (void *handle, x264_param_t *p_param);
30 static int (*p_write_nalu) (void *handle, uint8_t *p_nal, int i_size);
31 static int (*p_set_eop) (void *handle, x264_picture_t *p_picture);
32 static int (*p_close_outfile) (void *handle);
34 static int _set_drivers (gint int_container, gint out_container);
35 static int _encode_frame (x264_t *h, void *handle, x264_picture_t *pic);
39 x264_gtk_encode_encode (X264_Thread_Data *thread_data)
43 X264_Pipe_Data pipe_data;
58 g_print ("encoding...\n");
59 param = thread_data->param;
60 err = _set_drivers (thread_data->in_container, thread_data->out_container);
63 no_driver = gtk_message_dialog_new (GTK_WINDOW(thread_data->dialog),
64 GTK_DIALOG_DESTROY_WITH_PARENT,
67 (err == -2) ? "Error: unknown output file type"
68 : "Error: unknown input file type");
69 gtk_dialog_run (GTK_DIALOG (no_driver));
70 gtk_widget_destroy (no_driver);
74 if (p_open_infile (thread_data->file_input, &hin, param)) {
75 fprintf( stderr, "could not open input file '%s'\n", thread_data->file_input );
79 p_open_outfile ((char *)thread_data->file_output, &hout);
81 i_frame_total = p_get_frame_total (hin );
82 if (((i_frame_total == 0) || (param->i_frame_total < i_frame_total)) &&
83 (param->i_frame_total > 0))
84 i_frame_total = param->i_frame_total;
85 param->i_frame_total = i_frame_total;
87 if ((h = x264_encoder_open (param)) == NULL)
89 fprintf (stderr, "x264_encoder_open failed\n");
91 p_close_outfile (hout);
97 if (p_set_outfile_param (hout, param))
99 fprintf (stderr, "can't set outfile param\n");
100 p_close_infile (hin);
101 p_close_outfile (hout);
107 /* Create a new pic */
108 x264_picture_alloc (&pic, X264_CSP_I420, param->i_width, param->i_height );
110 i_start = x264_mdate();
113 for (i_frame = 0, i_file = 0, i_progress = 0;
114 ((i_frame < i_frame_total) || (i_frame_total == 0)); )
116 if (p_read_frame (&pic, hin, i_frame))
119 pic.i_pts = (int64_t)i_frame * param->i_fps_den;
121 i_file += _encode_frame (h, hout, &pic);
125 /* update status line (up to 1000 times per input file) */
126 if (param->i_log_level < X264_LOG_DEBUG &&
127 (i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
128 : i_frame % 10 == 0))
130 int64_t i_elapsed = x264_mdate () - i_start;
131 double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0;
135 pipe_data.frame = i_frame;
136 pipe_data.frame_total = i_frame_total;
137 pipe_data.file = i_file;
138 pipe_data.elapsed = i_elapsed;
139 status = g_io_channel_write_chars (thread_data->io_write,
140 (const gchar *)&pipe_data,
141 sizeof (X264_Pipe_Data),
143 if (status != G_IO_STATUS_NORMAL) {
144 g_print ("Error ! %d %d %d\n", status, sizeof (X264_Pipe_Data), size);
147 /* we force the GIOChannel to write to the pipeline */
148 status = g_io_channel_flush (thread_data->io_write,
150 if (status != G_IO_STATUS_NORMAL) {
151 g_print ("Error ! %d\n", status);
156 fprintf( stderr, "encoded frames: %d, %.2f fps \r", i_frame, fps );
157 fflush( stderr ); /* needed in windows */
160 /* Flush delayed B-frames */
162 i_file += i_frame_size = _encode_frame (h, hout, NULL);
163 } while (i_frame_size);
165 i_end = x264_mdate ();
166 x264_picture_clean (&pic);
167 x264_encoder_close (h);
168 fprintf (stderr, "\n");
170 p_close_infile (hin);
171 p_close_outfile (hout);
174 double fps = (double)i_frame * (double)1000000 /
175 (double)(i_end - i_start);
177 fprintf (stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n",
179 (double) i_file * 8 * param->i_fps_num /
180 ((double) param->i_fps_den * i_frame * 1000));
183 gtk_widget_set_sensitive (thread_data->end_button, TRUE);
184 gtk_widget_hide (thread_data->button);
189 _set_drivers (gint in_container, gint out_container)
191 switch (in_container) {
195 /* Default input file driver */
196 p_open_infile = open_file_yuv;
197 p_get_frame_total = get_frame_total_yuv;
198 p_read_frame = read_frame_yuv;
199 p_close_infile = close_file_yuv;
204 p_open_infile = open_file_avis;
205 p_get_frame_total = get_frame_total_avis;
206 p_read_frame = read_frame_avis;
207 p_close_infile = close_file_avis;
210 default: /* Unknown */
214 switch (out_container) {
216 /* Raw ES output file driver */
217 p_open_outfile = open_file_bsf;
218 p_set_outfile_param = set_param_bsf;
219 p_write_nalu = write_nalu_bsf;
220 p_set_eop = set_eop_bsf;
221 p_close_outfile = close_file_bsf;
224 /* Matroska output file driver */
225 p_open_outfile = open_file_mkv;
226 p_set_outfile_param = set_param_mkv;
227 p_write_nalu = write_nalu_mkv;
228 p_set_eop = set_eop_mkv;
229 p_close_outfile = close_file_mkv;
233 p_open_outfile = open_file_mp4;
234 p_set_outfile_param = set_param_mp4;
235 p_write_nalu = write_nalu_mp4;
236 p_set_eop = set_eop_mp4;
237 p_close_outfile = close_file_mp4;
248 _encode_frame (x264_t *h, void *handle, x264_picture_t *pic)
250 x264_picture_t pic_out;
256 /* Do not force any parameters */
259 pic->i_type = X264_TYPE_AUTO;
262 if (x264_encoder_encode (h, &nal, &i_nal, pic, &pic_out) < 0)
264 fprintf (stderr, "x264_encoder_encode failed\n");
267 for (i = 0; i < i_nal; i++)
273 if ((i_size = x264_nal_encode (data, &i_data, 1, &nal[i])) > 0 )
275 i_file += p_write_nalu (handle, data, i_size);
279 fprintf (stderr, "need to increase buffer size (size=%d)\n", -i_size);
283 p_set_eop (handle, &pic_out);