1
mirror of https://github.com/mpv-player/mpv synced 2024-08-24 07:21:49 +02:00

libmpdemux: remove demux_real, demux_viv, demux_audio

libavformat replaces demux_audio completely. I don't know/care what
vivo (demux_viv) is. libavformat has a Real demuxer; it seems it works
slightly better, with a different set of bugs.
This commit is contained in:
wm4 2012-08-18 11:13:58 +02:00
parent fc2ea37694
commit 8ca3ec1562
15 changed files with 58 additions and 4275 deletions

View File

@ -253,7 +253,6 @@ SRCS_COMMON = asxparser.c \
libmpdemux/aviprint.c \
libmpdemux/demuxer.c \
libmpdemux/demux_asf.c \
libmpdemux/demux_audio.c \
libmpdemux/demux_avi.c \
libmpdemux/demux_demuxers.c \
libmpdemux/demux_edl.c \
@ -263,9 +262,6 @@ SRCS_COMMON = asxparser.c \
libmpdemux/demux_mkv.c \
libmpdemux/demux_rawaudio.c \
libmpdemux/demux_rawvideo.c \
libmpdemux/demux_realaud.c \
libmpdemux/demux_real.c \
libmpdemux/demux_viv.c \
libmpdemux/ebml.c \
libmpdemux/extension.c \
libmpdemux/mf.c \

View File

