mux.c
上传用户:kjfoods
上传日期:2020-07-06
资源大小:29949k
文件大小:16k
源码类别:

midi

开发平台:

Unix_Linux

  1. /*****************************************************************************
  2.  * mux.c: muxer using ffmpeg (libavformat).
  3.  *****************************************************************************
  4.  * Copyright (C) 2006 the VideoLAN team
  5.  * $Id: 3e98975cd24396f8cde64a6f4aac43691e7720b6 $
  6.  *
  7.  * Authors: Gildas Bazin <gbazin@videolan.org>
  8.  *
  9.  * This program is free software; you can redistribute it and/or modify
  10.  * it under the terms of the GNU General Public License as published by
  11.  * the Free Software Foundation; either version 2 of the License, or
  12.  * (at your option) any later version.
  13.  *
  14.  * This program is distributed in the hope that it will be useful,
  15.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  17.  * GNU General Public License for more details.
  18.  *
  19.  * You should have received a copy of the GNU General Public License
  20.  * along with this program; if not, write to the Free Software
  21.  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
  22.  *****************************************************************************/
  23. /*****************************************************************************
  24.  * Preamble
  25.  *****************************************************************************/
  26. #ifdef HAVE_CONFIG_H
  27. # include "config.h"
  28. #endif
  29. #include <vlc_common.h>
  30. #include <vlc_block.h>
  31. #include <vlc_sout.h>
  32. /* ffmpeg header */
  33. #ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
  34. #   include <libavformat/avformat.h>
  35. #elif defined(HAVE_FFMPEG_AVFORMAT_H)
  36. #   include <ffmpeg/avformat.h>
  37. #endif
  38. #include "avformat.h"
  39. #include "../../codec/avcodec/avcodec.h"
  40. #include "../../codec/avcodec/avutil.h"
  41. //#define AVFORMAT_DEBUG 1
  42. static const char *const ppsz_mux_options[] = {
  43.     "mux", NULL
  44. };
  45. /*****************************************************************************
  46.  * mux_sys_t: mux descriptor
  47.  *****************************************************************************/
  48. struct sout_mux_sys_t
  49. {
  50.     ByteIOContext   io;
  51.     int             io_buffer_size;
  52.     uint8_t        *io_buffer;
  53.     AVFormatContext *oc;
  54.     URLContext     url;
  55.     URLProtocol    prot;
  56.     bool     b_write_header;
  57.     bool     b_error;
  58.     int64_t        i_initial_dts;
  59. };
  60. /*****************************************************************************
  61.  * Local prototypes
  62.  *****************************************************************************/
  63. static int Control  ( sout_mux_t *, int, va_list );
  64. static int AddStream( sout_mux_t *, sout_input_t * );
  65. static int DelStream( sout_mux_t *, sout_input_t * );
  66. static int Mux      ( sout_mux_t * );
  67. static int IOWrite( void *opaque, uint8_t *buf, int buf_size );
  68. static int64_t IOSeek( void *opaque, int64_t offset, int whence );
  69. /*****************************************************************************
  70.  * Open
  71.  *****************************************************************************/
  72. int OpenMux( vlc_object_t *p_this )
  73. {
  74.     AVOutputFormat *file_oformat;
  75.     sout_mux_t *p_mux = (sout_mux_t*)p_this;
  76.     sout_mux_sys_t *p_sys;
  77.     AVFormatParameters params, *ap = &params;
  78.     char *psz_mux;
  79.     /* Should we call it only once ? */
  80.     av_register_all();
  81.     av_log_set_callback( LibavutilCallback );
  82.     config_ChainParse( p_mux, "ffmpeg-", ppsz_mux_options, p_mux->p_cfg );
  83.     /* Find the requested muxer */
  84.     psz_mux = var_GetNonEmptyString( p_mux, "ffmpeg-mux" );
  85.     if( psz_mux )
  86.     {
  87.         file_oformat = guess_format( psz_mux, NULL, NULL );
  88.     }
  89.     else
  90.     {
  91.         file_oformat =
  92.             guess_format(NULL, p_mux->p_access->psz_path, NULL);
  93.     }
  94.     if (!file_oformat)
  95.     {
  96.       msg_Err( p_mux, "unable for find a suitable output format" );
  97.       return VLC_EGENERIC;
  98.     }
  99.     /* Fill p_mux fields */
  100.     p_mux->pf_control   = Control;
  101.     p_mux->pf_addstream = AddStream;
  102.     p_mux->pf_delstream = DelStream;
  103.     p_mux->pf_mux       = Mux;
  104.     p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) );
  105.     p_sys->oc = av_alloc_format_context();
  106.     p_sys->oc->oformat = file_oformat;
  107.     /* Create I/O wrapper */
  108.     p_sys->io_buffer_size = 32768;  /* FIXME */
  109.     p_sys->io_buffer = malloc( p_sys->io_buffer_size );
  110.     p_sys->url.priv_data = p_mux;
  111.     p_sys->url.prot = &p_sys->prot;
  112.     p_sys->url.prot->name = "VLC I/O wrapper";
  113.     p_sys->url.prot->url_open = 0;
  114.     p_sys->url.prot->url_read = 0;
  115.     p_sys->url.prot->url_write =
  116.                     (int (*) (URLContext *, unsigned char *, int))IOWrite;
  117.     p_sys->url.prot->url_seek =
  118.                     (int64_t (*) (URLContext *, int64_t, int))IOSeek;
  119.     p_sys->url.prot->url_close = 0;
  120.     p_sys->url.prot->next = 0;
  121.     init_put_byte( &p_sys->io, p_sys->io_buffer, p_sys->io_buffer_size,
  122.                    1, &p_sys->url, NULL, IOWrite, IOSeek );
  123.     memset( ap, 0, sizeof(*ap) );
  124.     if( av_set_parameters( p_sys->oc, ap ) < 0 )
  125.     {
  126.         msg_Err( p_mux, "invalid encoding parameters" );
  127.         av_free( p_sys->oc );
  128.         free( p_sys->io_buffer );
  129.         free( p_sys );
  130.         return VLC_EGENERIC;
  131.     }
  132. #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0)
  133.     p_sys->oc->pb = &p_sys->io;
  134. #else
  135.     p_sys->oc->pb = p_sys->io;
  136. #endif
  137.     p_sys->oc->nb_streams = 0;
  138.     p_sys->b_write_header = true;
  139.     p_sys->b_error = false;
  140.     p_sys->i_initial_dts = 0;
  141.     return VLC_SUCCESS;
  142. }
  143. /*****************************************************************************
  144.  * Close
  145.  *****************************************************************************/
  146. void CloseMux( vlc_object_t *p_this )
  147. {
  148.     sout_mux_t *p_mux = (sout_mux_t*)p_this;
  149.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  150.     unsigned int i;
  151.     if( av_write_trailer( p_sys->oc ) < 0 )
  152.     {
  153.         msg_Err( p_mux, "could not write trailer" );
  154.     }
  155.     for( i = 0 ; i < p_sys->oc->nb_streams; i++ )
  156.     {
  157.         if( p_sys->oc->streams[i]->codec->extradata )
  158.             av_free( p_sys->oc->streams[i]->codec->extradata );
  159.         av_free( p_sys->oc->streams[i]->codec );
  160.         av_free( p_sys->oc->streams[i] );
  161.     }
  162.     av_free( p_sys->oc );
  163.     free( p_sys->io_buffer );
  164.     free( p_sys );
  165. }
  166. /*****************************************************************************
  167.  * AddStream
  168.  *****************************************************************************/
  169. static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input )
  170. {
  171.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  172.     AVCodecContext *codec;
  173.     AVStream *stream;
  174.     int i_codec_id, i_aspect_num, i_aspect_den;
  175.     msg_Dbg( p_mux, "adding input" );
  176.     if( !GetFfmpegCodec( p_input->p_fmt->i_codec, 0, &i_codec_id, 0 ) )
  177.     {
  178.         msg_Dbg( p_mux, "couldn't find codec for fourcc '%4.4s'",
  179.                  (char *)&p_input->p_fmt->i_codec );
  180.         return VLC_EGENERIC;
  181.     }
  182.     p_input->p_sys = malloc( sizeof( int ) );
  183.     *((int *)p_input->p_sys) = p_sys->oc->nb_streams;
  184.     stream = av_new_stream( p_sys->oc, p_sys->oc->nb_streams);
  185.     if( !stream )
  186.     {
  187.         free( p_input->p_sys );
  188.         return VLC_EGENERIC;
  189.     }
  190.     codec = stream->codec;
  191.     /* This is used by LibavutilCallback (avutil.h) to print messages */
  192.     codec->opaque = (void*)p_mux;
  193.     switch( p_input->p_fmt->i_cat )
  194.     {
  195.     case AUDIO_ES:
  196.         codec->codec_type = CODEC_TYPE_AUDIO;
  197.         codec->channels = p_input->p_fmt->audio.i_channels;
  198.         codec->sample_rate = p_input->p_fmt->audio.i_rate;
  199.         codec->time_base = (AVRational){1, codec->sample_rate};
  200.         break;
  201.     case VIDEO_ES:
  202.         if( !p_input->p_fmt->video.i_frame_rate ||
  203.             !p_input->p_fmt->video.i_frame_rate_base )
  204.         {
  205.             msg_Warn( p_mux, "Missing frame rate, assuming 25fps" );
  206.             p_input->p_fmt->video.i_frame_rate = 25;
  207.             p_input->p_fmt->video.i_frame_rate_base = 1;
  208.         }
  209.         codec->codec_type = CODEC_TYPE_VIDEO;
  210.         codec->width = p_input->p_fmt->video.i_width;
  211.         codec->height = p_input->p_fmt->video.i_height;
  212.         av_reduce( &i_aspect_num, &i_aspect_den,
  213.                    p_input->p_fmt->video.i_aspect,
  214.                    VOUT_ASPECT_FACTOR, 1 << 30 /* something big */ );
  215.         av_reduce( &codec->sample_aspect_ratio.num,
  216.                    &codec->sample_aspect_ratio.den,
  217.                    i_aspect_num * (int64_t)codec->height,
  218.                    i_aspect_den * (int64_t)codec->width, 1 << 30 );
  219. #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(21<<8)+0)
  220.         stream->sample_aspect_ratio.num = codec->sample_aspect_ratio.num;
  221.         stream->sample_aspect_ratio.den = codec->sample_aspect_ratio.den;
  222. #endif
  223.         codec->time_base.den = p_input->p_fmt->video.i_frame_rate;
  224.         codec->time_base.num = p_input->p_fmt->video.i_frame_rate_base;
  225.         break;
  226.     default:
  227.         msg_Warn( p_mux, "Unhandled ES category" );
  228.     }
  229.     codec->bit_rate = p_input->p_fmt->i_bitrate;
  230. #if LIBAVFORMAT_VERSION_INT >= ((51<<16)+(8<<8)+0)
  231.     codec->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
  232.     if( !codec->codec_tag && i_codec_id == CODEC_ID_MP2 )
  233.     {
  234.         i_codec_id = CODEC_ID_MP3;
  235.         codec->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
  236.     }
  237. #else
  238. #   warning "WARNING!!!!!!!"
  239. #   warning "Using libavformat muxing with versions older than 51.8.0 (r7593) might produce broken files."
  240.     /* This is a hack */
  241.     if( i_codec_id == CODEC_ID_MP2 )
  242.         i_codec_id = CODEC_ID_MP3;
  243.     codec->codec_tag = p_input->p_fmt->i_codec;
  244. #endif
  245.     codec->codec_id = i_codec_id;
  246.     if( p_input->p_fmt->i_extra )
  247.     {
  248.         codec->extradata_size = p_input->p_fmt->i_extra;
  249.         codec->extradata = av_malloc( p_input->p_fmt->i_extra );
  250.         memcpy( codec->extradata, p_input->p_fmt->p_extra,
  251.                 p_input->p_fmt->i_extra );
  252.     }
  253.     return VLC_SUCCESS;
  254. }
  255. /*****************************************************************************
  256.  * DelStream
  257.  *****************************************************************************/
  258. static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input )
  259. {
  260.     msg_Dbg( p_mux, "removing input" );
  261.     free( p_input->p_sys );
  262.     return VLC_SUCCESS;
  263. }
  264. /*
  265.  * TODO  move this function to src/stream_output.c (used by nearly all muxers)
  266.  */
  267. static int MuxGetStream( sout_mux_t *p_mux, int *pi_stream, mtime_t *pi_dts )
  268. {
  269.     mtime_t i_dts;
  270.     int     i_stream, i;
  271.     for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ )
  272.     {
  273.         block_fifo_t  *p_fifo;
  274.         p_fifo = p_mux->pp_inputs[i]->p_fifo;
  275.         /* We don't really need to have anything in the SPU fifo */
  276.         if( p_mux->pp_inputs[i]->p_fmt->i_cat == SPU_ES &&
  277.             block_FifoCount( p_fifo ) == 0 ) continue;
  278.         if( block_FifoCount( p_fifo ) )
  279.         {
  280.             block_t *p_buf;
  281.             p_buf = block_FifoShow( p_fifo );
  282.             if( i_stream < 0 || p_buf->i_dts < i_dts )
  283.             {
  284.                 i_dts = p_buf->i_dts;
  285.                 i_stream = i;
  286.             }
  287.         }
  288.         else return -1;
  289.     }
  290.     if( pi_stream ) *pi_stream = i_stream;
  291.     if( pi_dts ) *pi_dts = i_dts;
  292.     if( !p_mux->p_sys->i_initial_dts ) p_mux->p_sys->i_initial_dts = i_dts;
  293.     return i_stream;
  294. }
  295. static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input )
  296. {
  297.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  298.     block_t *p_data = block_FifoGet( p_input->p_fifo );
  299.     int i_stream = *((int *)p_input->p_sys);
  300.     AVStream *p_stream = p_sys->oc->streams[i_stream];
  301.     AVPacket pkt;
  302.     memset( &pkt, 0, sizeof(AVPacket) );
  303.     av_init_packet(&pkt);
  304.     pkt.data = p_data->p_buffer;
  305.     pkt.size = p_data->i_buffer;
  306.     pkt.stream_index = i_stream;
  307.     if( p_data->i_flags & BLOCK_FLAG_TYPE_I ) pkt.flags |= PKT_FLAG_KEY;
  308.     /* avformat expects pts/dts which start from 0 */
  309.     p_data->i_dts -= p_mux->p_sys->i_initial_dts;
  310.     p_data->i_pts -= p_mux->p_sys->i_initial_dts;
  311.     if( p_data->i_pts > 0 )
  312.         pkt.pts = p_data->i_pts * p_stream->time_base.den /
  313.             INT64_C(1000000) / p_stream->time_base.num;
  314.     if( p_data->i_dts > 0 )
  315.         pkt.dts = p_data->i_dts * p_stream->time_base.den /
  316.             INT64_C(1000000) / p_stream->time_base.num;
  317.     /* this is another hack to prevent libavformat from triggering the "non monotone timestamps" check in avformat/utils.c */
  318.     p_stream->cur_dts = ( p_data->i_dts * p_stream->time_base.den /
  319.             INT64_C(1000000) / p_stream->time_base.num ) - 1;
  320.     if( av_write_frame( p_sys->oc, &pkt ) < 0 )
  321.     {
  322.         msg_Err( p_mux, "could not write frame (pts: %"PRId64", dts: %"PRId64") "
  323.                  "(pkt pts: %"PRId64", dts: %"PRId64")",
  324.                  p_data->i_pts, p_data->i_dts, pkt.pts, pkt.dts );
  325.         block_Release( p_data );
  326.         return VLC_EGENERIC;
  327.     }
  328.     block_Release( p_data );
  329.     return VLC_SUCCESS;
  330. }
  331. /*****************************************************************************
  332.  * Mux: multiplex available data in input fifos
  333.  *****************************************************************************/
  334. static int Mux( sout_mux_t *p_mux )
  335. {
  336.     sout_mux_sys_t *p_sys = p_mux->p_sys;
  337.     int i_stream;
  338.     if( p_sys->b_error ) return VLC_EGENERIC;
  339.     if( p_sys->b_write_header )
  340.     {
  341.         msg_Dbg( p_mux, "writing header" );
  342.         if( av_write_header( p_sys->oc ) < 0 )
  343.         {
  344.             msg_Err( p_mux, "could not write header" );
  345.             p_sys->b_write_header = false;
  346.             p_sys->b_error = true;
  347.             return VLC_EGENERIC;
  348.         }
  349. #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0)
  350.         put_flush_packet( p_sys->oc->pb );
  351. #else
  352.         put_flush_packet( &p_sys->oc->pb );
  353. #endif
  354.         p_sys->b_write_header = false;
  355.     }
  356.     for( ;; )
  357.     {
  358.         if( MuxGetStream( p_mux, &i_stream, 0 ) < 0 ) return VLC_SUCCESS;
  359.         MuxBlock( p_mux, p_mux->pp_inputs[i_stream] );
  360.     }
  361.     return VLC_SUCCESS;
  362. }
  363. /*****************************************************************************
  364.  * Control:
  365.  *****************************************************************************/
  366. static int Control( sout_mux_t *p_mux, int i_query, va_list args )
  367. {
  368.     bool *pb_bool;
  369.     switch( i_query )
  370.     {
  371.     case MUX_CAN_ADD_STREAM_WHILE_MUXING:
  372.         pb_bool = (bool*)va_arg( args, bool * );
  373.         *pb_bool = false;
  374.         return VLC_SUCCESS;
  375.     case MUX_GET_ADD_STREAM_WAIT:
  376.         pb_bool = (bool*)va_arg( args, bool * );
  377.         *pb_bool = true;
  378.         return VLC_SUCCESS;
  379.     case MUX_GET_MIME:
  380.     {
  381.         char **ppsz = (char**)va_arg( args, char ** );
  382.         *ppsz = strdup( p_mux->p_sys->oc->oformat->mime_type );
  383.         return VLC_SUCCESS;
  384.     }
  385.     default:
  386.         return VLC_EGENERIC;
  387.     }
  388. }
  389. /*****************************************************************************
  390.  * I/O wrappers for libavformat
  391.  *****************************************************************************/
  392. static int IOWrite( void *opaque, uint8_t *buf, int buf_size )
  393. {
  394.     URLContext *p_url = opaque;
  395.     sout_mux_t *p_mux = p_url->priv_data;
  396.     int i_ret;
  397. #ifdef AVFORMAT_DEBUG
  398.     msg_Dbg( p_mux, "IOWrite %i bytes", buf_size );
  399. #endif
  400.     block_t *p_buf = block_New( p_mux->p_sout, buf_size );
  401.     if( buf_size > 0 ) memcpy( p_buf->p_buffer, buf, buf_size );
  402.     if( p_mux->p_sys->b_write_header )
  403.         p_buf->i_flags |= BLOCK_FLAG_HEADER;
  404.     i_ret = sout_AccessOutWrite( p_mux->p_access, p_buf );
  405.     return i_ret ? i_ret : -1;
  406. }
  407. static int64_t IOSeek( void *opaque, int64_t offset, int whence )
  408. {
  409.     URLContext *p_url = opaque;
  410.     sout_mux_t *p_mux = p_url->priv_data;
  411.     int64_t i_absolute;
  412. #ifdef AVFORMAT_DEBUG
  413.     msg_Dbg( p_mux, "IOSeek offset: %"PRId64", whence: %i", offset, whence );
  414. #endif
  415.     switch( whence )
  416.     {
  417.     case SEEK_SET:
  418.         i_absolute = offset;
  419.         break;
  420.     case SEEK_CUR:
  421.     case SEEK_END:
  422.     default:
  423.         return -1;
  424.     }
  425.     if( sout_AccessOutSeek( p_mux->p_access, i_absolute ) )
  426.     {
  427.         return -1;
  428.     }
  429.     return 0;
  430. }