gpointer x264_gtk_encode_encode (X264_Thread_Data *thread_data) { GIOStatus status; gsize size; X264_Pipe_Data pipe_data; x264_param_t *param; x264_picture_t pic; x264_t *h; hnd_t hin; hnd_t hout; int i_frame; int i_frame_total; int64_t i_start; int64_t i_end; int64_t i_file; int i_frame_size; int i_progress; int err; g_print (_("encoding...\n")); param = thread_data->param; err = x264_set_drivers (thread_data->in_container, thread_data->out_container); if (err < 0) { GtkWidget *no_driver; no_driver = gtk_message_dialog_new (GTK_WINDOW(thread_data->dialog), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE, (err == -2) ? _("Error: unknown output file type") : _("Error: unknown input file type")); gtk_dialog_run (GTK_DIALOG (no_driver)); gtk_widget_destroy (no_driver); return NULL; } if (p_open_infile (thread_data->file_input, &hin, param)) { fprintf( stderr, _("could not open input file '%s'\n"), thread_data->file_input ); return NULL; } p_open_outfile ((char *)thread_data->file_output, &hout); i_frame_total = p_get_frame_total (hin ); if (((i_frame_total == 0) || (param->i_frame_total < i_frame_total)) && (param->i_frame_total > 0)) i_frame_total = param->i_frame_total; param->i_frame_total = i_frame_total; if ((h = x264_encoder_open (param)) == NULL) { fprintf (stderr, _("x264_encoder_open failed\n")); p_close_infile (hin); p_close_outfile (hout); g_free (param); return NULL; } if (p_set_outfile_param (hout, param)) { fprintf (stderr, _("can't set outfile param\n")); p_close_infile (hin); p_close_outfile (hout); g_free (param); return NULL; } /* Create a new pic */ x264_picture_alloc (&pic, X264_CSP_I420, param->i_width, param->i_height ); i_start = x264_mdate(); /* Encode frames */ for (i_frame = 0, i_file = 0, i_progress = 0; ((i_frame < i_frame_total) || (i_frame_total == 0)); ) { if (p_read_frame (&pic, hin, i_frame)) break; pic.i_pts = (int64_t)i_frame * param->i_fps_den; i_file += x264_encode_frame (h, hout, &pic); i_frame++; /* update status line (up to 1000 times per input file) */ if (param->i_log_level < X264_LOG_DEBUG && (i_frame_total ? i_frame * 1000 / i_frame_total > i_progress : i_frame % 10 == 0)) { int64_t i_elapsed = x264_mdate () - i_start; if (i_frame_total) { pipe_data.frame = i_frame; pipe_data.frame_total = i_frame_total; pipe_data.file = i_file; pipe_data.elapsed = i_elapsed; status = g_io_channel_write_chars (thread_data->io_write, (const gchar *)&pipe_data, sizeof (X264_Pipe_Data), &size, NULL); if (status != G_IO_STATUS_NORMAL) { g_print (_("Error ! %d %d %d\n"), status, (int)sizeof (X264_Pipe_Data), (int)size); } else { /* we force the GIOChannel to write to the pipeline */ status = g_io_channel_flush (thread_data->io_write, NULL); if (status != G_IO_STATUS_NORMAL) { g_print (_("Error ! %d\n"), status); } } } } } /* Flush delayed B-frames */ do { i_file += i_frame_size = x264_encode_frame (h, hout, NULL); } while (i_frame_size); i_end = x264_mdate (); x264_picture_clean (&pic); x264_encoder_close (h); fprintf (stderr, "\n"); p_close_infile (hin); p_close_outfile (hout); if (i_frame > 0) { double fps = (double)i_frame * (double)1000000 / (double)(i_end - i_start); fprintf (stderr, _("encoded %d frames, %.2f fps, %.2f kb/s\n"), i_frame, fps, (double) i_file * 8 * param->i_fps_num / ((double) param->i_fps_den * i_frame * 1000)); } gtk_widget_set_sensitive (thread_data->end_button, TRUE); gtk_widget_hide (thread_data->button); return NULL; }
/***************************************************************************** * Encode: *****************************************************************************/ static int Encode( x264_param_t *param, cli_opt_t *opt ) { x264_t *h; x264_picture_t pic; int i_frame, i_frame_total; int64_t i_start, i_end; int64_t i_file; int i_frame_size; int i_progress; i_frame_total = p_get_frame_total( opt->hin ); i_frame_total -= opt->i_seek; if( ( i_frame_total == 0 || param->i_frame_total < i_frame_total ) && param->i_frame_total > 0 ) i_frame_total = param->i_frame_total; param->i_frame_total = i_frame_total; if( ( h = x264_encoder_open( param ) ) == NULL ) { fprintf( stderr, "x264_encoder_open failed\n" ); p_close_infile( opt->hin ); p_close_outfile( opt->hout ); return -1; } if( p_set_outfile_param( opt->hout, param ) ) { fprintf( stderr, "can't set outfile param\n" ); p_close_infile( opt->hin ); p_close_outfile( opt->hout ); return -1; } /* Create a new pic */ x264_picture_alloc( &pic, X264_CSP_I420, param->i_width, param->i_height ); i_start = x264_mdate(); /* Encode frames */ for( i_frame = 0, i_file = 0, i_progress = 0; b_ctrl_c == 0 && (i_frame < i_frame_total || i_frame_total == 0); ) { if( p_read_frame( &pic, opt->hin, i_frame + opt->i_seek ) ) break; pic.i_pts = (int64_t)i_frame * param->i_fps_den; if( opt->qpfile ) parse_qpfile( opt, &pic, i_frame + opt->i_seek ); else { /* Do not force any parameters */ pic.i_type = X264_TYPE_AUTO; pic.i_qpplus1 = 0; } i_file += Encode_frame( h, opt->hout, &pic ); i_frame++; /* update status line (up to 1000 times per input file) */ if( opt->b_progress && param->i_log_level < X264_LOG_DEBUG && ( i_frame_total ? i_frame * 1000 / i_frame_total > i_progress : i_frame % 10 == 0 ) ) { int64_t i_elapsed = x264_mdate() - i_start; double fps = i_elapsed > 0 ? i_frame * 1000000. / i_elapsed : 0; if( i_frame_total ) { int eta = i_elapsed * (i_frame_total - i_frame) / ((int64_t)i_frame * 1000000); i_progress = i_frame * 1000 / i_frame_total; fprintf( stderr, "encoded frames: %d/%d (%.1f%%), %.2f fps, eta %d:%02d:%02d \r", i_frame, i_frame_total, (float)i_progress / 10, fps, eta/3600, (eta/60)%60, eta%60 ); } else fprintf( stderr, "encoded frames: %d, %.2f fps \r", i_frame, fps ); fflush( stderr ); // needed in windows } } /* Flush delayed B-frames */ do { i_file += i_frame_size = Encode_frame( h, opt->hout, NULL ); } while( i_frame_size ); i_end = x264_mdate(); x264_picture_clean( &pic ); x264_encoder_close( h ); fprintf( stderr, "\n" ); if( b_ctrl_c ) fprintf( stderr, "aborted at input frame %d\n", opt->i_seek + i_frame ); p_close_infile( opt->hin ); p_close_outfile( opt->hout ); if( i_frame > 0 ) { double fps = (double)i_frame * (double)1000000 / (double)( i_end - i_start ); fprintf( stderr, "encoded %d frames, %.2f fps, %.2f kb/s\n", i_frame, fps, (double) i_file * 8 * param->i_fps_num / ( (double) param->i_fps_den * i_frame * 1000 ) ); } return 0; }