avformat/cdxl: rework probe and fix sample rate and frame rate

This commit is contained in:
Paul B Mahol 2021-02-03 23:06:51 +01:00
parent 1873d128f9
commit a8b3a51790
7 changed files with 53 additions and 57 deletions

View File

@ -30,10 +30,9 @@
typedef struct CDXLDemuxContext {
AVClass *class;
int sample_rate;
char *framerate;
AVRational fps;
int read_chunk;
int frate;
int srate;
uint8_t header[CDXL_HEADER_SIZE];
int video_stream_index;
int audio_stream_index;
@ -43,42 +42,55 @@ typedef struct CDXLDemuxContext {
static int cdxl_read_probe(const AVProbeData *p)
{
int score = AVPROBE_SCORE_EXTENSION + 10;
const uint8_t *buf = p->buf;
if (p->buf_size < CDXL_HEADER_SIZE)
return 0;
/* check type */
if (p->buf[0] > 1)
if (buf[0] > 1)
return 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;
/* check palette size */
if (p->buf[0] == 1 && AV_RB16(&p->buf[20]) > 512)
if (!AV_RN16(&buf[20]))
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;
/* 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;
/* 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;
/* 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;
/* previous chunk size */
if (AV_RN32(&p->buf[6]))
if (AV_RN32(&buf[6]))
score /= 2;
/* current frame number, usually starts from 1 */
if (AV_RB16(&p->buf[12]) != 1)
if (AV_RB32(&buf[10]) != 1)
score /= 2;
return score;
@ -87,13 +99,6 @@ static int cdxl_read_probe(const AVProbeData *p)
static int cdxl_read_header(AVFormatContext *s)
{
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->video_stream_index = -1;
@ -134,6 +139,12 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
height = AV_RB16(&cdxl->header[16]);
palette_size = AV_RB16(&cdxl->header[20]);
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 ||
FFALIGN(width, 16) * (uint64_t)height * cdxl->header[19] > INT_MAX)
return AVERROR_INVALIDDATA;
@ -165,10 +176,10 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
st->codecpar->channels = 1;
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;
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);
@ -193,17 +204,17 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
if (audio_size + video_size && cdxl->filesize > 0) {
frames = cdxl->filesize / (audio_size + video_size);
if (cdxl->framerate)
if (cdxl->frate)
st->duration = frames;
else
st->duration = frames * (int64_t)audio_size;
}
st->start_time = 0;
cdxl->video_stream_index = st->index;
if (cdxl->framerate)
avpriv_set_pts_info(st, 64, cdxl->fps.den, cdxl->fps.num);
if (cdxl->frate)
avpriv_set_pts_info(st, 64, 1, cdxl->frate);
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)
@ -217,7 +228,7 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
pkt->stream_index = cdxl->video_stream_index;
pkt->flags |= AV_PKT_FLAG_KEY;
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;
}
@ -226,20 +237,6 @@ static int cdxl_read_packet(AVFormatContext *s, AVPacket *pkt)
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 = {
.name = "cdxl",
.long_name = NULL_IF_CONFIG_SMALL("Commodore CDXL video"),
@ -249,5 +246,4 @@ AVInputFormat ff_cdxl_demuxer = {
.read_packet = cdxl_read_packet,
.extensions = "cdxl,xl",
.flags = AVFMT_GENERIC_INDEX,
.priv_class = &cdxl_demuxer_class,
};

View File

@ -1,4 +1,4 @@
#tb 0: 1/50
#tb 0: 1/25
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 162x130

View File

@ -1,4 +1,4 @@
#tb 0: 1/11025
#tb 0: 1/25
#media_type 0: video
#codec_id 0: cdxl
#dimensions 0: 176x128
@ -9,22 +9,22 @@
#sample_rate 1: 11025
#channel_layout 1: 4
#channel_layout_name 1: mono
0, 0, 0, 1884, 22688, 0xc954a244
0, 0, 0, 1, 22688, 0xc954a244
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
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
0, 5652, 5652, 1884, 22688, 0xf00aa306
0, 9, 9, 1, 17896, 0x1a696b6e
1, 5652, 5652, 1884, 1884, 0xc974878e
0, 7536, 7536, 1884, 22688, 0x48aca307
1, 7536, 7536, 1884, 1884, 0xecb5c4c8
0, 9420, 9420, 1884, 22688, 0xa13fa308
1, 9420, 9420, 1884, 1884, 0x87adce5f
0, 11304, 11304, 1884, 22688, 0xf9d2a309
1, 11304, 11304, 1884, 1884, 0x3cf097e4
0, 13188, 13188, 1884, 22688, 0x5274a30a
1, 13188, 13188, 1884, 1884, 0xcc218105
0, 15072, 15072, 1884, 22688, 0xab07a30b
1, 15072, 15072, 1884, 1884, 0xf685762f
0, 16956, 16956, 1884, 17896, 0x1a696b6e

View File

@ -1,4 +1,4 @@
#tb 0: 52/525
#tb 0: 1/25
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 160x120

View File

@ -1,4 +1,4 @@
#tb 0: 12/281
#tb 0: 1/25
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 176x128

View File

@ -1,4 +1,4 @@
#tb 0: 1/50
#tb 0: 1/25
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 176x128

View File

@ -1,4 +1,4 @@
#tb 0: 368/11025
#tb 0: 1/25
#media_type 0: video
#codec_id 0: rawvideo
#dimensions 0: 128x80