@ -204,31 +204,8 @@ const m_option_t scaler_filter_conf[]={
{NULL, NULL, 0, 0, 0, 0, NULL}
};
/* VIVO demuxer options: */
extern int vivo_param_version;
extern char *vivo_param_acodec;
extern int vivo_param_abitrate;
extern int vivo_param_samplerate;
extern int vivo_param_bytesperblock;
extern int vivo_param_width;
extern int vivo_param_height;
extern int vivo_param_vformat;
extern char *dvd_device, *cdrom_device;
const m_option_t vivoopts_conf[]={
{"version", &vivo_param_version, CONF_TYPE_INT, 0, 0, 0, NULL},
/* audio options */
{"acodec", &vivo_param_acodec, CONF_TYPE_STRING, 0, 0, 0, NULL},
{"abitrate", &vivo_param_abitrate, CONF_TYPE_INT, 0, 0, 0, NULL},
{"samplerate", &vivo_param_samplerate, CONF_TYPE_INT, 0, 0, 0, NULL},
{"bytesperblock", &vivo_param_bytesperblock, CONF_TYPE_INT, 0, 0, 0, NULL},
/* video options */
{"width", &vivo_param_width, CONF_TYPE_INT, 0, 0, 0, NULL},
{"height", &vivo_param_height, CONF_TYPE_INT, 0, 0, 0, NULL},
{"vformat", &vivo_param_vformat, CONF_TYPE_INT, 0, 0, 0, NULL},
{NULL, NULL, 0, 0, 0, 0, NULL}
};
extern int mf_w;
extern int mf_h;
extern double mf_fps;
@ -485,7 +462,6 @@ const m_option_t common_opts[] = {
#ifdef CONFIG_PVR
{"pvr", (void *) pvropts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
#endif /* CONFIG_PVR */
{"vivo", (void *) vivoopts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
#ifdef CONFIG_DVBIN
{"dvbin", (void *) dvbin_opts_conf, CONF_TYPE_SUBCONFIG, 0, 0, 0, NULL},
#endif

View File

@ -1,830 +0,0 @@
/*
* 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 <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <libavutil/intreadwrite.h>
#include "config.h"
#include "options.h"
#include "mp_msg.h"
#include "stream/stream.h"
#include "aviprint.h"
#include "demuxer.h"
#include "stheader.h"
#include "genres.h"
#include "mp3_hdr.h"
#define MP3 1
#define WAV 2
#define fLaC 3
#define HDR_SIZE 4
typedef struct da_priv {
int frmt;
double next_pts;
} da_priv_t;
//! rather arbitrary value for maximum length of wav-format headers
#define MAX_WAVHDR_LEN (1 * 1024 * 1024)
//! how many valid frames in a row we need before accepting as valid MP3
#define MIN_MP3_HDRS 12
//! Used to describe a potential (chain of) MP3 headers we found
typedef struct mp3_hdr {
off_t frame_pos; // start of first frame in this "chain" of headers
off_t next_frame_pos; // here we expect the next header with same parameters
int mp3_chans;
int mp3_freq;
int mpa_spf;
int mpa_layer;
int mpa_br;
int cons_hdrs; // if this reaches MIN_MP3_HDRS we accept as MP3 file
struct mp3_hdr *next;
} mp3_hdr_t;
/**
* \brief free a list of MP3 header descriptions
* \param list pointer to the head-of-list pointer
*/
static void free_mp3_hdrs(mp3_hdr_t **list) {
mp3_hdr_t *tmp;
while (*list) {
tmp = (*list)->next;
free(*list);
*list = tmp;
}
}
/**
* \brief add another potential MP3 header to our list
* If it fits into an existing chain this one is expanded otherwise
* a new one is created.
* All entries that expected a MP3 header before the current position
* are discarded.
* The list is expected to be and will be kept sorted by next_frame_pos
* and when those are equal by frame_pos.
* \param list pointer to the head-of-list pointer
* \param st_pos stream position where the described header starts
* \param mp3_chans number of channels as specified by the header (*)
* \param mp3_freq sampling frequency as specified by the header (*)
* \param mpa_spf frame size as specified by the header
* \param mpa_layer layer type ("version") as specified by the header (*)
* \param mpa_br bitrate as specified by the header
* \param mp3_flen length of the frame as specified by the header
* \return If non-null the current file is accepted as MP3 and the
* mp3_hdr struct describing the valid chain is returned. Must be
* freed independent of the list.
*
* parameters marked by (*) must be the same for all headers in the same chain
*/
static mp3_hdr_t *add_mp3_hdr(mp3_hdr_t **list, off_t st_pos,
int mp3_chans, int mp3_freq, int mpa_spf,
int mpa_layer, int mpa_br, int mp3_flen) {
mp3_hdr_t *tmp;
int in_list = 0;
while (*list && (*list)->next_frame_pos <= st_pos) {
if (((*list)->next_frame_pos < st_pos) || ((*list)->mp3_chans != mp3_chans)
|| ((*list)->mp3_freq != mp3_freq) || ((*list)->mpa_layer != mpa_layer) ) {
// wasn't valid!
tmp = (*list)->next;
free(*list);
*list = tmp;
} else {
(*list)->cons_hdrs++;
(*list)->next_frame_pos = st_pos + mp3_flen;
(*list)->mpa_spf = mpa_spf;
(*list)->mpa_br = mpa_br;
if ((*list)->cons_hdrs >= MIN_MP3_HDRS) {
// copy the valid entry, so that the list can be easily freed
tmp = malloc(sizeof(mp3_hdr_t));
memcpy(tmp, *list, sizeof(mp3_hdr_t));
tmp->next = NULL;
return tmp;
}
in_list = 1;
list = &((*list)->next);
}
}
if (!in_list) { // does not belong into an existing chain, insert
// find right position to insert to keep sorting
while (*list && (*list)->next_frame_pos <= st_pos + mp3_flen)
list = &((*list)->next);
tmp = malloc(sizeof(mp3_hdr_t));
tmp->frame_pos = st_pos;
tmp->next_frame_pos = st_pos + mp3_flen;
tmp->mp3_chans = mp3_chans;
tmp->mp3_freq = mp3_freq;
tmp->mpa_spf = mpa_spf;
tmp->mpa_layer = mpa_layer;
tmp->mpa_br = mpa_br;
tmp->cons_hdrs = 1;
tmp->next = *list;
*list = tmp;
}
return NULL;
}
#if 0 /* this code is a mess, clean it up before reenabling */
#define FLAC_SIGNATURE_SIZE 4
#define FLAC_STREAMINFO_SIZE 34
#define FLAC_SEEKPOINT_SIZE 18
enum {
FLAC_STREAMINFO = 0,
FLAC_PADDING,
FLAC_APPLICATION,
FLAC_SEEKTABLE,
FLAC_VORBIS_COMMENT,
FLAC_CUESHEET
} flac_preamble_t;
static void
get_flac_metadata (demuxer_t* demuxer)
{
uint8_t preamble[4];
unsigned int blk_len;
stream_t *s = demuxer->stream;
/* file is qualified; skip over the signature bytes in the stream */
stream_seek (s, 4);
/* loop through the metadata blocks; use a do-while construct since there
* will always be 1 metadata block */
do {
int r;
r = stream_read (s, (char *) preamble, FLAC_SIGNATURE_SIZE);
if (r != FLAC_SIGNATURE_SIZE)
return;
blk_len = AV_RB24(preamble + 1);
switch (preamble[0] & 0x7F)
{
case FLAC_VORBIS_COMMENT:
{
/* For a description of the format please have a look at */
/* http://www.xiph.org/vorbis/doc/v-comment.html */
uint32_t length, comment_list_len;
char comments[blk_len];
uint8_t *ptr = comments;
char *comment;
int cn;
char c;
if (stream_read (s, comments, blk_len) == blk_len)
{
length = AV_RL32(ptr);
ptr += 4 + length;
comment_list_len = AV_RL32(ptr);
ptr += 4;
cn = 0;
for (; cn < comment_list_len; cn++)
{
length = AV_RL32(ptr);
ptr += 4;
comment = ptr;
if (&comment[length] < comments || &comment[length] >= &comments[blk_len])
return;
c = comment[length];
comment[length] = 0;
if (!strncasecmp ("TITLE=", comment, 6) && (length - 6 > 0))
demux_info_add (demuxer, "Title", comment + 6);
else if (!strncasecmp ("ARTIST=", comment, 7) && (length - 7 > 0))
demux_info_add (demuxer, "Artist", comment + 7);
else if (!strncasecmp ("ALBUM=", comment, 6) && (length - 6 > 0))
demux_info_add (demuxer, "Album", comment + 6);
else if (!strncasecmp ("DATE=", comment, 5) && (length - 5 > 0))
demux_info_add (demuxer, "Year", comment + 5);
else if (!strncasecmp ("GENRE=", comment, 6) && (length - 6 > 0))
demux_info_add (demuxer, "Genre", comment + 6);
else if (!strncasecmp ("Comment=", comment, 8) && (length - 8 > 0))
demux_info_add (demuxer, "Comment", comment + 8);
else if (!strncasecmp ("TRACKNUMBER=", comment, 12)
&& (length - 12 > 0))
{
char buf[31];
buf[30] = '\0';
sprintf (buf, "%d", atoi (comment + 12));
demux_info_add(demuxer, "Track", buf);
}
comment[length] = c;
ptr += length;
}
}
break;
}
case FLAC_STREAMINFO:
case FLAC_PADDING:
case FLAC_APPLICATION:
case FLAC_SEEKTABLE:
case FLAC_CUESHEET:
default:
/* 6-127 are presently reserved */
stream_skip (s, blk_len);
break;
}
} while ((preamble[0] & 0x80) == 0);
}
#endif
/**
* @brief Determine the number of frames of a file encoded with
* variable bitrate mode (VBR).
*
* @param s stream to be read
* @param off offset in stream to start reading from
*
* @return 0 (error or no variable bitrate mode) or number of frames
*/
static unsigned int mp3_vbr_frames(stream_t *s, off_t off) {
static const int xing_offset[2][2] = {{32, 17}, {17, 9}};
unsigned int data;
unsigned char hdr[4];
int framesize, chans, spf, layer;
if ((s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
if (!stream_seek(s, off)) return 0;
data = stream_read_dword(s);
hdr[0] = data >> 24;
hdr[1] = data >> 16;
hdr[2] = data >> 8;
hdr[3] = data;
if (!mp_check_mp3_header(data)) return 0;
framesize = mp_get_mp3_header(hdr, &chans, NULL, &spf, &layer, NULL);
if (framesize == -1 || layer != 3) return 0;
/* Xing / Info (at variable position: 32, 17 or 9 bytes after header) */
if (!stream_skip(s, xing_offset[spf < 1152][chans == 1])) return 0;
data = stream_read_dword(s);
if (data == MKBETAG('X','i','n','g') || data == MKBETAG('I','n','f','o')) {
data = stream_read_dword(s);
if (data & 0x1) // frames field is present
return stream_read_dword(s); // frames
}
/* VBRI (at fixed position: 32 bytes after header) */
if (!stream_seek(s, off + 4 + 32)) return 0;
data = stream_read_dword(s);
if (data == MKBETAG('V','B','R','I')) {
data = stream_read_word(s);
if (data == 1) { // check version
if (!stream_skip(s, 8)) return 0; // skip delay, quality and bytes
return stream_read_dword(s); // frames
}
}
}
return 0;
}
/**
* @brief Determine the total size of an ID3v2 tag.
*
* @param maj_ver major version of the ID3v2 tag
* @param s stream to be read, assumed to be positioned at revision byte
*
* @return 0 (error or malformed tag) or tag size
*/
static unsigned int id3v2_tag_size(uint8_t maj_ver, stream_t *s) {
unsigned int header_footer_size;
unsigned int size;
int i;
if(stream_read_char(s) == 0xff)
return 0;
header_footer_size = ((stream_read_char(s) & 0x10) && maj_ver >= 4) ? 20 : 10;
size = 0;
for(i = 0; i < 4; i++) {
uint8_t data = stream_read_char(s);
if (data & 0x80)
return 0;
size = size << 7 | data;
}
return header_footer_size + size;
}
static int demux_audio_open(demuxer_t* demuxer) {
stream_t *s;
sh_audio_t* sh_audio;
uint8_t hdr[HDR_SIZE];
int frmt = 0, n = 0, step;
off_t st_pos = 0, next_frame_pos = 0;
// mp3_hdrs list is sorted first by next_frame_pos and then by frame_pos
mp3_hdr_t *mp3_hdrs = NULL, *mp3_found = NULL;
da_priv_t* priv;
double duration;
int found_WAVE = 0;
s = demuxer->stream;
stream_read(s, hdr, HDR_SIZE);
while(n < 30000 && !s->eof) {
int mp3_freq, mp3_chans, mp3_flen, mpa_layer, mpa_spf, mpa_br;
st_pos = stream_tell(s) - HDR_SIZE;
step = 1;
if( hdr[0] == 'R' && hdr[1] == 'I' && hdr[2] == 'F' && hdr[3] == 'F' ) {
stream_skip(s,4);
if(s->eof)
break;
stream_read(s,hdr,4);
if(s->eof)
break;
if(hdr[0] != 'W' || hdr[1] != 'A' || hdr[2] != 'V' || hdr[3] != 'E' )
stream_skip(s,-8);
else
// We found wav header. Now we can have 'fmt ' or a mp3 header
// empty the buffer
step = 4;
} else if( hdr[0] == 'I' && hdr[1] == 'D' && hdr[2] == '3' && hdr[3] >= 2 && hdr[3] != 0xff) {
unsigned int len = id3v2_tag_size(hdr[3], s);
if(len > 0)
stream_skip(s,len-10);
step = 4;
} else if( found_WAVE && hdr[0] == 'f' && hdr[1] == 'm' && hdr[2] == 't' && hdr[3] == ' ' ) {
frmt = WAV;
break;
} else if((mp3_flen = mp_get_mp3_header(hdr, &mp3_chans, &mp3_freq,
&mpa_spf, &mpa_layer, &mpa_br)) > 0) {
mp3_found = add_mp3_hdr(&mp3_hdrs, st_pos, mp3_chans, mp3_freq,
mpa_spf, mpa_layer, mpa_br, mp3_flen);
if (mp3_found) {
frmt = MP3;
break;
}
} else if( hdr[0] == 'f' && hdr[1] == 'L' && hdr[2] == 'a' && hdr[3] == 'C' ) {
frmt = fLaC;
if (!mp3_hdrs || mp3_hdrs->cons_hdrs < 3)
break;
}
found_WAVE = hdr[0] == 'W' && hdr[1] == 'A' && hdr[2] == 'V' && hdr[3] == 'E';
// Add here some other audio format detection
if(step < HDR_SIZE)
memmove(hdr,&hdr[step],HDR_SIZE-step);
stream_read(s, &hdr[HDR_SIZE - step], step);
n++;
}
free_mp3_hdrs(&mp3_hdrs);
if(!frmt)
return 0;
sh_audio = new_sh_audio(demuxer,0);
switch(frmt) {
case MP3:
sh_audio->format = (mp3_found->mpa_layer < 3 ? 0x50 : 0x55);
demuxer->movi_start = mp3_found->frame_pos;
demuxer->movi_end = s->end_pos;
next_frame_pos = mp3_found->next_frame_pos;
sh_audio->audio.dwSampleSize= 0;
sh_audio->audio.dwScale = mp3_found->mpa_spf;
sh_audio->audio.dwRate = mp3_found->mp3_freq;
sh_audio->wf = malloc(sizeof(*sh_audio->wf));
sh_audio->wf->wFormatTag = sh_audio->format;
sh_audio->wf->nChannels = mp3_found->mp3_chans;
sh_audio->wf->nSamplesPerSec = mp3_found->mp3_freq;
sh_audio->wf->nAvgBytesPerSec = mp3_found->mpa_br * (1000 / 8);
sh_audio->wf->nBlockAlign = mp3_found->mpa_spf;
sh_audio->wf->wBitsPerSample = 16;
sh_audio->wf->cbSize = 0;
duration = (double) mp3_vbr_frames(s, demuxer->movi_start) * mp3_found->mpa_spf / mp3_found->mp3_freq;
free(mp3_found);
mp3_found = NULL;
if(demuxer->movi_end && (s->flags & MP_STREAM_SEEK) == MP_STREAM_SEEK) {
if(demuxer->movi_end >= 128) {
stream_seek(s,demuxer->movi_end-128);
stream_read(s,hdr,3);
if(!memcmp(hdr,"TAG",3)) {
char buf[31];
uint8_t g;
demuxer->movi_end -= 128;
stream_read(s,buf,30);
buf[30] = '\0';
demux_info_add(demuxer,"Title",buf);
stream_read(s,buf,30);
buf[30] = '\0';
demux_info_add(demuxer,"Artist",buf);
stream_read(s,buf,30);
buf[30] = '\0';
demux_info_add(demuxer,"Album",buf);
stream_read(s,buf,4);
buf[4] = '\0';
demux_info_add(demuxer,"Year",buf);
stream_read(s,buf,30);
buf[30] = '\0';
demux_info_add(demuxer,"Comment",buf);
if(buf[28] == 0 && buf[29] != 0) {
uint8_t trk = (uint8_t)buf[29];
sprintf(buf,"%d",trk);
demux_info_add(demuxer,"Track",buf);
}
g = stream_read_char(s);
demux_info_add(demuxer,"Genre",genres[g]);
}
}
if(demuxer->movi_end >= 10) {
stream_seek(s,demuxer->movi_end-10);
stream_read(s,hdr,4);
if(!memcmp(hdr,"3DI",3) && hdr[3] >= 4 && hdr[3] != 0xff) {
unsigned int len = id3v2_tag_size(hdr[3], s);
if(len > 0) {
if(len > demuxer->movi_end - demuxer->movi_start) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"Audio demuxer: bad ID3v2 tag size: larger than stream (%u).\n",len);
len = FFMIN(10,demuxer->movi_end-demuxer->movi_start);
} else {
stream_seek(s,demuxer->movi_end-len);
stream_read(s,hdr,4);
if(memcmp(hdr,"ID3",3) || hdr[3] < 4 || hdr[3] == 0xff || id3v2_tag_size(hdr[3], s) != len) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"Audio demuxer: damaged appended ID3v2 tag detected.\n");
len = FFMIN(10,demuxer->movi_end-demuxer->movi_start);
}
}
demuxer->movi_end -= len;
}
}
}
}
if (duration && demuxer->movi_end && demuxer->movi_end > demuxer->movi_start) sh_audio->wf->nAvgBytesPerSec = (demuxer->movi_end - demuxer->movi_start) / duration;
sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
break;
case WAV: {
unsigned int chunk_type;
unsigned int chunk_size;
WAVEFORMATEX* w;
int l;
l = stream_read_dword_le(s);
if(l < 16) {
mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too short (%d)!!!\n",l);
l = 16;
}
if(l > MAX_WAVHDR_LEN) {
mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] Bad wav header length: too long (%d)!!!\n",l);
l = 16;
}
sh_audio->wf = w = malloc(l > sizeof(*w) ? l : sizeof(*w));
w->wFormatTag = sh_audio->format = stream_read_word_le(s);
w->nChannels = sh_audio->channels = stream_read_word_le(s);
w->nSamplesPerSec = sh_audio->samplerate = stream_read_dword_le(s);
w->nAvgBytesPerSec = stream_read_dword_le(s);
w->nBlockAlign = stream_read_word_le(s);
w->wBitsPerSample = stream_read_word_le(s);
sh_audio->samplesize = (w->wBitsPerSample + 7) / 8;
w->cbSize = 0;
sh_audio->i_bps = sh_audio->wf->nAvgBytesPerSec;
l -= 16;
if (l >= 2) {
w->cbSize = stream_read_word_le(s);
l -= 2;
if (l < w->cbSize) {
mp_msg(MSGT_DEMUX,MSGL_ERR,"[demux_audio] truncated extradata (%d < %d)\n",
l,w->cbSize);
w->cbSize = l;
}
stream_read(s,(char*)(w + 1),w->cbSize);
l -= w->cbSize;
if (w->wFormatTag == 0xfffe && w->cbSize >= 22)
sh_audio->format = le2me_16(((WAVEFORMATEXTENSIBLE *)w)->SubFormat);
}
if( mp_msg_test(MSGT_DEMUX,MSGL_V) ) print_wave_header(w, MSGL_V);
if(l)
stream_skip(s,l);
do
{
chunk_type = stream_read_fourcc(demuxer->stream);
chunk_size = stream_read_dword_le(demuxer->stream);
if (chunk_type != mmioFOURCC('d', 'a', 't', 'a'))
stream_skip(demuxer->stream, chunk_size);
} while (!s->eof && chunk_type != mmioFOURCC('d', 'a', 't', 'a'));
demuxer->movi_start = stream_tell(s);
demuxer->movi_end = chunk_size ? demuxer->movi_start + chunk_size : s->end_pos;
// printf("wav: %X .. %X\n",(int)demuxer->movi_start,(int)demuxer->movi_end);
// Check if it contains dts audio
if((w->wFormatTag == 0x01) && (w->nChannels == 2) && (w->nSamplesPerSec == 44100)) {
unsigned char buf[16384]; // vlc uses 16384*4 (4 dts frames)
unsigned int i;
memset(buf, 0, sizeof(buf));
stream_read(s, buf, sizeof(buf));
for (i = 0; i < sizeof(buf) - 5; i += 2) {
// DTS, 14 bit, LE
if((buf[i] == 0xff) && (buf[i+1] == 0x1f) && (buf[i+2] == 0x00) &&
(buf[i+3] == 0xe8) && ((buf[i+4] & 0xfe) == 0xf0) && (buf[i+5] == 0x07)) {
sh_audio->format = 0x2001;
mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, LE\n");
break;
}
// DTS, 14 bit, BE
if((buf[i] == 0x1f) && (buf[i+1] == 0xff) && (buf[i+2] == 0xe8) &&
(buf[i+3] == 0x00) && (buf[i+4] == 0x07) && ((buf[i+5] & 0xfe) == 0xf0)) {
sh_audio->format = 0x2001;
mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 14 bit, BE\n");
break;
}
// DTS, 16 bit, BE
if((buf[i] == 0x7f) && (buf[i+1] == 0xfe) && (buf[i+2] == 0x80) &&
(buf[i+3] == 0x01)) {
sh_audio->format = 0x2001;
mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, BE\n");
break;
}
// DTS, 16 bit, LE
if((buf[i] == 0xfe) && (buf[i+1] == 0x7f) && (buf[i+2] == 0x01) &&
(buf[i+3] == 0x80)) {
sh_audio->format = 0x2001;
mp_msg(MSGT_DEMUX,MSGL_V,"[demux_audio] DTS audio in wav, 16 bit, LE\n");
break;
}
}
if (sh_audio->format == 0x2001) {
mp_msg(MSGT_DEMUX,MSGL_DBG2,"[demux_audio] DTS sync offset = %u\n", i);
}
}
// All formats that have a parser will need it when stored in WAV
sh_audio->needs_parsing = 1;
stream_seek(s,demuxer->movi_start);
} break;
case fLaC:
sh_audio->format = mmioFOURCC('f', 'L', 'a', 'C');
demuxer->movi_start = stream_tell(s) - 4;
demuxer->movi_end = s->end_pos;
if (demuxer->movi_end > demuxer->movi_start) {
// try to find out approx. bitrate
int64_t size = demuxer->movi_end - demuxer->movi_start;
int64_t num_samples;
int32_t srate;
stream_skip(s, 14);
srate = stream_read_int24(s) >> 4;
num_samples = stream_read_int24(s) << 16;
num_samples |= stream_read_word(s);
if (num_samples && srate)
sh_audio->i_bps = size * srate / num_samples;
}
if (sh_audio->i_bps < 1) // guess value to prevent crash
sh_audio->i_bps = 64 * 1024;
sh_audio->needs_parsing = 1;
// get_flac_metadata (demuxer);
break;
}
priv = malloc(sizeof(da_priv_t));
priv->frmt = frmt;
priv->next_pts = 0;
demuxer->priv = priv;
demuxer->audio->id = 0;
demuxer->audio->sh = sh_audio;
sh_audio->ds = demuxer->audio;
sh_audio->samplerate = sh_audio->audio.dwRate;
if(stream_tell(s) != demuxer->movi_start)
{
mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking from 0x%X to start pos 0x%X\n",
(int)stream_tell(s), (int)demuxer->movi_start);
stream_seek(s,demuxer->movi_start);
if (stream_tell(s) != demuxer->movi_start) {
mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking failed, now at 0x%X!\n",
(int)stream_tell(s));
if (next_frame_pos) {
mp_msg(MSGT_DEMUX, MSGL_V, "demux_audio: seeking to 0x%X instead\n",
(int)next_frame_pos);
stream_seek(s, next_frame_pos);
}
}
}
mp_msg(MSGT_DEMUX,MSGL_V,"demux_audio: audio data 0x%X - 0x%X \n",(int)demuxer->movi_start,(int)demuxer->movi_end);
return DEMUXER_TYPE_AUDIO;
}
static int demux_audio_fill_buffer(demuxer_t *demux, demux_stream_t *ds) {
int l;
demux_packet_t* dp;
sh_audio_t* sh_audio = ds->sh;
da_priv_t* priv = demux->priv;
double this_pts = priv->next_pts;
stream_t* s = demux->stream;
if(s->eof)
return 0;
switch(priv->frmt) {
case MP3 :
while(1) {
uint8_t hdr[4];
stream_read(s,hdr,4);
if (s->eof)
return 0;
l = mp_decode_mp3_header(hdr);
if(l < 0) {
if (demux->movi_end && stream_tell(s) >= demux->movi_end)
return 0; // might be ID3 tag, i.e. EOF
stream_skip(s,-3);
} else {
dp = new_demux_packet(l);
memcpy(dp->buffer,hdr,4);
if (stream_read(s,dp->buffer + 4,l-4) != l-4)
{
free_demux_packet(dp);
return 0;
}
priv->next_pts += sh_audio->audio.dwScale/(double)sh_audio->samplerate;
break;
}
} break;
case WAV : {
unsigned align = sh_audio->wf->nBlockAlign;
l = sh_audio->wf->nAvgBytesPerSec;
if (l <= 0) l = 65536;
if (demux->movi_end && l > demux->movi_end - stream_tell(s)) {
// do not read beyond end, there might be junk after data chunk
l = demux->movi_end - stream_tell(s);
if (l <= 0) return 0;
}
if (align)
l = (l + align - 1) / align * align;
dp = new_demux_packet(l);
l = stream_read(s,dp->buffer,l);
priv->next_pts += l/(double)sh_audio->i_bps;
break;
}
case fLaC: {
l = 65535;
dp = new_demux_packet(l);
l = stream_read(s,dp->buffer,l);
priv->next_pts = MP_NOPTS_VALUE;
break;
}
default:
mp_tmsg(MSGT_DEMUXER,MSGL_WARN,"Audio demuxer: unknown format %d.\n",priv->frmt);
return 0;
}
resize_demux_packet(dp, l);
dp->pts = this_pts;
ds_add_packet(ds, dp);
return 1;
}
static void high_res_mp3_seek(demuxer_t *demuxer,float time) {
uint8_t hdr[4];
int len,nf;
da_priv_t* priv = demuxer->priv;
sh_audio_t* sh = (sh_audio_t*)demuxer->audio->sh;
nf = time*sh->samplerate/sh->audio.dwScale;
while(nf > 0) {
stream_read(demuxer->stream,hdr,4);
len = mp_decode_mp3_header(hdr);
if(len < 0) {
stream_skip(demuxer->stream,-3);
continue;
}
stream_skip(demuxer->stream,len-4);
priv->next_pts += sh->audio.dwScale/(double)sh->samplerate;
nf--;
}
}
static void demux_audio_seek(demuxer_t *demuxer,float rel_seek_secs,float audio_delay,int flags){
struct MPOpts *opts = demuxer->opts;
sh_audio_t* sh_audio;
stream_t* s;
int64_t base,pos;
float len;
da_priv_t* priv;
if(!(sh_audio = demuxer->audio->sh))
return;
s = demuxer->stream;
priv = demuxer->priv;
if(priv->frmt == MP3 && opts->hr_mp3_seek && !(flags & SEEK_FACTOR)) {
len = (flags & SEEK_ABSOLUTE) ? rel_seek_secs - priv->next_pts : rel_seek_secs;
if(len < 0) {
stream_seek(s,demuxer->movi_start);
len = priv->next_pts + len;
priv->next_pts = 0;
}
if(len > 0)
high_res_mp3_seek(demuxer,len);
return;
}
base = flags&SEEK_ABSOLUTE ? demuxer->movi_start : stream_tell(s);
if(flags&SEEK_FACTOR)
pos = base + ((demuxer->movi_end - demuxer->movi_start)*rel_seek_secs);
else
pos = base + (rel_seek_secs*sh_audio->i_bps);
if(demuxer->movi_end && pos >= demuxer->movi_end) {
pos = demuxer->movi_end;
} else if(pos < demuxer->movi_start)
pos = demuxer->movi_start;
priv->next_pts = (pos-demuxer->movi_start)/(double)sh_audio->i_bps;
switch(priv->frmt) {
case WAV:
pos -= (pos - demuxer->movi_start) %
(sh_audio->wf->nBlockAlign ? sh_audio->wf->nBlockAlign :
(sh_audio->channels * sh_audio->samplesize));
break;
}
stream_seek(s,pos);
}
static void demux_close_audio(demuxer_t* demuxer) {
da_priv_t* priv = demuxer->priv;
free(priv);
}
static int demux_audio_control(demuxer_t *demuxer,int cmd, void *arg){
sh_audio_t *sh_audio=demuxer->audio->sh;
int audio_length = sh_audio->i_bps && demuxer->movi_end > demuxer->movi_start ?
(demuxer->movi_end - demuxer->movi_start) / sh_audio->i_bps : 0;
da_priv_t* priv = demuxer->priv;
switch(cmd) {
case DEMUXER_CTRL_GET_TIME_LENGTH:
if (audio_length<=0) return DEMUXER_CTRL_DONTKNOW;
*((double *)arg)=(double)audio_length;
return DEMUXER_CTRL_GUESS;
case DEMUXER_CTRL_GET_PERCENT_POS:
if (audio_length<=0)
return DEMUXER_CTRL_DONTKNOW;
*((int *)arg)=(int)( (priv->next_pts*100) / audio_length);
return DEMUXER_CTRL_OK;
default:
return DEMUXER_CTRL_NOTIMPL;
}
}
const demuxer_desc_t demuxer_desc_audio = {
"Audio demuxer",
"audio",
"Audio only",
"?",
"Audio only files",
DEMUXER_TYPE_AUDIO,
0, // unsafe autodetect
demux_audio_open,
demux_audio_fill_buffer,
NULL,
demux_close_audio,
demux_audio_seek,
demux_audio_control
};

