video_current = audio_current = -1;
horizontal_size = vertical_size = 0;
aspect_ratio = (enum AspectRatio) 0;
- cbAspectRatio = frame_rate = bit_rate = 0;
+ frame_rate = bit_rate = 0;
}
int Demuxer::shutdown()
video_current = id;
}
-void Demuxer::setAspectRatio()
+void Demuxer::setAspectRatio(enum AspectRatio ar)
{
- if (aspect_ratio != cbAspectRatio)
+ if (aspect_ratio != ar)
{
- cbAspectRatio = aspect_ratio;
+ aspect_ratio = ar;
callback->call(this);
}
}
-int Demuxer::getAspectRatio()
+int Demuxer::writeAudio(int fd)
{
- return aspect_ratio;
+ return audiostream.drain(fd);
+}
+
+int Demuxer::writeVideo(int fd)
+{
+ return videostream.drain(fd);
}
int Demuxer::scan(UCHAR *buf, int len)
void Demuxer::parse_video_details(UCHAR* buf, int len)
{
+ // Extract video PTS if it exists
+ if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+ {
+ video_pts = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
+ ( (ULLONG)(buf[4]) << 22 ) |
+ ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
+ ( (ULLONG)(buf[6]) << 7 ) |
+ ( (ULLONG)(buf[7] & 0xFE) >> 1 );
+ }
+ // Now, scan for a GOP header and extract video information
UCHAR byte;
int zeros = 0;
while (len >= 8) // 8 is length of a GOP header
if (len < 7) return;
horizontal_size = ((int)buf[0] << 4) | ((int)buf[1] >> 4);
vertical_size = (((int)buf[1] & 0xf) << 8) | (int)buf[2];
- aspect_ratio = (enum AspectRatio)(buf[3] >> 4);
+ setAspectRatio((enum AspectRatio)(buf[3] >> 4));
frame_rate = buf[3] & 0x0f;
if (frame_rate >= 1 && frame_rate <= 8)
frame_rate = FrameRates[frame_rate];
seeking = 0;
buf += 8; // Minimum length of sequence header
len -= 8;
- setAspectRatio();
break;
case 0xb8: // Group header
// We're not going to bother parsing anything.
}
}
}
+
+int Demuxer::findVideoPTS(UCHAR* buf, int len, ULLONG* dest)
+{
+ UINT LoPattern = 0x100 | FRAMETYPE_VID0,
+ HiPattern = 0x100 | FRAMETYPE_VIDMAX;
+
+ while (len >= 14)
+ {
+ UINT pattern = *(UINT*)buf;
+ buf++; len--;
+ if (pattern < LoPattern || pattern > HiPattern) continue;
+
+ UINT framelength = ((UINT)buf[3] << 8) | buf[4];
+ buf += 5; len -= 5;
+
+ if ( buf[1] & 0x80 ) // PTS_DTS_flags indicate that PTS is present
+ {
+ *dest = ( (ULLONG)(buf[3] & 0x0E) << 29 ) |
+ ( (ULLONG)(buf[4]) << 22 ) |
+ ( (ULLONG)(buf[5] & 0xFE) << 14 ) |
+ ( (ULLONG)(buf[6]) << 7 ) |
+ ( (ULLONG)(buf[7] & 0xFE) >> 1 );
+ return 1;
+ }
+
+ buf += framelength; len -= framelength;
+ }
+ // No PTS found.
+ return 0;
+}
void seek();
void setVideoStream(int id);
void setAudioStream(int id);
- int writeAudio(int fd) { return audiostream.drain(fd); }
- int writeVideo(int fd) { return videostream.drain(fd); }
+ int writeAudio(int fd);
+ int writeVideo(int fd);
int scan(UCHAR* buf, int len);
+ int findVideoPTS(UCHAR* buf, int len, ULLONG* dest);
int put(UCHAR* buf, int len);
- int getAspectRatio();
+ int getHorizontalSize() { return horizontal_size; }
+ int getVerticalSize() { return vertical_size; }
+ int getAspectRatio() { return aspect_ratio; }
+ int getFrameRate() { return frame_rate; }
+ int getBitRate() { return bit_rate; }
+ ULLONG getVideoPTS() { return video_pts; }
enum AspectRatio
{
int seeking;
UCHAR* inbuf;
- void setAspectRatio();
+ void setAspectRatio(enum AspectRatio);
Callback* callback;
int video_current, audio_current;
enum AspectRatio aspect_ratio;
int frame_rate;
int bit_rate;
-
- int cbAspectRatio;
+ ULLONG video_pts;
};
#endif