[FFmpeg-devel] [PATCH 4/4] avformat/psxstr: basic FPS detection instead of fixed value

Michael Niedermayer michael at niedermayer.cc
Wed Jan 10 04:56:39 EET 2024


On Tue, Jan 02, 2024 at 03:14:19AM +0000, aybe aybe wrote:
> This fourth and last patch is an attempt at removing the hard-coded value of 15 FPS.
> 
> In patch 1/4, although it would render video, the audio and video were not synchronized at all, now there are.
> 
> In this approach I kept it simple, grab min/max possible rates, pick min, clamp to 15/30 just in case.
> 
> It appears to work quite well, the right frame rate is picked up and both streams are in sync.
> 
> (tested against Wipeout introduction for both PAL and NTSC versions).
> 
> 
> Besides, there have been significant findings over the years regarding that format, specifically:
> https://problemkaputt.de/psxspx-macroblock-decoder-mdec.htm
> https://github.com/m35/jpsxdec/blob/readme/jpsxdec/PlayStation1_STR_format.txt
> 
> Maybe someone versed in this topic (I'm not) could further improve support of this format according these docs...
> 
> 
> 
> Signed-off-by: aybe <aybe at users.noreply.github.com>
> ---
>   libavformat/psxstr.c | 27 +++++++++++++++++++++++++--
>   1 file changed, 25 insertions(+), 2 deletions(-)
> 
> diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
> index 306a690f52..98897acde3 100644
> --- a/libavformat/psxstr.c
> +++ b/libavformat/psxstr.c
> @@ -52,6 +52,9 @@
> 
>   #define STR_MAGIC (0x80010160)
> 
> +#define MDEC_STR_FPS_MIN 15
> +#define MDEC_STR_FPS_MAX 30
> +
>   typedef struct StrChannel {
>       /* video parameters */
>       int video_stream_index;
> @@ -65,6 +68,10 @@ typedef struct StrDemuxContext {
> 
>       /* a STR file can contain up to 32 channels of data */
>       StrChannel channels[32];
> +    /* trivial FPS detection based on sectors per frame */
> +    int fps_min; /* slowest FPS found */
> +    int fps_max; /* fastest FPS found */
> +    int fps_val; /* nominal FPS value */
>   } StrDemuxContext;
> 
>   static const uint8_t sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
> @@ -150,6 +157,10 @@ static int str_read_header(AVFormatContext *s)
>           str->channels[i].audio_stream_index= -1;
>       }
> 
> +    str->fps_min = INT_MAX;
> +    str->fps_max = INT_MIN;
> +    str->fps_val = 0;
> +
>       s->ctx_flags |= AVFMTCTX_NOHEADER;
> 
>       return 0;
> @@ -161,7 +172,7 @@ static int str_read_packet(AVFormatContext *s,
>       AVIOContext *pb = s->pb;
>       StrDemuxContext *str = s->priv_data;
>       unsigned char sector[RAW_CD_SECTOR_SIZE];
> -    int channel, ret;
> +    int channel, ret, sub_mode, idx_sect, num_sect;
>       AVPacket *pkt;
>       AVStream *st;
> 
> @@ -178,6 +189,18 @@ static int str_read_packet(AVFormatContext *s,
>           if (channel >= 32)
>               return AVERROR_INVALIDDATA;
> 
> +        sub_mode = sector[0x12];
> +        idx_sect = AV_RL16(&sector[0x1C]);
> +        num_sect = AV_RL16(&sector[0x1E]);
> +
> +        /* compute FPS from sector count @ each new video frame */
> +        if (sub_mode & 0x02 && idx_sect == 0x00) {
> +            int fps = 150 / num_sect;
> +            str->fps_min = FFMIN(str->fps_min, fps);
> +            str->fps_max = FFMAX(str->fps_max, fps);
> +            str->fps_val = FFMIN(MDEC_STR_FPS_MAX, FFMAX(MDEC_STR_FPS_MIN, str->fps_min));
> +        }
> +
>           switch (sector[0x12] & CDXA_TYPE_MASK) {
> 
>           case CDXA_TYPE_DATA:
> @@ -200,7 +223,7 @@ static int str_read_packet(AVFormatContext *s,
>                       st = avformat_new_stream(s, NULL);
>                       if (!st)
>                           return AVERROR(ENOMEM);
> -                    avpriv_set_pts_info(st, 64, 1, 15);
> +                    avpriv_set_pts_info(st, 64, 1, str->fps_val);

This is not a FPS value,
avpriv_set_pts_info() sets the timebase in which timestamps are specified

I dont know psxstr but can you explain what information there is in it
about the video frames ?
is there some sort of information that indicates when a frame is to be
displayed ?
that is like a timestamp ?

thx

[...]
-- 
Michael     GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB

Elect your leaders based on what they did after the last election, not
based on what they say before an election.

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 195 bytes
Desc: not available
URL: <https://ffmpeg.org/pipermail/ffmpeg-devel/attachments/20240110/a10d0045/attachment.sig>


More information about the ffmpeg-devel mailing list