SlideShare a Scribd company logo
1 of 70
Windows Mobile  多媒體應用程式開發 王建興 qing@cs.nthu.edu.tw http://blog.qing.tw http://twitter.com/qing_wang 2009/6/26
講者簡介 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Agenda ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
多媒體應用程式對行動裝置的重要性 ,[object Object],[object Object],[object Object],[object Object],[object Object]
一些簡單的行動多媒體應用 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
何謂 DirectShow ? ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
DirectShow 的應用範圍 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
多媒體影音的一些基本的名詞 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
於 WM 上使用 DirectShow ,你需要會 ,[object Object],[object Object],[object Object],[object Object]
DirectShow 架構圖示
DirectShow 架構的優點 ,[object Object],[object Object],[object Object]
DirectShow 核心元件 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
何謂 Filter Graph ? *Render WMV9 時會自動建立的 Filter Graph *Render MPEG 時會自動建立的 Filter Graph Output Pin Input Pin 分流 Renderer Source Filter Splitter
Filter 的觀念如何對應應用 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
IFilterGraph ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
IGraphBuilder ,[object Object],[object Object],[object Object],[object Object]
何謂 Filter ? ,[object Object],[object Object],[object Object],[object Object]
IBaseFilter ,[object Object],[object Object],[object Object],[object Object],[object Object]
AM_MEDIA_TYPE ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
格式資料 ,[object Object],[object Object],[object Object],[object Object],[object Object]
何謂 Pin ,[object Object],[object Object],[object Object],[object Object]
IPin ( 1/2) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
IPin ( 2/2) ,[object Object],[object Object],[object Object],[object Object]
filter 的連接 ,[object Object],[object Object],[object Object]
經協商後 Pin 的連線媒體類型
Filter 的類型 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Filter Graph 的建立 ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
智慧型連接 ,[object Object],[object Object]
應用 DirectShow 在 Windows Mobile 上需留意的限制 ,[object Object],[object Object],[object Object],[object Object]
一般的 PC 上都安裝大量的 filter
Windows Mobile 上會有的 filter -範例  (1/2) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
Windows Mobile 上會有的 filter -範例 (2/2) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
透過 C# 操控 COM 元件,必須要能夠 ,[object Object],[object Object],[object Object],[object Object],[object Object]
在 C# 中建立 COM 元件 ,[object Object],[ComImport, Guid("e436ebb3-524f-11ce-9f53-0020af0ba770")] public class FilterGraph { } … FilterGraph graph = new FilterGraph(); CoCreateInstance(CLSID_FilterGraph, NULL, CLSCTX_INPROC,IID_IFilterGraph, (void**) &pFilterGraph);
在 C# 中釋放 COM 元件 ,[object Object],using System.Runtime.InteropServices; Marshal.ReleaseComObject(graph); pFilterGraph->Release();
在 C# 中查詢 COM 元件的介面 ,[object Object],IMediaControl mediaControl = (IMediaControl)graph; IMediaControl *pMediaControl = NULL; pFilterGraph->QueryInterface(IID_IMediaControl, (void **) &pMediaControl );
呼叫 COM 元件的 method ,[object Object],[object Object],mediaControl.Run(); pMediaControl->Run();
資料結構的對映  (1/2) [StructLayout(LayoutKind.Sequential)] public class AMMediaType { public Guid majorType; public Guid subType; [MarshalAs(UnmanagedType.Bool)] public bool fixedSizeSamples; [MarshalAs(UnmanagedType.Bool)] public bool temporalCompression;
資料結構的對映  (2/2) public int sampleSize; public Guid formatType; public IntPtr unkPtr;  public int formatSize; public IntPtr formatPtr;  }
DirectShow.NET & DirectShow.NET CF ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
DirectShow.NET  定義了廣泛的類別
DirectShow.NET  定義了廣泛的介面
DirectShow.NET  定義了廣泛的資料結構
如何使用 DirectShow.NET ,[object Object]
所需的 namespace ,[object Object],[object Object]
一個最簡單的 DirectShow 範例 ( DSFilePlayer) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
DSFilePlayer :撥放 graph = new FilterGraph(); mediaControl = (IMediaControl)graph; mediaPosition = (IMediaPosition)graph; videoWindow = (IVideoWindow)graph; int result = mediaControl.RenderFile(ofd.FileName); result = videoWindow.put_Owner(pbVideo.Handle); result = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings); result = mediaControl.Run(); timerProgress.Enabled = true;
DSFilePlayer :停止撥放 mediaControl.Stop(); Marshal.ReleaseComObject(graph); graph = null; mediaControl = null; mediaPosition = null; videoWindow = null;
DSFilePlayer :顯示撥放進度 double duration = 0.0; double position = 0.0; mediaPosition.get_Duration(out duration); mediaPosition.get_CurrentPosition(out position); int d = (int) duration; int p = (int) position; lbProgress.Text = p + "/" + d;
從擷取設備(視訊或音訊)取得資訊( VideoCap ) ,[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object],[object Object]
VideoCap:  初始動作 graph = new FilterGraph(); graphBuilder = (IGraphBuilder) graph; mediaControl = (IMediaControl)graph; videoWindow = (IVideoWindow)graph; // captureGraph = new CaptureGraphBuilder(); captureGraphBuilder = (ICaptureGraphBuilder2)captureGraph; captureGraphBuilder.SetFiltergraph(graphBuilder);
VideoCap:  取得設定 Video Capture Filter (1/2) [ComImport, Guid("F80B6E95-B55A-4619-AEC4-A10EAEDE980C")] public class VideoCapture { } videoCapture = new VideoCapture(); videoCaptureFilter = (IBaseFilter) videoCapture; // string name = ""; if (!getName(ref name)) return false;
VideoCap:  取得設定 Video Capture Filter (2/2) IPersistPropertyBag propBag = (IPersistPropertyBag)videoCaptureFilter; if (propBag == null) return false; CPropertyBag bag = new CPropertyBag(); object oname = name; bag.Write(" VCapName ", ref oname); int hr = propBag.Load(bag, null);
VideoCap:  取得 Video Capture 設備的名稱  (1/4) public struct DEVMGR_DEVICE_INFORMATION { public uint dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string  szLegacyName ; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; }
VideoCap:  取得 Video Capture 設備的名稱  (2/4) public class PInvoke { [DllImport("coredll.dll")] public static extern IntPtr FindFirstDevice( [In] int searchType,  [In] IntPtr searchParam,  [In, Out] ref DEVMGR_DEVICE_INFORMATION pdi); [DllImport("coredll.dll")] public static extern int FindClose([In] IntPtr hFindFile); }
VideoCap:  取得 Video Capture 設備的名稱  (3/4) IntPtr handle = IntPtr.Zero; IntPtr guid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))); Marshal.StructureToPtr(CLSIDDef.Camera, guid, false); // DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION(); di.dwSize = (uint) Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION)); public static readonly Guid Camera = new Guid("CB998A05-122C-4166-846A-933E4D7E3C86");
VideoCap:  取得 Video Capture 設備的名稱  (4/4) handle = PInvoke.FindFirstDevice( 3 , guid, ref di); Marshal.FreeHGlobal(guid); if ((handle == IntPtr.Zero)||(di.hDevice == IntPtr.Zero)) return false; // PInvoke.FindClose(handle); name = di.szLegacyName; 3: DeviceSearchByGuid
VideoCap:  取得 Video Renderer Filter [ComImport, Guid("70E102B0-5556-11CE-97C0-00AA0055595A")] public class VideoRenderer { } videoRenderer = new VideoRenderer(); videoRendererFilter = (IBaseFilter)videoRenderer;
VideoCap:  建立 Filter Graph graphBuilder.AddFilter(videoCaptureFilter, "Video Capture Filter"); graphBuilder.AddFilter(videoRendererFilter, "Video Renderer Filter"); captureGraphBuilder.RenderStream(null, null, videoCaptureFilter, null, videoRendererFilter);
VideoCap:  設定視窗並撥放 videoWindow.put_Owner(pbVideo.Handle); videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings); mediaControl.Run();
VideoCap:  釋放所有產生的物件 if (graph != null) { Marshal.ReleaseComObject(graph); graph = null; } if (videoCapture != null) { Marshal.ReleaseComObject(videoCapture); videoCapture = null; } if (videoRenderer != null) { Marshal.ReleaseComObject(videoRenderer); videoRenderer = null; }
音訊的擷取 ,[object Object],[ComImport, Guid("e30629d2-27e5-11ce-875d-00608cb78066")] public class  AudioCapture { }
檔案的儲存 IBaseFilter asfWriter = null; IFileSinkFilter fileSinker  = null; captureGraphBuilder.SetOutputFileName(MediaSubType.Asf, "My DocumentsidCap.wmv", out  asfWriter , out fileSinker);
手動 / 半手動建立 Filter Graph ,[object Object],[object Object],[object Object],[object Object],[object Object]
FindPinOnFilter (1/2) private int FindPinOnFilter(IBaseFilter filter, PinDirection pinDir, int pinIndex, out IPin pin) { IEnumPins pEnum; pin = null; int hr = filter.EnumPins(out pEnum); if (hr != 0) return hr; int nFound = 0; while (true) { IPin[] pins = new IPin[1]; hr = pEnum.Next(1, pins, pFetched); if (hr != 0) break;
FindPinOnFilter (2/2) pin = pins[0]; PinDirection pinDir2; hr = pin.QueryDirection(out pinDir2); if (hr == 0 && pinDir2 == pinDir) { if (nFound == pinIndex) break; nFound++; } } return hr; }
連接兩個 filter IPin pinOut; IPin pinIn; hr =  FindPinOnFilter (filter1,  PinDirection. Out put , 0, out pinOut); hr =  FindPinOnFilter (filter2,  PinDirection. In put , 0, out pinIn); hr = graph.ConnectDirect(pinOut, pinIn, null);
下載 ,[object Object],[object Object],[object Object],[object Object]
結語 ,[object Object],[object Object],[object Object]
Q&A Thanks

