Mercurial > mplayer.hg
changeset 19861:b251bca5820c
Add demux_nut to MPlayer repo
author | ods15 |
---|---|
date | Sun, 17 Sep 2006 09:32:28 +0000 |
parents | 5753779baf80 |
children | 0a220ddc2531 |
files | Makefile configure libmpdemux/Makefile libmpdemux/demux_nut.c libmpdemux/demuxer.c libmpdemux/demuxer.h |
diffstat | 6 files changed, 358 insertions(+), 1 deletions(-) [+] |
line wrap: on
line diff
--- a/Makefile Sat Sep 16 22:39:23 2006 +0000 +++ b/Makefile Sun Sep 17 09:32:28 2006 +0000 @@ -110,6 +110,7 @@ $(X264_LIB) \ $(MUSEPACK_LIB) \ $(SPEEX_LIB) \ + $(NUT_LIB) \ ifeq ($(TOOLAME),yes) CODEC_LIBS += $(TOOLAME_LIB)
--- a/configure Sat Sep 16 22:39:23 2006 +0000 +++ b/configure Sun Sep 17 09:32:28 2006 +0000 @@ -263,6 +263,7 @@ --disable-real disable RealPlayer DLL support [autodetect] --disable-xvid disable XviD codec [autodetect] --disable-x264 disable H.264 encoder [autodetect] + --disable-nut disable libnut demuxer [autodetect] --disable-libavutil disable libavutil [autodetect] --disable-libavcodec disable libavcodec [autodetect] --disable-libavformat disable libavformat [autodetect] @@ -1671,6 +1672,7 @@ _joystick=no _xvid=auto _x264=auto +_nut=auto _lirc=auto _lircc=auto _gui=no @@ -1929,6 +1931,8 @@ --disable-xvid) _xvid=no ;; --enable-x264) _x264=yes ;; --disable-x264) _x264=no ;; + --enable-nut) _nut=yes ;; + --disable-nut) _nut=no ;; --enable-libavutil) _libavutil=yes ;; --disable-libavutil) _libavutil=no ;; --enable-libavutil_so) _libavutil_so=yes ;; @@ -6518,6 +6522,29 @@ echores "$_x264" +echocheck "nut" +if test "$_nut" = auto ; then + cat > $TMPC << EOF +#include <stdio.h> +#include <stdlib.h> +#include <inttypes.h> +#include <nut.h> +int main(void) { (void)nut_error(0); return 0; } +EOF + _ld_nut="-lnut" + _nut=no + cc_check $_ld_nut && _nut=yes +fi + +if test "$_nut" = yes ; then + _def_nut='#define HAVE_LIBNUT 1' +else + _ld_nut='' + _def_nut='#undef HAVE_LIBNUT' +fi +echores "$_nut" + + # mencoder requires (optional) those libs: libmp3lame if test "$_mencoder" != no ; then @@ -7476,6 +7503,8 @@ XVID_LIB = $_ld_xvid X264 = $_x264 X264_LIB = $_ld_x264 +LIBNUT = $_nut +NUT_LIB = $_ld_nut CONFIG_DTS = $_libdts DTS_LIB = $_ld_libdts DECORE_LIB = $_ld_mp3lame @@ -7667,6 +7696,9 @@ /* Define if you are using the X.264 library */ $_def_x264 +/* Define if you are using libnut */ +$_def_nut + /* Define to include support for libdv-0.9.5 */ $_def_libdv
--- a/libmpdemux/Makefile Sat Sep 16 22:39:23 2006 +0000 +++ b/libmpdemux/Makefile Sun Sep 17 09:32:28 2006 +0000 @@ -53,6 +53,9 @@ demux_y4m.c \ demux_mkv.c ebml.c \ +ifeq ($(LIBNUT),yes) +SRCS += demux_nut.c +endif ifeq ($(LIBVORBIS),yes) SRCS += demux_ogg.c endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libmpdemux/demux_nut.c Sun Sep 17 09:32:28 2006 +0000 @@ -0,0 +1,316 @@ +#include <stdio.h> + +#include "config.h" +#include "mp_msg.h" + +#include "stream.h" +#include "demuxer.h" +#include "stheader.h" + +#define USE_LIBNUT +#ifdef USE_LIBNUT + +#include "nut.h" + +typedef struct { + int last_pts; // FIXME + nut_context_t * nut; + nut_stream_header_t * s; +} nut_priv_t; + +static size_t mp_read(void * h, size_t len, uint8_t * buf) { + stream_t * stream = (stream_t*)h; + + if(stream_eof(stream)) return 0; + + return stream_read(stream, buf, len); +} + +static off_t mp_seek(void * h, long long pos, int whence) { + stream_t * stream = (stream_t*)h; + + if (stream->end_pos < stream_tell(stream)) + stream->end_pos = stream_tell(stream); + + if (whence == SEEK_CUR) pos += stream_tell(stream); + else if (whence == SEEK_END) pos += stream->end_pos; + else if (whence != SEEK_SET) return -1; + + if (pos < stream->end_pos && stream->eof) stream_reset(stream); + if (stream_seek(stream, pos) == 0) return -1; + + return pos; +} + +#define ID_STRING "nut/multimedia container" +#define ID_LENGTH (strlen(ID_STRING) + 1) + +static int nut_check_file(demuxer_t * demuxer) { + uint8_t buf[ID_LENGTH]; + nut_priv_t * priv = demuxer->priv = calloc(1, sizeof(nut_priv_t)); + + if (stream_read(demuxer->stream, buf, ID_LENGTH) != ID_LENGTH) return 0; + + if (memcmp(buf, ID_STRING, ID_LENGTH)) return 0; + + stream_seek(demuxer->stream, 0); + return DEMUXER_TYPE_NUT; +} + +static demuxer_t * demux_open_nut(demuxer_t * demuxer) { + extern int index_mode; + nut_demuxer_opts_t dopts = { + .input = { + .priv = demuxer->stream, + .seek = mp_seek, + .read = mp_read, + .eof = NULL, + .file_pos = stream_tell(demuxer->stream), + }, + .read_index = index_mode + }; + nut_priv_t * priv = demuxer->priv; + nut_context_t * nut = priv->nut = nut_demuxer_init(&dopts); + nut_stream_header_t * s; + int ret; + int i; + + if ((ret = nut_read_headers(nut, &s))) { + if (ret < 0) mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", + nut_error(-ret)); + nut_demuxer_uninit(nut); + free(priv); + return NULL; + } + + priv->s = s; + + for (i = 0; s[i].type != -1 && i < 2; i++) switch(s[i].type) { + case NUT_AUDIO_CLASS: { + WAVEFORMATEX *wf = + calloc(sizeof(WAVEFORMATEX) + + s[i].codec_specific_len, 1); + sh_audio_t* sh_audio = new_sh_audio(demuxer, i); + int j; + + sh_audio->wf= wf; sh_audio->ds = demuxer->audio; + sh_audio->audio.dwSampleSize = 0; // FIXME + sh_audio->audio.dwScale = s[i].time_base.nom; + sh_audio->audio.dwRate = s[i].time_base.den; + sh_audio->format = 0; + for (j = 0; j < s[i].fourcc_len && j < 4; j++) + sh_audio->format |= s[i].fourcc[j]<<(j*8); + sh_audio->channels = s[i].channel_count; + sh_audio->samplerate = + s[i].samplerate_nom / s[i].samplerate_denom; + sh_audio->i_bps = 0; // FIXME + + wf->wFormatTag = sh_audio->format; + wf->nChannels = s[i].channel_count; + wf->nSamplesPerSec = + s[i].samplerate_nom / s[i].samplerate_denom; + wf->nAvgBytesPerSec = 0; // FIXME + wf->nBlockAlign = 0; // FIXME + wf->wBitsPerSample = 0; // FIXME + wf->cbSize = s[i].codec_specific_len; + if (s[i].codec_specific_len) + memcpy(wf + 1, s[i].codec_specific, + s[i].codec_specific_len); + + demuxer->audio->id = i; + demuxer->audio->sh= demuxer->a_streams[i]; + break; + } + case NUT_VIDEO_CLASS: { + BITMAPINFOHEADER * bih = + calloc(sizeof(BITMAPINFOHEADER) + + s[i].codec_specific_len, 1); + sh_video_t * sh_video = new_sh_video(demuxer, i); + int j; + + sh_video->bih = bih; + sh_video->ds = demuxer->video; + sh_video->disp_w = s[i].width; + sh_video->disp_h = s[i].height; + sh_video->video.dwScale = s[i].time_base.nom; + sh_video->video.dwRate = s[i].time_base.den; + + sh_video->fps = sh_video->video.dwRate/ + (float)sh_video->video.dwScale; + sh_video->frametime = 1./sh_video->fps; + sh_video->format = 0; + for (j = 0; j < s[i].fourcc_len && j < 4; j++) + sh_video->format |= s[i].fourcc[j]<<(j*8); + if (!s[i].sample_height) sh_video->aspect = 0; + else sh_video->aspect = + s[i].sample_width / (float)s[i].sample_height; + sh_video->i_bps = 0; // FIXME + + bih->biSize = sizeof(BITMAPINFOHEADER) + + s[i].codec_specific_len; + bih->biWidth = s[i].width; + bih->biHeight = s[i].height; + bih->biBitCount = 0; // FIXME + bih->biSizeImage = 0; // FIXME + bih->biCompression = sh_video->format; + + if (s[i].codec_specific_len) + memcpy(bih + 1, s[i].codec_specific, + s[i].codec_specific_len); + + demuxer->video->id = i; + demuxer->video->sh = demuxer->v_streams[i]; + break; + } + } + + return demuxer; +} + +static int demux_nut_fill_buffer(demuxer_t * demuxer, demux_stream_t * dsds) { + nut_priv_t * priv = demuxer->priv; + nut_context_t * nut = priv->nut; + demux_packet_t *dp; + demux_stream_t *ds; + nut_packet_t pd; + int ret; + double pts; + + demuxer->filepos = stream_tell(demuxer->stream); + if (stream_eof(demuxer->stream)) return 0; + + while (1) { + ret = nut_read_next_packet(nut, &pd); + if (ret < 0) { + mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", + nut_error(-ret)); + continue; + } + if (ret == 1) return 0; // EOF + if (pd.type == e_frame) break; + // else, skip this packet + while ((ret = nut_skip_packet(nut, &pd.len))) { + if (ret < 0) { + mp_msg(MSGT_HEADER, MSGL_ERR, + "NUT error: %s\n", nut_error(-ret)); + break; + } + if (ret == 1) return 0; // EOF + } + } + + pts = (double)pd.pts * priv->s[pd.stream].time_base.nom / + priv->s[pd.stream].time_base.den; + + if (pd.stream == demuxer->audio->id) { + ds = demuxer->audio; + if (!demuxer->video->sh) { + ((sh_audio_t*)ds->sh)->delay = pts; + } + } + else if (pd.stream == demuxer->video->id) { + ds = demuxer->video; + } + else { + while ((ret = nut_skip_packet(nut, &pd.len))) { + if (ret < 0) { + mp_msg(MSGT_HEADER, MSGL_ERR, + "NUT error: %s\n", nut_error(-ret)); + break; + } + if (ret == 1) return 0; // EOF + } + return 1; + } + + if (pd.stream == 0) priv->last_pts = pd.pts; + + dp = new_demux_packet(pd.len); + + dp->pts = pts; + + dp->pos = demuxer->filepos; + dp->flags= (pd.flags & NUT_FLAG_KEY) ? 0x10 : 0; + + while ((ret = nut_read_frame(nut, &pd.len, dp->buffer))) { + if (ret < 0) { + mp_msg(MSGT_HEADER, MSGL_ERR, + "NUT error: %s\n", nut_error(-ret)); + break; + } + if (ret == 1) return 0; // EOF + } + ds_add_packet(ds, dp); // append packet to DS stream + return 1; +} + +static void demux_seek_nut(demuxer_t * demuxer, float time_pos, float audio_delay, int flags) { + nut_context_t * nut = ((nut_priv_t*)demuxer->priv)->nut; + nut_priv_t * priv = demuxer->priv; + sh_audio_t * sh_audio = demuxer->audio->sh; + int nutflags = 0; + int ret; + const int tmp[] = { 0, -1 }; + + if (!(flags & 1)) { + nutflags |= 1; // relative + if (time_pos > 0) nutflags |= 2; // forwards + } + + if (flags & 2) // percent + time_pos *= priv->s[0].max_pts * + (double)priv->s[0].time_base.nom / + priv->s[0].time_base.den; + + ret = nut_seek(nut, time_pos, nutflags, tmp); + if (ret < 0) + mp_msg(MSGT_HEADER, MSGL_ERR, "NUT error: %s\n", nut_error(-ret)); + if (sh_audio) resync_audio_stream(sh_audio); +} + +static int demux_control_nut(demuxer_t * demuxer, int cmd, void * arg) { + nut_priv_t * priv = demuxer->priv; + switch (cmd) { + case DEMUXER_CTRL_GET_TIME_LENGTH: + *((double *)arg) = priv->s[0].max_pts * + (double)priv->s[0].time_base.nom / + priv->s[0].time_base.den; + return DEMUXER_CTRL_OK; + case DEMUXER_CTRL_GET_PERCENT_POS: + if (priv->s[0].max_pts == 0) + return DEMUXER_CTRL_DONTKNOW; + *((int *)arg) = priv->last_pts * 100 / + (double)priv->s[0].max_pts; + return DEMUXER_CTRL_OK; + default: + return DEMUXER_CTRL_NOTIMPL; + } +} + +static void demux_close_nut(demuxer_t *demuxer) { + nut_context_t * nut = ((nut_priv_t*)demuxer->priv)->nut; + nut_demuxer_uninit(nut); + free(((nut_priv_t*)demuxer->priv)->s); + free(demuxer->priv); + demuxer->priv = NULL; +} + + +demuxer_desc_t demuxer_desc_nut = { + "NUT demuxer", + "nut", + "libnut", + "Oded Shimon (ods15)", + "NUT demuxer, requires libnut", + DEMUXER_TYPE_NUT, + 1, // safe check demuxer + nut_check_file, + demux_nut_fill_buffer, + demux_open_nut, + demux_close_nut, + demux_seek_nut, + demux_control_nut +}; + +#endif // USE_LIBNUT +
--- a/libmpdemux/demuxer.c Sat Sep 16 22:39:23 2006 +0000 +++ b/libmpdemux/demuxer.c Sun Sep 17 09:32:28 2006 +0000 @@ -66,6 +66,7 @@ extern demuxer_desc_t demuxer_desc_lavf; #endif extern demuxer_desc_t demuxer_desc_aac; +extern demuxer_desc_t demuxer_desc_nut; demuxer_desc_t* demuxer_list[] = { &demuxer_desc_rawaudio, @@ -120,6 +121,9 @@ &demuxer_desc_rawdv, #endif &demuxer_desc_aac, +#ifdef HAVE_LIBNUT + &demuxer_desc_nut, +#endif #ifdef HAVE_XMMS &demuxer_desc_xmms, #endif
--- a/libmpdemux/demuxer.h Sat Sep 16 22:39:23 2006 +0000 +++ b/libmpdemux/demuxer.h Sun Sep 17 09:32:28 2006 +0000 @@ -54,11 +54,12 @@ #define DEMUXER_TYPE_MPC 40 #define DEMUXER_TYPE_MPEG_PES 41 #define DEMUXER_TYPE_MPEG_GXF 42 +#define DEMUXER_TYPE_NUT 43 // This should always match the higest demuxer type number. // Unless you want to disallow users to force the demuxer to some types #define DEMUXER_TYPE_MIN 0 -#define DEMUXER_TYPE_MAX 42 +#define DEMUXER_TYPE_MAX 43 #define DEMUXER_TYPE_DEMUXERS (1<<16) // A virtual demuxer type for the network code