X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fdemux%2Favformat%2Fmux.c;h=bebe5838d5cf60f581813fc0a8ebd26d54260a98;hb=c14b0b5e14f98643c71b62aae9f4ce9d85d74192;hp=c48eee8aab3c1bb6b7de96cba4edd975ec9f0ae0;hpb=d466fd4185ffd791413658e948205e2676d2f470;p=vlc diff --git a/modules/demux/avformat/mux.c b/modules/demux/avformat/mux.c index c48eee8aab..bebe5838d5 100644 --- a/modules/demux/avformat/mux.c +++ b/modules/demux/avformat/mux.c @@ -1,5 +1,5 @@ /***************************************************************************** - * mux.c: muxer using ffmpeg (libavformat). + * mux.c: muxer using libavformat ***************************************************************************** * Copyright (C) 2006 the VideoLAN team * $Id$ @@ -33,21 +33,21 @@ #include #include -/* ffmpeg header */ -#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H -# include -#elif defined(HAVE_FFMPEG_AVFORMAT_H) -# include -#endif +#include #include "avformat.h" #include "../../codec/avcodec/avcodec.h" -#include "../../codec/avcodec/avutil.h" +#include "../../codec/avcodec/avcommon.h" + +/* Support for deprecated APIs */ +#if LIBAVFORMAT_VERSION_INT < ((52<<16)+(105<<8)+0) +# define avio_flush put_flush_packet +#endif //#define AVFORMAT_DEBUG 1 static const char *const ppsz_mux_options[] = { - "mux", NULL + "mux", "options", NULL }; /***************************************************************************** @@ -55,13 +55,15 @@ static const char *const ppsz_mux_options[] = { *****************************************************************************/ struct sout_mux_sys_t { +#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(105<<8)+0) + AVIOContext *io; +#else ByteIOContext io; +#endif int io_buffer_size; uint8_t *io_buffer; AVFormatContext *oc; - URLContext url; - URLProtocol prot; bool b_write_header; bool b_error; @@ -88,25 +90,31 @@ int OpenMux( vlc_object_t *p_this ) 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( LibavutilCallback ); + vlc_init_avformat(); - config_ChainParse( p_mux, "ffmpeg-", ppsz_mux_options, p_mux->p_cfg ); + config_ChainParse( p_mux, "sout-avformat-", ppsz_mux_options, p_mux->p_cfg ); /* Find the requested muxer */ - psz_mux = var_GetNonEmptyString( p_mux, "ffmpeg-mux" ); + psz_mux = var_GetNonEmptyString( p_mux, "sout-avformat-mux" ); if( psz_mux ) { +#if( LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( 52, 45, 0 ) ) + file_oformat = av_guess_format( psz_mux, NULL, NULL ); +#else file_oformat = guess_format( psz_mux, NULL, NULL ); +#endif + free( psz_mux ); } else { file_oformat = - guess_format(NULL, p_mux->p_access->psz_path, NULL); +#if( LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( 52, 45, 0 ) ) + av_guess_format( NULL, p_mux->p_access->psz_path, NULL); +#else + guess_format( NULL, p_mux->p_access->psz_path, NULL); +#endif } if (!file_oformat) { @@ -120,27 +128,30 @@ int OpenMux( vlc_object_t *p_this ) p_mux->pf_delstream = DelStream; p_mux->pf_mux = Mux; p_mux->p_sys = p_sys = malloc( sizeof( sout_mux_sys_t ) ); + if( !p_sys ) + return VLC_ENOMEM; - p_sys->oc = av_alloc_format_context(); + p_sys->oc = avformat_alloc_context(); p_sys->oc->oformat = file_oformat; + /* If we use dummy access, let avformat write output */ + if( !strcmp( p_mux->p_access->psz_access, "dummy") ) + strcpy( p_sys->oc->filename, p_mux->p_access->psz_path ); /* Create I/O wrapper */ p_sys->io_buffer_size = 32768; /* FIXME */ p_sys->io_buffer = malloc( p_sys->io_buffer_size ); - p_sys->url.priv_data = p_mux; - p_sys->url.prot = &p_sys->prot; - p_sys->url.prot->name = "VLC I/O wrapper"; - p_sys->url.prot->url_open = 0; - p_sys->url.prot->url_read = 0; - p_sys->url.prot->url_write = - (int (*) (URLContext *, unsigned char *, int))IOWrite; - p_sys->url.prot->url_seek = - (int64_t (*) (URLContext *, int64_t, int))IOSeek; - p_sys->url.prot->url_close = 0; - p_sys->url.prot->next = 0; - init_put_byte( &p_sys->io, p_sys->io_buffer, p_sys->io_buffer_size, - 1, &p_sys->url, NULL, IOWrite, IOSeek ); +#if (LIBAVFORMAT_VERSION_INT >= ((52<<16)+(105<<8)+0)) + p_sys->io = avio_alloc_context( +#else + init_put_byte( &p_sys->io, +#endif + p_sys->io_buffer, p_sys->io_buffer_size, + 1, p_mux, NULL, IOWrite, IOSeek ); + + +#if (LIBAVFORMAT_VERSION_INT < ((52<<16)+(105<<8)+0)) + AVFormatParameters params, *ap = ¶ms; memset( ap, 0, sizeof(*ap) ); if( av_set_parameters( p_sys->oc, ap ) < 0 ) { @@ -150,11 +161,12 @@ int OpenMux( vlc_object_t *p_this ) free( p_sys ); return VLC_EGENERIC; } +#endif -#if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0) - p_sys->oc->pb = &p_sys->io; -#else +#if (LIBAVFORMAT_VERSION_INT >= ((52<<16)+(105<<8)+0)) p_sys->oc->pb = p_sys->io; +#else + p_sys->oc->pb = &p_sys->io; #endif p_sys->oc->nb_streams = 0; @@ -172,21 +184,27 @@ void CloseMux( vlc_object_t *p_this ) { sout_mux_t *p_mux = (sout_mux_t*)p_this; sout_mux_sys_t *p_sys = p_mux->p_sys; - unsigned int i; - if( av_write_trailer( p_sys->oc ) < 0 ) + if( !p_sys->b_write_header && !p_sys->b_error && av_write_trailer( p_sys->oc ) < 0 ) { msg_Err( p_mux, "could not write trailer" ); } - for( i = 0 ; i < p_sys->oc->nb_streams; i++ ) +#if( LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( 52, 96, 0 ) ) + avformat_free_context(p_sys->oc); +#else + for( unsigned i = 0 ; i < p_sys->oc->nb_streams; i++ ) { - if( p_sys->oc->streams[i]->codec->extradata ) - av_free( p_sys->oc->streams[i]->codec->extradata ); + av_free( p_sys->oc->streams[i]->codec->extradata ); av_free( p_sys->oc->streams[i]->codec ); +#if( LIBAVFORMAT_VERSION_INT >= AV_VERSION_INT( 52, 81, 0 ) ) + av_free( p_sys->oc->streams[i]->info ); +#endif av_free( p_sys->oc->streams[i] ); } + av_free( p_sys->oc->streams ); av_free( p_sys->oc ); +#endif free( p_sys->io_buffer ); free( p_sys ); @@ -200,7 +218,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) sout_mux_sys_t *p_sys = p_mux->p_sys; AVCodecContext *codec; AVStream *stream; - int i_codec_id, i_aspect_num, i_aspect_den; + int i_codec_id; msg_Dbg( p_mux, "adding input" ); @@ -214,7 +232,17 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) p_input->p_sys = malloc( sizeof( int ) ); *((int *)p_input->p_sys) = p_sys->oc->nb_streams; + if( p_input->p_fmt->i_cat != VIDEO_ES && p_input->p_fmt->i_cat != AUDIO_ES) + { + msg_Warn( p_mux, "Unhandled ES category" ); + return VLC_EGENERIC; + } + +#if (LIBAVFORMAT_VERSION_INT >= ((53<<16)+(10<<8)+0)) + stream = avformat_new_stream( p_sys->oc, NULL); +#else stream = av_new_stream( p_sys->oc, p_sys->oc->nb_streams); +#endif if( !stream ) { free( p_input->p_sys ); @@ -222,16 +250,16 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) } codec = stream->codec; - /* This is used by LibavutilCallback (avutil.h) to print messages */ - codec->opaque = (void*)p_mux; + codec->opaque = p_mux; switch( p_input->p_fmt->i_cat ) { case AUDIO_ES: - codec->codec_type = CODEC_TYPE_AUDIO; + codec->codec_type = AVMEDIA_TYPE_AUDIO; codec->channels = p_input->p_fmt->audio.i_channels; codec->sample_rate = p_input->p_fmt->audio.i_rate; codec->time_base = (AVRational){1, codec->sample_rate}; + codec->frame_size = p_input->p_fmt->audio.i_frame_length; break; case VIDEO_ES: @@ -242,7 +270,7 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) p_input->p_fmt->video.i_frame_rate = 25; p_input->p_fmt->video.i_frame_rate_base = 1; } - codec->codec_type = CODEC_TYPE_VIDEO; + codec->codec_type = AVMEDIA_TYPE_VIDEO; codec->width = p_input->p_fmt->video.i_width; codec->height = p_input->p_fmt->video.i_height; av_reduce( &codec->sample_aspect_ratio.num, @@ -257,8 +285,6 @@ static int AddStream( sout_mux_t *p_mux, sout_input_t *p_input ) 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; @@ -315,7 +341,7 @@ static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input ) pkt.size = p_data->i_buffer; pkt.stream_index = i_stream; - if( p_data->i_flags & BLOCK_FLAG_TYPE_I ) pkt.flags |= PKT_FLAG_KEY; + if( p_data->i_flags & BLOCK_FLAG_TYPE_I ) pkt.flags |= AV_PKT_FLAG_KEY; /* avformat expects pts/dts which start from 0 */ p_data->i_dts -= p_mux->p_sys->i_initial_dts; @@ -356,20 +382,37 @@ static int Mux( sout_mux_t *p_mux ) if( p_sys->b_write_header ) { + int error; msg_Dbg( p_mux, "writing header" ); - if( av_write_header( p_sys->oc ) < 0 ) +#if (LIBAVFORMAT_VERSION_INT >= ((53<<16)+(2<<8)+0)) + char *psz_opts = var_GetNonEmptyString( p_mux, "sout-avformat-options" ); + AVDictionary *options = NULL; + if (psz_opts && *psz_opts) + options = vlc_av_get_options(psz_opts); + free(psz_opts); + error = avformat_write_header( p_sys->oc, options ? &options : NULL); + AVDictionaryEntry *t = NULL; + while ((t = av_dict_get(options, "", t, AV_DICT_IGNORE_SUFFIX))) { + msg_Err( p_mux, "Unknown option \"%s\"", t->key ); + } + av_dict_free(&options); +#else + error = av_write_header( p_sys->oc ); +#endif + if( error < 0 ) { - msg_Err( p_mux, "could not write header" ); + errno = AVUNERROR(error); + msg_Err( p_mux, "could not write header: %m" ); p_sys->b_write_header = false; p_sys->b_error = true; return VLC_EGENERIC; } #if LIBAVFORMAT_VERSION_INT >= ((52<<16)+(0<<8)+0) - put_flush_packet( p_sys->oc->pb ); + avio_flush( p_sys->oc->pb ); #else - put_flush_packet( &p_sys->oc->pb ); + avio_flush( &p_sys->oc->pb ); #endif p_sys->b_write_header = false; } @@ -427,8 +470,7 @@ static int Control( sout_mux_t *p_mux, int i_query, va_list args ) *****************************************************************************/ static int IOWrite( void *opaque, uint8_t *buf, int buf_size ) { - URLContext *p_url = opaque; - sout_mux_t *p_mux = p_url->priv_data; + sout_mux_t *p_mux = opaque; int i_ret; #ifdef AVFORMAT_DEBUG @@ -447,8 +489,7 @@ static int IOWrite( void *opaque, uint8_t *buf, int buf_size ) static int64_t IOSeek( void *opaque, int64_t offset, int whence ) { - URLContext *p_url = opaque; - sout_mux_t *p_mux = p_url->priv_data; + sout_mux_t *p_mux = opaque; #ifdef AVFORMAT_DEBUG msg_Dbg( p_mux, "IOSeek offset: %"PRId64", whence: %i", offset, whence );