Commit 3b454e8a authored by Chris Robinson's avatar Chris Robinson Committed by Alexandre Julliard

quartz: Improve MPEG header parsing and sync recovery.

parent 037cefc4
...@@ -124,17 +124,14 @@ static const DWORD tabsel_123[2][3][16] = { ...@@ -124,17 +124,14 @@ static const DWORD tabsel_123[2][3][16] = {
static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration) static HRESULT parse_header(BYTE *header, LONGLONG *plen, LONGLONG *pduration)
{ {
LONGLONG duration;
int bitrate_index, freq_index, lsf = 1, mpeg1, layer, padding, bitrate, length; int bitrate_index, freq_index, lsf = 1, mpeg1, layer, padding, bitrate, length;
if (header[0] != 0xff) LONGLONG duration;
return E_INVALIDARG;
if (!(((header[1]>>5)&0x7) == 0x7 && if (!(header[0] == 0xff && ((header[1]>>5)&0x7) == 0x7 &&
((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf && ((header[1]>>1)&0x3) != 0 && ((header[2]>>4)&0xf) != 0xf &&
((header[2]>>2)&0x3) != 0x3)) ((header[2]>>2)&0x3) != 0x3))
{ {
FIXME("Not a valid header: %02x:%02x\n", header[1], header[2]); FIXME("Not a valid header: %02x:%02x:%02x:%02x\n", header[0], header[1], header[2], header[3]);
return E_INVALIDARG; return E_INVALIDARG;
} }
...@@ -509,17 +506,23 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO ...@@ -509,17 +506,23 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO
/* Skip ID3 v2 tag, if any */ /* Skip ID3 v2 tag, if any */
if (SUCCEEDED(hr) && !memcmp("ID3", header, 3)) if (SUCCEEDED(hr) && !memcmp("ID3", header, 3))
do { do {
UINT length; UINT length = 0;
hr = IAsyncReader_SyncRead(pPin->pReader, pos, 6, header + 4); hr = IAsyncReader_SyncRead(pPin->pReader, pos, 6, header + 4);
if (FAILED(hr)) if (FAILED(hr))
break; break;
pos += 6; pos += 6;
TRACE("Found ID3 v2.%d.%d\n", header[3], header[4]); TRACE("Found ID3 v2.%d.%d\n", header[3], header[4]);
length = (header[6] & 0x7F) << 21; if(header[3] <= 4 && header[4] != 0xff &&
length += (header[7] & 0x7F) << 14; (header[5]&0x0f) == 0 && (header[6]&0x80) == 0 &&
length += (header[8] & 0x7F) << 7; (header[7]&0x80) == 0 && (header[8]&0x80) == 0 &&
length += (header[9] & 0x7F); (header[9]&0x80) == 0)
TRACE("Length: %u\n", length); {
length = (header[6]<<21) | (header[7]<<14) |
(header[8]<< 7) | (header[9] );
if((header[5]&0x10))
length += 10;
TRACE("Length: %u\n", length);
}
pos += length; pos += length;
/* Read the real header for the mpeg splitter */ /* Read the real header for the mpeg splitter */
...@@ -592,14 +595,17 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO ...@@ -592,14 +595,17 @@ static HRESULT MPEGSplitter_pre_connect(IPin *iface, IPin *pConnectPin, ALLOCATO
hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header); hr = IAsyncReader_SyncRead(pPin->pReader, pos, 4, header);
if (hr != S_OK) if (hr != S_OK)
break; break;
while (parse_header(header, &length, &duration)) while ((hr=parse_header(header, &length, &duration)) != S_OK &&
pos + 4 < This->EndOfFile)
{ {
/* No valid header yet; shift by a byte and check again */ /* No valid header yet; shift by a byte and check again */
memmove(header, header+1, 3); memmove(header, header+1, 3);
hr = IAsyncReader_SyncRead(pPin->pReader, pos++, 1, header + 3); hr = IAsyncReader_SyncRead(pPin->pReader, ++pos + 3, 1, header + 3);
if (hr != S_OK || This->EndOfFile - pos < 4) if (hr != S_OK)
break; break;
} }
if (hr != S_OK)
break;
pos += length; pos += length;
if (This->seektable && (duration / SEEK_INTERVAL) > last_entry) if (This->seektable && (duration / SEEK_INTERVAL) > last_entry)
...@@ -692,11 +698,11 @@ static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface) ...@@ -692,11 +698,11 @@ static HRESULT WINAPI MPEGSplitter_seek(IMediaSeeking *iface)
if (hr != S_OK || timepos >= newpos) if (hr != S_OK || timepos >= newpos)
break; break;
while (parse_header(header, &length, &timepos) && bytepos + 3 < This->EndOfFile) while (parse_header(header, &length, &timepos) && bytepos + 4 < This->EndOfFile)
{ {
/* No valid header yet; shift by a byte and check again */ /* No valid header yet; shift by a byte and check again */
memmove(header, header+1, 3); memmove(header, header+1, 3);
hr = IAsyncReader_SyncRead(pPin->pReader, ++bytepos, 1, header + 3); hr = IAsyncReader_SyncRead(pPin->pReader, ++bytepos + 3, 1, header + 3);
if (hr != S_OK) if (hr != S_OK)
break; break;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment