avformat/cdxl: rework probe and fix sample rate and frame rate
This commit is contained in:
parent
1873d128f9
commit
a8b3a51790
@ -30,10 +30,9 @@
|
|||||||
|
|
||||||
typedef struct CDXLDemuxContext {
|
typedef struct CDXLDemuxContext {
|
||||||
AVClass *class;
|
AVClass *class;
|
||||||
int sample_rate;
|
|
||||||
char *framerate;
|
|
||||||
AVRational fps;
|
|
||||||
int read_chunk;
|
int read_chunk;
|
||||||
|
int frate;
|
||||||
|
int srate;
|
||||||
uint8_t header[CDXL_HEADER_SIZE];
|
uint8_t header[CDXL_HEADER_SIZE];
|
||||||
int video_stream_index;
|
int video_stream_index;
|
||||||
int audio_stream_index;
|
int audio_stream_index;
|
||||||
@ -43,42 +42,55 @@ typedef struct CDXLDemuxContext {
|
|||||||
static int cdxl_read_probe(const AVProbeData *p)
|
static int cdxl_read_probe(const AVProbeData *p)
|
||||||
{
|
{
|
||||||
int score = AVPROBE_SCORE_EXTENSION + 10;
|
int score = AVPROBE_SCORE_EXTENSION + 10;
|
||||||
|
const uint8_t *buf = p->buf;
|
||||||
|
|
||||||
if (p->buf_size < CDXL_HEADER_SIZE)
|
if (p->buf_size < CDXL_HEADER_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check type */
|
/* check type */
|
||||||
if (p->buf[0] > 1)
|
if (buf[0] > 1)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* reserved bytes should always be set to 0 */
|
/* reserved bytes should always be set to 0 */
|
||||||
if (p->buf[0] == 1 && (AV_RN64(&p->buf[24]) || AV_RN16(&p->buf[10])))
|
if (AV_RL24(&buf[29]))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check palette size */
|
/* check palette size */
|
||||||
if (p->buf[0] == 1 && AV_RB16(&p->buf[20]) > 512)
|
if (!AV_RN16(&buf[20]))
|
||||||
return 0;
|
return 0;
|
||||||
if (p->buf[0] == 0 && AV_RB16(&p->buf[20]) > 768)
|
if (buf[0] == 1 && AV_RB16(&buf[20]) > 512)
|
||||||
|
return 0;
|
||||||
|
if (buf[0] == 0 && AV_RB16(&buf[20]) > 768)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (!AV_RN16(&buf[22]) && AV_RN16(&buf[24]))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (buf[0] == 0 && (!buf[26] || !AV_RB16(&buf[24])))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check number of planes */
|
/* check number of planes */
|
||||||
if (p->buf[18] || !p->buf[19])
|
if (buf[19] != 6 && buf[19] != 8 && buf[19] != 24)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (buf[18])
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* check widh and height */
|
/* check widh and height */
|
||||||
if (!AV_RN16(&p->buf[14]) || !AV_RN16(&p->buf[16]))
|
if (AV_RB16(&buf[14]) > 640 || AV_RB16(&buf[16]) > 480 ||
|
||||||
|
AV_RB16(&buf[14]) == 0 || AV_RB16(&buf[16]) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* chunk size */
|
/* chunk size */
|
||||||
if (AV_RB32(&p->buf[2]) < AV_RB16(&p->buf[22]) + AV_RB16(&p->buf[20]) + CDXL_HEADER_SIZE)
|
if (AV_RB32(&buf[2]) <= AV_RB16(&buf[20]) + AV_RB16(&buf[22]) * (1 + !!(buf[1] & 0x10)) + CDXL_HEADER_SIZE)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/* previous chunk size */
|
/* previous chunk size */
|
||||||
if (AV_RN32(&p->buf[6]))
|
if (AV_RN32(&buf[6]))
|
||||||
score /= 2;
|
score /= 2;
|
||||||
|
|
||||||
/* current frame number, usually starts from 1 */
|
/* current frame number, usually starts from 1 */
|
||||||
if (AV_RB16(&p->buf[12]) != 1)
|
if (AV_RB32(&buf[10]) != 1)
|
||||||
score /= 2;
|
score /= 2;
|
||||||
|
|
||||||
return score;
|
return score;
|
||||||
@ -87,13 +99,6 @@ static int cdxl_read_probe(const AVProbeData *p)
|
|||||||
static int cdxl_read_header(AVFormatContext *s)
|
static int cdxl_read_header(AVFormatContext *s)
|
||||||
{
|
{
|
||||||
CDXLDemuxContext *cdxl = s->priv_data;
|
CDXLDemuxContext *cdxl = s->priv_data;
|
||||||
int ret;
|
|
||||||
|
|
||||||
if (cdxl->framerate && (ret = av_parse_video_rate(&cdxl->fps, cdxl->framerate)) < 0) {
|
|
||||||
av_log(s, AV_LOG_ERROR,
|
|
||||||
"Could not parse framerate: %s.\n", cdxl->framerate);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
cdxl->read_chunk = 0;
|
cdxl->read_chunk = 0;
|
||||||
cdxl->video_stream_index = -1;
|
cdxl->video_stream_index = -1;
|
||||||
@ -134,6 +139,12 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
height = AV_RB16(&cdxl->header[16]);
|
height = AV_RB16(&cdxl->header[16]);
|
||||||
palette_size = AV_RB16(&cdxl->header[20]);
|
palette_size = AV_RB16(&cdxl->header[20]);
|
||||||
audio_size = AV_RB16(&cdxl->header[22]) * (1 + !!(cdxl->header[1] & 0x10));
|
audio_size = AV_RB16(&cdxl->header[22]) * (1 + !!(cdxl->header[1] & 0x10));
|
||||||
|
cdxl->srate = AV_RB16(&cdxl->header[24]);
|
||||||
|
if (!cdxl->srate)
|
||||||
|
cdxl->srate = 11025;
|
||||||
|
cdxl->frate = cdxl->header[26];
|
||||||
|
if (!cdxl->frate)
|
||||||
|
cdxl->frate = 25;
|
||||||
if (cdxl->header[19] == 0 ||
|
if (cdxl->header[19] == 0 ||
|
||||||
FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX)
|
FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX)
|
||||||
return AVERROR_INVALIDDATA;
|
return AVERROR_INVALIDDATA;
|
||||||
@ -165,10 +176,10 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
st->codecpar->channels = 1;
|
st->codecpar->channels = 1;
|
||||||
st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
|
st->codecpar->channel_layout = AV_CH_LAYOUT_MONO;
|
||||||
}
|
}
|
||||||
st->codecpar->sample_rate = cdxl->sample_rate;
|
st->codecpar->sample_rate= cdxl->srate;
|
||||||
st->start_time = 0;
|
st->start_time = 0;
|
||||||
cdxl->audio_stream_index = st->index;
|
cdxl->audio_stream_index = st->index;
|
||||||
avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate);
|
avpriv_set_pts_info(st, 64, 1, cdxl->srate);
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = av_get_packet(pb, pkt, audio_size);
|
ret = av_get_packet(pb, pkt, audio_size);
|
||||||
@ -193,17 +204,17 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
if (audio_size + video_size && cdxl->filesize > 0) {
|
if (audio_size + video_size && cdxl->filesize > 0) {
|
||||||
frames = cdxl->filesize / (audio_size + video_size);
|
frames = cdxl->filesize / (audio_size + video_size);
|
||||||
|
|
||||||
if (cdxl->framerate)
|
if (cdxl->frate)
|
||||||
st->duration = frames;
|
st->duration = frames;
|
||||||
else
|
else
|
||||||
st->duration = frames * (int64_t)audio_size;
|
st->duration = frames * (int64_t)audio_size;
|
||||||
}
|
}
|
||||||
st->start_time = 0;
|
st->start_time = 0;
|
||||||
cdxl->video_stream_index = st->index;
|
cdxl->video_stream_index = st->index;
|
||||||
if (cdxl->framerate)
|
if (cdxl->frate)
|
||||||
avpriv_set_pts_info(st, 64, cdxl->fps.den, cdxl->fps.num);
|
avpriv_set_pts_info(st, 64, 1, cdxl->frate);
|
||||||
else
|
else
|
||||||
avpriv_set_pts_info(st, 64, 1, cdxl->sample_rate);
|
avpriv_set_pts_info(st, 64, 1, cdxl->srate);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = av_new_packet(pkt, video_size + CDXL_HEADER_SIZE)) < 0)
|
if ((ret = av_new_packet(pkt, video_size + CDXL_HEADER_SIZE)) < 0)
|
||||||
@ -217,7 +228,7 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
pkt->stream_index = cdxl->video_stream_index;
|
pkt->stream_index = cdxl->video_stream_index;
|
||||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||||
pkt->pos = pos;
|
pkt->pos = pos;
|
||||||
pkt->duration = cdxl->framerate ? 1 : audio_size ? audio_size : 220;
|
pkt->duration = cdxl->frate ? 1 : audio_size ? audio_size : 220;
|
||||||
cdxl->read_chunk = audio_size;
|
cdxl->read_chunk = audio_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -226,20 +237,6 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define OFFSET(x) offsetof(CDXLDemuxContext, x)
|
|
||||||
static const AVOption cdxl_options[] = {
|
|
||||||
{ "sample_rate", "", OFFSET(sample_rate), AV_OPT_TYPE_INT, { .i64 = 11025 }, 1, INT_MAX, AV_OPT_FLAG_DECODING_PARAM },
|
|
||||||
{ "framerate", "", OFFSET(framerate), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, AV_OPT_FLAG_DECODING_PARAM },
|
|
||||||
{ NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
static const AVClass cdxl_demuxer_class = {
|
|
||||||
.class_name = "CDXL demuxer",
|
|
||||||
.item_name = av_default_item_name,
|
|
||||||
.option = cdxl_options,
|
|
||||||
.version = LIBAVUTIL_VERSION_INT,
|
|
||||||
};
|
|
||||||
|
|
||||||
AVInputFormat ff_cdxl_demuxer = {
|
AVInputFormat ff_cdxl_demuxer = {
|
||||||
.name = "cdxl",
|
.name = "cdxl",
|
||||||
.long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
|
.long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
|
||||||
@ -249,5 +246,4 @@ AVInputFormat ff_cdxl_demuxer = {
|
|||||||
.read_packet = cdxl_read_packet,
|
.read_packet = cdxl_read_packet,
|
||||||
.extensions = "cdxl,xl",
|
.extensions = "cdxl,xl",
|
||||||
.flags = AVFMT_GENERIC_INDEX,
|
.flags = AVFMT_GENERIC_INDEX,
|
||||||
.priv_class = &cdxl_demuxer_class,
|
|
||||||
};
|
};
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 1/50
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: rawvideo
|
#codec_id 0: rawvideo
|
||||||
#dimensions 0: 162x130
|
#dimensions 0: 162x130
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 1/11025
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: cdxl
|
#codec_id 0: cdxl
|
||||||
#dimensions 0: 176x128
|
#dimensions 0: 176x128
|
||||||
@ -9,22 +9,22 @@
|
|||||||
#sample_rate 1: 11025
|
#sample_rate 1: 11025
|
||||||
#channel_layout 1: 4
|
#channel_layout 1: 4
|
||||||
#channel_layout_name 1: mono
|
#channel_layout_name 1: mono
|
||||||
0, 0, 0, 1884, 22688, 0xc954a244
|
0, 0, 0, 1, 22688, 0xc954a244
|
||||||
1, 0, 0, 1884, 1884, 0x06925e3e
|
1, 0, 0, 1884, 1884, 0x06925e3e
|
||||||
0, 1884, 1884, 1884, 22688, 0x3ee4a304
|
0, 1, 1, 1, 22688, 0x3ee4a304
|
||||||
|
0, 2, 2, 1, 22688, 0x9777a305
|
||||||
|
0, 3, 3, 1, 22688, 0xf00aa306
|
||||||
|
0, 4, 4, 1, 22688, 0x48aca307
|
||||||
1, 1884, 1884, 1884, 1884, 0x1957ab65
|
1, 1884, 1884, 1884, 1884, 0x1957ab65
|
||||||
0, 3768, 3768, 1884, 22688, 0x9777a305
|
0, 5, 5, 1, 22688, 0xa13fa308
|
||||||
|
0, 6, 6, 1, 22688, 0xf9d2a309
|
||||||
|
0, 7, 7, 1, 22688, 0x5274a30a
|
||||||
|
0, 8, 8, 1, 22688, 0xab07a30b
|
||||||
1, 3768, 3768, 1884, 1884, 0x7fcd6e47
|
1, 3768, 3768, 1884, 1884, 0x7fcd6e47
|
||||||
0, 5652, 5652, 1884, 22688, 0xf00aa306
|
0, 9, 9, 1, 17896, 0x1a696b6e
|
||||||
1, 5652, 5652, 1884, 1884, 0xc974878e
|
1, 5652, 5652, 1884, 1884, 0xc974878e
|
||||||
0, 7536, 7536, 1884, 22688, 0x48aca307
|
|
||||||
1, 7536, 7536, 1884, 1884, 0xecb5c4c8
|
1, 7536, 7536, 1884, 1884, 0xecb5c4c8
|
||||||
0, 9420, 9420, 1884, 22688, 0xa13fa308
|
|
||||||
1, 9420, 9420, 1884, 1884, 0x87adce5f
|
1, 9420, 9420, 1884, 1884, 0x87adce5f
|
||||||
0, 11304, 11304, 1884, 22688, 0xf9d2a309
|
|
||||||
1, 11304, 11304, 1884, 1884, 0x3cf097e4
|
1, 11304, 11304, 1884, 1884, 0x3cf097e4
|
||||||
0, 13188, 13188, 1884, 22688, 0x5274a30a
|
|
||||||
1, 13188, 13188, 1884, 1884, 0xcc218105
|
1, 13188, 13188, 1884, 1884, 0xcc218105
|
||||||
0, 15072, 15072, 1884, 22688, 0xab07a30b
|
|
||||||
1, 15072, 15072, 1884, 1884, 0xf685762f
|
1, 15072, 15072, 1884, 1884, 0xf685762f
|
||||||
0, 16956, 16956, 1884, 17896, 0x1a696b6e
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 52/525
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: rawvideo
|
#codec_id 0: rawvideo
|
||||||
#dimensions 0: 160x120
|
#dimensions 0: 160x120
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 12/281
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: rawvideo
|
#codec_id 0: rawvideo
|
||||||
#dimensions 0: 176x128
|
#dimensions 0: 176x128
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 1/50
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: rawvideo
|
#codec_id 0: rawvideo
|
||||||
#dimensions 0: 176x128
|
#dimensions 0: 176x128
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#tb 0: 368/11025
|
#tb 0: 1/25
|
||||||
#media_type 0: video
|
#media_type 0: video
|
||||||
#codec_id 0: rawvideo
|
#codec_id 0: rawvideo
|
||||||
#dimensions 0: 128x80
|
#dimensions 0: 128x80
|
||||||
|
Loading…
x
Reference in New Issue
Block a user