View File

@ -46,7 +46,7 @@
#include "stheader.h"
#include "ebml.h"
#include "matroska.h"
#include "demux_real.h"
//#include "demux_real.h"
#include "mp_msg.h"
@ -1814,6 +1814,54 @@ static int demux_mkv_read_block_lacing(uint8_t *buffer, uint64_t *size,
return 1;
}
#define SKIP_BITS(n) buffer<<=n
#define SHOW_BITS(n) ((buffer)>>(32-(n)))
static double real_fix_timestamp(unsigned char *buf, unsigned int timestamp, unsigned int format, int64_t *kf_base, int *kf_pts, double *pts){
double v_pts;
unsigned char *s = buf + 1 + (*buf+1)*8;
uint32_t buffer= (s[0]<<24) + (s[1]<<16) + (s[2]<<8) + s[3];
unsigned int kf=timestamp;
int pict_type;
if(format==mmioFOURCC('R','V','3','0') || format==mmioFOURCC('R','V','4','0')){
if(format==mmioFOURCC('R','V','3','0')){
SKIP_BITS(3);
pict_type= SHOW_BITS(2);
SKIP_BITS(2 + 7);
}else{
SKIP_BITS(1);
pict_type= SHOW_BITS(2);
SKIP_BITS(2 + 7 + 3);
}
kf= SHOW_BITS(13); // kf= 2*SHOW_BITS(12);
// if(pict_type==0)
if(pict_type<=1){
// I frame, sync timestamps:
*kf_base=(int64_t)timestamp-kf;
mp_msg(MSGT_DEMUX, MSGL_DBG2,"\nTS: base=%08"PRIX64"\n",*kf_base);
kf=timestamp;
} else {
// P/B frame, merge timestamps:
int64_t tmp=(int64_t)timestamp-*kf_base;
kf|=tmp&(~0x1fff); // combine with packet timestamp
if(kf<tmp-4096) kf+=8192; else // workaround wrap-around problems
if(kf>tmp+4096) kf-=8192;
kf+=*kf_base;
}
if(pict_type != 3){ // P || I frame -> swap timestamps
unsigned int tmp=kf;
kf=*kf_pts;
*kf_pts=tmp;
// if(kf<=tmp) kf=0;
}
}
v_pts=kf*0.001f;
// if(pts && (v_pts<*pts || !kf)) v_pts=*pts+frametime;
if(pts) *pts=v_pts;
return v_pts;
}
static void handle_realvideo(demuxer_t *demuxer, mkv_track_t *track,
uint8_t *buffer, uint32_t size, bool keyframe)
{

File diff suppressed because it is too large Load Diff

View File

@ -1,28 +0,0 @@
/*
* 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.
*/
#ifndef MPLAYER_DEMUX_REAL_H
#define MPLAYER_DEMUX_REAL_H
#include <stdint.h>
double real_fix_timestamp(unsigned char *buf, unsigned int timestamp,
unsigned int format, int64_t *kf_base,
int *kf_pts, double *pts);
#endif /* MPLAYER_DEMUX_REAL_H */

View File

@ -1,375 +0,0 @@
/*
* Realaudio demuxer
* copyright (c) 2003, 2005 Roberto Togni
*
* 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 "mp_msg.h"
#include "stream/stream.h"
#include "aviprint.h"
#include "demuxer.h"
#include "stheader.h"
#define FOURCC_DOTRA mmioFOURCC('.','r','a', 0xfd)
#define FOURCC_144 mmioFOURCC('1','4','_','4')
#define FOURCC_288 mmioFOURCC('2','8','_','8')
#define FOURCC_DNET mmioFOURCC('d','n','e','t')
#define FOURCC_LPCJ mmioFOURCC('l','p','c','J')
#define FOURCC_SIPR mmioFOURCC('s','i','p','r')
#define INTLID_INT4 mmioFOURCC('I','n','t','4')
#define INTLID_SIPR mmioFOURCC('s','i','p','r')
static unsigned char sipr_swaps[38][2]={
{0,63},{1,22},{2,44},{3,90},{5,81},{7,31},{8,86},{9,58},{10,36},{12,68},
{13,39},{14,73},{15,53},{16,69},{17,57},{19,88},{20,34},{21,71},{24,46},
{25,94},{26,54},{28,75},{29,50},{32,70},{33,92},{35,74},{38,85},{40,56},
{42,87},{43,65},{45,59},{48,79},{49,93},{51,89},{55,95},{61,76},{67,83},
{77,80} };
// Map flavour to bytes per second
static int sipr_fl2bps[4] = {813, 1062, 625, 2000}; // 6.5, 8.5, 5, 16 kbit per second
typedef struct {
unsigned short version;
unsigned int dotranum;
unsigned int data_size;
unsigned short version2;
unsigned int hdr_size;
unsigned short codec_flavor;
unsigned int coded_framesize;
unsigned short sub_packet_h;
unsigned short frame_size;
unsigned short sub_packet_size;
unsigned intl_id;
unsigned char *audio_buf;
} ra_priv_t;
static int ra_check_file(demuxer_t* demuxer)
{
unsigned int chunk_id;
chunk_id = stream_read_dword_le(demuxer->stream);
if (chunk_id == FOURCC_DOTRA)
return DEMUXER_TYPE_REALAUDIO;
else
return 0;
}
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
static int demux_ra_fill_buffer(demuxer_t *demuxer, demux_stream_t *dsds)
{
ra_priv_t *ra_priv = demuxer->priv;
int len;
demux_stream_t *ds = demuxer->audio;
sh_audio_t *sh = ds->sh;
WAVEFORMATEX *wf = sh->wf;
demux_packet_t *dp;
int x, y;
if (demuxer->stream->eof)
return 0;
len = wf->nBlockAlign;
demuxer->filepos = stream_tell(demuxer->stream);
if ((ra_priv->intl_id == INTLID_INT4) || (ra_priv->intl_id == INTLID_SIPR)) {
if (ra_priv->intl_id == INTLID_SIPR) {
int n;
int bs = ra_priv->sub_packet_h * ra_priv->frame_size * 2 / 96; // nibbles per subpacket
stream_read(demuxer->stream, ra_priv->audio_buf, ra_priv->sub_packet_h * ra_priv->frame_size);
// Perform reordering
for(n = 0; n < 38; n++) {
int j;
int i = bs * sipr_swaps[n][0];
int o = bs * sipr_swaps[n][1];
// swap nibbles of block 'i' with 'o' TODO: optimize
for(j = 0; j < bs; j++) {
int x = (i & 1) ? (ra_priv->audio_buf[i >> 1] >> 4) : (ra_priv->audio_buf[i >> 1] & 0x0F);
int y = (o & 1) ? (ra_priv->audio_buf[o >> 1] >> 4) : (ra_priv->audio_buf[o >> 1] & 0x0F);
if(o & 1)
ra_priv->audio_buf[o >> 1] = (ra_priv->audio_buf[o >> 1] & 0x0F) | (x << 4);
else
ra_priv->audio_buf[o >> 1] = (ra_priv->audio_buf[o >> 1] & 0xF0) | x;
if(i & 1)
ra_priv->audio_buf[i >> 1] = (ra_priv->audio_buf[i >> 1] & 0x0F) | (y << 4);
else
ra_priv->audio_buf[i >> 1] = (ra_priv->audio_buf[i >> 1] & 0xF0) | y;
++i; ++o;
}
}
} else {
for (y = 0; y < ra_priv->sub_packet_h; y++)
for (x = 0; x < ra_priv->sub_packet_h / 2; x++)
stream_read(demuxer->stream, ra_priv->audio_buf + x * 2 *ra_priv->frame_size +
y * ra_priv->coded_framesize, ra_priv->coded_framesize);
}
// Release all the audio packets
for (x = 0; x < ra_priv->sub_packet_h * ra_priv->frame_size / len; x++) {
dp = new_demux_packet(len);
memcpy(dp->buffer, ra_priv->audio_buf + x * len, len);
dp->pts = x ? 0 : demuxer->filepos / ra_priv->data_size;
dp->pos = demuxer->filepos; // all equal
dp->keyframe = !x; // Mark first packet as keyframe
ds_add_packet(ds, dp);
}
} else {
dp = new_demux_packet(len);
stream_read(demuxer->stream, dp->buffer, len);
dp->pts = demuxer->filepos / ra_priv->data_size;
dp->pos = demuxer->filepos;
ds_add_packet(ds, dp);
}
return 1;
}
static demuxer_t* demux_open_ra(demuxer_t* demuxer)
{
ra_priv_t* ra_priv = demuxer->priv;
sh_audio_t *sh;
int i;
char *buf;
if ((ra_priv = malloc(sizeof(ra_priv_t))) == NULL) {
mp_msg(MSGT_DEMUX, MSGL_ERR, "[RealAudio] Can't allocate memory for private data.\n");
return 0;
}
memset(ra_priv, 0, sizeof(ra_priv_t));
demuxer->priv = ra_priv;
sh = new_sh_audio(demuxer, 0);
demuxer->audio->id = 0;
sh->ds=demuxer->audio;
demuxer->audio->sh = sh;
ra_priv->version = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] File version: %d\n", ra_priv->version);
if ((ra_priv->version < 3) || (ra_priv->version > 4)) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"[RealAudio] ra version %d is not supported yet, please "
"contact MPlayer developers\n", ra_priv->version);
return 0;
}
if (ra_priv->version == 3) {
ra_priv->hdr_size = stream_read_word(demuxer->stream);
stream_skip(demuxer->stream, 10);
ra_priv->data_size = stream_read_dword(demuxer->stream);
} else {
stream_skip(demuxer->stream, 2);
ra_priv->dotranum = stream_read_dword(demuxer->stream);
ra_priv->data_size = stream_read_dword(demuxer->stream);
ra_priv->version2 = stream_read_word(demuxer->stream);
ra_priv->hdr_size = stream_read_dword(demuxer->stream);
ra_priv->codec_flavor = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Flavor: %d\n", ra_priv->codec_flavor);
ra_priv->coded_framesize = stream_read_dword(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Coded frame size: %d\n", ra_priv->coded_framesize);
stream_skip(demuxer->stream, 4); // data size?
stream_skip(demuxer->stream, 8);
ra_priv->sub_packet_h = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Sub packet h: %d\n", ra_priv->sub_packet_h);
ra_priv->frame_size = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Frame size: %d\n", ra_priv->frame_size);
ra_priv->sub_packet_size = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] Sub packet size: %d\n", ra_priv->sub_packet_size);
stream_skip(demuxer->stream, 2);
sh->samplerate = stream_read_word(demuxer->stream);
stream_skip(demuxer->stream, 2);
sh->samplesize = stream_read_word(demuxer->stream);
sh->channels = stream_read_word(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"[RealAudio] %d channel, %d bit, %dHz\n", sh->channels,
sh->samplesize, sh->samplerate);
i = stream_read_char(demuxer->stream);
ra_priv->intl_id = stream_read_dword_le(demuxer->stream);
if (i != 4) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"[RealAudio] Interleaver Id size is not 4 (%d), please report to "
"MPlayer developers\n", i);
stream_skip(demuxer->stream, i - 4);
}
i = stream_read_char(demuxer->stream);
sh->format = stream_read_dword_le(demuxer->stream);
if (i != 4) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"[RealAudio] FourCC size is not 4 (%d), please report to "
"MPlayer developers\n", i);
stream_skip(demuxer->stream, i - 4);
}
stream_skip(demuxer->stream, 3);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buf = malloc(i+1);
stream_read(demuxer->stream, buf, i);
buf[i] = 0;
demux_info_add(demuxer, "Title", buf);
free(buf);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buf = malloc(i+1);
stream_read(demuxer->stream, buf, i);
buf[i] = 0;
demux_info_add(demuxer, "Author", buf);
free(buf);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buf = malloc(i+1);
stream_read(demuxer->stream, buf, i);
buf[i] = 0;
demux_info_add(demuxer, "Copyright", buf);
free(buf);
}
if ((i = stream_read_char(demuxer->stream)) != 0) {
buf = malloc(i+1);
stream_read(demuxer->stream, buf, i);
buf[i] = 0;
demux_info_add(demuxer, "Comment", buf);
free(buf);
}
if (ra_priv->version == 3) {
if(ra_priv->hdr_size + 8 > stream_tell(demuxer->stream)) {
stream_skip(demuxer->stream, 1);
i = stream_read_char(demuxer->stream);
sh->format = stream_read_dword_le(demuxer->stream);
if (i != 4) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"[RealAudio] FourCC size is not 4 (%d), please report to "
"MPlayer developers\n", i);
stream_skip(demuxer->stream, i - 4);
}
if (sh->format != FOURCC_LPCJ) {
mp_msg(MSGT_DEMUX,MSGL_WARN,"[RealAudio] Version 3 with FourCC %8x, please report to "
"MPlayer developers\n", sh->format);
}
} else
// If a stream does not have fourcc, let's assume it's 14.4
sh->format = FOURCC_LPCJ;
sh->channels = 1;
sh->samplesize = 16;
sh->samplerate = 8000;
ra_priv->frame_size = 240;
sh->format = FOURCC_144;
}
/* Fill WAVEFORMATEX */
sh->wf = calloc(1, sizeof(*sh->wf));
sh->wf->nChannels = sh->channels;
sh->wf->wBitsPerSample = sh->samplesize;
sh->wf->nSamplesPerSec = sh->samplerate;
sh->wf->nAvgBytesPerSec = sh->samplerate*sh->samplesize/8;
sh->wf->nBlockAlign = ra_priv->frame_size;
sh->wf->cbSize = 0;
sh->wf->wFormatTag = sh->format;
switch (sh->format) {
case FOURCC_144:
mp_msg(MSGT_DEMUX,MSGL_V,"Audio: 14_4\n");
sh->wf->nBlockAlign = 0x14;
break;
case FOURCC_288:
mp_msg(MSGT_DEMUX,MSGL_V,"Audio: 28_8\n");
sh->wf->nBlockAlign = ra_priv->coded_framesize;
ra_priv->audio_buf = calloc(ra_priv->sub_packet_h, ra_priv->frame_size);
break;
case FOURCC_DNET:
mp_msg(MSGT_DEMUX,MSGL_V,"Audio: DNET -> AC3\n");
break;
case FOURCC_SIPR:
mp_msg(MSGT_DEMUX,MSGL_V,"Audio: SIPR\n");
sh->wf->nBlockAlign = ra_priv->coded_framesize;
sh->wf->nAvgBytesPerSec = sipr_fl2bps[ra_priv->codec_flavor];
ra_priv->audio_buf = calloc(ra_priv->sub_packet_h, ra_priv->frame_size);
break;
default:
mp_msg(MSGT_DEMUX,MSGL_V,"Audio: Unknown (%d)\n", sh->format);
}
print_wave_header(sh->wf, MSGL_V);
/* disable seeking */
demuxer->seekable = 0;
if(!ds_fill_buffer(demuxer->audio))
mp_msg(MSGT_DEMUXER,MSGL_INFO,"[RealAudio] No data.\n");
return demuxer;
}
static void demux_close_ra(demuxer_t *demuxer)
{
ra_priv_t* ra_priv = demuxer->priv;
if (ra_priv) {
free(ra_priv->audio_buf);
free(ra_priv);
}
}
#if 0
/* please upload RV10 samples WITH INDEX CHUNK */
int demux_seek_ra(demuxer_t *demuxer, float rel_seek_secs, float audio_delay, int flags)
{
real_priv_t *priv = demuxer->priv;
demux_stream_t *d_audio = demuxer->audio;
sh_audio_t *sh_audio = d_audio->sh;
int aid = d_audio->id;
int next_offset = 0;
int rel_seek_frames = 0;
int streams = 0;
return stream_seek(demuxer->stream, next_offset);
}
#endif
const demuxer_desc_t demuxer_desc_realaudio = {
"Realaudio demuxer",
"realaudio",
"REALAUDIO",
"Roberto Togni",
"handles old audio only .ra files",
DEMUXER_TYPE_REALAUDIO,
1, // safe autodetect
ra_check_file,
demux_ra_fill_buffer,
demux_open_ra,
demux_close_ra,
NULL,
NULL
};

