x264_gtk_encode_encode.c
上传用户:hjq518
上传日期:2021-12-09
资源大小:5084k
文件大小:9k
源码类别:

Audio

开发平台:

Visual C++

  1. /*****************************************************************************
  2.  * x264_gtk_encode_encode.c: h264 gtk encoder frontend
  3.  *****************************************************************************
  4.  * Copyright (C) 2006 Vincent Torri
  5.  *
  6.  * This program is free software; you can redistribute it and/or modify
  7.  * it under the terms of the GNU General Public License as published by
  8.  * the Free Software Foundation; either version 2 of the License, or
  9.  * (at your option) any later version.
  10.  *
  11.  * This program is distributed in the hope that it will be useful,
  12.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  * GNU General Public License for more details.
  15.  *
  16.  * You should have received a copy of the GNU General Public License
  17.  * along with this program; if not, write to the Free Software
  18.  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02111, USA.
  19.  *****************************************************************************/
  20. #include <string.h>
  21. #if defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__ || defined __DragonFly__
  22. #  include <inttypes.h>
  23. #else
  24. #  include <stdint.h>
  25. #endif
  26. #include <gtk/gtk.h>
  27. #include "../x264.h"
  28. #include "x264_gtk_i18n.h"
  29. #include "x264_gtk_demuxers.h"
  30. #include "x264_gtk_encode_private.h"
  31. #define DATA_MAX 3000000
  32. uint8_t data[DATA_MAX];
  33. int64_t x264_mdate (void);
  34. /* input interface */
  35. int           (*p_open_infile)( char *psz_filename, hnd_t *p_handle, x264_param_t *p_param );
  36. int           (*p_get_frame_total)( hnd_t handle );
  37. int           (*p_read_frame)( x264_picture_t *p_pic, hnd_t handle, int i_frame );
  38. int           (*p_close_infile)( hnd_t handle );
  39. /* output interface */
  40. static int (*p_open_outfile)      (char *filename, void **handle);
  41. static int (*p_set_outfile_param) (void *handle, x264_param_t *p_param);
  42. static int (*p_write_nalu)        (void *handle, uint8_t *p_nal, int i_size);
  43. static int (*p_set_eop)           (void *handle, x264_picture_t *p_picture);
  44. static int (*p_close_outfile)     (void *handle);
  45. static int x264_set_drivers  (X264_Demuxer_Type in_container, gint out_container);
  46. static int x264_encode_frame (x264_t *h, void *handle, x264_picture_t *pic);
  47. gpointer
  48. x264_gtk_encode_encode (X264_Thread_Data *thread_data)
  49. {
  50.   GIOStatus       status;
  51.   gsize           size;
  52.   X264_Pipe_Data  pipe_data;
  53.   x264_param_t   *param;
  54.   x264_picture_t  pic;
  55.   x264_t         *h;
  56.   hnd_t           hin;
  57.   hnd_t           hout;
  58.   int             i_frame;
  59.   int             i_frame_total;
  60.   int64_t         i_start;
  61.   int64_t         i_end;
  62.   int64_t         i_file;
  63.   int             i_frame_size;
  64.   int             i_progress;
  65.   int             err;
  66.   g_print (_("encoding...n"));
  67.   param = thread_data->param;
  68.   err = x264_set_drivers (thread_data->in_container, thread_data->out_container);
  69.   if (err < 0) {
  70.     GtkWidget *no_driver;
  71.     no_driver = gtk_message_dialog_new (GTK_WINDOW(thread_data->dialog),
  72.                                         GTK_DIALOG_DESTROY_WITH_PARENT,
  73.                                         GTK_MESSAGE_ERROR,
  74.                                         GTK_BUTTONS_CLOSE,
  75.                                         (err == -2) ? _("Error: unknown output file type")
  76.                                                     : _("Error: unknown input file type"));
  77.     gtk_dialog_run (GTK_DIALOG (no_driver));
  78.     gtk_widget_destroy (no_driver);
  79.     return NULL;
  80.   }
  81.   if (p_open_infile (thread_data->file_input, &hin, param)) {
  82.     fprintf( stderr, _("could not open input file '%s'n"), thread_data->file_input );
  83.     return NULL;
  84.   }
  85.   p_open_outfile ((char *)thread_data->file_output, &hout);
  86.   i_frame_total = p_get_frame_total (hin );
  87.   if (((i_frame_total == 0) || (param->i_frame_total < i_frame_total)) &&
  88.       (param->i_frame_total > 0))
  89.     i_frame_total = param->i_frame_total;
  90.   param->i_frame_total = i_frame_total;
  91.   if ((h = x264_encoder_open (param)) == NULL)
  92.     {
  93.       fprintf (stderr, _("x264_encoder_open failedn"));
  94.       p_close_infile (hin);
  95.       p_close_outfile (hout);
  96.       g_free (param);
  97.       return NULL;
  98.     }
  99.   if (p_set_outfile_param (hout, param))
  100.     {
  101.       fprintf (stderr, _("can't set outfile paramn"));
  102.       p_close_infile (hin);
  103.       p_close_outfile (hout);
  104.       g_free (param);
  105.       return NULL;
  106.     }
  107.   /* Create a new pic */
  108.   x264_picture_alloc (&pic, X264_CSP_I420, param->i_width, param->i_height );
  109.   i_start = x264_mdate();
  110.   /* Encode frames */
  111.   for (i_frame = 0, i_file = 0, i_progress = 0;
  112.        ((i_frame < i_frame_total) || (i_frame_total == 0)); )
  113.     {
  114.       if (p_read_frame (&pic, hin, i_frame))
  115.         break;
  116.       pic.i_pts = (int64_t)i_frame * param->i_fps_den;
  117.       i_file += x264_encode_frame (h, hout, &pic);
  118.       i_frame++;
  119.       /* update status line (up to 1000 times per input file) */
  120.       if (param->i_log_level < X264_LOG_DEBUG &&
  121.           (i_frame_total ? i_frame * 1000 / i_frame_total > i_progress
  122.            : i_frame % 10 == 0))
  123.         {
  124.           int64_t i_elapsed = x264_mdate () - i_start;
  125.           if (i_frame_total)
  126.             {
  127.               pipe_data.frame = i_frame;
  128.               pipe_data.frame_total = i_frame_total;
  129.               pipe_data.file = i_file;
  130.               pipe_data.elapsed = i_elapsed;
  131.               status = g_io_channel_write_chars (thread_data->io_write,
  132.                                                  (const gchar *)&pipe_data,
  133.                                                  sizeof (X264_Pipe_Data),
  134.                                                  &size, NULL);
  135.               if (status != G_IO_STATUS_NORMAL) {
  136.                 g_print (_("Error ! %d %d %dn"), status, (int)sizeof (X264_Pipe_Data), (int)size);
  137.               }
  138.               else {
  139.                 /* we force the GIOChannel to write to the pipeline */
  140.                 status = g_io_channel_flush (thread_data->io_write,
  141.                                              NULL);
  142.                 if (status != G_IO_STATUS_NORMAL) {
  143.                   g_print (_("Error ! %dn"), status);
  144.                 }
  145.               }
  146.             }
  147.         }
  148.     }
  149.   /* Flush delayed B-frames */
  150.   do {
  151.     i_file += i_frame_size = x264_encode_frame (h, hout, NULL);
  152.   } while (i_frame_size);
  153.   i_end = x264_mdate ();
  154.   x264_picture_clean (&pic);
  155.   x264_encoder_close (h);
  156.   fprintf (stderr, "n");
  157.   p_close_infile (hin);
  158.   p_close_outfile (hout);
  159.   if (i_frame > 0) {
  160.     double fps = (double)i_frame * (double)1000000 /
  161.       (double)(i_end - i_start);
  162.     fprintf (stderr, _("encoded %d frames, %.2f fps, %.2f kb/sn"),
  163.              i_frame, fps,
  164.              (double) i_file * 8 * param->i_fps_num /
  165.              ((double) param->i_fps_den * i_frame * 1000));
  166.   }
  167.   gtk_widget_set_sensitive (thread_data->end_button, TRUE);
  168.   gtk_widget_hide (thread_data->button);
  169.   return NULL;
  170. }
  171. static int
  172. x264_set_drivers (X264_Demuxer_Type in_container, gint out_container)
  173. {
  174.   switch (in_container) {
  175.   case X264_DEMUXER_YUV:
  176.   case X264_DEMUXER_CIF:
  177.   case X264_DEMUXER_QCIF:
  178.     /*   Default input file driver */
  179.     p_open_infile = open_file_yuv;
  180.     p_get_frame_total = get_frame_total_yuv;
  181.     p_read_frame = read_frame_yuv;
  182.     p_close_infile = close_file_yuv;
  183.     break;
  184.   case X264_DEMUXER_Y4M:
  185.     p_open_infile = open_file_y4m;
  186.     p_get_frame_total = get_frame_total_y4m;
  187.     p_read_frame = read_frame_y4m;
  188.     p_close_infile = close_file_y4m;
  189.     break;
  190. #ifdef AVIS_INPUT
  191.   case X264_DEMUXER_AVI:
  192.   case X264_DEMUXER_AVS:
  193.     p_open_infile = open_file_avis;
  194.     p_get_frame_total = get_frame_total_avis;
  195.     p_read_frame = read_frame_avis;
  196.     p_close_infile = close_file_avis;
  197.     break;
  198. #endif
  199.   default: /* Unknown */
  200.     return -1;
  201.   }
  202.   switch (out_container) {
  203.   case 0:
  204. /*     Raw ES output file driver */
  205.     p_open_outfile = open_file_bsf;
  206.     p_set_outfile_param = set_param_bsf;
  207.     p_write_nalu = write_nalu_bsf;
  208.     p_set_eop = set_eop_bsf;
  209.     p_close_outfile = close_file_bsf;
  210.     break;
  211.   case 1:
  212. /*     Matroska output file driver */
  213.     p_open_outfile = open_file_mkv;
  214.     p_set_outfile_param = set_param_mkv;
  215.     p_write_nalu = write_nalu_mkv;
  216.     p_set_eop = set_eop_mkv;
  217.     p_close_outfile = close_file_mkv;
  218.     break;
  219. #ifdef MP4_OUTPUT
  220.   case 2:
  221.     p_open_outfile = open_file_mp4;
  222.     p_set_outfile_param = set_param_mp4;
  223.     p_write_nalu = write_nalu_mp4;
  224.     p_set_eop = set_eop_mp4;
  225.     p_close_outfile = close_file_mp4;
  226.     break;
  227. #endif
  228.   default:
  229.     return -2;
  230.   }
  231.   return 1;
  232. }
  233. static int
  234. x264_encode_frame (x264_t *h, void *handle, x264_picture_t *pic)
  235. {
  236.   x264_picture_t pic_out;
  237.   x264_nal_t    *nal;
  238.   int            i_nal;
  239.   int            i;
  240.   int            i_file = 0;
  241.   /* Do not force any parameters */
  242.   if (pic)
  243.     {
  244.       pic->i_type = X264_TYPE_AUTO;
  245.       pic->i_qpplus1 = 0;
  246.     }
  247.   if (x264_encoder_encode (h, &nal, &i_nal, pic, &pic_out) < 0)
  248.     {
  249.       fprintf (stderr, _("x264_encoder_encode failedn"));
  250.     }
  251.   for (i = 0; i < i_nal; i++)
  252.     {
  253.       int i_size;
  254.       int i_data;
  255.       i_data = DATA_MAX;
  256.       if ((i_size = x264_nal_encode (data, &i_data, 1, &nal[i])) > 0 )
  257.         {
  258.           i_file += p_write_nalu (handle, data, i_size);
  259.         }
  260.       else if (i_size < 0)
  261.         {
  262.           fprintf (stderr, _("need to increase buffer size (size=%d)n"), -i_size);
  263.         }
  264.     }
  265.   if (i_nal)
  266.     p_set_eop (handle, &pic_out);
  267.   return i_file;
  268. }