More Related Content

Similar to Windows Mobile 多媒體應用程式開發

Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門Chui-Wen Chiu
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appBen Lue
 
Dalet電視數位製播系統 Dalet 數位片庫
Dalet電視數位製播系統  Dalet 數位片庫Dalet電視數位製播系統  Dalet 數位片庫
Dalet電視數位製播系統 Dalet 數位片庫bradeley
 
ICT-old-ch18-converted.pptx
ICT-old-ch18-converted.pptxICT-old-ch18-converted.pptx
ICT-old-ch18-converted.pptxliutommy1
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式Will Huang
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海Shaoning Pan
 
MFC tips for single document
MFC tips for single documentMFC tips for single document
MFC tips for single documentChris Wang
 
常用开发工具介绍
常用开发工具介绍常用开发工具介绍
常用开发工具介绍haozes
 
Windows Mobile 6 程式開發入門
Windows Mobile 6 程式開發入門Windows Mobile 6 程式開發入門
Windows Mobile 6 程式開發入門Chui-Wen Chiu
 
TI702_Android_MID
TI702_Android_MIDTI702_Android_MID
TI702_Android_MIDguestd2ec7f
 
2019 Technology Planning (for DOOH System)
2019 Technology Planning (for DOOH System)2019 Technology Planning (for DOOH System)
2019 Technology Planning (for DOOH System)August Lin
 
