|
|
@ -28,14 +28,19 @@ |
|
|
|
|
|
|
|
|
|
|
|
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l') |
|
|
|
#define SCHl_TAG MKTAG('S', 'C', 'H', 'l') |
|
|
|
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) |
|
|
|
#define PT00_TAG MKTAG('P', 'T', 0x0, 0x0) |
|
|
|
|
|
|
|
#define GSTR_TAG MKTAG('G', 'S', 'T', 'R') |
|
|
|
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l') |
|
|
|
#define SCDl_TAG MKTAG('S', 'C', 'D', 'l') |
|
|
|
#define SCEl_TAG MKTAG('S', 'C', 'E', 'l') |
|
|
|
#define SCEl_TAG MKTAG('S', 'C', 'E', 'l') |
|
|
|
|
|
|
|
#define MVhd_TAG MKTAG('M', 'V', 'h', 'd') |
|
|
|
|
|
|
|
#define MV0K_TAG MKTAG('M', 'V', '0', 'K') |
|
|
|
|
|
|
|
#define MV0F_TAG MKTAG('M', 'V', '0', 'F') |
|
|
|
|
|
|
|
|
|
|
|
#define EA_SAMPLE_RATE 22050 |
|
|
|
#define EA_SAMPLE_RATE 22050 |
|
|
|
#define EA_BITS_PER_SAMPLE 16 |
|
|
|
#define EA_BITS_PER_SAMPLE 16 |
|
|
|
#define EA_PREAMBLE_SIZE 8 |
|
|
|
#define EA_PREAMBLE_SIZE 8 |
|
|
|
|
|
|
|
|
|
|
|
typedef struct EaDemuxContext { |
|
|
|
typedef struct EaDemuxContext { |
|
|
|
|
|
|
|
AVRational time_base; |
|
|
|
int video_stream_index; |
|
|
|
int video_stream_index; |
|
|
|
|
|
|
|
|
|
|
|
int audio_stream_index; |
|
|
|
int audio_stream_index; |
|
|
@ -71,14 +76,28 @@ static uint32_t read_arbitary(ByteIOContext *pb) { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
static int process_ea_header(AVFormatContext *s) { |
|
|
|
static int process_ea_header(AVFormatContext *s) { |
|
|
|
int inHeader = 1; |
|
|
|
int inHeader = 1; |
|
|
|
uint32_t blockid, size; |
|
|
|
uint32_t blockid, size = 0; |
|
|
|
|
|
|
|
int num, den; |
|
|
|
EaDemuxContext *ea = s->priv_data; |
|
|
|
EaDemuxContext *ea = s->priv_data; |
|
|
|
ByteIOContext *pb = &s->pb; |
|
|
|
ByteIOContext *pb = &s->pb; |
|
|
|
|
|
|
|
|
|
|
|
if (get_le32(pb) != SCHl_TAG) |
|
|
|
blockid = get_le32(pb); |
|
|
|
|
|
|
|
if (blockid == MVhd_TAG) { |
|
|
|
|
|
|
|
size = get_le32(pb); |
|
|
|
|
|
|
|
url_fskip(pb, 16); |
|
|
|
|
|
|
|
den = get_le32(pb); |
|
|
|
|
|
|
|
num = get_le32(pb); |
|
|
|
|
|
|
|
ea->time_base = (AVRational) {num, den}; |
|
|
|
|
|
|
|
url_fskip(pb, size-32); |
|
|
|
|
|
|
|
blockid = get_le32(pb); |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
if (blockid != SCHl_TAG) |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
size = get_le32(pb); |
|
|
|
size += get_le32(pb); |
|
|
|
if (get_le32(pb) != PT00_TAG) { |
|
|
|
blockid = get_le32(pb); |
|
|
|
|
|
|
|
if (blockid == GSTR_TAG) { |
|
|
|
|
|
|
|
url_fskip(pb, 4); |
|
|
|
|
|
|
|
} else if (blockid != PT00_TAG) { |
|
|
|
av_log (s, AV_LOG_ERROR, "PT header missing\n"); |
|
|
|
av_log (s, AV_LOG_ERROR, "PT header missing\n"); |
|
|
|
return 0; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
@ -114,6 +133,10 @@ static int process_ea_header(AVFormatContext *s) { |
|
|
|
av_log (s, AV_LOG_INFO, "exited audio subheader\n"); |
|
|
|
av_log (s, AV_LOG_INFO, "exited audio subheader\n"); |
|
|
|
inSubheader = 0; |
|
|
|
inSubheader = 0; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
case 0xFF: |
|
|
|
|
|
|
|
inSubheader = 0; |
|
|
|
|
|
|
|
inHeader = 0; |
|
|
|
|
|
|
|
break; |
|
|
|
default: |
|
|
|
default: |
|
|
|
av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); |
|
|
|
av_log (s, AV_LOG_INFO, "element 0x%02x set to 0x%08x\n", subbyte, read_arbitary(pb)); |
|
|
|
break; |
|
|
|
break; |
|
|
@ -130,11 +153,6 @@ static int process_ea_header(AVFormatContext *s) { |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
if ((ea->num_channels != 2) || (ea->compression_type != 7)) { |
|
|
|
|
|
|
|
av_log (s, AV_LOG_ERROR, "unsupported stream type\n"); |
|
|
|
|
|
|
|
return 0; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* skip to the start of the data */ |
|
|
|
/* skip to the start of the data */ |
|
|
|
url_fseek(pb, size, SEEK_SET); |
|
|
|
url_fseek(pb, size, SEEK_SET); |
|
|
|
|
|
|
|
|
|
|
@ -144,10 +162,13 @@ static int process_ea_header(AVFormatContext *s) { |
|
|
|
|
|
|
|
|
|
|
|
static int ea_probe(AVProbeData *p) |
|
|
|
static int ea_probe(AVProbeData *p) |
|
|
|
{ |
|
|
|
{ |
|
|
|
if (AV_RL32(&p->buf[0]) != SCHl_TAG) |
|
|
|
uint32_t tag; |
|
|
|
return 0; |
|
|
|
|
|
|
|
|
|
|
|
tag = AV_RL32(&p->buf[0]); |
|
|
|
|
|
|
|
if (tag == SCHl_TAG || tag == MVhd_TAG) |
|
|
|
|
|
|
|
return AVPROBE_SCORE_MAX; |
|
|
|
|
|
|
|
|
|
|
|
return AVPROBE_SCORE_MAX; |
|
|
|
return 0; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
static int ea_read_header(AVFormatContext *s, |
|
|
|
static int ea_read_header(AVFormatContext *s, |
|
|
@ -159,17 +180,17 @@ static int ea_read_header(AVFormatContext *s, |
|
|
|
if (!process_ea_header(s)) |
|
|
|
if (!process_ea_header(s)) |
|
|
|
return AVERROR(EIO); |
|
|
|
return AVERROR(EIO); |
|
|
|
|
|
|
|
|
|
|
|
#if 0 |
|
|
|
if (ea->time_base.num && ea->time_base.den) { |
|
|
|
/* initialize the video decoder stream */ |
|
|
|
/* initialize the video decoder stream */ |
|
|
|
st = av_new_stream(s, 0); |
|
|
|
st = av_new_stream(s, 0); |
|
|
|
if (!st) |
|
|
|
if (!st) |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
return AVERROR(ENOMEM); |
|
|
|
av_set_pts_info(st, 33, 1, 90000); |
|
|
|
|
|
|
|
ea->video_stream_index = st->index; |
|
|
|
ea->video_stream_index = st->index; |
|
|
|
st->codec->codec_type = CODEC_TYPE_VIDEO; |
|
|
|
st->codec->codec_type = CODEC_TYPE_VIDEO; |
|
|
|
st->codec->codec_id = CODEC_ID_EA_MJPEG; |
|
|
|
st->codec->codec_id = CODEC_ID_VP6; |
|
|
|
st->codec->codec_tag = 0; /* no fourcc */ |
|
|
|
st->codec->codec_tag = 0; /* no fourcc */ |
|
|
|
#endif |
|
|
|
st->codec->time_base = ea->time_base; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* initialize the audio decoder stream */ |
|
|
|
/* initialize the audio decoder stream */ |
|
|
|
st = av_new_stream(s, 0); |
|
|
|
st = av_new_stream(s, 0); |
|
|
@ -201,6 +222,7 @@ static int ea_read_packet(AVFormatContext *s, |
|
|
|
int packet_read = 0; |
|
|
|
int packet_read = 0; |
|
|
|
unsigned char preamble[EA_PREAMBLE_SIZE]; |
|
|
|
unsigned char preamble[EA_PREAMBLE_SIZE]; |
|
|
|
unsigned int chunk_type, chunk_size; |
|
|
|
unsigned int chunk_type, chunk_size; |
|
|
|
|
|
|
|
int key = 0; |
|
|
|
|
|
|
|
|
|
|
|
while (!packet_read) { |
|
|
|
while (!packet_read) { |
|
|
|
|
|
|
|
|
|
|
@ -236,6 +258,19 @@ static int ea_read_packet(AVFormatContext *s, |
|
|
|
packet_read = 1; |
|
|
|
packet_read = 1; |
|
|
|
break; |
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
case MV0K_TAG: |
|
|
|
|
|
|
|
key = PKT_FLAG_KEY; |
|
|
|
|
|
|
|
case MV0F_TAG: |
|
|
|
|
|
|
|
ret = av_get_packet(pb, pkt, chunk_size); |
|
|
|
|
|
|
|
if (ret != chunk_size) |
|
|
|
|
|
|
|
ret = AVERROR_IO; |
|
|
|
|
|
|
|
else { |
|
|
|
|
|
|
|
pkt->stream_index = ea->video_stream_index; |
|
|
|
|
|
|
|
pkt->flags |= key; |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
packet_read = 1; |
|
|
|
|
|
|
|
break; |
|
|
|
|
|
|
|
|
|
|
|
default: |
|
|
|
default: |
|
|
|
url_fseek(pb, chunk_size, SEEK_CUR); |
|
|
|
url_fseek(pb, chunk_size, SEEK_CUR); |
|
|
|
break; |
|
|
|
break; |
|
|
|