Mercurial > mplayer.hg
changeset 14757:7a2adc5e8928
initial, extremely experimental, libavformat muxer; don't expect anything to work yet
author | nicodvb |
---|---|
date | Mon, 21 Feb 2005 23:18:31 +0000 |
parents | 0c755d34ce18 |
children | 94456deb0624 |
files | cfg-mencoder.h libmpdemux/Makefile libmpdemux/muxer.c libmpdemux/muxer.h libmpdemux/muxer_lavf.c mencoder.c |
diffstat | 6 files changed, 328 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- a/cfg-mencoder.h Mon Feb 21 22:28:06 2005 +0000 +++ b/cfg-mencoder.h Mon Feb 21 23:18:31 2005 +0000 @@ -73,6 +73,9 @@ extern m_option_t nuvopts_conf[]; extern m_option_t mpegopts_conf[]; +#ifdef USE_LIBAVFORMAT +extern m_option_t lavfopts_conf[]; +#endif m_option_t ovc_conf[]={ {"copy", &out_video_codec, CONF_TYPE_FLAG, 0, 0, VCODEC_COPY, NULL}, @@ -177,6 +180,9 @@ m_option_t of_conf[]={ {"avi", &out_file_format, CONF_TYPE_FLAG, 0, 0, MUXER_TYPE_AVI, NULL}, {"mpeg", &out_file_format, CONF_TYPE_FLAG, 0, 0, MUXER_TYPE_MPEG, NULL}, +#ifdef USE_LIBAVFORMAT + {"lavf", &out_file_format, CONF_TYPE_FLAG, 0, 0, MUXER_TYPE_LAVF, NULL}, +#endif {"rawvideo", &out_file_format, CONF_TYPE_FLAG, 0, 0, MUXER_TYPE_RAWVIDEO, NULL}, {"help", "\nAvailable output formats:\n" " avi - Microsoft Audio/Video Interleaved\n" @@ -271,6 +277,9 @@ {"nuvopts", nuvopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, {"mpegopts", mpegopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, +#ifdef USE_LIBAVFORMAT + {"lavfopts", lavfopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL}, +#endif #define MAIN_CONF #include "cfg-common.h"
--- a/libmpdemux/Makefile Mon Feb 21 22:28:06 2005 +0000 +++ b/libmpdemux/Makefile Mon Feb 21 23:18:31 2005 +0000 @@ -31,6 +31,7 @@ ifeq ($(CONFIG_LIBAVFORMAT),yes) LIBAV_INC = -I../libavcodec -I../libavformat +SRCS += muxer_lavf.c endif OBJS = $(SRCS:.c=.o)
--- a/libmpdemux/muxer.c Mon Feb 21 22:28:06 2005 +0000 +++ b/libmpdemux/muxer.c Mon Feb 21 23:18:31 2005 +0000 @@ -31,6 +31,12 @@ if(! muxer_init_muxer_rawvideo(muxer)) return NULL; break; +#ifdef USE_LIBAVFORMAT + case MUXER_TYPE_LAVF: + if(! muxer_init_muxer_lavf(muxer)) + return NULL; + break; +#endif case MUXER_TYPE_AVI: default: if(! muxer_init_muxer_avi(muxer))
--- a/libmpdemux/muxer.h Mon Feb 21 22:28:06 2005 +0000 +++ b/libmpdemux/muxer.h Mon Feb 21 23:18:31 2005 +0000 @@ -7,6 +7,7 @@ #define MUXER_TYPE_AVI 0 #define MUXER_TYPE_MPEG 1 #define MUXER_TYPE_RAWVIDEO 2 +#define MUXER_TYPE_LAVF 3 typedef struct {
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/muxer_lavf.c Mon Feb 21 23:18:31 2005 +0000 @@ -0,0 +1,307 @@ +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <sys/types.h> +#include <inttypes.h> +#include "config.h" +#include "../version.h" +#include "../mp_msg.h" + +#include "bswap.h" +#include "aviheader.h" +#include "ms_hdr.h" + +#include "muxer.h" +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" +#include "../m_option.h" +#include "avformat.h" + +typedef struct { + //AVInputFormat *avif; + AVFormatContext *oc; + ByteIOContext pb; + int audio_streams; + int video_streams; + int64_t last_pts; +} muxer_priv_t; + +typedef struct { + int64_t last_pts; + AVStream *avstream; +} muxer_stream_priv_t; + +static char *conf_format = NULL; + +m_option_t lavfopts_conf[] = { + {"format", &(conf_format), CONF_TYPE_STRING, 0, 0, 0, NULL}, + {NULL, NULL, 0, 0, 0, 0, NULL} +}; + +static int mp_open(URLContext *h, const char *filename, int flags) +{ + return 0; +} + +static int mp_close(URLContext *h) +{ + return 0; +} + + +static int mp_read(URLContext *h, unsigned char *buf, int size) +{ + fprintf(stderr, "READ %d\n", size); + return -1; +} + +static int mp_write(URLContext *h, unsigned char *buf, int size) +{ + muxer_t *muxer = (muxer_t*)h->priv_data; + return fwrite(buf, 1, size, muxer->file); +} + +static offset_t mp_seek(URLContext *h, offset_t pos, int whence) +{ + muxer_t *muxer = (muxer_t*)h->priv_data; + fprintf(stderr, "SEEK %llu\n", pos); + return fseeko(muxer->file, pos, whence); +} + + +static URLProtocol mp_protocol = { + "menc", + mp_open, + mp_read, + mp_write, + mp_seek, + mp_close, +}; + +static muxer_stream_t* lavf_new_stream(muxer_t *muxer, int type) +{ + muxer_priv_t *priv = (muxer_priv_t*) muxer->priv; + muxer_stream_t *stream; + muxer_stream_priv_t *spriv; + AVCodecContext *ctx; + + if(!muxer || (type != MUXER_TYPE_VIDEO && type != MUXER_TYPE_AUDIO)) + { + mp_msg(MSGT_MUXER, MSGL_ERR, "UNKNOW TYPE %d\n", type); + return NULL; + } + + stream = (muxer_stream_t*) calloc(1, sizeof(muxer_stream_t)); + if(!stream) + { + mp_msg(MSGT_MUXER, MSGL_ERR, "Could not alloc muxer_stream, EXIT\n"); + return NULL; + } + stream->b_buffer = malloc(2048); + if(!stream->b_buffer) + { + mp_msg(MSGT_MUXER, MSGL_ERR, "Could not alloc b_buffer, EXIT\n"); + free(stream); + return NULL; + } + stream->b_buffer_size = 2048; + stream->b_buffer_ptr = 0; + stream->b_buffer_len = 0; + + spriv = (muxer_stream_priv_t*) calloc(1, sizeof(muxer_stream_priv_t)); + if(!spriv) + { + free(stream); + return NULL; + } + stream->priv = spriv; + + spriv->avstream = av_new_stream(priv->oc, 1); + if(!spriv->avstream) + { + mp_msg(MSGT_MUXER, MSGL_ERR, "Could not alloc avstream, EXIT\n"); + return NULL; + } + spriv->avstream->stream_copy = 1; + + ctx = &(spriv->avstream->codec); + ctx->codec_id = muxer->avih.dwStreams; + switch(type) + { + case MUXER_TYPE_VIDEO: + ctx->codec_type = CODEC_TYPE_VIDEO; + break; + case MUXER_TYPE_AUDIO: + ctx->codec_type = CODEC_TYPE_AUDIO; + break; + } + + muxer->avih.dwStreams++; + stream->muxer = muxer; + stream->type = type; + mp_msg(MSGT_MUXER, MSGL_V, "ALLOCATED STREAM N. %d, type=%d\n", muxer->avih.dwStreams, type); + return stream; +} + + +static void fix_parameters(muxer_stream_t *stream, void *sh) +{ + muxer_stream_priv_t *spriv = (muxer_stream_priv_t *) stream->priv; + AVCodecContext *ctx; + + ctx = &(spriv->avstream->codec); + + if(stream->type == MUXER_TYPE_AUDIO) + { + ctx->codec_id = codec_get_wav_id(stream->wf->wFormatTag); + ctx->codec_tag = codec_get_wav_tag(ctx->codec_id); + mp_msg(MSGT_MUXER, MSGL_INFO, "AUDIO CODEC ID: %x, TAG: %x\n", ctx->codec_id, (uint32_t) ctx->codec_tag); + ctx->bit_rate = stream->wf->nAvgBytesPerSec * 8; + ctx->sample_rate = stream->h.dwSampleSize; + ctx->channels = stream->wf->nChannels; + ctx->frame_size = 576; + ctx->block_align = stream->wf->nBlockAlign; + } + else if(stream->type == MUXER_TYPE_VIDEO) + { + ctx->codec_id = codec_get_bmp_id(stream->bih->biCompression); + mp_msg(MSGT_MUXER, MSGL_INFO, "VIDEO CODEC ID: %d\n", ctx->codec_id); + ctx->width = stream->bih->biWidth; + ctx->height = stream->bih->biHeight; + ctx->bit_rate = 800000; + ctx->frame_rate = (int) (10000 * stream->h.dwRate)/ stream->h.dwScale;; + ctx->frame_rate_base = 10000; + } +} + +static void write_chunk(muxer_stream_t *stream, size_t len, unsigned int flags) +{ + muxer_t *muxer = (muxer_t*) stream->muxer; + muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; + muxer_stream_priv_t *spriv = (muxer_stream_priv_t *) stream->priv; + AVPacket pkt; + AVCodecContext *ctx; + + stream->size += len; + if(stream->type == MUXER_TYPE_VIDEO && !len) + return; + + av_init_packet(&pkt); + pkt.size = len; + pkt.stream_index= spriv->avstream->index; + pkt.data = stream->buffer; + + if((stream->type == MUXER_TYPE_VIDEO) && (flags & AVIIF_KEYFRAME)) + pkt.flags |= PKT_FLAG_KEY; + else + pkt.flags = 0; + + + //pkt.pts = AV_NOPTS_VALUE; + pkt.pts = AV_TIME_BASE * stream->timer; + + if(stream->h.dwSampleSize) // CBR + stream->h.dwLength += len / stream->h.dwSampleSize; + else // VBR + stream->h.dwLength++; + + //; + if(av_interleaved_write_frame(priv->oc, &pkt) != 0) //av_write_frame(priv->oc, &pkt) + { + mp_msg(MSGT_MUXER, MSGL_ERR, "Error while writing frame\n"); + } + + stream->timer = (double) stream->h.dwLength * stream->h.dwScale / stream->h.dwRate; + return; +} + + +static void write_header(muxer_t *muxer) +{ + muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; + + av_write_header(priv->oc); + muxer->cont_write_header = NULL; + mp_msg(MSGT_MUXER, MSGL_INFO, "WRITTEN HEADER\n"); +} + + +static void write_trailer(muxer_t *muxer) +{ + int i; + muxer_priv_t *priv = (muxer_priv_t *) muxer->priv; + + av_write_trailer(priv->oc); + mp_msg(MSGT_MUXER, MSGL_INFO, "WRITTEN TRAILER\n"); + for(i = 0; i < priv->oc->nb_streams; i++) + { + av_freep(&(priv->oc->streams[i])); + } + + url_fclose(&(priv->oc->pb)); + + av_free(priv->oc); +} + +extern char *out_filename; +int muxer_init_muxer_lavf(muxer_t *muxer) +{ + muxer_priv_t *priv; + AVOutputFormat *fmt = NULL; + char mp_filename[256] = "menc://stream.dummy"; + + priv = (muxer_priv_t *) calloc(1, sizeof(muxer_priv_t)); + if(priv == NULL) + return 0; + + av_register_all(); + + priv->oc = av_alloc_format_context(); + if(!priv->oc) + { + mp_msg(MSGT_MUXER, MSGL_FATAL, "Couldn't get format context\n"); + goto fail; + } + + if(conf_format) + fmt = guess_format(conf_format, NULL, NULL); + if(! fmt) + fmt = guess_format(NULL, out_filename, NULL); + if(! fmt) + { + mp_msg(MSGT_MUXER, MSGL_FATAL, "CAN'T GET SPECIFIED FORMAT\n"); + goto fail; + } + priv->oc->oformat = fmt; + + + if(av_set_parameters(priv->oc, NULL) < 0) + { + mp_msg(MSGT_MUXER, MSGL_FATAL, "Invalid output format parameters\n"); + goto fail; + } + + register_protocol(&mp_protocol); + + if(url_fopen(&priv->oc->pb, mp_filename, URL_WRONLY)) + { + mp_msg(MSGT_MUXER, MSGL_FATAL, "Coulnd't open outfile\n"); + goto fail; + } + + ((URLContext*)(priv->oc->pb.opaque))->priv_data= muxer; + + muxer->priv = (void *) priv; + muxer->cont_new_stream = &lavf_new_stream; + muxer->cont_write_chunk = &write_chunk; + muxer->cont_write_header = &write_header; + muxer->cont_write_index = &write_trailer; + muxer->fix_stream_parameters = &fix_parameters; + mp_msg(MSGT_MUXER, MSGL_INFO, "OK, exit\n"); + return 1; + +fail: + free(priv); + return 0; +}
--- a/mencoder.c Mon Feb 21 22:28:06 2005 +0000 +++ b/mencoder.c Mon Feb 21 23:18:31 2005 +0000 @@ -746,6 +746,8 @@ mux_v->bih->biCompression, (char *)&mux_v->bih->biCompression); } +if(muxer->fix_stream_parameters) + muxer_stream_fix_parameters(muxer,mux_v); //if(demuxer->file_format!=DEMUXER_TYPE_AVI) pts_from_bps=0; // it must be 0 for mpeg/asf! // ============= AUDIO =============== @@ -1062,6 +1064,8 @@ mux_a->h.dwStart=audio_delay*mux_a->h.dwRate/mux_a->h.dwScale; mp_msg(MSGT_FIXME, MSGL_FIXME, MSGTR_SettingAudioDelay,mux_a->h.dwStart*mux_a->h.dwScale/(float)mux_a->h.dwRate); } +if(muxer->fix_stream_parameters) + muxer_stream_fix_parameters(muxer,mux_a); } // if(sh_audio)