为独立工作室构建跨平台引擎
为独立工作室构建跨平台引擎为独立工作室构建跨平台引擎
为独立工作室构建跨平台引擎Coconut Island
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐zhangsuoyong
 
漫談 Source Control Management
漫談 Source Control Management漫談 Source Control Management
漫談 Source Control ManagementWen-Shih Chao
 
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure National Cheng Kung University
 
Flex 4.5 action custom component development
Flex 4.5 action custom component developmentFlex 4.5 action custom component development
Flex 4.5 action custom component developmentjexchan
 
廖雪峰 Saa s ovp
廖雪峰 Saa s ovp廖雪峰 Saa s ovp
廖雪峰 Saa s ovpdrewz lin
 

Similar to Windows Mobile 多媒體應用程式開發 (20)

Borland C++Builder 入門課程
Borland C++Builder 入門課程Borland C++Builder 入門課程
Borland C++Builder 入門課程
 
Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門Windows Mobile 6 遊戲開發入門
Windows Mobile 6 遊戲開發入門
 
HTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 appHTML+COIMOTION 開發跨平台 app
HTML+COIMOTION 開發跨平台 app
 
Dalet電視數位製播系統 Dalet 數位片庫
Dalet電視數位製播系統  Dalet 數位片庫Dalet電視數位製播系統  Dalet 數位片庫
Dalet電視數位製播系統 Dalet 數位片庫
 
