PDA

View Full Version : Audio Delay


Chatwalker
7th August 2002, 13:37
Hi all

Could someone explain how to get the Audiodelay from the Vob-Files.

Big thanks
Chatwalker

P.S.: Is it possible to get the Audio-SubID's from the IFO-File? At the moment i get the SubID'S from the first NAV-Pack of the first VOB. Sorry for my bad englisch.

tateu
9th August 2002, 02:38
A VOB is a type of mpeg-2 file so I just read the PTS (Presentation Time Stamp) values of the first Pack containing Audio Data and the first Video Pack with a frame of video that has Temporal Reference = 0. This works on VOBs with mpeg audio and AC3 audio. I don't have a VOB with LPCM audio in front of me to know if it works the same, but I am guessing that it will work the same as AC3.

My technique is slightly different than other programs such as DVD2Avi. I don't really know which one is correct but my way seems more logical to me. DVD2Avi seems to read the first Video PTS value in the file (which is usually an I Frame but not always the first frame in the Playback order, it is often the 3rd frame to be played back) and then reads the 1st Audio PTS and subtracts the two to get the Audio delay. I believe a better way to do it is to make sure that the Video PTS value that you read is from the frame with Temporal Reference = 0 (this is the first frame to be played back). Sometimes the frame with Temporal Reference = 0 does not have a PTS Value. In this case, you use the PTS Value from the I Frame and subtract it's Temporal Reference multiplied by an FPS based millisecond (ms) offset.

For Example:

For fps = 30, FPS_Offset = 1/30 = 33.33ms
For fps = 29.97 DF, FPS_Offset = 33.366667ms
For fps = 25, FPS_Offset = 25/1000 = 40ms

I Frame: Temporal Reference = 2, PTS Value = 6916.011111ms
PTS Value of Temporal Reference 0 = 6916.011111 - (2 * FPS_Offset) = 6916.011111 - 66.733334 = 6849.277777ms
First Audio PTS = 6881.522222ms

Audio Delay = 6881.522222 - 6849.277777 = +32ms

DVD2Avi reports this same file as having Audio Delay = -34ms.

To find the PTS values, you can use something like the code provided below. And for a description of the mpeg-2 syntax:
http://mpucoder.kewlhair.com/DVD/index.html
and go to "MPEG Quick Reference"

Code will look something like this:

Seek_Bytes( 0x000001EO, 4 ); //Search the file for a Video Pack Header
byteLoc += 3; //This skips the file pointer ahead 3 bytes
PTS_DTS_Flags = Read_Some_Bits( 2 ); //This reads 2 bits of data from the file

if ( PTS_DTS_Flags == 10 || PTS_DTS_Flags == 11 )
{
bitLoc = 7; //This aligns the bit location counter to byte aligned
byteLoc += 2; //This skips the file pointer ahead 2 bytes
MarkerData = Read_Some_Bits( 4 ); //This reads 4 bits of Marker Data
PTS_32 = Read_Some_Bits( 3 );
MarkerData = Read_Some_Bits( 1 ); //This reads 1 bit of Marker Data
PTS_29 = Read_Some_Bits( 15 );
MarkerData = Read_Some_Bits( 1 ); //This reads bit of Marker Data
PTS_14 = Read_Some_Bits( 15 );
MarkerData = Read_Some_Bits( 1 ); //This reads bit of Marker Data

Video_PTS = PTS_32 << 30;
Video_PTS |= ( PTS_29 << 15 );
Video_PTS |= PTS_14;
Video_PTS /= 90.0;
}

Seek_Bytes( 0x00000100, 4 ); //Search for the next Picture Header immediately after the Video Pack referenced above
Temporal_Reference = Read_Some_Bits( 10 ); //This reads 10 bits of data from the file

If the Temporal_Reference is != 0 you can run the above again two or three times until you find a Video Pack that contains a Picture Header that is == 0. Or you can just use the Video_PTS value from your I Frame:

Video_PTS -= ( Temporal_Reference * FPS_Offset );


To find the first Audio PTS Value:

Seek_Bytes( 0x000001BD, 4 ); //Use for AC3 Audio - Search the file for a Private Stream
//Seek_Bytes( 0x000001C0, 4 ); //Use for Mpeg Audio - Search the file for an Audio Pack
byteLoc += 3; //This skips the file pointer ahead 3 bytes
PTS_DTS_Flags = Read_Some_Bits( 2 ); //This reads 2 bits of data from the file

if ( PTS_DTS_Flags == 10 || PTS_DTS_Flags == 11 )
{
bitLoc = 7; //This aligns the bit location counter to byte aligned
byteLoc += 2; //This skips the file pointer ahead 2 bytes
MarkerData = Read_Some_Bits( 4 ); //This reads 4 bits of Marker Data
PTS_32 = Read_Some_Bits( 3 );
MarkerData = Read_Some_Bits( 1 ); //This reads 1 bit of Marker Data
PTS_29 = Read_Some_Bits( 15 );
MarkerData = Read_Some_Bits( 1 ); //This reads 1 bit of Marker Data
PTS_14 = Read_Some_Bits( 15 );
MarkerData = Read_Some_Bits( 1 ); //This reads bit of Marker Data

Audio_PTS = PTS_32 << 30;
Audio_PTS |= ( PTS_29 << 15 );
Audio_PTS |= PTS_14;
Audio_PTS /= 90.0;
}

Audio_Delay = Audio_PTS - Video_PTS;


Hopefully this made sense and helped.

Chatwalker
13th August 2002, 13:03
Hi Tateu

Big thanks for your help. I got it work.

Chatwalker

colasonic
6th December 2002, 08:47
no, I don't know how to use the code. Sorry, I am not a programmer. So anybody can tell me how to directly acquire the Video PTS and Audio PTS number? or anybody can please compile the code into an EXE file so that everyone including newbies like me can use it?

Gew
20th March 2019, 11:41
I reckon a ~17 year old thread necromancy is in good order, rather than creating a new thread, since I can't think of any to date obsolete or misleading answers being given here.

Back in the day I used PgcDemux for DVD's, and it often gave me a 100~200ms delay report when I clicked the "Check A/V Delay" button. In recent years though, this click has always yielded me a "0 ms", which is not true for sure; many times the audio is obviously up to 300ms off. Then I have to sit and do the calculations by hand when doing film backups not using "one-click utilities" but step-by-step, mostly from command line.

I'm not sure why PgcDemux has stopped given any delay reports, i.e. it always shows 0ms. Some of the DVDs in my collection has copy protection so I have to run through AnyDVD to gain access, but this "layer" shouldn't mess with PgcDemux, should it? Also, back in the day I had a DVD-Rom in my computer, now a BD-Rom sits there, but the player shouldn't make any difference, should it? Also, back in the day I recall using Windows XP or Windows 7, now using Windows 10, but this should make any difference, should it?

Also, I see the "PTS solution" being mentioned in this thread. Now since FFmpeg has gotten so advanced, is there any way to extract this PTS data using for instance FFprobe?

Selur
21st March 2019, 16:58
is there any way to extract this PTS data using for instance FFprobe?
If you want to see the pts etc. scroll by you could use something like:
ffprobe -show_entries "packet=pts_time,duration_time,stream_index : stream=index,codec_type" -i "INPUT FILE"
see: https://ffmpeg.org/ffprobe.html
using:
ffprobe -show_entries stream -i "INPUT FILE"
should output the most basic info about the contained streams and comparing the start_time or the streams should inform you about the delays between the streams, but that is probably similar to what mediainfo does.

Cu Selur