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

pull/371/head
Paul B Mahol 4 years ago
parent 1873d128f9
commit a8b3a51790
  1. 78
      libavformat/cdxl.c
  2. 2
      tests/ref/fate/cdxl-bitline-ham6
  3. 22
      tests/ref/fate/cdxl-demux
  4. 2
      tests/ref/fate/cdxl-ham6
  5. 2
      tests/ref/fate/cdxl-ham8
  6. 2
      tests/ref/fate/cdxl-pal8
  7. 2
      tests/ref/fate/cdxl-pal8-small

@ -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,
};

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

@ -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

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

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

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

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

Loading…
Cancel
Save