You've already forked FFmpeg
mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-08-04 22:03:09 +02:00
avformat/lrcdec: support arbitrary precision timestamp
Apparently files with milliseconds exist in the wild. And since it cost nothing to support arbitrary number of digits, extend format to support that. Depending on number of digits, the time base of fractional part is changing. Most LRCs use 2 digits and centiseconds base, but subs with 3 digits and miliseconds exist too. Set internal time base to AV_TIME_BASE, which in parcitice allows to hold microseconds with 6 digits. Totally artificial, but who knows maybe someone wants that. Fixes: #11677 Signed-off-by: Kacper Michajłow <kasper93@gmail.com>
This commit is contained in:
@ -78,7 +78,9 @@ static int64_t count_ts(const char *p)
|
|||||||
static int64_t read_ts(const char *p, int64_t *start)
|
static int64_t read_ts(const char *p, int64_t *start)
|
||||||
{
|
{
|
||||||
int64_t offset = 0;
|
int64_t offset = 0;
|
||||||
uint64_t mm, ss, cs;
|
uint64_t mm;
|
||||||
|
double ss;
|
||||||
|
char prefix[3];
|
||||||
|
|
||||||
while(p[offset] == ' ' || p[offset] == '\t') {
|
while(p[offset] == ' ' || p[offset] == '\t') {
|
||||||
offset++;
|
offset++;
|
||||||
@ -86,14 +88,14 @@ static int64_t read_ts(const char *p, int64_t *start)
|
|||||||
if(p[offset] != '[') {
|
if(p[offset] != '[') {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if(sscanf(p, "[-%"SCNu64":%"SCNu64".%"SCNu64"]", &mm, &ss, &cs) == 3) {
|
int ret = sscanf(p, "%2[[-]%"SCNu64":%lf]", prefix, &mm, &ss);
|
||||||
/* Just in case negative pts, players may drop it but we won't. */
|
if (ret != 3 || prefix[0] != '[') {
|
||||||
*start = -(int64_t) (mm*60000 + ss*1000 + cs*10);
|
|
||||||
} else if(sscanf(p, "[%"SCNu64":%"SCNu64".%"SCNu64"]", &mm, &ss, &cs) == 3) {
|
|
||||||
*start = mm*60000 + ss*1000 + cs*10;
|
|
||||||
} else {
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
*start = (mm * 60 + ss) * AV_TIME_BASE;
|
||||||
|
if (prefix[1] == '-') {
|
||||||
|
*start = - *start;
|
||||||
|
}
|
||||||
do {
|
do {
|
||||||
offset++;
|
offset++;
|
||||||
} while(p[offset] && p[offset-1] != ']');
|
} while(p[offset] && p[offset-1] != ']');
|
||||||
@ -164,7 +166,7 @@ static int lrc_read_header(AVFormatContext *s)
|
|||||||
if(!st) {
|
if(!st) {
|
||||||
return AVERROR(ENOMEM);
|
return AVERROR(ENOMEM);
|
||||||
}
|
}
|
||||||
avpriv_set_pts_info(st, 64, 1, 1000);
|
avpriv_set_pts_info(st, 64, 1, AV_TIME_BASE);
|
||||||
lrc->ts_offset = 0;
|
lrc->ts_offset = 0;
|
||||||
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
||||||
st->codecpar->codec_id = AV_CODEC_ID_TEXT;
|
st->codecpar->codec_id = AV_CODEC_ID_TEXT;
|
||||||
|
Reference in New Issue
Block a user