View File

@ -1,769 +0,0 @@
/*
* VIVO file parser
* copyright (c) 2001 A'rpi
* VIVO text header parser and audio support by alex
*
* 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 <string.h> /* strtok */
#include "config.h"
#include "mp_msg.h"
#include "stream/stream.h"
#include "demuxer.h"
#include "stheader.h"
/* parameters ! */
int vivo_param_version = -1;
char *vivo_param_acodec = NULL;
int vivo_param_abitrate = -1;
int vivo_param_samplerate = -1;
int vivo_param_bytesperblock = -1;
int vivo_param_width = -1;
int vivo_param_height = -1;
int vivo_param_vformat = -1;
/* VIVO audio standards from vivog723.acm:
G.723:
FormatTag = 0x111
Channels = 1 - mono
SamplesPerSec = 8000 - 8khz
AvgBytesPerSec = 800
BlockAlign (bytes per block) = 24
BitsPerSample = 8
Siren:
FormatTag = 0x112
Channels = 1 - mono
SamplesPerSec = 16000 - 16khz
AvgBytesPerSec = 2000
BlockAlign (bytes per block) = 40
BitsPerSample = 8
*/
//enum { VIVO_AUDIO_G723, VIVO_AUDIO_SIREN };
#define VIVO_AUDIO_G723 1
#define VIVO_AUDIO_SIREN 2
typedef struct {
/* generic */
char version;
int supported;
/* info */
char *title;
char *author;
char *copyright;
char *producer;
/* video */
float fps;
int width;
int height;
int disp_width;
int disp_height;
/* audio */
int audio_codec;
int audio_bitrate;
int audio_samplerate;
int audio_bytesperblock;
} vivo_priv_t;
/* parse all possible extra headers */
/* (audio headers are separate - mostly with recordtype=3 or 4) */
#define TEXTPARSE_ALL 1
static void vivo_parse_text_header(demuxer_t *demux, int header_len)
{
vivo_priv_t* priv = demux->priv;
char *buf;
int i;
char *token;
char *opt, *param;
int parser_in_audio_block = 0;
if (!demux->priv)
{
priv = malloc(sizeof(vivo_priv_t));
memset(priv, 0, sizeof(vivo_priv_t));
demux->priv = priv;
priv->supported = 0;
}
buf = malloc(header_len);
opt = malloc(header_len);
param = malloc(header_len);
stream_read(demux->stream, buf, header_len);
i=0;
while(i<header_len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines
token = strtok(buf, (char *)&("\x0d\x0a"));
while (token && (header_len>2))
{
header_len -= strlen(token)+2;
if (sscanf(token, "%[^:]:%[^\n]", opt, param) != 2)
{
mp_msg(MSGT_DEMUX, MSGL_V, "viv_text_header_parser: bad line: '%s' at ~%#"PRIx64"\n",
token, (int64_t)stream_tell(demux->stream));
break;
}
mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token: '%s' (%zd bytes/%d bytes left)\n",
token, strlen(token), header_len);
mp_dbg(MSGT_DEMUX, MSGL_DBG3, "token => o: '%s', p: '%s'\n",
opt, param);
/* checking versions: only v1 or v2 is suitable (or known?:) */
if (!strcmp(opt, "Version"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Version: %s\n", param);
if (!strncmp(param, "Vivo/1", 6) || !strncmp(param, "Vivo/2", 6))
{
priv->supported = 1;
/* save major version for fourcc */
priv->version = param[5];
}
}
/* video specific */
if (!strcmp(opt, "FPS"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "FPS: %f\n", atof(param));
priv->fps = atof(param);
}
if (!strcmp(opt, "Width"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Width: %d\n", atoi(param));
priv->width = atoi(param);
}
if (!strcmp(opt, "Height"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Height: %d\n", atoi(param));
priv->height = atoi(param);
}
if (!strcmp(opt, "DisplayWidth"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Width: %d\n", atoi(param));
priv->disp_width = atoi(param);
}
if (!strcmp(opt, "DisplayHeight"))
{
mp_msg(MSGT_DEMUX, MSGL_DBG2, "Display Height: %d\n", atoi(param));
priv->disp_height = atoi(param);
}
/* audio specific */
if (!strcmp(opt, "RecordType"))
{
/* no audio recordblock by Vivo/1.00, 3 and 4 by Vivo/2.00 */
if ((atoi(param) == 3) || (atoi(param) == 4))
parser_in_audio_block = 1;
else
parser_in_audio_block = 0;
}
if (!strcmp(opt, "NominalBitrate"))
{
priv->audio_bitrate = atoi(param);
if (priv->audio_bitrate == 2000)
priv->audio_codec = VIVO_AUDIO_SIREN;
if (priv->audio_bitrate == 800)
priv->audio_codec = VIVO_AUDIO_G723;
}
if (!strcmp(opt, "SamplingFrequency"))
{
priv->audio_samplerate = atoi(param);
if (priv->audio_samplerate == 16000)
priv->audio_codec = VIVO_AUDIO_SIREN;
if (priv->audio_samplerate == 8000)
priv->audio_codec = VIVO_AUDIO_G723;
}
if (!strcmp(opt, "Length") && (parser_in_audio_block == 1))
{
priv->audio_bytesperblock = atoi(param); /* 24 or 40 kbps */
if (priv->audio_bytesperblock == 40)
priv->audio_codec = VIVO_AUDIO_SIREN;
if (priv->audio_bytesperblock == 24)
priv->audio_codec = VIVO_AUDIO_G723;
}
/* only for displaying some informations about movie*/
if (!strcmp(opt, "Title"))
{
demux_info_add(demux, "title", param);
priv->title = strdup(param);
}
if (!strcmp(opt, "Author"))
{
demux_info_add(demux, "author", param);
priv->author = strdup(param);
}
if (!strcmp(opt, "Copyright"))
{
demux_info_add(demux, "copyright", param);
priv->copyright = strdup(param);
}
if (!strcmp(opt, "Producer"))
{
demux_info_add(demux, "encoder", param);
priv->producer = strdup(param);
}
/* get next token */
token = strtok(NULL, (char *)&("\x0d\x0a"));
}
free(buf);
free(opt);
free(param);
}
static int vivo_check_file(demuxer_t* demuxer){
int i=0;
int len;
int c;
unsigned char buf[2048+256];
vivo_priv_t* priv;
int orig_pos = stream_tell(demuxer->stream);
mp_msg(MSGT_DEMUX,MSGL_V,"Checking for VIVO\n");
c=stream_read_char(demuxer->stream);
if(c==-256) return 0;
len=0;
while((c=stream_read_char(demuxer->stream))>=0x80){
len+=0x80*(c-0x80);
if(len>1024) return 0;
}
len+=c;
mp_msg(MSGT_DEMUX,MSGL_V,"header block 1 size: %d\n",len);
//stream_skip(demuxer->stream,len);
priv=malloc(sizeof(vivo_priv_t));
memset(priv,0,sizeof(vivo_priv_t));
demuxer->priv=priv;
#if 0
vivo_parse_text_header(demuxer, len);
if (priv->supported == 0)
return 0;
#else
/* this is enought for check (for now) */
stream_read(demuxer->stream,buf,len);
buf[len]=0;
// printf("VIVO header: '%s'\n",buf);
// parse header:
i=0;
while(i<len && buf[i]==0x0D && buf[i+1]==0x0A) i+=2; // skip empty lines
if(strncmp(buf+i,"Version:Vivo/",13)) return 0; // bad version/type!
#endif
#if 0
c=stream_read_char(demuxer->stream);
if(c) return 0;
len2=0;
while((c=stream_read_char(demuxer->stream))>=0x80){
len2+=0x80*(c-0x80);
if(len+len2>2048) return 0;
}
len2+=c;
mp_msg(MSGT_DEMUX,MSGL_V,"header block 2 size: %d\n",len2);
stream_skip(demuxer->stream,len2);
// stream_read(demuxer->stream,buf+len,len2);
#endif
// c=stream_read_char(demuxer->stream);
// printf("first packet: %02X\n",c);
stream_seek(demuxer->stream, orig_pos);
return DEMUXER_TYPE_VIVO;
}
static int audio_pos=0;
static int audio_rate=0;
// return value:
// 0 = EOF or no stream found
// 1 = successfully read a packet
static int demux_vivo_fill_buffer(demuxer_t *demux, demux_stream_t *dsds){
demux_stream_t *ds=NULL;
int c;
int len=0;
int seq;
int prefix=0;
demux->filepos=stream_tell(demux->stream);
c=stream_read_char(demux->stream);
if (c == -256) /* EOF */
return 0;
// printf("c=%x,%02X\n",c,c&0xf0);
if (c == 0x82)
{
/* ok, this works, but pts calculating from header is required! */
/* FIXME: "Calculate PTS from picture header!" */
prefix = 1;
c = stream_read_char(demux->stream);
mp_msg(MSGT_DEMUX, MSGL_V, "packet 0x82(pos=%u) chunk=%x\n",
(int)stream_tell(demux->stream), c);
}
switch(c&0xF0){
case 0x00: // header - skip it!
{
len=stream_read_char(demux->stream);
if(len>=0x80) len=0x80*(len-0x80)+stream_read_char(demux->stream);
mp_msg(MSGT_DEMUX, MSGL_V, "vivo extra header: %d bytes\n",len);
#ifdef TEXTPARSE_ALL
{
int pos;
/* also try to parse all headers */
pos = stream_tell(demux->stream);
vivo_parse_text_header(demux, len);
stream_seek(demux->stream, pos);
}
#endif
break;
}
case 0x10: // video packet
if (prefix == 1)
len = stream_read_char(demux->stream);
else
len=128;
ds=demux->video;
break;
case 0x20: // video packet
len=stream_read_char(demux->stream);
ds=demux->video;
break;
case 0x30: // audio packet
if (prefix == 1)
len = stream_read_char(demux->stream);
else
len=40; /* 40kbps */
ds=demux->audio;
audio_pos+=len;
break;
case 0x40: // audio packet
if (prefix == 1)
len = stream_read_char(demux->stream);
else
len=24; /* 24kbps */
ds=demux->audio;
audio_pos+=len;
break;
default:
mp_msg(MSGT_DEMUX,MSGL_WARN,"VIVO - unknown ID found: %02X at pos %"PRIu64" contact author!\n",
c, (int64_t)stream_tell(demux->stream));
return 0;
}
// printf("chunk=%x, len=%d\n", c, len);
if(!ds || ds->id<-1){
if(len) stream_skip(demux->stream,len);
return 1;
}
seq=c&0x0F;
if(ds->asf_packet){
if(ds->asf_seq!=seq){
// closed segment, finalize packet:
ds_add_packet(ds,ds->asf_packet);
ds->asf_packet=NULL;
// printf("packet!\n");
} else {
// append data to it!
demux_packet_t* dp=ds->asf_packet;
if(dp->len + len + MP_INPUT_BUFFER_PADDING_SIZE < 0)
return 0;
dp->buffer=realloc(dp->buffer,dp->len+len+MP_INPUT_BUFFER_PADDING_SIZE);
memset(dp->buffer+dp->len+len, 0, MP_INPUT_BUFFER_PADDING_SIZE);
//memcpy(dp->buffer+dp->len,data,len);
stream_read(demux->stream,dp->buffer+dp->len,len);
mp_dbg(MSGT_DEMUX,MSGL_DBG4,"data appended! %d+%d\n",dp->len,len);
dp->len+=len;
// we are ready now.
if((c&0xF0)==0x20) --ds->asf_seq; // hack!
return 1;
}
}
// create new packet:
{ demux_packet_t* dp;
dp=new_demux_packet(len);
//memcpy(dp->buffer,data,len);
stream_read(demux->stream,dp->buffer,len);
dp->pts=audio_rate?((float)audio_pos/(float)audio_rate):0;
// dp->flags=keyframe;
// if(ds==demux->video) printf("ASF time: %8d dur: %5d \n",time,dur);
dp->pos=demux->filepos;
ds->asf_packet=dp;
ds->asf_seq=seq;
// we are ready now.
return 1;
}
}
static const short h263_format[8][2] = {
{ 0, 0 },
{ 128, 96 },
{ 176, 144 },
{ 352, 288 },
{ 704, 576 },
{ 1408, 1152 },
{ 320, 240 } // ??????? or 240x180 (found in vivo2) ?
};
static unsigned char* buffer;
static int bufptr=0;
static int bitcnt=0;
static unsigned char buf=0;
static int format, width, height;
static unsigned int x_get_bits(int n){
unsigned int x=0;
while(n-->0){
if(!bitcnt){
// fill buff
buf=buffer[bufptr++];
bitcnt=8;
}
//x=(x<<1)|(buf&1);buf>>=1;
x=(x<<1)|(buf>>7);buf<<=1;
--bitcnt;
}
return x;
}
#define get_bits(xxx,n) x_get_bits(n)
#define get_bits1(xxx) x_get_bits(1)
#define skip_bits(xxx,n) x_get_bits(n)
#define skip_bits1(xxx) x_get_bits(1)
/* most is hardcoded. should extend to handle all h263 streams */
static int h263_decode_picture_header(unsigned char *b_ptr)
{
// int i;
// for(i=0;i<16;i++) printf(" %02X",b_ptr[i]); printf("\n");
buffer=b_ptr;
bufptr=bitcnt=buf=0;
/* picture header */
if (get_bits(&s->gb, 22) != 0x20){
mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad picture header\n");
return -1;
}
skip_bits(&s->gb, 8); /* picture timestamp */
if (get_bits1(&s->gb) != 1){
mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad marker\n");
return -1; /* marker */
}
if (get_bits1(&s->gb) != 0){
mp_msg(MSGT_DEMUX, MSGL_FATAL, "bad h263 id\n");
return -1; /* h263 id */
}
skip_bits1(&s->gb); /* split screen off */
skip_bits1(&s->gb); /* camera off */
skip_bits1(&s->gb); /* freeze picture release off */
format = get_bits(&s->gb, 3);
if (format != 7) {
mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 0 format = %d\n", format);
/* H.263v1 */
width = h263_format[format][0];
height = h263_format[format][1];
mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height);
// if (!width) return -1;
mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits1(&s->gb));
mp_msg(MSGT_DEMUX, MSGL_V, "unrestricted_mv=%d\n", get_bits1(&s->gb));
#if 1
mp_msg(MSGT_DEMUX, MSGL_V, "SAC: %d\n", get_bits1(&s->gb));
mp_msg(MSGT_DEMUX, MSGL_V, "advanced prediction mode: %d\n", get_bits1(&s->gb));
mp_msg(MSGT_DEMUX, MSGL_V, "PB frame: %d\n", get_bits1(&s->gb));
#else
if (get_bits1(&s->gb) != 0)
return -1; /* SAC: off */
if (get_bits1(&s->gb) != 0)
return -1; /* advanced prediction mode: off */
if (get_bits1(&s->gb) != 0)
return -1; /* not PB frame */
#endif
mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5));
skip_bits1(&s->gb); /* Continuous Presence Multipoint mode: off */
} else {
mp_msg(MSGT_DEMUX, MSGL_V, "h263_plus = 1\n");
/* H.263v2 */
if (get_bits(&s->gb, 3) != 1){
mp_msg(MSGT_DEMUX, MSGL_FATAL, "H.263v2 A error\n");
return -1;
}
if (get_bits(&s->gb, 3) != 6){ /* custom source format */
mp_msg(MSGT_DEMUX, MSGL_FATAL, "custom source format\n");
return -1;
}
skip_bits(&s->gb, 12);
skip_bits(&s->gb, 3);
mp_msg(MSGT_DEMUX, MSGL_V, "pict_type=%d\n", get_bits(&s->gb, 3) + 1);
// if (s->pict_type != I_TYPE &&
// s->pict_type != P_TYPE)
// return -1;
skip_bits(&s->gb, 7);
skip_bits(&s->gb, 4); /* aspect ratio */
width = (get_bits(&s->gb, 9) + 1) * 4;
skip_bits1(&s->gb);
height = get_bits(&s->gb, 9) * 4;
mp_msg(MSGT_DEMUX, MSGL_V, "%d x %d\n", width, height);
//if (height == 0)
// return -1;
mp_msg(MSGT_DEMUX, MSGL_V, "qscale=%d\n", get_bits(&s->gb, 5));
}
/* PEI */
while (get_bits1(&s->gb) != 0) {
skip_bits(&s->gb, 8);
}
// s->f_code = 1;
// s->width = width;
// s->height = height;
return 0;
}
static demuxer_t* demux_open_vivo(demuxer_t* demuxer){
vivo_priv_t* priv=demuxer->priv;
if(!ds_fill_buffer(demuxer->video)){
mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: %s",
mp_gtext("Missing video stream!? Contact the author, it may be a bug :(\n"));
return NULL;
}
audio_pos=0;
h263_decode_picture_header(demuxer->video->buffer);
if (vivo_param_version != -1)
priv->version = '0' + vivo_param_version;
{ sh_video_t* sh=new_sh_video(demuxer,0);
/* viv1, viv2 (for better codecs.conf) */
sh->format = mmioFOURCC('v', 'i', 'v', priv->version);
if(!sh->fps)
{
if (priv->fps)
sh->fps=priv->fps;
else
sh->fps=15.0f;
}
sh->frametime=1.0f/sh->fps;
/* XXX: FIXME: can't scale image. */
/* hotfix to disable: */
priv->disp_width = priv->width;
priv->disp_height = priv->height;
if (vivo_param_width != -1)
priv->disp_width = priv->width = vivo_param_width;
if (vivo_param_height != -1)
priv->disp_height = priv->height = vivo_param_height;
if (vivo_param_vformat != -1)
{
priv->disp_width = priv->width = h263_format[vivo_param_vformat][0];
priv->disp_height = priv->height = h263_format[vivo_param_vformat][1];
}
if (priv->disp_width)
sh->disp_w = priv->disp_width;
else
sh->disp_w = width;
if (priv->disp_height)
sh->disp_h = priv->disp_height;
else
sh->disp_h = height;
// emulate BITMAPINFOHEADER:
sh->bih=calloc(1, sizeof(*sh->bih));
sh->bih->biSize=40;
if (priv->width)
sh->bih->biWidth = priv->width;
else
sh->bih->biWidth = width;
if (priv->height)
sh->bih->biHeight = priv->height;
else
sh->bih->biHeight = height;
sh->bih->biPlanes=1;
sh->bih->biBitCount=24;
sh->bih->biCompression=sh->format;
sh->bih->biSizeImage=sh->bih->biWidth*sh->bih->biHeight*3;
/* insert as stream */
demuxer->video->sh=sh;
sh->ds=demuxer->video;
demuxer->video->id=0;
/* disable seeking */
demuxer->seekable = 0;
mp_msg(MSGT_DEMUX,MSGL_V,"VIVO Video stream %d size: display: %dx%d, codec: %ux%u\n",
demuxer->video->id, sh->disp_w, sh->disp_h, sh->bih->biWidth,
sh->bih->biHeight);
}
/* AUDIO init */
if (demuxer->audio->id >= -1){
if(!ds_fill_buffer(demuxer->audio)){
mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: %s",
mp_gtext("No audio stream found -> no sound.\n"));
} else
{ sh_audio_t* sh=new_sh_audio(demuxer,1);
/* Select audio codec */
if (priv->audio_codec == 0)
{
if (priv->version == '2')
priv->audio_codec = VIVO_AUDIO_SIREN;
else
priv->audio_codec = VIVO_AUDIO_G723;
}
if (vivo_param_acodec != NULL)
{
if (!strcasecmp(vivo_param_acodec, "g723"))
priv->audio_codec = VIVO_AUDIO_G723;
if (!strcasecmp(vivo_param_acodec, "siren"))
priv->audio_codec = VIVO_AUDIO_SIREN;
}
if (priv->audio_codec == VIVO_AUDIO_G723)
sh->format = 0x111;
else if (priv->audio_codec == VIVO_AUDIO_SIREN)
sh->format = 0x112;
else
{
mp_msg(MSGT_DEMUX, MSGL_ERR, "VIVO: Not support audio codec (%d)\n",
priv->audio_codec);
free_sh_audio(demuxer, 1);
goto nosound;
}
// Emulate WAVEFORMATEX struct:
sh->wf=calloc(1, sizeof(*sh->wf));
sh->wf->wFormatTag=sh->format;
sh->wf->nChannels=1; /* 1 channels for both Siren and G.723 */
/* Set bits per sample */
if (priv->audio_codec == VIVO_AUDIO_SIREN)
sh->wf->wBitsPerSample = 16;
else
if (priv->audio_codec == VIVO_AUDIO_G723)
sh->wf->wBitsPerSample = 8;
/* Set sampling rate */
if (priv->audio_samplerate) /* got from header */
sh->wf->nSamplesPerSec = priv->audio_samplerate;
else
{
if (priv->audio_codec == VIVO_AUDIO_SIREN)
sh->wf->nSamplesPerSec = 16000;
if (priv->audio_codec == VIVO_AUDIO_G723)
sh->wf->nSamplesPerSec = 8000;
}
if (vivo_param_samplerate != -1)
sh->wf->nSamplesPerSec = vivo_param_samplerate;
/* Set audio bitrate */
if (priv->audio_bitrate) /* got from header */
sh->wf->nAvgBytesPerSec = priv->audio_bitrate;
else
{
if (priv->audio_codec == VIVO_AUDIO_SIREN)
sh->wf->nAvgBytesPerSec = 2000;
if (priv->audio_codec == VIVO_AUDIO_G723)
sh->wf->nAvgBytesPerSec = 800;
}
if (vivo_param_abitrate != -1)
sh->wf->nAvgBytesPerSec = vivo_param_abitrate;
audio_rate=sh->wf->nAvgBytesPerSec;
if (!priv->audio_bytesperblock)
{
if (priv->audio_codec == VIVO_AUDIO_SIREN)
sh->wf->nBlockAlign = 40;
if (priv->audio_codec == VIVO_AUDIO_G723)
sh->wf->nBlockAlign = 24;
}
else
sh->wf->nBlockAlign = priv->audio_bytesperblock;
if (vivo_param_bytesperblock != -1)
sh->wf->nBlockAlign = vivo_param_bytesperblock;
/*sound_ok:*/
/* insert as stream */
demuxer->audio->sh=sh;
sh->ds=demuxer->audio;
demuxer->audio->id=1;
nosound:
return demuxer;
}
}
return demuxer;
}
static void demux_close_vivo(demuxer_t *demuxer)
{
vivo_priv_t* priv=demuxer->priv;
if (priv) {
free(priv->title);
free(priv->author);
free(priv->copyright);
free(priv->producer);
free(priv);
}
return;
}
const demuxer_desc_t demuxer_desc_vivo = {
"Vivo demuxer",
"vivo",
"VIVO",
"A'rpi, Alex Beregszasi",
"",
DEMUXER_TYPE_VIVO,
0, // unsafe autodetect
vivo_check_file,
demux_vivo_fill_buffer,
demux_open_vivo,
demux_close_vivo,
NULL,
NULL
};

