Y4M loader: fix support for unexpected framerates

Add support for F1:1 images, and in general with any framerate ratio.

Also added "F60:1" mode support.

Tested:

Added a test frame with a 1:1 framerate. This is produced by ffmpeg when
converting from another image format.
```
$ ffmpeg -i in.265 out.y4m
$ head -1 out.y4m
YUV4MPEG2 W490 H490 F1:1 Ip A0:0 C420jpeg XYSCSS=420JPEG XCOLORRANGE=FULL
```

Before
```
$ imlib2_view -v ./test/images/icon-64.framerate_1_1.y4m
Show  0: './test/images/icon-64.framerate_1_1.y4m'
*** Error -2:'Imlib2: No loader for file format' loading image: './test/images/icon-64.framerate_1_1.y4m'
```

After:
```
$ IMLIB2_DEBUG=31:0 IMLIB2_LOADER_PATH=./src/modules/loaders/.libs/ LD_LIBRARY_PATH=./src/lib/.libs:${LD_LIBRARY_PATH} ./src/bin/imlib2_view -v ./test/images/icon-64.framerate_1_1.y4m
Show  0: './test/images/icon-64.framerate_1_1.y4m'
IMG : __imlib_FindCachedImage: './test/images/icon-64.framerate_1_1.y4m' frame 1
IMG :  got none
LOAD: __imlib_FindBestLoader: file='./test/images/icon-64.framerate_1_1.y4m' fmt='(null)'
FILE: __imlib_FileExtension: './test/images/icon-64.framerate_1_1.y4m'
FILE: __imlib_FileIsFile: './src/modules/loaders/.libs//y4m.so'
FILE: __imlib_FileStat: './src/modules/loaders/.libs//y4m.so'
LOAD: __imlib_ProduceLoader: ./src/modules/loaders/.libs//y4m.so
LOAD: __imlib_LookupKnownLoader: 'y4m' -> 'y4m': 0x524d50
LOAD: __imlib_FindBestLoader: fmt='y4m': ./src/modules/loaders/.libs//y4m.so
IMG : __imlib_LoadImageWrapper: fmt='y4m' file='./test/images/icon-64.framerate_1_1.y4m'(./test/images/icon-64.framerate_1_1.y4m) frame=1, imm=1
IMG : __imlib_LoadImageWrapper: y4m : ./test/images/icon-64.framerate_1_1.y4m: Elapsed time: 18.099 ms
IMG : __imlib_AddImageToCache: 0x5139e0: './test/images/icon-64.framerate_1_1.y4m' frame 1
```
This commit is contained in:
Chema Gonzalez 2023-12-27 14:15:44 -08:00
parent 3106fbd0d2
commit a780b47892
2 changed files with 22 additions and 2 deletions

View File

@ -36,11 +36,14 @@ enum Y4mParseStatus {
// values are (roughly) equal to the delay in microseconds
#define Y4M_PARSE_FPS_INVALID 0
#define Y4M_PARSE_FPS_OTHER -1
#define Y4M_PARSE_FPS_23_976 41708
#define Y4M_PARSE_FPS_24 41667
#define Y4M_PARSE_FPS_25 40000
#define Y4M_PARSE_FPS_29_97 33367
#define Y4M_PARSE_FPS_30 33333
#define Y4M_PARSE_FPS_60 16667
#define Y4M_PARSE_FPS_1 1000000
typedef struct {
ptrdiff_t w, h;
@ -155,8 +158,22 @@ y4m__parse_params(Y4mParse * res, const uint8_t ** start, const uint8_t * end)
res->fps = Y4M_PARSE_FPS_29_97;
else if (y4m__match("24000:1001", 10, &p, end))
res->fps = Y4M_PARSE_FPS_23_976;
else
return Y4M_PARSE_CORRUPTED;
else if (y4m__match("60:1", 4, &p, end))
res->fps = Y4M_PARSE_FPS_60;
else {
int rate_num;
int rate_den;
int nlen;
if (sscanf((char *)p, "%i:%i%n", &rate_num, &rate_den, &nlen) < 2) {
return Y4M_PARSE_CORRUPTED;
}
p += nlen;
if (rate_num == rate_den) {
res->fps = Y4M_PARSE_FPS_1;
} else {
res->fps = Y4M_PARSE_FPS_OTHER;
}
}
break;
case 'I':
if (y4m__match("p", 1, &p, end))

File diff suppressed because one or more lines are too long