[Freeswitch-dev] Video synchronization
Paulo Rogério Panhoto
paulo at voicetechnology.com.br
Tue Jul 13 09:55:20 PDT 2010
Hi,
This is my first post to this list and I hope this is the right one
to ask. For the last couple of weeks, I've been working on a mod to play
MP4 Video files (recording will be the next step). For simplicity, I
chose to use the same kind of MP4 files as the Asterisk app: H26x/MPEG
Video track + PCMU audio track. I used as base the mod_fsv code and
added code based on the mpeg4ip library. I've actually got a video to
work but I'm having some problem to synchronize the audio and video. I
have an idea of how the algorithm should be but I don't know how to use
the switch_core_timer to implement it.
the current loop is much like mod_fsv:
while (switch_channel_ready(channel))
{
vid_frame.packetlen = vid_frame.buflen;
write_frame.datalen = write_frame.buflen;
bool vOk = vc.getVideoPacket(vid_frame.packet, vid_frame.packetlen);
bool aOk = vc.getAudioPacket(write_frame.data, write_frame.datalen);
if (!vOk && !aOk)
break;
if (vOk)
{
switch_rtp_hdr_t *hdr = reinterpret_cast<switch_rtp_hdr_t
*>(vid_frame.packet);
// Adjusts timestamp to standard 90KHz clock.
ts = ntohl(hdr->ts) * 90000 / vc.videoTrack().track.clock;
hdr->ts = htonl(ts);
if (pt)
hdr->pt = pt;
if (switch_channel_test_flag(channel, CF_VIDEO))
{
switch_byte_t *data = (switch_byte_t *) vid_frame.packet;
vid_frame.data = data + 12;
vid_frame.datalen = vid_frame.packetlen - 12;
switch_core_session_write_video_frame(session,
&vid_frame, SWITCH_IO_FLAG_NONE, 0);
}
if (ts && last && last != ts) {
switch_cond_next();
}
last = ts;
}
if(aOk)
{
if (write_frame.datalen > (int) write_frame.buflen)
write_frame.datalen = write_frame.buflen;
switch_core_session_write_frame(session, &write_frame,
SWITCH_IO_FLAG_NONE, 0);
}
switch_core_timer_next(&timer);
}
I think it should be like this (pseudocode)
nextAudio = nextVideo = ts = 0
while(switch_channel_ready())
{
read_video_frame();
read_audio_frame();
nextVideo = ntohl(hdr->ts) * 90000 / video.clock;
waitTime = min(nextAudio, nextVideo) - ts;
if(waitTime > 0)
{
wait(waitTime);
ts += waitTime;
}
if(ts >= nextAudio)
{
send_audio_frame();
nextAudio += 20 * 90/8; // use the same clock source
}
if(ts >= nextVideo)
{
send_video_frame();
}
}
Any suggestion is much appreciated.
Regards,
Paulo R. Panhoto
More information about the FreeSWITCH-dev
mailing list