View File

@ -58,14 +58,9 @@ 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_real;
extern const demuxer_desc_t demuxer_desc_matroska;
extern const demuxer_desc_t demuxer_desc_realaudio;
extern const demuxer_desc_t demuxer_desc_vivo;
extern const demuxer_desc_t demuxer_desc_gif;
extern const demuxer_desc_t demuxer_desc_avs;
extern const demuxer_desc_t demuxer_desc_rawdv;
extern const demuxer_desc_t demuxer_desc_audio;
extern const demuxer_desc_t demuxer_desc_rtp;
extern const demuxer_desc_t demuxer_desc_rtp_nemesi;
extern const demuxer_desc_t demuxer_desc_lavf;
@ -89,14 +84,9 @@ const demuxer_desc_t *const demuxer_list[] = {
&demuxer_desc_avi,
&demuxer_desc_asf,
&demuxer_desc_matroska,
&demuxer_desc_realaudio,
#ifdef CONFIG_GIF
&demuxer_desc_gif,
#endif
#ifdef CONFIG_WIN32DLL
&demuxer_desc_avs,
#endif
&demuxer_desc_audio,
#ifdef CONFIG_LIVE555
&demuxer_desc_rtp,
#endif

View File

@ -49,12 +49,9 @@ enum demuxer_type {
DEMUXER_TYPE_AVI_NI,
DEMUXER_TYPE_AVI_NINI,
DEMUXER_TYPE_ASF,
DEMUXER_TYPE_VIVO,
DEMUXER_TYPE_TV,
DEMUXER_TYPE_REAL,
DEMUXER_TYPE_Y4M,
DEMUXER_TYPE_MF,
DEMUXER_TYPE_AUDIO,
DEMUXER_TYPE_RAWAUDIO,
DEMUXER_TYPE_RTP,
DEMUXER_TYPE_RAWDV,
@ -62,7 +59,6 @@ enum demuxer_type {
DEMUXER_TYPE_GIF,
DEMUXER_TYPE_MPEG_TS,
DEMUXER_TYPE_MATROSKA,
DEMUXER_TYPE_REALAUDIO,
DEMUXER_TYPE_LAVF,
DEMUXER_TYPE_NSV,
DEMUXER_TYPE_AVS,

View File

@ -45,16 +45,14 @@ static struct {
{ "asf", DEMUXER_TYPE_ASF },
{ "wmv", DEMUXER_TYPE_ASF },
{ "wma", DEMUXER_TYPE_ASF },
{ "viv", DEMUXER_TYPE_VIVO },
{ "vivo", DEMUXER_TYPE_VIVO },
{ "rm", DEMUXER_TYPE_REAL },
{ "rmvb", DEMUXER_TYPE_REAL },
{ "ra", DEMUXER_TYPE_REAL },
{ "rm", DEMUXER_TYPE_LAVF },
{ "rmvb", DEMUXER_TYPE_LAVF },
{ "ra", DEMUXER_TYPE_LAVF },
{ "y4m", DEMUXER_TYPE_Y4M },
{ "mp3", DEMUXER_TYPE_AUDIO },
{ "wav", DEMUXER_TYPE_AUDIO },
{ "flac", DEMUXER_TYPE_AUDIO },
{ "fla", DEMUXER_TYPE_AUDIO },
{ "mp3", DEMUXER_TYPE_LAVF },
{ "wav", DEMUXER_TYPE_LAVF },
{ "flac", DEMUXER_TYPE_LAVF },
{ "fla", DEMUXER_TYPE_LAVF },
{ "ogg", DEMUXER_TYPE_LAVF },
{ "ogm", DEMUXER_TYPE_LAVF },
// { "pls", DEMUXER_TYPE_PLAYLIST },

View File

@ -1,293 +0,0 @@
/***********************************
* Copyright (C) 2001 Jason Carter
*
* This program 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.
*
* This program 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 this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
***********************************
* FILE: GENRES.H
* NAME: ID3EDIT - ID3 tag v 1.1 editor
* DESCRIPTION: Genres character array
* AUTHOR: Jason Carter
***********************************
*
* Initially modified for use with MPlayer by Diego Biurrun on 2004-08-22
* $Id$
* detailed changelog at http://svn.mplayerhq.hu/mplayer/trunk/
*/
#ifndef MPLAYER_GENRES_H
#define MPLAYER_GENRES_H
const char * const genres[] = {
"Blues", /* 0 */
"Classic Rock", /* 1 */
"Country", /* 2 */
"Dance", /* 3 */
"Disco", /* 4 */
"Funk", /* 5 */
"Grunge", /* 6 */
"Hip-Hop", /* 7 */
"Jazz", /* 8 */
"Metal", /* 9 */
"New Age", /* 10 */
"Oldies", /* 11 */
"Other", /* 12 */
"Pop", /* 13 */
"R&B", /* 14 */
"Rap", /* 15 */
"Reggae", /* 16 */
"Rock", /* 17 */
"Techno", /* 18 */
"Industrial", /* 19 */
"Alternative", /* 20 */
"Ska", /* 21 */
"Death Metal", /* 22 */
"Pranks", /* 23 */
"Soundtrack", /* 24 */
"Eurotechno", /* 25 */
"Ambient", /* 26 */
"Trip-Hop", /* 27 */
"Vocal", /* 28 */
"Jazz+Funk", /* 29 */
"Fusion", /* 30 */
"Trance", /* 31 */
"Classical", /* 32 */
"Instrumental", /* 33 */
"Acid", /* 34 */
"House", /* 35 */
"Game", /* 36 */
"Sound Clip", /* 37 */
"Gospel", /* 38 */
"Noise", /* 39 */
"Alternative Rock", /* 40 */
"Bass", /* 41 */
"Soul", /* 42 */
"Punk", /* 43 */
"Space", /* 44 */
"Meditative", /* 45 */
"Instrumental Pop", /* 46 */
"Instrumental Rock", /* 47 */
"Ethnic", /* 48 */
"Gothic", /* 49 */
"Darkwave", /* 50 */
"Techno-Industrial", /* 51 */
"Electronic", /* 52 */
"Pop-Folk", /* 53 */
"Eurodance", /* 54 */
"Dream", /* 55 */
"Southern Rock", /* 56 */
"Comedy", /* 57 */
"Cult", /* 58 */
"Gangsta", /* 59 */
"Top 40", /* 60 */
"Christian Rap", /* 61 */
"Pop/Funk", /* 62 */
"Jungle", /* 63 */
"Native American", /* 64 */
"Cabaret", /* 65 */
"New Wave", /* 66 */
"Psychadelic", /* 67 */ /* typo taken from the id3v2spec*/
"Rave", /* 68 */
"Show Tunes", /* 69 */
"Trailer", /* 70 */
"Lo-Fi", /* 71 */
"Tribal", /* 72 */
"Acid Punk", /* 73 */
"Acid Jazz", /* 74 */
"Polka", /* 75 */
"Retro", /* 76 */
"Musical", /* 77 */
"Rock & Roll", /* 78 */
"Hard Rock", /* 79 */
"Folk", /* 80 */
"Folk/Rock", /* 81 */
"National Folk", /* 82 */
"Swing", /* 83 */
"Fast-Fusion", /* 84 */
"Bebop", /* 85 */
"Latin", /* 86 */
"Revival", /* 87 */
"Celtic", /* 88 */
"Bluegrass", /* 89 */
"Avantgarde", /* 90 */
"Gothic Rock", /* 91 */
"Progressive Rock", /* 92 */
"Psychedelic Rock", /* 93 */
"Symphonic Rock", /* 94 */
"Slow Rock", /* 95 */
"Big Band", /* 96 */
"Chorus", /* 97 */
"Easy Listening", /* 98 */
"Acoustic", /* 99 */
"Humour", /* 100 */
"Speech", /* 101 */
"Chanson", /* 102 */
"Opera", /* 103 */
"Chamber Music", /* 104 */
"Sonata", /* 105 */
"Symphony", /* 106 */
"Booty Bass", /* 107 */
"Primus", /* 108 */
"Porn Groove", /* 109 */
"Satire", /* 110 */
"Slow Jam", /* 111 */
"Club", /* 112 */
"Tango", /* 113 */
"Samba", /* 114 */
"Folklore", /* 115 */
"Ballad", /* 116 */
"Power Ballad", /* 117 */
"Rhytmic Soul", /* 118 */
"Freestyle", /* 119 */
"Duet", /* 120 */
"Punk Rock", /* 121 */
"Drum Solo", /* 122 */
"Acapella", /* 123 */
"Euro-House", /* 124 */
"Dance Hall", /* 125 */
"Goa", /* 126 */
"Drum & Bass", /* 127 */
"Club-House", /* 128 */
"Hardcore", /* 129 */
"Terror", /* 130 */
"Indie", /* 131 */
"BritPop", /* 132 */
"Negerpunk", /* 133 */
"Polsk Punk", /* 134 */
"Beat", /* 135 */
"Christian Gangsta Rap", /* 136 */
"Heavy Metal", /* 137 */
"Black Metal", /* 138 */
"Crossover", /* 139 */
"Contemporary Christian", /* 140 */
"Christian Rock", /* 141 */
"Merengue", /* 142 */
"Salsa", /* 143 */
"Thrash Metal", /* 144 */
"Anime", /* 145 */
"Jpop", /* 146 */
"Synthpop", /* 147 */
"Unknown", /* 148 */
"Unknown", /* 149 */
"Unknown", /* 150 */
"Unknown", /* 151 */
"Unknown", /* 152 */
"Unknown", /* 153 */
"Unknown", /* 154 */
"Unknown", /* 155 */
"Unknown", /* 156 */
"Unknown", /* 157 */
"Unknown", /* 158 */
"Unknown", /* 159 */
"Unknown", /* 160 */
"Unknown", /* 161 */
"Unknown", /* 162 */
"Unknown", /* 163 */
"Unknown", /* 164 */
"Unknown", /* 165 */
"Unknown", /* 166 */
"Unknown", /* 167 */
"Unknown", /* 168 */
"Unknown", /* 169 */
"Unknown", /* 170 */
"Unknown", /* 171 */
"Unknown", /* 172 */
"Unknown", /* 173 */
"Unknown", /* 174 */
"Unknown", /* 175 */
"Unknown", /* 176 */
"Unknown", /* 177 */
"Unknown", /* 178 */
"Unknown", /* 179 */
"Unknown", /* 180 */
"Unknown", /* 181 */
"Unknown", /* 182 */
"Unknown", /* 183 */
"Unknown", /* 184 */
"Unknown", /* 185 */
"Unknown", /* 186 */
"Unknown", /* 187 */
"Unknown", /* 188 */
"Unknown", /* 189 */
"Unknown", /* 190 */
"Unknown", /* 191 */
"Unknown", /* 192 */
"Unknown", /* 193 */
"Unknown", /* 194 */
"Unknown", /* 195 */
"Unknown", /* 196 */
"Unknown", /* 197 */
"Unknown", /* 198 */
"Unknown", /* 199 */
"Unknown", /* 200 */
"Unknown", /* 201 */
"Unknown", /* 202 */
"Unknown", /* 203 */
"Unknown", /* 204 */
"Unknown", /* 205 */
"Unknown", /* 206 */
"Unknown", /* 207 */
"Unknown", /* 208 */
"Unknown", /* 209 */
"Unknown", /* 210 */
"Unknown", /* 211 */
"Unknown", /* 212 */
"Unknown", /* 213 */
"Unknown", /* 214 */
"Unknown", /* 215 */
"Unknown", /* 216 */
"Unknown", /* 217 */
"Unknown", /* 218 */
"Unknown", /* 219 */
"Unknown", /* 220 */
"Unknown", /* 221 */
"Unknown", /* 222 */
"Unknown", /* 223 */
"Unknown", /* 224 */
"Unknown", /* 225 */
"Unknown", /* 226 */
"Unknown", /* 227 */
"Unknown", /* 228 */
"Unknown", /* 229 */
"Unknown", /* 230 */
"Unknown", /* 231 */
"Unknown", /* 232 */
"Unknown", /* 233 */
"Unknown", /* 234 */
"Unknown", /* 235 */
"Unknown", /* 236 */
"Unknown", /* 237 */
"Unknown", /* 238 */
"Unknown", /* 239 */
"Unknown", /* 240 */
"Unknown", /* 241 */
"Unknown", /* 242 */
"Unknown", /* 243 */
"Unknown", /* 244 */
"Unknown", /* 245 */
"Unknown", /* 246 */
"Unknown", /* 247 */
"Unknown", /* 248 */
"Unknown", /* 249 */
"Unknown", /* 250 */
"Unknown", /* 251 */
"Unknown", /* 252 */
"Unknown", /* 253 */
"Unknown", /* 254 */
"Unknown", /* 255 */
};
#endif /* MPLAYER_GENRES_H */

View File

@ -86,8 +86,6 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
if(d_video->pts>0 && pts1>0 && d_video->pts>pts1)
frame_time=d_video->pts-pts1;
break;
case DEMUXER_TYPE_TV:
case DEMUXER_TYPE_VIVO:
case DEMUXER_TYPE_ASF: {
double next_pts = ds_get_next_pts(d_video);
double d= (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts-pts1;
@ -115,14 +113,6 @@ int video_read_frame(sh_video_t* sh_video,float* frame_time_ptr,unsigned char**
}
}
break;
case DEMUXER_TYPE_REAL:
{
double next_pts = ds_get_next_pts(d_video);
double d = (next_pts != MP_NOPTS_VALUE) ? next_pts - d_video->pts : d_video->pts - pts1;
frame_time = (d >= 0 && pts1 > 0) ? d : 0.001;
}
break;
}

View File

@ -771,7 +771,7 @@ static int http_streaming_start(stream_t *stream, int* file_format) {
else if ( (field_data = http_get_field(http_hdr, "content-type")) != NULL && (!strcmp(field_data, "audio/aacp") || !strcmp(field_data, "audio/aac")))
*file_format = DEMUXER_TYPE_AAC;
else
*file_format = DEMUXER_TYPE_AUDIO;
*file_format = DEMUXER_TYPE_LAVF;
res = STREAM_ERROR;
goto out;
}

View File

@ -66,7 +66,7 @@ int network_ipv4_only_proxy = 0;
const mime_struct_t mime_type_table[] = {
// MP3 streaming, some MP3 streaming server answer with audio/mpeg
{ "audio/mpeg", DEMUXER_TYPE_AUDIO },
{ "audio/mpeg", DEMUXER_TYPE_LAVF },
// ASF
{ "audio/x-ms-wax", DEMUXER_TYPE_ASF },
{ "audio/x-ms-wma", DEMUXER_TYPE_ASF },