[FFmpeg-devel] [PATCH 1/2] avformat/psxstr: infer video FPS using sector LBA
aybe aybe
aybe.one at hotmail.com
Tue Jan 16 16:36:24 EET 2024
Signed-off-by: aybe <aybe at users.noreply.github.com>
---
libavformat/psxstr.c | 44 ++++++++++++++++++++++++++++++++++++++++++--
1 file changed, 42 insertions(+), 2 deletions(-)
diff --git a/libavformat/psxstr.c b/libavformat/psxstr.c
index 306a690f52..c718fb6daf 100644
--- a/libavformat/psxstr.c
+++ b/libavformat/psxstr.c
@@ -65,6 +65,9 @@ typedef struct StrDemuxContext {
/* a STR file can contain up to 32 channels of data */
StrChannel channels[32];
+
+ /* the index for the first frame (sector, LBA units)*/
+ int64_t first_frame_index;
} StrDemuxContext;
static const uint8_t sync_header[12] = {0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00};
@@ -150,18 +153,51 @@ static int str_read_header(AVFormatContext *s)
str->channels[i].audio_stream_index= -1;
}
+ str->first_frame_index = 0;
+
s->ctx_flags |= AVFMTCTX_NOHEADER;
return 0;
}
+static uint8_t bcd_to_dec(uint8_t bcd)
+{
+ uint8_t dec = (bcd & 0xF) + (((bcd >> 4) & 0xF) * 10);
+
+ return dec;
+}
+
+static int32_t msf_to_lba(uint8_t m, uint8_t s, uint8_t f)
+{
+ int32_t lba = 0; /* int because it can be negative! */
+
+ m = bcd_to_dec(m);
+ s = bcd_to_dec(s);
+ f = bcd_to_dec(f);
+
+ lba = (((m * 60 + s) * 75) + f) - 150;
+
+ return lba;
+}
+
+static int32_t str_get_frame_lba(uint8_t sector[2352])
+{
+ uint8_t m = sector[0xC];
+ uint8_t s = sector[0xD];
+ uint8_t f = sector[0xE];
+
+ int32_t lba = msf_to_lba(m, s, f);
+
+ return lba;
+}
+
static int str_read_packet(AVFormatContext *s,
AVPacket *ret_pkt)
{
AVIOContext *pb = s->pb;
StrDemuxContext *str = s->priv_data;
unsigned char sector[RAW_CD_SECTOR_SIZE];
- int channel, ret;
+ int channel, ret, frame_lba;
AVPacket *pkt;
AVStream *st;
@@ -200,10 +236,12 @@ 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, 150); /* 150 sectors at 2x speed */
str->channels[channel].video_stream_index = st->index;
+ str->first_frame_index = str_get_frame_lba(sector);
+
st->codecpar->codec_type = AVMEDIA_TYPE_VIDEO;
st->codecpar->codec_id = AV_CODEC_ID_MDEC;
st->codecpar->codec_tag = 0; /* no fourcc */
@@ -223,6 +261,8 @@ static int str_read_packet(AVFormatContext *s,
return ret;
memset(pkt->data, 0, sector_count*VIDEO_DATA_CHUNK_SIZE);
+ frame_lba = str_get_frame_lba(sector);
+ pkt->pts = frame_lba - str->first_frame_index;
pkt->pos= avio_tell(pb) - RAW_CD_SECTOR_SIZE;
pkt->stream_index =
str->channels[channel].video_stream_index;
--
2.41.0.windows.1
More information about the ffmpeg-devel
mailing list