int tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE * mediatype, const uint8 * pMediaType) { uint32 cbFormat; const uint8 * pFormat; int i; int ret = 0; memset(mediatype, 0, sizeof(TS_AM_MEDIA_TYPE)); LLOG(0, ("MajorType: ")); tsmf_print_guid(pMediaType); for (i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_major_type_map[i].guid, pMediaType, 16) == 0) break; } mediatype->MajorType = tsmf_major_type_map[i].type; if (mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN) ret = 1; LLOGLN(0, (" (%s)", tsmf_major_type_map[i].name)); LLOG(0, ("SubType: ")); tsmf_print_guid(pMediaType + 16); for (i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_sub_type_map[i].guid, pMediaType + 16, 16) == 0) break; } mediatype->SubType = tsmf_sub_type_map[i].type; if (mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN) ret = 1; LLOGLN(0, (" (%s)", tsmf_sub_type_map[i].name)); LLOG(0, ("FormatType: ")); tsmf_print_guid(pMediaType + 44); for (i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_format_type_map[i].guid, pMediaType + 44, 16) == 0) break; } mediatype->FormatType = tsmf_format_type_map[i].type; if (mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN) ret = 1; LLOGLN(0, (" (%s)", tsmf_format_type_map[i].name)); cbFormat = GET_UINT32(pMediaType, 60); LLOGLN(0, ("tsmf_stream_set_format: cbFormat %d", cbFormat)); pFormat = pMediaType + 64; for (i = 0; i < cbFormat; i++) { LLOG(0, ("%02X ", pFormat[i])); if (i % 16 == 15) LLOG(0, ("\n")); } LLOG(0, ("\n")); switch (mediatype->FormatType) { case TSMF_FORMAT_TYPE_MFVIDEOFORMAT: /* http://msdn.microsoft.com/en-us/library/aa473808.aspx */ /* MFVIDEOFORMAT.videoInfo.dwWidth */ mediatype->Width = GET_UINT32(pFormat, 8); /* MFVIDEOFORMAT.videoInfo.dwHeight */ mediatype->Height = GET_UINT32(pFormat, 12); /* MFVIDEOFORMAT.compressedInfo.AvgBitrate */ mediatype->BitRate = GET_UINT32(pFormat, 136); /* MFVIDEOFORMAT.videoInfo.FramesPerSecond */ mediatype->SamplesPerSecond.Numerator = GET_UINT32(pFormat, 48); mediatype->SamplesPerSecond.Denominator = GET_UINT32(pFormat, 52); if (cbFormat > 176) { mediatype->ExtraDataSize = cbFormat - 176; mediatype->ExtraData = pFormat + 176; } break; case TSMF_FORMAT_TYPE_WAVEFORMATEX: /* http://msdn.microsoft.com/en-us/library/dd757720.aspx */ mediatype->Channels = GET_UINT16(pFormat, 2); mediatype->SamplesPerSecond.Numerator = GET_UINT32(pFormat, 4); mediatype->SamplesPerSecond.Denominator = 1; mediatype->BitRate = GET_UINT32(pFormat, 8) * 8; mediatype->BlockAlign = GET_UINT16(pFormat, 12); mediatype->BitsPerSample = GET_UINT16(pFormat, 14); mediatype->ExtraDataSize = GET_UINT16(pFormat, 16); if (mediatype->ExtraDataSize > 0) mediatype->ExtraData = pFormat + 18; break; case TSMF_FORMAT_TYPE_MPEG2VIDEOINFO: /* http://msdn.microsoft.com/en-us/library/dd390707.aspx */ i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, pFormat); i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, pFormat + i); if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; mediatype->ExtraData = pFormat + i; } break; case TSMF_FORMAT_TYPE_VIDEOINFO2: i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, pFormat); tsmf_codec_parse_BITMAPINFOHEADER(mediatype, pFormat + i); i += 40; /* Skip only BITMAPINFOHEADER */ if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; mediatype->ExtraData = pFormat + i; } break; default: break; } if (mediatype->SamplesPerSecond.Numerator == 0) mediatype->SamplesPerSecond.Numerator = 1; if (mediatype->SamplesPerSecond.Denominator == 0) mediatype->SamplesPerSecond.Denominator = 1; return ret; }
BOOL tsmf_codec_parse_media_type(TS_AM_MEDIA_TYPE* mediatype, wStream* s) { int i; UINT32 cbFormat; BOOL ret = TRUE; memset(mediatype, 0, sizeof(TS_AM_MEDIA_TYPE)); /* MajorType */ DEBUG_DVC("MajorType:"); tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_major_type_map[i].type != TSMF_MAJOR_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_major_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->MajorType = tsmf_major_type_map[i].type; if (mediatype->MajorType == TSMF_MAJOR_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("MajorType %s", tsmf_major_type_map[i].name); Stream_Seek(s, 16); /* SubType */ DEBUG_DVC("SubType:"); tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_sub_type_map[i].type != TSMF_SUB_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_sub_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->SubType = tsmf_sub_type_map[i].type; if (mediatype->SubType == TSMF_SUB_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("SubType %s", tsmf_sub_type_map[i].name); Stream_Seek(s, 16); /* bFixedSizeSamples, bTemporalCompression, SampleSize */ Stream_Seek(s, 12); /* FormatType */ DEBUG_DVC("FormatType:"); tsmf_print_guid(Stream_Pointer(s)); for (i = 0; tsmf_format_type_map[i].type != TSMF_FORMAT_TYPE_UNKNOWN; i++) { if (memcmp(tsmf_format_type_map[i].guid, Stream_Pointer(s), 16) == 0) break; } mediatype->FormatType = tsmf_format_type_map[i].type; if (mediatype->FormatType == TSMF_FORMAT_TYPE_UNKNOWN) ret = FALSE; DEBUG_DVC("FormatType %s", tsmf_format_type_map[i].name); Stream_Seek(s, 16); /* cbFormat */ Stream_Read_UINT32(s, cbFormat); DEBUG_DVC("cbFormat %d", cbFormat); #ifdef WITH_DEBUG_DVC winpr_HexDump(Stream_Pointer(s), cbFormat); #endif switch (mediatype->FormatType) { case TSMF_FORMAT_TYPE_MFVIDEOFORMAT: /* http://msdn.microsoft.com/en-us/library/aa473808.aspx */ Stream_Seek(s, 8); /* dwSize and ? */ Stream_Read_UINT32(s, mediatype->Width); /* videoInfo.dwWidth */ Stream_Read_UINT32(s, mediatype->Height); /* videoInfo.dwHeight */ Stream_Seek(s, 32); /* videoInfo.FramesPerSecond */ Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Numerator); Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Denominator); Stream_Seek(s, 80); Stream_Read_UINT32(s, mediatype->BitRate); /* compressedInfo.AvgBitrate */ Stream_Seek(s, 36); if (cbFormat > 176) { mediatype->ExtraDataSize = cbFormat - 176; mediatype->ExtraData = Stream_Pointer(s); } break; case TSMF_FORMAT_TYPE_WAVEFORMATEX: /* http://msdn.microsoft.com/en-us/library/dd757720.aspx */ Stream_Seek_UINT16(s); Stream_Read_UINT16(s, mediatype->Channels); Stream_Read_UINT32(s, mediatype->SamplesPerSecond.Numerator); mediatype->SamplesPerSecond.Denominator = 1; Stream_Read_UINT32(s, mediatype->BitRate); mediatype->BitRate *= 8; Stream_Read_UINT16(s, mediatype->BlockAlign); Stream_Read_UINT16(s, mediatype->BitsPerSample); Stream_Read_UINT16(s, mediatype->ExtraDataSize); if (mediatype->ExtraDataSize > 0) mediatype->ExtraData = Stream_Pointer(s); break; case TSMF_FORMAT_TYPE_MPEG1VIDEOINFO: /* http://msdn.microsoft.com/en-us/library/dd390700.aspx */ i = tsmf_codec_parse_VIDEOINFOHEADER(mediatype, s); i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, TRUE); if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; mediatype->ExtraData = Stream_Pointer(s); } break; case TSMF_FORMAT_TYPE_MPEG2VIDEOINFO: /* http://msdn.microsoft.com/en-us/library/dd390707.aspx */ i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s); i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, TRUE); if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; mediatype->ExtraData = Stream_Pointer(s); } break; case TSMF_FORMAT_TYPE_VIDEOINFO2: i = tsmf_codec_parse_VIDEOINFOHEADER2(mediatype, s); i += tsmf_codec_parse_BITMAPINFOHEADER(mediatype, s, FALSE); if (cbFormat > i) { mediatype->ExtraDataSize = cbFormat - i; mediatype->ExtraData = Stream_Pointer(s); } break; default: break; } if (mediatype->SamplesPerSecond.Numerator == 0) mediatype->SamplesPerSecond.Numerator = 1; if (mediatype->SamplesPerSecond.Denominator == 0) mediatype->SamplesPerSecond.Denominator = 1; return ret; }