ICT-old-ch18-converted.pptx
ICT-old-ch18-converted.pptxICT-old-ch18-converted.pptx
ICT-old-ch18-converted.pptx
 
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
TypeScript 開發實戰:開發即時互動的 html5 websocket 聊天室應用程式
 
Android应用开发 - 沈大海
Android应用开发 - 沈大海Android应用开发 - 沈大海
Android应用开发 - 沈大海
 
MFC tips for single document
MFC tips for single documentMFC tips for single document
MFC tips for single document
 
常用开发工具介绍
常用开发工具介绍常用开发工具介绍
常用开发工具介绍
 
Windows Mobile 6 程式開發入門
Windows Mobile 6 程式開發入門Windows Mobile 6 程式開發入門
Windows Mobile 6 程式開發入門
 
TI702_Android_MID
TI702_Android_MIDTI702_Android_MID
TI702_Android_MID
 
2019 Technology Planning (for DOOH System)
2019 Technology Planning (for DOOH System)2019 Technology Planning (for DOOH System)
2019 Technology Planning (for DOOH System)
 
Inside VCL
Inside VCLInside VCL
Inside VCL
 
为独立工作室构建跨平台引擎
为独立工作室构建跨平台引擎为独立工作室构建跨平台引擎
为独立工作室构建跨平台引擎
 
张所勇:前端开发工具推荐
张所勇:前端开发工具推荐张所勇:前端开发工具推荐
张所勇:前端开发工具推荐
 
漫談 Source Control Management
漫談 Source Control Management漫談 Source Control Management
漫談 Source Control Management
 
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
Accelerating or Complicating PHP execution by LLVM Compiler Infrastructure
 
Dev307
Dev307Dev307
Dev307
 
Flex 4.5 action custom component development
Flex 4.5 action custom component developmentFlex 4.5 action custom component development
Flex 4.5 action custom component development
 
廖雪峰 Saa s ovp
廖雪峰 Saa s ovp廖雪峰 Saa s ovp
廖雪峰 Saa s ovp
 

More from 建興 王

認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算建興 王
 
「沙中撈金術」﹣談開放原始碼的推薦系統
「沙中撈金術」﹣談開放原始碼的推薦系統 「沙中撈金術」﹣談開放原始碼的推薦系統
「沙中撈金術」﹣談開放原始碼的推薦系統 建興 王
 
Introduction to C++ over CLI
Introduction to C++ over CLIIntroduction to C++ over CLI
Introduction to C++ over CLI建興 王
 
開放原始碼的回收與再利用
開放原始碼的回收與再利用開放原始碼的回收與再利用
開放原始碼的回收與再利用建興 王
 
lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫建興 王
 
IKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 JavaIKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 Java建興 王
 
開發實用創新的 Android 應用程式
開發實用創新的 Android 應用程式開發實用創新的 Android 應用程式
開發實用創新的 Android 應用程式建興 王
 
從 Java programmer 的觀點看 ruby
從 Java programmer 的觀點看 ruby從 Java programmer 的觀點看 ruby
從 Java programmer 的觀點看 ruby建興 王
 

More from 建興 王 (8)

認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算認識 C++11 新標準及使用 AMP 函式庫作平行運算
認識 C++11 新標準及使用 AMP 函式庫作平行運算
 
「沙中撈金術」﹣談開放原始碼的推薦系統
「沙中撈金術」﹣談開放原始碼的推薦系統 「沙中撈金術」﹣談開放原始碼的推薦系統
「沙中撈金術」﹣談開放原始碼的推薦系統
 
