private static void AssignStreamInfoFields(InputstreamInfo streamInfo, ref WaveFormatEx wf, ref AMMediaType amt) { wf.nChannels = (ushort)streamInfo.Channels; wf.nSamplesPerSec = (int)streamInfo.SampleRate; if (wf.nSamplesPerSec == 0) { wf.nSamplesPerSec = 48000; // Fallback if missing, otherwise audio decoder filter will not connect } wf.nAvgBytesPerSec = streamInfo.Bandwidth / 8; amt.sampleSize = streamInfo.Bandwidth; }
private static uint CustomChannelCountSorting(InputstreamInfo i) { var channelCount = i.Channels; // Gives mono channels a higher number, so they are not preferred over stereo in ascending order. if (channelCount == 1) { channelCount *= 10; } return(channelCount); }
/// <summary> /// Tries to create a matching <see cref="AMMediaType"/> for the given <paramref name="streamInfo"/>. /// </summary> /// <param name="streamInfo">stream</param> /// <param name="mediaType">media type</param> /// <returns><c>true</c> if successful</returns> public static bool TryGetType(InputstreamInfo streamInfo, out AMMediaType mediaType) { Func <InputstreamInfo, AMMediaType> mediaTypeFn; if (TYPE_MAPPINGS.TryGetValue(streamInfo.CodecInternalName, out mediaTypeFn) || TYPE_MAPPINGS.TryGetValue(streamInfo.CodecName, out mediaTypeFn)) { mediaType = mediaTypeFn(streamInfo); return(true); } mediaType = null; return(false); }
public static AMMediaType E_AC3(InputstreamInfo streamInfo) { WaveFormatEx wf = new WaveFormatEx(); wf.wFormatTag = 8192; wf.nBlockAlign = 24; wf.wBitsPerSample = 32; wf.cbSize = 0; AMMediaType amt = new AMMediaType(); AssignStreamInfoFields(streamInfo, ref wf, ref amt); amt.majorType = MediaType.Audio; amt.subType = MEDIASUBTYPE_DOLBY_DDPLUS; amt.temporalCompression = false; amt.fixedSizeSamples = true; amt.SetFormat(wf); return(amt); }
public static AMMediaType AAC_LC(InputstreamInfo streamInfo) { WaveFormatEx wf = new WaveFormatEx(); wf.wFormatTag = 255; wf.nBlockAlign = 1; wf.wBitsPerSample = 16; wf.cbSize = 0; AMMediaType amt = new AMMediaType(); AssignStreamInfoFields(streamInfo, ref wf, ref amt); amt.majorType = MediaType.Audio; amt.subType = MEDIASUBTYPE_ADTS; // Works better than RAW_AAC1 (tested with Amazon Prime and 7TV) amt.temporalCompression = false; amt.fixedSizeSamples = true; amt.SetFormat(wf); return(amt); }
/// <summary> /// AnnexB formatted h264 bitstream /// </summary> /// <param name="streamInfo"></param> /// <returns></returns> public static AMMediaType H264_AnnexB(InputstreamInfo streamInfo) { int width = (int)streamInfo.Width; int height = (int)streamInfo.Height; if (streamInfo.ExtraData.Length > 0) { var codecData = new H264CodecData(streamInfo.ExtraData); SPSUnit spsUnit = new SPSUnit(codecData.SPS); width = spsUnit.Width(); height = spsUnit.Height(); } VideoInfoHeader2 vi = new VideoInfoHeader2(); vi.SrcRect.right = width; vi.SrcRect.bottom = height; vi.TargetRect.right = width; vi.TargetRect.bottom = height; int hcf = HCF(width, height); vi.PictAspectRatioX = width / hcf; vi.PictAspectRatioY = height / hcf; vi.BmiHeader.Width = width; vi.BmiHeader.Height = height; vi.BmiHeader.Planes = 1; vi.BmiHeader.Compression = FOURCC_H264; AMMediaType amt = new AMMediaType(); amt.majorType = MediaType.Video; amt.subType = MediaSubType.H264; amt.temporalCompression = true; amt.fixedSizeSamples = false; amt.sampleSize = 1; amt.SetFormat(vi); return(amt); }
/// <summary> /// AVC1 formatted H264 bitstream /// </summary> /// <param name="streamInfo"></param> /// <returns></returns> public static AMMediaType H264_AVC1(InputstreamInfo streamInfo) { H264CodecData codecData = null; Mpeg2VideoInfo vi = new Mpeg2VideoInfo(); byte[] extraData = new byte[0]; int width = (int)streamInfo.Width; int height = (int)streamInfo.Height; if (streamInfo.ExtraData.Length > 0) { codecData = new H264CodecData(streamInfo.ExtraData); SPSUnit spsUnit = new SPSUnit(codecData.SPS); width = spsUnit.Width(); height = spsUnit.Height(); } vi.hdr.SrcRect.right = width; vi.hdr.SrcRect.bottom = height; vi.hdr.TargetRect.right = width; vi.hdr.TargetRect.bottom = height; int hcf = HCF(width, height); vi.hdr.PictAspectRatioX = width / hcf; vi.hdr.PictAspectRatioY = height / hcf; vi.hdr.BmiHeader.Width = width; vi.hdr.BmiHeader.Height = height; vi.hdr.BmiHeader.Planes = 1; vi.hdr.BmiHeader.Compression = FOURCC_AVC1; vi.hdr.BmiHeader.BitCount = 24; if (codecData != null) { vi.dwProfile = (uint)codecData.Profile; vi.dwLevel = (uint)codecData.Level; vi.dwFlags = (uint)codecData.NALSizeMinusOne + 1; extraData = NaluParser.CreateAVC1ParameterSet(codecData.SPS, codecData.PPS, 2); } else { // Example: avc1.4D401F -> Main Level 3.1 // Profile Value // Baseline 42E0 // Main 4D40 // High 6400 // Extended 58A0 // Level Hex Value // 3.0 1E // 3.1 1F // 4.1 29 // 5.1 33 string codecInfo = streamInfo.CodecInternalName.Split('.').Last(); if (codecInfo.Length == 6) { int codecNum; if (int.TryParse(codecInfo.Substring(0, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codecNum)) { vi.dwProfile = (uint)codecNum; } if (int.TryParse(codecInfo.Substring(4, 2), NumberStyles.HexNumber, CultureInfo.InvariantCulture, out codecNum)) { vi.dwLevel = (uint)codecNum; } } } vi.cbSequenceHeader = (uint)extraData.Length; AMMediaType amt = new AMMediaType(); amt.majorType = MediaType.Video; amt.subType = MEDIASUBTYPE_AVC1; amt.temporalCompression = true; amt.fixedSizeSamples = false; amt.sampleSize = 1; SetFormat(vi, extraData, amt); return(amt); }