/*
* DEMUXER v2.5
*
* 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 <string.h>
#include <assert.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include "config.h"
#include "core/options.h"
#include "core/av_common.h"
#include "talloc.h"
#include "core/mp_msg.h"
#include "stream/stream.h"
#include "demux.h"
#include "stheader.h"
#include "mf.h"
#include "audio/format.h"
#include <libavcodec/avcodec.h>
#if MP_INPUT_BUFFER_PADDING_SIZE < FF_INPUT_BUFFER_PADDING_SIZE
#error MP_INPUT_BUFFER_PADDING_SIZE is too small!
#endif
static void clear_parser(sh_audio_t *sh);
// Demuxer list
extern const struct demuxer_desc demuxer_desc_edl;
extern const struct demuxer_desc demuxer_desc_cue;
extern const demuxer_desc_t demuxer_desc_rawaudio;
extern const demuxer_desc_t demuxer_desc_rawvideo;
extern const demuxer_desc_t demuxer_desc_tv;
extern const demuxer_desc_t demuxer_desc_mf;
extern const demuxer_desc_t demuxer_desc_avi;
extern const demuxer_desc_t demuxer_desc_asf;
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_mpeg_ps;
extern const demuxer_desc_t demuxer_desc_mpeg_pes;
extern const demuxer_desc_t demuxer_desc_mpeg_gxf;
extern const demuxer_desc_t demuxer_desc_mpeg_es;
extern const demuxer_desc_t demuxer_desc_mpeg4_es;
extern const demuxer_desc_t demuxer_desc_h264_es;
extern const demuxer_desc_t demuxer_desc_mpeg_ts;
extern const demuxer_desc_t demuxer_desc_libass;
extern const demuxer_desc_t demuxer_desc_subreader;
/* Please do not add any new demuxers here. If you want to implement a new
* demuxer, add it to libavformat, except for wrappers around external
* libraries and demuxers requiring binary support. */
const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_edl,
&demuxer_desc_cue,
&demuxer_desc_rawaudio,
&demuxer_desc_rawvideo,
#ifdef CONFIG_TV
&demuxer_desc_tv,
#endif
&demuxer_desc_libass,
&demuxer_desc_matroska,
&demuxer_desc_lavf,
&demuxer_desc_subreader,
&demuxer_desc_avi,
&demuxer_desc_asf,
#ifdef CONFIG_MNG
&demuxer_desc_mng,
#endif
&demuxer_desc_mpeg_ps,
&demuxer_desc_mpeg_pes,
&demuxer_desc_mpeg_gxf,
&demuxer_desc_mpeg_es,
&demuxer_desc_mpeg4_es,
&demuxer_desc_h264_es,
&demuxer_desc_mpeg_ts,
// auto-probe last, because it checks file-extensions only
&demuxer_desc_mf,
/* Please do not add any new demuxers here. If you want to implement a new
* demuxer, add it to libavformat, except for wrappers around external
* libraries and demuxers requiring binary support. */
NULL
};
static void add_stream_chapters(struct demuxer *demuxer);
static int packet_destroy(void *ptr)
{
struct demux_packet *dp = ptr;
talloc_free(dp->avpacket);
free(dp->allocation);
return 0;
}
static struct demux_packet *create_packet(size_t len)
{
if (len > 1000000000) {
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "Attempt to allocate demux packet "
"over 1 GB!\n");
abort();
}
struct demux_packet *dp = talloc(NULL, struct demux_packet);
talloc_set_destructor(dp, packet_destroy);
*dp = (struct demux_packet) {
.len = len,
.pts = MP_NOPTS_VALUE,
.duration = -1,
.stream_pts = MP_NOPTS_VALUE,
};
return dp;
}
struct demux_packet *new_demux_packet(size_t len)
{
struct demux_packet *dp = create_packet(len);
dp->buffer = malloc(len + MP_INPUT_BUFFER_PADDING_SIZE);
if (!dp->buffer) {
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "Memory allocation failure!\n");
abort();
}
memset(dp->buffer + len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
dp->allocation = dp->buffer;
return dp;
}
// data must already have suitable padding, and does not copy the data
struct demux_packet *new_demux_packet_fromdata(void *data, size_t len)
{
struct demux_packet *dp = create_packet(len);
dp->buffer = data;
return dp;
}
struct demux_packet *new_demux_packet_from(void *data, size_t len)
{
struct demux_packet *dp = new_demux_packet(len);
memcpy(dp->buffer, data, len);
return dp;
}
void resize_demux_packet(struct demux_packet *dp, size_t len)
{
if (len > 1000000000) {
mp_msg(MSGT_DEMUXER, MSGL_FATAL, "Attempt to realloc demux packet "
"over 1 GB!\n");
abort();
}
assert(dp->allocation);
dp->buffer = realloc(dp->buffer, len + MP_INPUT_BUFFER_PADDING_SIZE);
if (!dp->buffer) {
mp_msg(MSGT_DEMUXER,
|