Hi,
In some DVB streams, there are TS packets that belong to an mp2 audio
stream, have payload_unit_start set but that are _not_ the start of an
mp2 audio packet. I noticed this when linking against ffmpeg-cvs and
getting "Header missing skipping one byte.".
However, also the old ffmpeg version included with dvbcut appears to
have this "problem"; at least when the libavformat muxer is used there
are error messages about "non-monotonous timestamp" when such packets
are encountered.
Did anyone else ever notice this?
I think the proper long-term solution would be to use a framer/parser
such as the one from ffmpeg. Below is a more minimal patch to make
sure only full audio frames can become an "item".
Regards,
Wolfram.
--- dvbcut/src/tsfile.cpp Sun Oct 29 21:03:53 2006
+++ dvbcut-wg/src/tsfile.cpp Sat Nov 25 20:49:51 2006
@@ -109,6 +109,21 @@
tsfile::~tsfile()
{}
+static inline int is_mpa(const uint8_t header[4], offset_t filepos)
+{
+ /* header */
+ if (header[0] != 0xff || (header[1] & 0xe0) != 0xe0 ||
+ /* layer check */
+ (header[1] & (3<<1)) == 0 ||
+ /* bit rate */
+ (header[2] & (0xf<<4)) == 0xf<<4 ||
+ /* frequency */
+ (header[2] & (3<<2)) == 3<<2) {
+ return 0;
+ }
+ return 1;
+}
+
int tsfile::streamreader(streamhandle &s)
{
int returnvalue=0;
@@ -176,27 +191,18 @@
sd->nextfilepos=packetpos;
} else if (!sd->header.empty())
sd->header+=std::string((const char *)p->payload(),p->payload_length());
- else {
- if (!sd->itemlist().empty()) {
- returnvalue += p->payload_length();
- sd->append(p->payload(),p->payload_length());
- }
- continue;
- }
- if (sd->header.size()<9)
- continue;
+ if (sd->header.size()>=9 &&
+ sd->header[0]==0 && sd->header[1]==0 && sd->header[2]==1) {
+ // we may have a valid header
+ unsigned int payloadbegin = 9u+(uint8_t)sd->header[8];
+ if (sd->header.size()<payloadbegin)
+ continue;
+ int sid=(uint8_t)sd->header[3];
+ if (((sid & 0xe0) != 0xc0 ||
+ is_mpa((const uint8_t*)&sd->header[payloadbegin],
+ s.fileposition-TSPACKETSIZE))) {
- if (sd->header[0]!=0 || sd->header[1]!=0 || sd->header[2]!=1) {
- sd->header.clear();
- continue;
- }
- int sid=(uint8_t)sd->header[3];
-
- unsigned int payloadbegin=9u+(uint8_t)sd->header[8];
-
- if (sd->header.size()<payloadbegin)
- continue;
// if (sid==0xbd || sid==0xbf)
// {
// if (sd->header.size()<payloadbegin+1) continue;
@@ -206,16 +212,33 @@
// else
{
if (sid>=0xe0 && sid<0xf0 && sd->header.size()>=payloadbegin+4)
- if ( *(uint32_t*)(sd->header.c_str()+payloadbegin)==mbo32(0x00000001) )
+ if ( *(uint32_t*)(&sd->header[payloadbegin])==mbo32(0x00000001) )
++payloadbegin;
}
sd->appenditem(filepos_t(sd->nextfilepos,0),
std::string(sd->header,6,payloadbegin-6),
- sd->header.c_str()+payloadbegin,
sd->header.size()-payloadbegin);
+ &sd->header[payloadbegin], sd->header.size()-payloadbegin);
returnvalue += sd->header.size()-payloadbegin;
sd->header.clear();
return returnvalue;
- }
+
+ } else {
+ // header ok, but no new valid item
+ if (!sd->itemlist().empty()) {
+ returnvalue += sd->header.size()-payloadbegin;
+ sd->append(&sd->header[payloadbegin], sd->header.size()-payloadbegin);
+ }
+ sd->header.clear();
+ }
+ } else {
+ // no valid header
+ if (!sd->itemlist().empty()) {
+ returnvalue += p->payload_length();
+ sd->append(p->payload(),p->payload_length());
+ }
+ }
+ continue;
+ }
}
/// This function probes the data in the given inbuffer for an mpeg transport
stream.
-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
DVBCUT-user mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/dvbcut-user