summaryrefslogtreecommitdiffstats
path: root/demux
diff options
context:
space:
mode:
Diffstat (limited to 'demux')
-rw-r--r--demux/codec_tags.c1
-rw-r--r--demux/demux.c4
-rw-r--r--demux/demux_mf.c209
-rw-r--r--demux/demux_mkv.c5
-rw-r--r--demux/demux_mng.c572
-rw-r--r--demux/matroska.h1
-rw-r--r--demux/mf.c211
-rw-r--r--demux/mf.h19
8 files changed, 210 insertions, 812 deletions
diff --git a/demux/codec_tags.c b/demux/codec_tags.c
index 66489aae03..dbf384fdbd 100644
--- a/demux/codec_tags.c
+++ b/demux/codec_tags.c
@@ -132,7 +132,6 @@ static const struct mp_codec_tag mp_audio_codec_tags[] = {
{MKTAG('B', 'P', 'C', 'M'), "pcm_bluray"},
{MKTAG('P', 'L', 'X', 'F'), "pcm_lxf"},
{MKTAG('T', 'W', 'I', '2'), "twinvq"},
- {0x20776172, "pcm"}, // demux_mpg.c dvdpcm
{0},
};
diff --git a/demux/demux.c b/demux/demux.c
index ded0dd895e..da5957efdd 100644
--- a/demux/demux.c
+++ b/demux/demux.c
@@ -56,7 +56,6 @@ extern const demuxer_desc_t demuxer_desc_tv;
extern const demuxer_desc_t demuxer_desc_mf;
extern const demuxer_desc_t demuxer_desc_matroska;
extern const demuxer_desc_t demuxer_desc_lavf;
-extern const demuxer_desc_t demuxer_desc_mng;
extern const demuxer_desc_t demuxer_desc_libass;
extern const demuxer_desc_t demuxer_desc_subreader;
extern const demuxer_desc_t demuxer_desc_playlist;
@@ -79,9 +78,6 @@ const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_matroska,
&demuxer_desc_lavf,
&demuxer_desc_mf,
-#if HAVE_MNG
- &demuxer_desc_mng,
-#endif
&demuxer_desc_playlist,
// Pretty aggressive, so should be last.
&demuxer_desc_subreader,
diff --git a/demux/demux_mf.c b/demux/demux_mf.c
index 50888f59ad..6042771241 100644
--- a/demux/demux_mf.c
+++ b/demux/demux_mf.c
@@ -28,35 +28,29 @@
#include "talloc.h"
#include "config.h"
#include "mpvcore/mp_msg.h"
+#include "mpvcore/mp_talloc.h"
#include "stream/stream.h"
#include "demux.h"
#include "stheader.h"
#include "mf.h"
-#define MF_MAX_FILE_SIZE (1024*1024*256)
-
-static void free_mf(mf_t *mf)
-{
- if (mf) {
- for (int n = 0; n < mf->nr_of_files; n++)
- free(mf->names[n]);
- free(mf->names);
- free(mf->streams);
- free(mf);
- }
-}
+#define MF_MAX_FILE_SIZE (1024 * 1024 * 256)
static void demux_seek_mf(demuxer_t *demuxer, float rel_seek_secs, int flags)
{
- mf_t * mf = (mf_t *)demuxer->priv;
- int newpos = (flags & SEEK_ABSOLUTE)?0:mf->curr_frame - 1;
-
- if ( flags & SEEK_FACTOR ) newpos+=rel_seek_secs*(mf->nr_of_files - 1);
- else newpos+=rel_seek_secs * mf->sh->fps;
- if ( newpos < 0 ) newpos=0;
- if( newpos >= mf->nr_of_files) newpos=mf->nr_of_files - 1;
- mf->curr_frame=newpos;
+ mf_t *mf = demuxer->priv;
+ int newpos = (flags & SEEK_ABSOLUTE) ? 0 : mf->curr_frame - 1;
+
+ if (flags & SEEK_FACTOR)
+ newpos += rel_seek_secs * (mf->nr_of_files - 1);
+ else
+ newpos += rel_seek_secs * mf->sh->fps;
+ if (newpos < 0)
+ newpos = 0;
+ if (newpos >= mf->nr_of_files)
+ newpos = mf->nr_of_files - 1;
+ mf->curr_frame = newpos;
}
// return value:
@@ -101,52 +95,52 @@ static int demux_mf_fill_buffer(demuxer_t *demuxer)
// map file extension/type to a codec name
static const struct {
- const char *type;
- const char *codec;
+ const char *type;
+ const char *codec;
} type2format[] = {
- { "bmp", "bmp" },
- { "dpx", "dpx" },
- { "j2c", "jpeg2000" },
- { "j2k", "jpeg2000" },
- { "jp2", "jpeg2000" },
- { "jpc", "jpeg2000" },
- { "jpeg", "mjpeg" },
- { "jpg", "mjpeg" },
- { "jps", "mjpeg" },
- { "jls", "ljpeg" },
- { "thm", "mjpeg" },
- { "db", "mjpeg" },
- { "pcx", "pcx" },
- { "png", "png" },
- { "pns", "png" },
- { "ptx", "ptx" },
- { "tga", "targa" },
- { "tif", "tiff" },
- { "tiff", "tiff" },
- { "sgi", "sgi" },
- { "sun", "sunrast" },
- { "ras", "sunrast" },
- { "rs", "sunrast" },
- { "ra", "sunrast" },
- { "im1", "sunrast" },
- { "im8", "sunrast" },
- { "im24", "sunrast" },
- { "im32", "sunrast" },
- { "sunras", "sunrast" },
- { "xbm", "xbm" },
- { "pam", "pam" },
- { "pbm", "pbm" },
- { "pgm", "pgm" },
- { "pgmyuv", "pgmyuv" },
- { "ppm", "ppm" },
- { "pnm", "ppm" },
- { "gif", "gif" }, // usually handled by demux_lavf
- { "pix", "brender_pix" },
- { "exr", "exr" },
- { "pic", "pictor" },
- { "xface", "xface" },
- { "xwd", "xwd" },
- {0}
+ { "bmp", "bmp" },
+ { "dpx", "dpx" },
+ { "j2c", "jpeg2000" },
+ { "j2k", "jpeg2000" },
+ { "jp2", "jpeg2000" },
+ { "jpc", "jpeg2000" },
+ { "jpeg", "mjpeg" },
+ { "jpg", "mjpeg" },
+ { "jps", "mjpeg" },
+ { "jls", "ljpeg" },
+ { "thm", "mjpeg" },
+ { "db", "mjpeg" },
+ { "pcx", "pcx" },
+ { "png", "png" },
+ { "pns", "png" },
+ { "ptx", "ptx" },
+ { "tga", "targa" },
+ { "tif", "tiff" },
+ { "tiff", "tiff" },
+ { "sgi", "sgi" },
+ { "sun", "sunrast" },
+ { "ras", "sunrast" },
+ { "rs", "sunrast" },
+ { "ra", "sunrast" },
+ { "im1", "sunrast" },
+ { "im8", "sunrast" },
+ { "im24", "sunrast" },
+ { "im32", "sunrast" },
+ { "sunras", "sunrast" },
+ { "xbm", "xbm" },
+ { "pam", "pam" },
+ { "pbm", "pbm" },
+ { "pgm", "pgm" },
+ { "pgmyuv", "pgmyuv" },
+ { "ppm", "ppm" },
+ { "pnm", "ppm" },
+ { "gif", "gif" }, // usually handled by demux_lavf
+ { "pix", "brender_pix" },
+ { "exr", "exr" },
+ { "pic", "pictor" },
+ { "xface", "xface" },
+ { "xwd", "xwd" },
+ {0}
};
static const char *probe_format(mf_t *mf, enum demux_check check)
@@ -167,7 +161,7 @@ static const char *probe_format(mf_t *mf, enum demux_check check)
if (!mf_type) {
mp_msg(MSGT_DEMUX, MSGL_ERR,
"[demux_mf] file type was not set! (try --mf-type=ext)\n");
- } else {
+ } else {
mp_msg(MSGT_DEMUX, MSGL_ERR,
"[demux_mf] --mf-type set to an unknown codec!\n");
}
@@ -175,67 +169,64 @@ static const char *probe_format(mf_t *mf, enum demux_check check)
return NULL;
}
-static int demux_open_mf(demuxer_t* demuxer, enum demux_check check)
+static int demux_open_mf(demuxer_t *demuxer, enum demux_check check)
{
- sh_video_t *sh_video = NULL;
- mf_t *mf;
-
- if (strncmp(demuxer->stream->url, "mf://", 5) == 0 &&
- demuxer->stream->type == STREAMTYPE_MF)
- {
- mf = open_mf_pattern(demuxer->stream->url + 5);
- } else {
- mf = open_mf_single(demuxer->stream->url);
- mf->streams = calloc(1, sizeof(struct stream *));
- mf->streams[0] = demuxer->stream;
- }
+ sh_video_t *sh_video = NULL;
+ mf_t *mf;
+
+ if (strncmp(demuxer->stream->url, "mf://", 5) == 0 &&
+ demuxer->stream->type == STREAMTYPE_MF)
+ mf = open_mf_pattern(demuxer, demuxer->stream->url + 5);
+ else {
+ mf = open_mf_single(demuxer, demuxer->stream->url);
+ int bog = 0;
+ MP_TARRAY_APPEND(mf, mf->streams, bog, demuxer->stream);
+ }
- if (!mf || mf->nr_of_files < 1)
- goto error;
+ if (!mf || mf->nr_of_files < 1)
+ goto error;
- const char *codec = probe_format(mf, check);
- if (!codec)
- goto error;
+ const char *codec = probe_format(mf, check);
+ if (!codec)
+ goto error;
- mf->curr_frame = 0;
+ mf->curr_frame = 0;
- // create a new video stream header
- struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO);
- sh_video = sh->video;
+ // create a new video stream header
+ struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO);
+ sh_video = sh->video;
- sh_video->gsh->codec = codec;
- sh_video->disp_w = 0;
- sh_video->disp_h = 0;
- sh_video->fps = mf_fps;
+ sh_video->gsh->codec = codec;
+ sh_video->disp_w = 0;
+ sh_video->disp_h = 0;
+ sh_video->fps = mf_fps;
- mf->sh = sh_video;
- demuxer->priv=(void*)mf;
- demuxer->seekable = true;
+ mf->sh = sh_video;
+ demuxer->priv = (void *)mf;
+ demuxer->seekable = true;
- return 0;
+ return 0;
error:
- free_mf(mf);
- return -1;
+ return -1;
}
-static void demux_close_mf(demuxer_t* demuxer) {
- mf_t *mf = demuxer->priv;
-
- free_mf(mf);
+static void demux_close_mf(demuxer_t *demuxer)
+{
}
-static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg) {
- mf_t *mf = (mf_t *)demuxer->priv;
+static int demux_control_mf(demuxer_t *demuxer, int cmd, void *arg)
+{
+ mf_t *mf = demuxer->priv;
- switch(cmd) {
+ switch (cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
- *((double *)arg) = (double)mf->nr_of_files / mf->sh->fps;
- return DEMUXER_CTRL_OK;
+ *((double *)arg) = (double)mf->nr_of_files / mf->sh->fps;
+ return DEMUXER_CTRL_OK;
default:
- return DEMUXER_CTRL_NOTIMPL;
- }
+ return DEMUXER_CTRL_NOTIMPL;
+ }
}
const demuxer_desc_t demuxer_desc_mf = {
diff --git a/demux/demux_mkv.c b/demux/demux_mkv.c
index 7a9aaa0f87..7a30721e66 100644
--- a/demux/demux_mkv.c
+++ b/demux/demux_mkv.c
@@ -1355,6 +1355,7 @@ static struct mkv_audio_tag {
{ MKV_A_DTS, 0, 0x2001 },
{ MKV_A_PCM, 0, 0x0001 },
{ MKV_A_PCM_BE, 0, 0x0001 },
+ { MKV_A_PCM_FLT, 0, 0x0003 },
{ MKV_A_AAC_2MAIN, 0, MP_FOURCC('M', 'P', '4', 'A') },
{ MKV_A_AAC_2LC, 1, MP_FOURCC('M', 'P', '4', 'A') },
{ MKV_A_AAC_2SSR, 0, MP_FOURCC('M', 'P', '4', 'A') },
@@ -1464,10 +1465,10 @@ static int demux_mkv_open_audio(demuxer_t *demuxer, mkv_track_t *track)
free(sh_a->wf);
sh_a->wf = NULL;
} else if (track->a_formattag == 0x0001) { /* PCM || PCM_BE */
- sh_a->wf->nAvgBytesPerSec = sh_a->channels.num * sh_a->samplerate * 2;
- sh_a->wf->nBlockAlign = sh_a->wf->nAvgBytesPerSec;
if (!strcmp(track->codec_id, MKV_A_PCM_BE))
sh_a->format = MP_FOURCC('t', 'w', 'o', 's');
+ } else if (track->a_formattag == 0x0003) { /* PCM_FLT */
+ /* ok */
} else if (!strcmp(track->codec_id, MKV_A_QDMC)
|| !strcmp(track->codec_id, MKV_A_QDMC2)) {
sh_a->wf->nAvgBytesPerSec = 16000;
diff --git a/demux/demux_mng.c b/demux/demux_mng.c
deleted file mode 100644
index f408687c1b..0000000000
--- a/demux/demux_mng.c
+++ /dev/null
@@ -1,572 +0,0 @@
-/*
- * MNG file demuxer for MPlayer
- *
- * Copyright (C) 2008 Stefan Schuermans <stefan blinkenarea org>
- *
- * This file is part of MPlayer.
- *
- * MPlayer is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * MPlayer is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with MPlayer; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "config.h"
-
-#include "mpvcore/mp_msg.h"
-
-#include "stream/stream.h"
-#include "demux.h"
-#include "stheader.h"
-#include "video/img_fourcc.h"
-
-#define MNG_SUPPORT_READ
-#define MNG_SUPPORT_DISPLAY
-#include <libmng.h>
-
-/**
- * \brief private context structure
- *
- * This structure is used as private data for MPlayer demuxer
- * and also as private data for the MNG library.
- *
- * All members ending in \p _ms are in milliseconds
- */
-typedef struct {
- stream_t * stream; ///< pointer to MNG data input stream
- mng_handle h_mng; ///< MNG library image handle
- int header_processed; ///< if MNG image header is processed
- mng_uint32 width; ///< MNG image width
- mng_uint32 height; ///< MNG image height
- int total_time_ms; ///< total MNG animation time
- unsigned char * canvas; /**< \brief canvas to draw the image onto
- * \details
- * \li lines top-down
- * \li pixels left-to-right
- * \li channels RGB
- * \li no padding
- * \li NULL if no canvas yet
- */
- int displaying; /**< \brief if displaying already,
- * i.e. if mng_display has
- * already been called
- */
- int finished; ///< if animation is finished
- int global_time_ms; ///< current global time for MNG library
- int anim_cur_time_ms; ///< current frame time in MNG animation
- int anim_frame_duration_ms; ///< current frame duration in MNG animation
- int show_cur_time_ms; /**< \brief current time in the show process,
- * i.e. time of last demux packet
- */
- int show_next_time_ms; /**< \brief next time in the show process,
- * i.e. time of next demux packet
- */
- int timer_ms; /**< \brief number of milliseconds after which
- * libmng wants to be called again
- */
-} mng_priv_t;
-
-/**
- * \brief MNG library callback: Allocate a new zero-filled memory block.
- * \param[in] size memory block size
- * \return pointer to new memory block
- */
-static mng_ptr demux_mng_alloc(mng_size_t size)
-{
- return calloc(1, size);
-}
-
-/**
- * \brief MNG library callback: Free memory block.
- * \param[in] ptr pointer to memory block
- * \param[in] size memory block size
- */
-static void demux_mng_free(mng_ptr ptr, mng_size_t size)
-{
- free(ptr);
-}
-
-/**
- * \brief MNG library callback: Open MNG stream.
- * \param[in] h_mng MNG library image handle
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error (never happens)
- */
-static mng_bool demux_mng_openstream(mng_handle h_mng)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
- stream_t * stream = mng_priv->stream;
-
- // rewind stream to the beginning
- stream_seek(stream, stream->start_pos);
-
- return MNG_TRUE;
-}
-
-/**
- * \brief MNG library callback: Close MNG stream.
- * \param[in] h_mng MNG library image handle
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error (never happens)
- */
-static mng_bool demux_mng_closestream(mng_handle h_mng)
-{
- return MNG_TRUE;
-}
-
-/**
- * \brief MNG library callback: Read data from stream.
- * \param[in] h_mng MNG library image handle
- * \param[in] buf pointer to buffer to fill with data
- * \param[in] size size of buffer
- * \param[out] read number of bytes read from stream
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error (never happens)
- */
-static mng_bool demux_mng_readdata(mng_handle h_mng, mng_ptr buf,
- mng_uint32 size, mng_uint32 * read)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
- stream_t * stream = mng_priv->stream;
-
- // simply read data from stream and return number of bytes or error
- *read = stream_read(stream, buf, size);
-
- return MNG_TRUE;
-}
-
-/**
- * \brief MNG library callback: Header information is processed now.
- * \param[in] h_mng MNG library image handle
- * \param[in] width image width
- * \param[in] height image height
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error
- */
-static mng_bool demux_mng_processheader(mng_handle h_mng, mng_uint32 width,
- mng_uint32 height)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
-
- // remember size in private data
- mng_priv->header_processed = 1;
- mng_priv->width = width;
- mng_priv->height = height;
-
- // get total animation time
- mng_priv->total_time_ms = mng_get_playtime(h_mng);
-
- // allocate canvas
- mng_priv->canvas = malloc(height * width * 4);
- if (!mng_priv->canvas) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not allocate canvas of size %dx%d\n",
- width, height);
- return MNG_FALSE;
- }
-
- return MNG_TRUE;
-}
-
-/**
- * \brief MNG library callback: Get access to a canvas line.
- * \param[in] h_mng MNG library image handle
- * \param[in] line y coordinate of line to access
- * \return pointer to line on success, \p MNG_NULL on error
- */
-static mng_ptr demux_mng_getcanvasline(mng_handle h_mng, mng_uint32 line)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
-
- // return pointer to canvas line
- if (line < mng_priv->height && mng_priv->canvas)
- return (mng_ptr)(mng_priv->canvas + line * mng_priv->width * 4);
- else
- return (mng_ptr)MNG_NULL;
-}
-
-/**
- * \brief MNG library callback: A part of the canvas should be shown.
- *
- * This function is called by libmng whenever it thinks a
- * rectangular part of the display should be updated. This
- * can happen multiple times for a frame and/or a single time
- * for a frame. Only the the part of the display occupied by
- * the rectangle defined by x, y, width, height is to be updated.
- * It is possible that some parts of the display are not updated
- * for many frames. There is no chance here to find out if the
- * current frame is completed with this update or not.
- *
- * This mechanism does not match MPlayer's demuxer architecture,
- * so it will not be used exactly as intended by libmng.
- * A new frame is generated in the demux_mng_fill_buffer() function
- * whenever libmng tells us to wait for some time.
- *
- * \param[in] h_mng MNG library image handle
- * \param[in] x rectangle's left edge
- * \param[in] y rectangle's top edge
- * \param[in] width rectangle's width
- * \param[in] height rectangle's heigt
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error (never happens)
- */
-static mng_bool demux_mng_refresh(mng_handle h_mng, mng_uint32 x, mng_uint32 y,
- mng_uint32 width, mng_uint32 height)
-{
- // nothing to do here, the image data is already on the canvas
- return MNG_TRUE;
-}
-
-/**
- * \brief MNG library callback: Get how many milliseconds have passed.
- * \param[in] h_mng MNG library image handle
- * \return global time in milliseconds
- */
-static mng_uint32 demux_mng_gettickcount(mng_handle h_mng)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
-
- // return current global time
- return mng_priv->global_time_ms;
-}
-
-/**
- * \brief MNG library callback: Please call again after some milliseconds.
- * \param[in] h_mng MNG library image handle
- * \param[in] msecs number of milliseconds after which to call again
- * \return \p MNG_TRUE on success, \p MNG_FALSE on error (never happens)
- */
-static mng_bool demux_mng_settimer(mng_handle h_mng, mng_uint32 msecs)
-{
- mng_priv_t * mng_priv = mng_get_userdata(h_mng);
-
- // Save number of milliseconds after which to call the MNG library again
- // in private data.
- mng_priv->timer_ms = msecs;
- return MNG_TRUE;
-}
-
-/**
- * \brief MPlayer callback: Fill buffer from MNG stream.
- * \param[in] demuxer demuxer structure
- * \return \p 1 on success, \p 0 on error
- */
-static int demux_mng_fill_buffer(demuxer_t * demuxer)
-{
- mng_priv_t * mng_priv = demuxer->priv;
- mng_handle h_mng = mng_priv->h_mng;
- mng_retcode mng_ret;
- demux_packet_t * dp;
-
- // exit if animation is finished
- if (mng_priv->finished)
- return 0;
-
- // advance animation to requested next show time
- while (mng_priv->anim_cur_time_ms + mng_priv->anim_frame_duration_ms
- <= mng_priv->show_next_time_ms && !mng_priv->finished) {
-
- // advance global and animation time
- mng_priv->global_time_ms += mng_priv->anim_frame_duration_ms;
- mng_priv->anim_cur_time_ms += mng_priv->anim_frame_duration_ms;
-
- // Clear variable MNG library will write number of milliseconds to
- // (via settimer callback).
- mng_priv->timer_ms = 0;
-
- // get next image from MNG library
- if (mng_priv->displaying)
- mng_ret = mng_display_resume(h_mng); // resume displaying MNG data
- // to canvas
- else
- mng_ret = mng_display(h_mng); // start displaying MNG data to canvas
- if (mng_ret && mng_ret != MNG_NEEDTIMERWAIT) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not display MNG data to canvas: "
- "mng_retcode %d\n", mng_ret);
- return 0;
- }
- mng_priv->displaying = 1; // mng_display() has been called now
- mng_priv->finished = mng_ret == 0; // animation is finished iff
- // mng_display() returned 0
-
- // save current frame duration
- mng_priv->anim_frame_duration_ms = mng_priv->timer_ms < 1
- ? 1 : mng_priv->timer_ms;
-
- } // while (mng_priv->anim_cur_time_ms + ...
-
- // create a new demuxer packet
- dp = new_demux_packet(mng_priv->height * mng_priv->width * 4);
-
- // copy image data into demuxer packet
- memcpy(dp->buffer, mng_priv->canvas,
- mng_priv->height * mng_priv->width * 4);
-
- // set current show time to requested show time
- mng_priv->show_cur_time_ms = mng_priv->show_next_time_ms;
-
- // get time of next frame to show
- mng_priv->show_next_time_ms = mng_priv->anim_cur_time_ms
- + mng_priv->anim_frame_duration_ms;
-
- // Set position and timing information in demuxer video and demuxer packet.
- // - Time must be time of next frame and always be > 0 for the variable
- // frame time mechanism (GIF, MATROSKA, MNG) in video.c to work.
- dp->pts = (float)mng_priv->show_next_time_ms / 1000.0f;
- dp->pos = stream_tell(demuxer->stream);
- demuxer_add_packet(demuxer, demuxer->streams[0], dp);
-
- return 1;
-}
-
-static int demux_mng_open(demuxer_t * demuxer, enum demux_check check)
-{
- mng_priv_t * mng_priv;
- mng_handle h_mng;
- mng_retcode mng_ret;
- sh_video_t * sh_video;
-
- if (check > DEMUX_CHECK_REQUEST)
- return -1; // check too unsafe
- if (check > DEMUX_CHECK_FORCE) {
- char buf[4];
- if (stream_read(demuxer->stream, buf, 4) != 4)
- return -1;
- if (memcmp(buf, "\x8AMNG", 4))
- return -1;
- stream_seek(demuxer->stream, demuxer->stream->start_pos);
- }
-
- // create private data structure
- mng_priv = calloc(1, sizeof(mng_priv_t));
-
- //stream pointer into private data
- mng_priv->stream = demuxer->stream;
-
- // initialize MNG image instance
- h_mng = mng_initialize((mng_ptr)mng_priv, demux_mng_alloc,
- demux_mng_free, MNG_NULL);
- if (!h_mng) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not initialize MNG image instance\n");
- free(mng_priv);
- return -1;
- }
-
- // MNG image handle into private data
- mng_priv->h_mng = h_mng;
-
- // set required MNG callbacks
- if (mng_setcb_openstream(h_mng, demux_mng_openstream) ||
- mng_setcb_closestream(h_mng, demux_mng_closestream) ||
- mng_setcb_readdata(h_mng, demux_mng_readdata) ||
- mng_setcb_processheader(h_mng, demux_mng_processheader) ||
- mng_setcb_getcanvasline(h_mng, demux_mng_getcanvasline) ||
- mng_setcb_refresh(h_mng, demux_mng_refresh) ||
- mng_setcb_gettickcount(h_mng, demux_mng_gettickcount) ||
- mng_setcb_settimer(h_mng, demux_mng_settimer) ||
- mng_set_canvasstyle(h_mng, MNG_CANVAS_RGBA8)) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not set MNG callbacks\n");
- mng_cleanup(&h_mng);
- free(mng_priv);
- return -1;
- }
-
- // start reading MNG data
- mng_ret = mng_read(h_mng);
- if (mng_ret) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not start reading MNG data: "
- "mng_retcode %d\n", mng_ret);
- mng_cleanup(&h_mng);
- free(mng_priv);
- return -1;
- }
-
- // check that MNG header is processed now
- if (!mng_priv->header_processed) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: internal error: header not processed\n");
- mng_cleanup(&h_mng);
- free(mng_priv);
- return -1;
- }
-
- // create a new video stream header
- struct sh_stream *sh = new_sh_stream(demuxer, STREAM_VIDEO);
- sh_video = sh->video;
-
- // set format of pixels in video packets
- sh_video->gsh->codec = "rawvideo";
- sh_video->format = MP_FOURCC_RGB32;
-
- // set framerate to some value (MNG does not have a fixed framerate)
- sh_video->fps = 5.0f;
-
- // set video frame parameters
- sh_video->bih = calloc(1, sizeof(*sh_video->bih));
- sh_video->bih->biCompression = sh_video->format;
- sh_video->bih->biWidth = mng_priv->width;
- sh_video->bih->biHeight = mng_priv->height;
- sh_video->bih->biBitCount = 32;
- sh_video->bih->biPlanes = 1;
-
- // weirdly broken
- demuxer->accurate_seek = false;
-
- // set private data in demuxer and return demuxer
- demuxer->priv = mng_priv;
- return 0;
-}
-
-/**
- * \brief MPlayer callback: Close MNG stream.
- * \param[in] demuxer demuxer structure
- */
-static void demux_mng_close(demuxer_t* demuxer)
-{
- mng_priv_t * mng_priv = demuxer->priv;
-
- if (mng_priv) {
-
- // shutdown MNG image instance
- if (mng_priv->h_mng)
- mng_cleanup(&mng_priv->h_mng);
-
- // free private data
- free(mng_priv->canvas);
-
- free(mng_priv);
- }
-}
-
-/**
- * \brief MPlayer callback: Seek in MNG stream.
- * \param[in] demuxer demuxer structure
- * \param[in] rel_seek_secs relative seek time in seconds
- * \param[in] audio_delay unused, MNG does not contain audio
- * \param[in] flags bit flags, \p 1: absolute, \p 2: fractional position
- */
-static void demux_mng_seek(demuxer_t * demuxer, float rel_seek_secs, int flags)
-{
- mng_priv_t * mng_priv = demuxer->priv;
- mng_handle h_mng = mng_priv->h_mng;
- mng_retcode mng_ret;
- int seek_ms, pos_ms;
-
- // exit if not ready to seek (header not yet read or not yet displaying)
- if (!mng_priv->header_processed || !mng_priv->displaying)
- return;
-
- // get number of milliseconds to seek to
- if (flags & 2) // seek by fractional position (0.0 ... 1.0)
- seek_ms = (int)(rel_seek_secs * (float)mng_priv->total_time_ms);
- else // seek by time in seconds
- seek_ms = (int)(rel_seek_secs * 1000.0f + 0.5f);
-
- // get new position in milliseconds
- if (flags & 1) // absolute
- pos_ms = seek_ms;
- else // relative
- pos_ms = mng_priv->show_cur_time_ms + seek_ms;
-
- // fix position
- if (pos_ms < 0)
- pos_ms = 0;
- if (pos_ms > mng_priv->total_time_ms)
- pos_ms = mng_priv->total_time_ms;
-
- // FIXME
- // In principle there is a function to seek in MNG: mng_display_gotime().
- // - Using it did not work out (documentation is very brief,
- // example code does not exist?).
- // - The following code works, but its performance is quite bad.
-
- // seeking forward
- if (pos_ms >= mng_priv->show_cur_time_ms) {
-
- // Simply advance show time to seek position.
- // - Everything else will be handled in demux_mng_fill_buffer().
- mng_priv->show_next_time_ms = pos_ms;
-
- } // if (pos_ms > mng_priv->show_time_ms)
-
- // seeking backward
- else { // if (pos_ms > mng_priv->show_time_ms)
-
- // Clear variable MNG library will write number of milliseconds to
- // (via settimer callback).
- mng_priv->timer_ms = 0;
-
- // Restart displaying and advance show time to seek position.
- // - Everything else will be handled in demux_mng_fill_buffer().
- mng_ret = mng_display_reset(h_mng);
- // If a timer wait is needed, fool libmng that requested time
- // passed and try again.
- if (mng_ret == MNG_NEEDTIMERWAIT) {
- mng_priv->global_time_ms += mng_priv->timer_ms;
- mng_ret = mng_display_reset(h_mng);
- }
- if (mng_ret) {
- mp_msg(MSGT_DEMUX, MSGL_ERR,
- "demux_mng: could not reset MNG display state: "
- "mng_retcode %d\n", mng_ret);
- return;
- }
- mng_priv->displaying = 0;
- mng_priv->finished = 0;
- mng_priv->anim_cur_time_ms = 0;
- mng_priv->anim_frame_duration_ms = 0;
- mng_priv->show_next_time_ms = pos_ms;
-
- } // if (pos_ms > mng_priv->show_time_ms) ... else
-}
-
-/**
- * \brief MPlayer callback: Control MNG stream.
- * \param[in] demuxer demuxer structure
- * \param[in] cmd code of control command to perform
- * \param[in,out] arg command argument
- * \return demuxer control response code
- */
-static int demux_mng_control(demuxer_t * demuxer, int cmd, void * arg)
-{
- mng_priv_t * mng_priv = demuxer->priv;
-
- switch(cmd) {
-
- // get total movie length
- case DEMUXER_CTRL_GET_TIME_LENGTH:
- if (mng_priv->header_processed) {
- *(double *)arg = (double)mng_priv->total_time_ms / 1000.0;
- return DEMUXER_CTRL_OK;
- } else {
- return DEMUXER_CTRL_DONTKNOW;
- }
- break;
-
- default:
- return DEMUXER_CTRL_NOTIMPL;
-
- } // switch (cmd)
-}
-
-const demuxer_desc_t demuxer_desc_mng = {
- .name = "mng",
- .desc = "MNG",
- .fill_buffer = demux_mng_fill_buffer,
- .open = demux_mng_open,
- .close = demux_mng_close,
- .seek = demux_mng_seek,
- .control = demux_mng_control,
-};
diff --git a/demux/matroska.h b/demux/matroska.h
index 796f6c24d3..a6be019b2d 100644
--- a/demux/matroska.h
+++ b/demux/matroska.h
@@ -40,6 +40,7 @@
#define MKV_A_MP3 "A_MPEG/L3"
#define MKV_A_PCM "A_PCM/INT/LIT"
#define MKV_A_PCM_BE "A_PCM/INT/BIG"
+#define MKV_A_PCM_FLT "A_PCM/FLOAT/IEEE"
#define MKV_A_VORBIS "A_VORBIS"
#define MKV_A_OPUS "A_OPUS"
#define MKV_A_OPUS_EXP "A_OPUS/EXPERIMENTAL"
diff --git a/demux/mf.c b/demux/mf.c
index d1060efc3c..13021aa53a 100644
--- a/demux/mf.c
+++ b/demux/mf.c
@@ -36,149 +36,132 @@
#include "osdep/glob.h"
#endif
+#include "talloc.h"
#include "mpvcore/mp_msg.h"
#include "stream/stream.h"
#include "mpvcore/path.h"
+#include "mpvcore/mp_talloc.h"
#include "mf.h"
double mf_fps = 25.0;
-char * mf_type = NULL; //"jpg";
+char *mf_type = NULL; //"jpg";
-mf_t* open_mf_pattern(char * filename)
+static void mf_add(mf_t *mf, const char *fname)
+{
+ fname = talloc_strdup(mf, fname);
+ MP_TARRAY_APPEND(mf, mf->names, mf->nr_of_files, fname);
+}
+
+mf_t *open_mf_pattern(void *talloc_ctx, char *filename)
{
#if defined(HAVE_GLOB) || defined(__MINGW32__)
- glob_t gg;
- int i;
- char * fname = NULL;
- mf_t * mf;
- int error_count = 0;
- int count = 0;
-
- mf=calloc( 1,sizeof( mf_t ) );
-
- if( filename[0] == '@' )
- {
- FILE *lst_f=fopen(filename + 1,"r");
- if ( lst_f )
- {
- fname=malloc(MP_PATH_MAX);
- while ( fgets( fname,MP_PATH_MAX,lst_f ) )
- {
- /* remove spaces from end of fname */
- char *t=fname + strlen( fname ) - 1;
- while ( t > fname && isspace( *t ) ) *(t--)=0;
- if ( !mp_path_exists( fname ) )
- {
- mp_msg( MSGT_STREAM,MSGL_V,"[mf] file not found: '%s'\n",fname );
+ int error_count = 0;
+ int count = 0;
+
+ mf_t *mf = talloc_zero(talloc_ctx, mf_t);
+