示例#1
0
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;
}
示例#2
0
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;
}