📄 mux.c
字号:
i_aspect_den * (int64_t)codec->width, 1 << 30 ); 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 ) { codec->extradata_size = p_input->p_fmt->i_extra; codec->extradata = av_malloc( p_input->p_fmt->i_extra ); memcpy( codec->extradata, p_input->p_fmt->p_extra, p_input->p_fmt->i_extra ); } return VLC_SUCCESS;}/***************************************************************************** * DelStream *****************************************************************************/static int DelStream( sout_mux_t *p_mux, sout_input_t *p_input ){ msg_Dbg( p_mux, "removing input" ); free( p_input->p_sys ); return VLC_SUCCESS;}/* * TODO move this function to src/stream_output.c (used by nearly all muxers) */static int MuxGetStream( sout_mux_t *p_mux, int *pi_stream, mtime_t *pi_dts ){ mtime_t i_dts; int i_stream, i; for( i = 0, i_dts = 0, i_stream = -1; i < p_mux->i_nb_inputs; i++ ) { block_fifo_t *p_fifo; p_fifo = p_mux->pp_inputs[i]->p_fifo; /* We don't really need to have anything in the SPU fifo */ if( p_mux->pp_inputs[i]->p_fmt->i_cat == SPU_ES && block_FifoCount( p_fifo ) == 0 ) continue; if( block_FifoCount( p_fifo ) ) { block_t *p_buf; p_buf = block_FifoShow( p_fifo ); if( i_stream < 0 || p_buf->i_dts < i_dts ) { i_dts = p_buf->i_dts; i_stream = i; } } else return -1; } if( pi_stream ) *pi_stream = i_stream; if( pi_dts ) *pi_dts = i_dts; if( !p_mux->p_sys->i_initial_dts ) p_mux->p_sys->i_initial_dts = i_dts; return i_stream;}static int MuxBlock( sout_mux_t *p_mux, sout_input_t *p_input ){ sout_mux_sys_t *p_sys = p_mux->p_sys; block_t *p_data = block_FifoGet( p_input->p_fifo ); int i_stream = *((int *)p_input->p_sys); AVStream *p_stream = p_sys->oc->streams[i_stream]; AVPacket pkt; memset( &pkt, 0, sizeof(AVPacket) ); av_init_packet(&pkt); pkt.data = p_data->p_buffer; 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; /* avformat expects pts/dts which start from 0 */ p_data->i_dts -= p_mux->p_sys->i_initial_dts; p_data->i_pts -= p_mux->p_sys->i_initial_dts; if( p_data->i_pts > 0 ) pkt.pts = p_data->i_pts * p_stream->time_base.den / INT64_C(1000000) / p_stream->time_base.num; if( p_data->i_dts > 0 ) pkt.dts = p_data->i_dts * p_stream->time_base.den / INT64_C(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 / INT64_C(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: %"PRId64", dts: %"PRId64") " "(pkt pts: %"PRId64", dts: %"PRId64")", p_data->i_pts, p_data->i_dts, pkt.pts, pkt.dts ); block_Release( p_data ); return VLC_EGENERIC; } block_Release( p_data ); return VLC_SUCCESS;}/***************************************************************************** * Mux: multiplex available data in input fifos *****************************************************************************/static int Mux( sout_mux_t *p_mux ){ sout_mux_sys_t *p_sys = p_mux->p_sys; int i_stream; if( p_sys->b_error ) return VLC_EGENERIC; if( p_sys->b_write_header ) { msg_Dbg( p_mux, "writing header" ); if( av_write_header( p_sys->oc ) < 0 ) { msg_Err( p_mux, "could not write header" ); 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 );#else put_flush_packet( &p_sys->oc->pb );#endif p_sys->b_write_header = false; } for( ;; ) { if( MuxGetStream( p_mux, &i_stream, 0 ) < 0 ) return VLC_SUCCESS; MuxBlock( p_mux, p_mux->pp_inputs[i_stream] ); } return VLC_SUCCESS;}/***************************************************************************** * Control: *****************************************************************************/static int Control( sout_mux_t *p_mux, int i_query, va_list args ){ bool *pb_bool; switch( i_query ) { case MUX_CAN_ADD_STREAM_WHILE_MUXING: pb_bool = (bool*)va_arg( args, bool * ); *pb_bool = false; return VLC_SUCCESS; case MUX_GET_ADD_STREAM_WAIT: pb_bool = (bool*)va_arg( args, bool * ); *pb_bool = true; 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; }}/***************************************************************************** * I/O wrappers for libavformat *****************************************************************************/static int IOWrite( void *opaque, uint8_t *buf, int buf_size ){ URLContext *p_url = opaque; sout_mux_t *p_mux = p_url->priv_data; int i_ret;#ifdef AVFORMAT_DEBUG msg_Dbg( p_mux, "IOWrite %i bytes", buf_size );#endif 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;}static offset_t IOSeek( void *opaque, offset_t offset, int whence ){ URLContext *p_url = opaque; sout_mux_t *p_mux = p_url->priv_data; int64_t i_absolute;#ifdef AVFORMAT_DEBUG msg_Dbg( p_mux, "IOSeek offset: %"PRId64", whence: %i", offset, whence );#endif switch( whence ) { case SEEK_SET: i_absolute = offset; break; case SEEK_CUR: case SEEK_END: default: return -1; } if( sout_AccessOutSeek( p_mux->p_access, i_absolute ) ) { return -1; } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -