Это мой код в виде я добавил:Как я могу получить и установить разрешение предварительного просмотра directshow?
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DirectShowLib;
using DirectShowLib.BDA;
using DirectShowLib.DES;
using DirectShowLib.DMO;
using DirectShowLib.Dvd;
using DirectShowLib.MultimediaStreaming;
using DirectShowLib.SBE;
using System.Runtime.InteropServices;
using System.Management;
namespace Youtube_Manager
{
public partial class Elgato_Video_Capture : Form
{
IAMStreamConfig iasc;
IFilterGraph2 graph;
ICaptureGraphBuilder2 captureGraph;
IBaseFilter elgatoFilter;
IBaseFilter smartTeeFilter;
IBaseFilter videoRendererFilter;
Size videoSize;
string error = "";
List<Object> devices = new List<Object>();
public Elgato_Video_Capture()
{
InitializeComponent();
try
{
//Set the video size to use for capture and recording
videoSize = new Size(827, 505);//1280, 720);
//Initialize filter graph and capture graph
graph = (IFilterGraph2)new FilterGraph();
captureGraph = (ICaptureGraphBuilder2)new CaptureGraphBuilder2();
captureGraph.SetFiltergraph(graph);
//Create filter for Elgato
Guid elgatoGuid = new Guid("39F50F4C-99E1-464A-B6F9-D605B4FB5918");
Type comType = Type.GetTypeFromCLSID(elgatoGuid);
elgatoFilter = (IBaseFilter)Activator.CreateInstance(comType);
graph.AddFilter(elgatoFilter, "Elgato Video Capture Filter");
//Create smart tee filter, add to graph, connect Elgato's video out to smart tee in
smartTeeFilter = (IBaseFilter)new SmartTee();
graph.AddFilter(smartTeeFilter, "Smart Tee");
IPin outPin = GetPin(elgatoFilter, "Video");
IPin inPin = GetPin(smartTeeFilter, "Input");
graph.Connect(outPin, inPin);
//Create video renderer filter, add it to graph, connect smartTee Preview pin to video renderer's input pin
videoRendererFilter = (IBaseFilter)new VideoRenderer();
graph.AddFilter(videoRendererFilter, "Video Renderer");
outPin = GetPin(smartTeeFilter, "Preview");
inPin = GetPin(videoRendererFilter, "Input");
graph.Connect(outPin, inPin);
//Render stream from video renderer
captureGraph.RenderStream(PinCategory.Preview, MediaType.Video, videoRendererFilter, null, null);
//Set the video preview to be the videoFeed panel
IVideoWindow vw = (IVideoWindow)graph;
vw.put_Owner(pictureBox1.Handle);
vw.put_MessageDrain(this.Handle);
vw.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings | WindowStyle.ClipChildren);
vw.SetWindowPosition(0, 0, 827, 505);//1280, 720);
//Start the preview
IMediaControl mediaControl = graph as IMediaControl;
mediaControl.Run();
}
catch (Exception err)
{
error = err.ToString();
}
}
IPin GetPin(IBaseFilter filter, string pinname)
{
IEnumPins epins;
int hr = filter.EnumPins(out epins);
checkHR(hr, "Can't enumerate pins");
IntPtr fetched = Marshal.AllocCoTaskMem(4);
IPin[] pins = new IPin[1];
while (epins.Next(1, pins, fetched) == 0)
{
PinInfo pinfo;
pins[0].QueryPinInfo(out pinfo);
bool found = (pinfo.name == pinname);
DsUtils.FreePinInfo(pinfo);
if (found)
return pins[0];
}
checkHR(-1, "Pin not found");
return null;
}
public void checkHR(int hr, string msg)
{
if (hr < 0)
{
MessageBox.Show(msg);
DsError.ThrowExceptionForHR(hr);
}
}
private void Elgato_Video_Capture_Load(object sender, EventArgs e)
{
}
}
}
Я читал в некоторых постах, что мне нужно использовать IAMStreamConfig::SetFormat
и GetFormat
первым найти текущий формат, то, чтобы найти то, что форматы/разрешения опорного устройства/штырьковый и в конце до SetFormat
в формат (разрешение?) Я хочу.
Но я не понял, как использовать его в своем коде. Я пробовал перед объявлением в верхней части формы IAMStreamConfig
, но я не уверен, как и где использовать его в моем коде.
Редактировать
Я использую этот метод:
public void GetAllAvailableResolution(IPin VideoOutPin)
{
IAMStreamConfig streamConfig = (IAMStreamConfig)VideoOutPin;
AMMediaType searchmedia;
AMMediaType CorectvidFormat = new AMMediaType();
IntPtr ptr;
int piCount, piSize;
hr = streamConfig.GetNumberOfCapabilities(out piCount, out piSize);
ptr = Marshal.AllocCoTaskMem(piSize);
for (int i = 0; i < piCount; i++)
{
hr = streamConfig.GetStreamCaps(i, out searchmedia, ptr);
VideoInfoHeader v = new VideoInfoHeader();
Marshal.PtrToStructure(searchmedia.formatPtr, v);
if (i == 4)
{
CorectvidFormat = searchmedia;
}
}
hr = streamConfig.SetFormat(CorectvidFormat);
}
Когда я установить, если (я == 4), то я вижу на переменном об разрешении 1920 х 1080 Но до сих пор, когда я посмотрите в видео графический доцент, выглядящий таким гладко. Может быть, я получаю слишком мало fps и вам нужно его изменить?
Это похоже на разрешение 1920x1080?
Сравнение ELGATO Устройство 640х480 (по умолчанию), и мой же разрешение 640х480 выглядеть так же?
EDIT
Я использую GetFormat, чтобы получить текущее разрешение, но не уверен, что это правильный путь, и если он работает нормально:
После первого graph.Connect я добавил эта строка:
int hr = 0;
IntPtr pmt = IntPtr.Zero;
AMMediaType mediaType = new AMMediaType();
IAMStreamConfig streamConfig1 = (IAMStreamConfig)outPin;
hr = streamConfig1.GetFormat(out mediaType);
VideoInfoHeader v = new VideoInfoHeader();
Marshal.PtrToStructure(mediaType.formatPtr, v);
x = v.BmiHeader.Width;
y = v.BmiHeader.Height;
Я получаю разрешение 16x0 странно. X = 0 и Y = 16.
Изменен метод еще раз закончился с этим:
public void SetAndGetAllAvailableResolution(IPin VideoOutPin)
{
int hr = 0;
IAMStreamConfig streamConfig = (IAMStreamConfig)VideoOutPin;
AMMediaType searchmedia;
AMMediaType CorectvidFormat = new AMMediaType();
IntPtr ptr;
int piCount, piSize;
hr = streamConfig.GetNumberOfCapabilities(out piCount, out piSize);
ptr = Marshal.AllocCoTaskMem(piSize);
for (int i = 0; i < piCount; i++)
{
hr = streamConfig.GetStreamCaps(i, out searchmedia, ptr);
VideoInfoHeader v = new VideoInfoHeader();
Marshal.PtrToStructure(searchmedia.formatPtr, v);
if (i == 2)// 4
{
CorectvidFormat = searchmedia;
}
}
hr = streamConfig.SetFormat(CorectvidFormat);
IntPtr pmt = IntPtr.Zero;
AMMediaType mediaType = new AMMediaType();
IAMStreamConfig streamConfig1 = (IAMStreamConfig)VideoOutPin;
hr = streamConfig1.GetFormat(out mediaType);
BitmapInfoHeader bmpih = new BitmapInfoHeader();
Marshal.PtrToStructure(mediaType.formatPtr, bmpih);
x = bmpih.Width;
y = bmpih.Height;
}
В нижней части х и у Ноты возвращает значение 0. Но если я смотрю на bmih XPelesPerMeter 1280 И YPelesPerMeter 720 Может быть, это разрешение, которое в настоящее время используется? И если это почему, то это не значит, что я хотел? hr = streamConfig.SetFormat (CorectvidFormat); Это должно быть 640x480
Я думаю, что нашел, как это сделать, используя метод в моем вопросе. Но я не думаю, что графика выглядит как 1920 x 1080, так что либо метод неправильный, либо, может быть, мне нужно установить для более высоких кадров в секунду? –
Вам не нужно гадать. Вы строите конвейер, а затем просматриваете его, вы можете увидеть все свойства, включая разрешение. –
Спасибо, Роман, я только что добавил два изображения слева от устройства elgato, правильно моя программа. Посмотрите же 640x480? По-моему, это так. Благодарю. –