/*****************************************************************************
* Preamble
*****************************************************************************/
-#include <stdlib.h> /* malloc(), free() */
+
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
#include <vlc/vlc.h>
-#include <vlc/input.h>
-#include <vlc/sout.h>
+#include <vlc_block.h>
+#include <vlc_sout.h>
/* ffmpeg header */
-#ifdef HAVE_FFMPEG_AVFORMAT_H
-# include <ffmpeg/avformat.h>
+#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
+# include <libavformat/avformat.h>
#elif defined(HAVE_LIBAVFORMAT_TREE)
# include <avformat.h>
#endif
//#define AVFORMAT_DEBUG 1
/* Version checking */
-#if (LIBAVFORMAT_BUILD >= 4687) && (defined(HAVE_FFMPEG_AVFORMAT_H) || defined(HAVE_LIBAVFORMAT_TREE))
+#if defined(HAVE_LIBSWSCALE_SWSCALE_H) || defined(HAVE_FFMPEG_SWSCALE_H) || defined(HAVE_LIBSWSCALE_TREE)
+
+static const char *ppsz_mux_options[] = {
+ "mux", NULL
+};
/*****************************************************************************
* mux_sys_t: mux descriptor
*****************************************************************************/
int E_(OpenMux)( vlc_object_t *p_this )
{
- AVOutputFormat *file_oformat;
+ AVOutputFormat *file_oformat;
sout_mux_t *p_mux = (sout_mux_t*)p_this;
sout_mux_sys_t *p_sys;
AVFormatParameters params, *ap = ¶ms;
+ char *psz_mux;
/* Should we call it only once ? */
av_register_all();
+ av_log_set_callback( E_(LibavcodecCallback) );
+
+ config_ChainParse( p_mux, "ffmpeg-", ppsz_mux_options, p_mux->p_cfg );
/* Find the requested muxer */
- file_oformat =
- guess_format(NULL, p_mux->p_access->psz_name, NULL);
+ psz_mux = var_GetNonEmptyString( p_mux, "ffmpeg-mux" );
+ if( psz_mux )
+ {
+ file_oformat = guess_format( psz_mux, NULL, NULL );
+ }
+ else
+ {
+ file_oformat =
+ guess_format(NULL, p_mux->p_access->psz_path, NULL);
+ }
if (!file_oformat)
{
msg_Err( p_mux, "unable for find a suitable output format" );
return VLC_EGENERIC;
}
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0)
+ p_sys->oc->pb = &p_sys->io;
+#else
p_sys->oc->pb = p_sys->io;
+#endif
p_sys->oc->nb_streams = 0;
p_sys->b_write_header = VLC_TRUE;
{
sout_mux_t *p_mux = (sout_mux_t*)p_this;
sout_mux_sys_t *p_sys = p_mux->p_sys;
- int i;
+ unsigned int i;
if( av_write_trailer( p_sys->oc ) < 0 )
{
}
codec = stream->codec;
+ /* This is used by LibavcodecCallback (ffmpeg.c) to print messages */
+ codec->opaque = (void*)p_mux;
+
switch( p_input->p_fmt->i_cat )
{
case AUDIO_ES:
codec->time_base.den = p_input->p_fmt->video.i_frame_rate;
codec->time_base.num = p_input->p_fmt->video.i_frame_rate_base;
break;
+
+ default:
+ msg_Warn( p_mux, "Unhandled ES category" );
}
codec->bit_rate = p_input->p_fmt->i_bitrate;
+#if LIBAVFORMAT_VERSION_INT >= ((51<<16)+(8<<8)+0)
+ codec->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
+ if( !codec->codec_tag && i_codec_id == CODEC_ID_MP2 )
+ {
+ i_codec_id = CODEC_ID_MP3;
+ codec->codec_tag = av_codec_get_tag( p_sys->oc->oformat->codec_tag, i_codec_id );
+ }
+#else
+# warning "WARNING!!!!!!!"
+# warning "Using libavformat muxing with versions older than 51.8.0 (r7593) might produce broken files."
+ /* This is a hack */
+ if( i_codec_id == CODEC_ID_MP2 )
+ i_codec_id = CODEC_ID_MP3;
codec->codec_tag = p_input->p_fmt->i_codec;
+#endif
codec->codec_id = i_codec_id;
if( p_input->p_fmt->i_extra )
/* We don't really need to have anything in the SPU fifo */
if( p_mux->pp_inputs[i]->p_fmt->i_cat == SPU_ES &&
- p_fifo->i_depth == 0 ) continue;
+ block_FifoCount( p_fifo ) == 0 ) continue;
- if( p_fifo->i_depth )
+ if( block_FifoCount( p_fifo ) )
{
block_t *p_buf;
pkt.dts = p_data->i_dts * p_stream->time_base.den /
I64C(1000000) / p_stream->time_base.num;
+ /* this is another hack to prevent libavformat from triggering the "non monotone timestamps" check in avformat/utils.c */
+ p_stream->cur_dts = ( p_data->i_dts * p_stream->time_base.den /
+ I64C(1000000) / p_stream->time_base.num ) - 1;
+
if( av_write_frame( p_sys->oc, &pkt ) < 0 )
{
msg_Err( p_mux, "could not write frame (pts: "I64Fd", dts: "I64Fd") "
{
msg_Dbg( p_mux, "writing header" );
- p_sys->b_write_header = VLC_FALSE;
-
if( av_write_header( p_sys->oc ) < 0 )
{
msg_Err( p_mux, "could not write header" );
+ p_sys->b_write_header = VLC_FALSE;
p_sys->b_error = VLC_TRUE;
return VLC_EGENERIC;
}
+
+#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0)
+ put_flush_packet( p_sys->oc->pb );
+#else
+ put_flush_packet( &p_sys->oc->pb );
+#endif
+ p_sys->b_write_header = VLC_FALSE;
}
for( ;; )
return VLC_SUCCESS;
case MUX_GET_MIME:
+ {
+ char **ppsz = (char**)va_arg( args, char ** );
+ *ppsz = strdup( p_mux->p_sys->oc->oformat->mime_type );
+ return VLC_SUCCESS;
+ }
+
default:
return VLC_EGENERIC;
}
block_t *p_buf = block_New( p_mux->p_sout, buf_size );
if( buf_size > 0 ) memcpy( p_buf->p_buffer, buf, buf_size );
+ if( p_mux->p_sys->b_write_header )
+ p_buf->i_flags |= BLOCK_FLAG_HEADER;
+
i_ret = sout_AccessOutWrite( p_mux->p_access, p_buf );
return i_ret ? i_ret : -1;
}
return 0;
}
-#else /* LIBAVFORMAT_BUILD >= 4687 */
-
-int E_(OpenMux)( vlc_object_t *p_this )
-{
- return VLC_EGENERIC;
-}
-
-void E_(CloseMux)( vlc_object_t *p_this )
-{
-}
-
-#endif /* LIBAVFORMAT_BUILD >= 4687 */
+#endif /* HAVE_LIBAVFORMAT_AVFORMAT_H */