Introduction to C++ over CLI
Introduction to C++ over CLIIntroduction to C++ over CLI
Introduction to C++ over CLI
 
開放原始碼的回收與再利用
開放原始碼的回收與再利用開放原始碼的回收與再利用
開放原始碼的回收與再利用
 
lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫lwdba – 開放原始碼的輕量級資料庫存取程式庫
lwdba – 開放原始碼的輕量級資料庫存取程式庫
 
IKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 JavaIKVM.NET 深入敵營的 Java
IKVM.NET 深入敵營的 Java
 
開發實用創新的 Android 應用程式
開發實用創新的 Android 應用程式開發實用創新的 Android 應用程式
開發實用創新的 Android 應用程式
 
從 Java programmer 的觀點看 ruby
從 Java programmer 的觀點看 ruby從 Java programmer 的觀點看 ruby
從 Java programmer 的觀點看 ruby
 

Windows Mobile 多媒體應用程式開發

  • 1. Windows Mobile 多媒體應用程式開發 王建興 qing@cs.nthu.edu.tw http://blog.qing.tw http://twitter.com/qing_wang 2009/6/26
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 11.
  • 12.
  • 13. 何謂 Filter Graph ? *Render WMV9 時會自動建立的 Filter Graph *Render MPEG 時會自動建立的 Filter Graph Output Pin Input Pin 分流 Renderer Source Filter Splitter
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 26.
  • 27.
  • 28.
  • 29.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38. 資料結構的對映 (1/2) [StructLayout(LayoutKind.Sequential)] public class AMMediaType { public Guid majorType; public Guid subType; [MarshalAs(UnmanagedType.Bool)] public bool fixedSizeSamples; [MarshalAs(UnmanagedType.Bool)] public bool temporalCompression;
  • 39. 資料結構的對映 (2/2) public int sampleSize; public Guid formatType; public IntPtr unkPtr; public int formatSize; public IntPtr formatPtr; }
  • 40.
  • 44.
  • 45.
  • 46.
  • 47. DSFilePlayer :撥放 graph = new FilterGraph(); mediaControl = (IMediaControl)graph; mediaPosition = (IMediaPosition)graph; videoWindow = (IVideoWindow)graph; int result = mediaControl.RenderFile(ofd.FileName); result = videoWindow.put_Owner(pbVideo.Handle); result = videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings); result = mediaControl.Run(); timerProgress.Enabled = true;
  • 48. DSFilePlayer :停止撥放 mediaControl.Stop(); Marshal.ReleaseComObject(graph); graph = null; mediaControl = null; mediaPosition = null; videoWindow = null;
  • 49. DSFilePlayer :顯示撥放進度 double duration = 0.0; double position = 0.0; mediaPosition.get_Duration(out duration); mediaPosition.get_CurrentPosition(out position); int d = (int) duration; int p = (int) position; lbProgress.Text = p + "/" + d;
  • 50.
  • 51. VideoCap: 初始動作 graph = new FilterGraph(); graphBuilder = (IGraphBuilder) graph; mediaControl = (IMediaControl)graph; videoWindow = (IVideoWindow)graph; // captureGraph = new CaptureGraphBuilder(); captureGraphBuilder = (ICaptureGraphBuilder2)captureGraph; captureGraphBuilder.SetFiltergraph(graphBuilder);
  • 52. VideoCap: 取得設定 Video Capture Filter (1/2) [ComImport, Guid("F80B6E95-B55A-4619-AEC4-A10EAEDE980C")] public class VideoCapture { } videoCapture = new VideoCapture(); videoCaptureFilter = (IBaseFilter) videoCapture; // string name = ""; if (!getName(ref name)) return false;
  • 53. VideoCap: 取得設定 Video Capture Filter (2/2) IPersistPropertyBag propBag = (IPersistPropertyBag)videoCaptureFilter; if (propBag == null) return false; CPropertyBag bag = new CPropertyBag(); object oname = name; bag.Write(" VCapName ", ref oname); int hr = propBag.Load(bag, null);
  • 54. VideoCap: 取得 Video Capture 設備的名稱 (1/4) public struct DEVMGR_DEVICE_INFORMATION { public uint dwSize; public IntPtr hDevice; public IntPtr hParentDevice; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 6)] public string szLegacyName ; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceKey; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szDeviceName; [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)] public string szBusName; }
  • 55. VideoCap: 取得 Video Capture 設備的名稱 (2/4) public class PInvoke { [DllImport("coredll.dll")] public static extern IntPtr FindFirstDevice( [In] int searchType, [In] IntPtr searchParam, [In, Out] ref DEVMGR_DEVICE_INFORMATION pdi); [DllImport("coredll.dll")] public static extern int FindClose([In] IntPtr hFindFile); }
  • 56. VideoCap: 取得 Video Capture 設備的名稱 (3/4) IntPtr handle = IntPtr.Zero; IntPtr guid = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Guid))); Marshal.StructureToPtr(CLSIDDef.Camera, guid, false); // DEVMGR_DEVICE_INFORMATION di = new DEVMGR_DEVICE_INFORMATION(); di.dwSize = (uint) Marshal.SizeOf(typeof(DEVMGR_DEVICE_INFORMATION)); public static readonly Guid Camera = new Guid("CB998A05-122C-4166-846A-933E4D7E3C86");
  • 57. VideoCap: 取得 Video Capture 設備的名稱 (4/4) handle = PInvoke.FindFirstDevice( 3 , guid, ref di); Marshal.FreeHGlobal(guid); if ((handle == IntPtr.Zero)||(di.hDevice == IntPtr.Zero)) return false; // PInvoke.FindClose(handle); name = di.szLegacyName; 3: DeviceSearchByGuid
  • 58. VideoCap: 取得 Video Renderer Filter [ComImport, Guid("70E102B0-5556-11CE-97C0-00AA0055595A")] public class VideoRenderer { } videoRenderer = new VideoRenderer(); videoRendererFilter = (IBaseFilter)videoRenderer;
  • 59. VideoCap: 建立 Filter Graph graphBuilder.AddFilter(videoCaptureFilter, "Video Capture Filter"); graphBuilder.AddFilter(videoRendererFilter, "Video Renderer Filter"); captureGraphBuilder.RenderStream(null, null, videoCaptureFilter, null, videoRendererFilter);
  • 60. VideoCap: 設定視窗並撥放 videoWindow.put_Owner(pbVideo.Handle); videoWindow.put_WindowStyle(WindowStyle.Child | WindowStyle.ClipSiblings); mediaControl.Run();
  • 61. VideoCap: 釋放所有產生的物件 if (graph != null) { Marshal.ReleaseComObject(graph); graph = null; } if (videoCapture != null) { Marshal.ReleaseComObject(videoCapture); videoCapture = null; } if (videoRenderer != null) { Marshal.ReleaseComObject(videoRenderer); videoRenderer = null; }
  • 62.
  • 63. 檔案的儲存 IBaseFilter asfWriter = null; IFileSinkFilter fileSinker = null; captureGraphBuilder.SetOutputFileName(MediaSubType.Asf, "My DocumentsidCap.wmv", out asfWriter , out fileSinker);
  • 64.
  • 65. FindPinOnFilter (1/2) private int FindPinOnFilter(IBaseFilter filter, PinDirection pinDir, int pinIndex, out IPin pin) { IEnumPins pEnum; pin = null; int hr = filter.EnumPins(out pEnum); if (hr != 0) return hr; int nFound = 0; while (true) { IPin[] pins = new IPin[1]; hr = pEnum.Next(1, pins, pFetched); if (hr != 0) break;
  • 66. FindPinOnFilter (2/2) pin = pins[0]; PinDirection pinDir2; hr = pin.QueryDirection(out pinDir2); if (hr == 0 && pinDir2 == pinDir) { if (nFound == pinIndex) break; nFound++; } } return hr; }
  • 67. 連接兩個 filter IPin pinOut; IPin pinIn; hr = FindPinOnFilter (filter1, PinDirection. Out put , 0, out pinOut); hr = FindPinOnFilter (filter2, PinDirection. In put , 0, out pinIn); hr = graph.ConnectDirect(pinOut, pinIn, null);
  • 68.
  • 69.