You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-07-11 14:30:22 +02:00
support for older real audio files (<= version 3)
Originally committed as revision 2119 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
137
libavformat/rm.c
137
libavformat/rm.c
@ -39,6 +39,7 @@ typedef struct {
|
|||||||
StreamInfo *audio_stream, *video_stream;
|
StreamInfo *audio_stream, *video_stream;
|
||||||
int data_pos; /* position of the data after the header */
|
int data_pos; /* position of the data after the header */
|
||||||
int nb_packets;
|
int nb_packets;
|
||||||
|
int old_format;
|
||||||
} RMContext;
|
} RMContext;
|
||||||
|
|
||||||
static void put_str(ByteIOContext *s, const char *tag)
|
static void put_str(ByteIOContext *s, const char *tag)
|
||||||
@ -465,6 +466,85 @@ static void get_str8(ByteIOContext *pb, char *buf, int buf_size)
|
|||||||
*q = '\0';
|
*q = '\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rm_read_audio_stream_info(AVFormatContext *s, AVStream *st,
|
||||||
|
int read_all)
|
||||||
|
{
|
||||||
|
ByteIOContext *pb = &s->pb;
|
||||||
|
char buf[128];
|
||||||
|
uint32_t version;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* ra type header */
|
||||||
|
version = get_be32(pb); /* version */
|
||||||
|
if (((version >> 16) & 0xff) == 3) {
|
||||||
|
/* very old version */
|
||||||
|
for(i = 0; i < 14; i++)
|
||||||
|
get_byte(pb);
|
||||||
|
get_str8(pb, s->title, sizeof(s->title));
|
||||||
|
get_str8(pb, s->author, sizeof(s->author));
|
||||||
|
get_str8(pb, s->copyright, sizeof(s->copyright));
|
||||||
|
get_str8(pb, s->comment, sizeof(s->comment));
|
||||||
|
get_byte(pb);
|
||||||
|
get_str8(pb, buf, sizeof(buf));
|
||||||
|
st->codec.sample_rate = 8000;
|
||||||
|
st->codec.channels = 1;
|
||||||
|
st->codec.codec_type = CODEC_TYPE_AUDIO;
|
||||||
|
st->codec.codec_id = CODEC_ID_RA_144;
|
||||||
|
} else {
|
||||||
|
/* old version (4) */
|
||||||
|
get_be32(pb); /* .ra4 */
|
||||||
|
get_be32(pb);
|
||||||
|
get_be16(pb);
|
||||||
|
get_be32(pb); /* header size */
|
||||||
|
get_be16(pb); /* add codec info */
|
||||||
|
get_be32(pb); /* coded frame size */
|
||||||
|
get_be32(pb); /* ??? */
|
||||||
|
get_be32(pb); /* ??? */
|
||||||
|
get_be32(pb); /* ??? */
|
||||||
|
get_be16(pb); /* 1 */
|
||||||
|
get_be16(pb); /* coded frame size */
|
||||||
|
get_be32(pb);
|
||||||
|
st->codec.sample_rate = get_be16(pb);
|
||||||
|
get_be32(pb);
|
||||||
|
st->codec.channels = get_be16(pb);
|
||||||
|
get_str8(pb, buf, sizeof(buf)); /* desc */
|
||||||
|
get_str8(pb, buf, sizeof(buf)); /* desc */
|
||||||
|
st->codec.codec_type = CODEC_TYPE_AUDIO;
|
||||||
|
if (!strcmp(buf, "dnet")) {
|
||||||
|
st->codec.codec_id = CODEC_ID_AC3;
|
||||||
|
} else {
|
||||||
|
st->codec.codec_id = CODEC_ID_NONE;
|
||||||
|
pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name),
|
||||||
|
buf);
|
||||||
|
}
|
||||||
|
if (read_all) {
|
||||||
|
get_byte(pb);
|
||||||
|
get_byte(pb);
|
||||||
|
get_byte(pb);
|
||||||
|
|
||||||
|
get_str8(pb, s->title, sizeof(s->title));
|
||||||
|
get_str8(pb, s->author, sizeof(s->author));
|
||||||
|
get_str8(pb, s->copyright, sizeof(s->copyright));
|
||||||
|
get_str8(pb, s->comment, sizeof(s->comment));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rm_read_header_old(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
|
{
|
||||||
|
RMContext *rm = s->priv_data;
|
||||||
|
AVStream *st;
|
||||||
|
|
||||||
|
rm->old_format = 1;
|
||||||
|
st = av_new_stream(s, 0);
|
||||||
|
if (!st)
|
||||||
|
goto fail;
|
||||||
|
rm_read_audio_stream_info(s, st, 1);
|
||||||
|
return 0;
|
||||||
|
fail:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
||||||
{
|
{
|
||||||
RMContext *rm = s->priv_data;
|
RMContext *rm = s->priv_data;
|
||||||
@ -477,8 +557,13 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
char buf[128];
|
char buf[128];
|
||||||
int flags = 0;
|
int flags = 0;
|
||||||
|
|
||||||
if (get_le32(pb) != MKTAG('.', 'R', 'M', 'F'))
|
tag = get_le32(pb);
|
||||||
|
if (tag == MKTAG('.', 'r', 'a', 0xfd)) {
|
||||||
|
/* very old .ra format */
|
||||||
|
return rm_read_header_old(s, ap);
|
||||||
|
} else if (tag != MKTAG('.', 'R', 'M', 'F')) {
|
||||||
return -EIO;
|
return -EIO;
|
||||||
|
}
|
||||||
|
|
||||||
get_be32(pb); /* header size */
|
get_be32(pb); /* header size */
|
||||||
get_be16(pb);
|
get_be16(pb);
|
||||||
@ -545,32 +630,7 @@ static int rm_read_header(AVFormatContext *s, AVFormatParameters *ap)
|
|||||||
v = get_be32(pb);
|
v = get_be32(pb);
|
||||||
if (v == MKTAG(0xfd, 'a', 'r', '.')) {
|
if (v == MKTAG(0xfd, 'a', 'r', '.')) {
|
||||||
/* ra type header */
|
/* ra type header */
|
||||||
get_be32(pb); /* version */
|
rm_read_audio_stream_info(s, st, 0);
|
||||||
get_be32(pb); /* .ra4 */
|
|
||||||
get_be32(pb);
|
|
||||||
get_be16(pb);
|
|
||||||
get_be32(pb); /* header size */
|
|
||||||
get_be16(pb); /* add codec info */
|
|
||||||
get_be32(pb); /* coded frame size */
|
|
||||||
get_be32(pb); /* ??? */
|
|
||||||
get_be32(pb); /* ??? */
|
|
||||||
get_be32(pb); /* ??? */
|
|
||||||
get_be16(pb); /* 1 */
|
|
||||||
get_be16(pb); /* coded frame size */
|
|
||||||
get_be32(pb);
|
|
||||||
st->codec.sample_rate = get_be16(pb);
|
|
||||||
get_be32(pb);
|
|
||||||
st->codec.channels = get_be16(pb);
|
|
||||||
get_str8(pb, buf, sizeof(buf)); /* desc */
|
|
||||||
get_str8(pb, buf, sizeof(buf)); /* desc */
|
|
||||||
st->codec.codec_type = CODEC_TYPE_AUDIO;
|
|
||||||
if (!strcmp(buf, "dnet")) {
|
|
||||||
st->codec.codec_id = CODEC_ID_AC3;
|
|
||||||
} else {
|
|
||||||
st->codec.codec_id = CODEC_ID_NONE;
|
|
||||||
pstrcpy(st->codec.codec_name, sizeof(st->codec.codec_name),
|
|
||||||
buf);
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
|
if (get_le32(pb) != MKTAG('V', 'I', 'D', 'O')) {
|
||||||
fail1:
|
fail1:
|
||||||
@ -645,6 +705,9 @@ static int get_num(ByteIOContext *pb, int *len)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* multiple of 20 bytes for ra144 (ugly) */
|
||||||
|
#define RAW_PACKET_SIZE 1000
|
||||||
|
|
||||||
static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
|
static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||||
{
|
{
|
||||||
RMContext *rm = s->priv_data;
|
RMContext *rm = s->priv_data;
|
||||||
@ -654,6 +717,19 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
uint8_t *ptr;
|
uint8_t *ptr;
|
||||||
int flags;
|
int flags;
|
||||||
|
|
||||||
|
if (rm->old_format) {
|
||||||
|
/* just read raw bytes */
|
||||||
|
len = RAW_PACKET_SIZE;
|
||||||
|
av_new_packet(pkt, len);
|
||||||
|
pkt->stream_index = 0;
|
||||||
|
len = get_buffer(pb, pkt->data, len);
|
||||||
|
if (len <= 0) {
|
||||||
|
av_free_packet(pkt);
|
||||||
|
return -EIO;
|
||||||
|
}
|
||||||
|
pkt->size = len;
|
||||||
|
st = s->streams[0];
|
||||||
|
} else {
|
||||||
redo:
|
redo:
|
||||||
if (rm->nb_packets == 0)
|
if (rm->nb_packets == 0)
|
||||||
return -EIO;
|
return -EIO;
|
||||||
@ -713,6 +789,7 @@ static int rm_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
av_new_packet(pkt, len);
|
av_new_packet(pkt, len);
|
||||||
pkt->stream_index = i;
|
pkt->stream_index = i;
|
||||||
get_buffer(pb, pkt->data, len);
|
get_buffer(pb, pkt->data, len);
|
||||||
|
}
|
||||||
|
|
||||||
/* for AC3, needs to swap bytes */
|
/* for AC3, needs to swap bytes */
|
||||||
if (st->codec.codec_id == CODEC_ID_AC3) {
|
if (st->codec.codec_id == CODEC_ID_AC3) {
|
||||||
@ -737,9 +814,11 @@ static int rm_probe(AVProbeData *p)
|
|||||||
/* check file header */
|
/* check file header */
|
||||||
if (p->buf_size <= 32)
|
if (p->buf_size <= 32)
|
||||||
return 0;
|
return 0;
|
||||||
if (p->buf[0] == '.' && p->buf[1] == 'R' &&
|
if ((p->buf[0] == '.' && p->buf[1] == 'R' &&
|
||||||
p->buf[2] == 'M' && p->buf[3] == 'F' &&
|
p->buf[2] == 'M' && p->buf[3] == 'F' &&
|
||||||
p->buf[4] == 0 && p->buf[5] == 0)
|
p->buf[4] == 0 && p->buf[5] == 0) ||
|
||||||
|
(p->buf[0] == '.' && p->buf[1] == 'r' &&
|
||||||
|
p->buf[2] == 'a' && p->buf[3] == 0xfd))
|
||||||
return AVPROBE_SCORE_MAX;
|
return AVPROBE_SCORE_MAX;
|
||||||
else
|
else
|
||||||
return 0;
|
return 0;
|
||||||
|
Reference in New Issue
Block a user