/*
Real parser & demuxer
(C) Alex Beregszaszi
Based on FFmpeg's libav/rm.c.
Audio codecs: (supported by RealPlayer8 for Linux)
DNET - RealAudio 3.0, really it's AC3 in swapped-byteorder
SIPR - SiproLab's audio codec, ACELP decoder working with MPlayer,
needs fine-tuning too :)
ATRC - RealAudio 8 (ATRAC3) - www.minidisc.org/atrac3_article.pdf,
ACM decoder uploaded, needs some fine-tuning to work
-> RealAudio 8
COOK/COKR - Real Cooker -> RealAudio G2
Video codecs: (supported by RealPlayer8 for Linux)
RV10 - H.263 based, working with libavcodec's decoder
RV20-RV40 - using RealPlayer's codec plugins
*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "config.h"
#include "mp_msg.h"
#include "help_mp.h"
#include "stream.h"
#include "demuxer.h"
#include "stheader.h"
#include "bswap.h"
//#define mp_dbg(mod,lev, args... ) mp_msg_c((mod<<8)|lev, ## args )
#define MKTAG(a, b, c, d) (a | (b << 8) | (c << 16) | (d << 24))
#define MAX_STREAMS 32
typedef struct {
int timestamp;
int offset;
// int packetno;
// int len; /* only filled by our index generator */
// int flags; /* only filled by our index generator */
} real_index_table_t;
typedef struct {
/* for seeking */
int index_chunk_offset;
real_index_table_t *index_table[MAX_STREAMS];
// int *index_table[MAX_STREAMS];
int index_table_size[MAX_STREAMS];
int index_malloc_size[MAX_STREAMS];
int data_chunk_offset;
int num_of_packets;
int current_packet;
// need for seek
int audio_need_keyframe;
int video_after_seek;
int current_apacket;
int current_vpacket;
// timestamp correction:
int kf_base;// timestamp of the prev. video keyframe
int kf_pts; // timestamp of next video keyframe
int a_pts; // previous audio timestamp
float v_pts; // previous video timestamp
unsigned long duration;
/* stream id table */
// int last_a_stream;
// int a_streams[MAX_STREAMS];
// int last_v_stream;
// int v_streams[MAX_STREAMS];
} real_priv_t;
/* originally from FFmpeg */
static void get_str(int isbyte, demuxer_t *demuxer, char *buf, int buf_size)
{
int len;
if (isbyte)
len = stream_read_char(demuxer->stream);
else
len = stream_read_word(demuxer->stream);
stream_read(demuxer->stream, buf, (len > buf_size) ? buf_size : len);
if (len > buf_size)
stream_skip(demuxer->stream, len-buf_size);
mp_msg(MSGT_DEMUX, MSGL_V, "read_str: %d bytes read\n", len);
}
static void skip_str(int isbyte, demuxer_t *demuxer)
{
int len;
if (isbyte)
len = stream_read_char(demuxer->stream);
else
len = stream_read_word(demuxer->stream);
stream_skip(demuxer->stream, len);
mp_msg(MSGT_DEMUX, MSGL_V, "skip_str: %d bytes skipped\n", len);
}
static void dump_index(demuxer_t *demuxer, int stream_id)
{
real_priv_t *priv = demuxer->priv;
real_index_table_t *index;
int i, entries;
if (verbose<=0)
return;
if (stream_id > MAX_STREAMS)
return;
index = priv->index_table[stream_id];
entries = priv->index_table_size[stream_id];
|