Mercurial > mplayer.hg
annotate stream/tvi_dshow.c @ 34115:3d7ee643b110
Port to Wine.
This makes MPlayer and the GUI compile and run as a Wine executable,
which is mainly to allow Windows code checking in a Linux environment.
In Makefile: Generalize the windres call by specifying option "-o" for
the output file.
In gui/win32/interface.c: Use the same function to create a thread as
Cygwin, and convert Windows style file names so that they are accessible
in the Linux environment.
In osdep/priority.c: Include windows.h.
In configure: Add system "Wine" which shall be considered (mostly) a
win32 system. Since winegcc by default compiles all files with the
"-fpic" flag, remove it, and remove all MinGW compatibility WIN32
defines, because we're not compiling for real Windows. Define to not use
Windows sockets (Wine uses different ones) and replace Windows' stricmp
by strcasecmp. Ensure that yasm's object format isn't win32 and that
HAVE_LINUX_DVD_STRUCT will be defined.
In stream/tvi_dshow.c: Define MP_DEFINE_LOCAL_GUID, because Wine's
DEFINE_GUID macro isn't compatible using "static" with it.
In loader/com.h: Rename the IIDs to become local ones, because Wine's
unknwn.h not only declares but defines them.
In mplayer.c: Don't define a SIGSEGV signal handler, or the Wine
executable will crash.
author | ib |
---|---|
date | Sat, 15 Oct 2011 13:20:52 +0000 |
parents | 277ec491a8a7 |
children | 389d43c448b3 |
rev | line source |
---|---|
24744 | 1 /* |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
2 * TV support under Win32 |
24744 | 3 * |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
4 * (C) 2007 Vladimir Voroshilov <voroshil@gmail.com> |
24744 | 5 * |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
6 * Based on tvi_dummy.c with help of tv.c, tvi_v4l2.c code. |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
7 * |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
8 * This file is part of MPlayer. |
24744 | 9 * |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
10 * MPlayer is free software; you can redistribute it and/or modify |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
11 * it under the terms of the GNU General Public License as published by |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
12 * the Free Software Foundation; either version 2 of the License, or |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
13 * (at your option) any later version. |
24744 | 14 * |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
15 * MPlayer is distributed in the hope that it will be useful, |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
18 * GNU General Public License for more details. |
24744 | 19 * |
26737
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
20 * You should have received a copy of the GNU General Public License along |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
21 * with MPlayer; if not, write to the Free Software Foundation, Inc., |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
23 */ |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
24 |
a26e50cae389
Use standard license headers with standard formatting.
diego
parents:
25689
diff
changeset
|
25 /* |
24744 | 26 * WARNING: This is alpha code! |
27 * | |
28 * Abilities: | |
29 * * Watching TV under Win32 using WDM Capture driver and DirectShow | |
30 * * Grabbing synchronized audio/video with mencoder (synchronization is beeing done by DirectShow) | |
31 * * If device driver provides IAMStreamConfig interface, user can choose width/height with "-tv height=<h>:width=<w>" | |
32 * * Adjusting BRIGHTNESS,HUE,SATURATION,CONTRAST if supported by device | |
33 * * Selecting Tuner,S-Video,... as media source | |
34 * * User can select used video capture device, passing -tv device=<dev#> | |
35 * * User can select used audio input, passing -tv audioid=<input#> | |
36 * | |
37 * options which will not be implemented (probably sometime in future, if possible): | |
38 * * alsa | |
39 * * mjpeg | |
40 * * decimation=<1|2|4> | |
41 * * quality=<0\-100> | |
42 * * forceaudio | |
43 * * forcechan=<1\-2> | |
44 * * [volume|bass|treble|balance] | |
45 * | |
46 * Works with: | |
47 * - LifeView FlyTV Prime 34FM (SAA7134 based) with driver from Ivan Uskov | |
48 * Partially works with: | |
49 * - ATI 9200 VIVO based card | |
50 * - ATI AIW 7500 | |
51 * - nVidia Ti-4400 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
52 * |
24744 | 53 * Known bugs: |
54 * * stream goes with 24.93 FPS (NTSC), while reporting 25 FPS (PAL) ?! | |
55 * * direct set frequency call does not work ('Insufficient Buffer' error) | |
56 * * audio stream goes with about 1 sample/sec rate when capturing sound from audio card | |
57 * | |
58 * TODO: | |
59 * * check audio with small buffer on vivo !!! | |
60 * * norm for IAMVideoDecoder and for IAMTVtuner - differs !! | |
61 * * check how to change TVFormat on VIVO card without tuner | |
62 * * Flip image upside-down for RGB formats. | |
63 * * | |
64 * * remove debug sleep() | |
65 * * Add some notes to methods' parameters | |
66 * * refactor console messages | |
67 * * check using header files and keep only needed | |
68 * * add additional comments to methods' bodies | |
69 * | |
70 */ | |
71 | |
72 | |
73 /// \ingroup tvi_dshow | |
74 | |
75 #include "config.h" | |
76 | |
77 #include <stdio.h> | |
78 #include "libmpcodecs/img_format.h" | |
29759
d287e2785570
Move teletext specific code from stream into libmpcodecs.
cehoyos
parents:
29263
diff
changeset
|
79 #include "libmpcodecs/dec_teletext.h" |
24744 | 80 #include "libaf/af_format.h" |
81 #include "help_mp.h" | |
82 #include "osdep/timer.h" | |
83 | |
84 | |
85 #include "tv.h" | |
86 #include "mp_msg.h" | |
87 #include "frequencies.h" | |
88 | |
89 | |
34115 | 90 #define MP_DEFINE_LOCAL_GUID(name, l, w1, w2, b1, b2, b3, b4, b5, b6, b7, b8) \ |
91 static const GUID name = {l, w1, w2, {b1, b2, b3, b4, b5, b6, b7, b8}} | |
92 | |
93 #ifdef __WINE__ | |
94 // take care of unions which are normally declared | |
95 // named by Wine but nameless (anonymous) by Windows | |
96 #define _FORCENAMELESSUNION | |
97 #endif | |
98 | |
24744 | 99 #include "tvi_dshow.h" |
100 | |
30127
774aa6f7399e
Several hacks to fix compilation of tvi_dshow on MinGW64.
reimar
parents:
29809
diff
changeset
|
101 #ifndef STDCALL |
774aa6f7399e
Several hacks to fix compilation of tvi_dshow on MinGW64.
reimar
parents:
29809
diff
changeset
|
102 // mingw64 needs this |
774aa6f7399e
Several hacks to fix compilation of tvi_dshow on MinGW64.
reimar
parents:
29809
diff
changeset
|
103 #define STDCALL __stdcall |
774aa6f7399e
Several hacks to fix compilation of tvi_dshow on MinGW64.
reimar
parents:
29809
diff
changeset
|
104 #endif |
774aa6f7399e
Several hacks to fix compilation of tvi_dshow on MinGW64.
reimar
parents:
29809
diff
changeset
|
105 |
24744 | 106 static tvi_handle_t *tvi_init_dshow(tv_param_t* tv_param); |
107 | |
108 /* | |
109 *--------------------------------------------------------------------------------------- | |
110 * | |
111 * Data structures | |
112 * | |
113 *--------------------------------------------------------------------------------------- | |
114 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
115 /** |
24744 | 116 information about this file |
117 */ | |
25689 | 118 const tvi_info_t tvi_info_dshow = { |
24744 | 119 tvi_init_dshow, |
120 "DirectShow TV", | |
121 "dshow", | |
122 "Vladimir Voroshilov", | |
123 "Very experimental!! Use with caution" | |
124 }; | |
125 | |
126 | |
127 /** | |
128 ringbuffer related info | |
129 */ | |
130 typedef struct { | |
131 CRITICAL_SECTION *pMutex; ///< pointer to critical section (mutex) | |
132 char **ringbuffer; ///< ringbuffer array | |
133 double*dpts; ///< samples' timestamps | |
134 | |
135 int buffersize; ///< size of buffer in blocks | |
136 int blocksize; ///< size of individual block | |
137 int head; ///< index of first valid sample | |
138 int tail; ///< index of last valid sample | |
139 int count; ///< count of valid samples in ringbuffer | |
140 double tStart; ///< pts of first sample (first sample should have pts 0) | |
141 } grabber_ringbuffer_t; | |
142 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
143 typedef enum { unknown, video, audio, vbi } stream_type; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
144 |
24744 | 145 /** |
146 CSampleGrabberCD definition | |
147 */ | |
148 typedef struct CSampleGrabberCB { | |
149 ISampleGrabberCBVtbl *lpVtbl; | |
150 int refcount; | |
151 GUID interfaces[2]; | |
152 grabber_ringbuffer_t *pbuf; | |
153 } CSampleGrabberCB; | |
154 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
155 /** |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
156 Chain related structure |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
157 */ |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
158 typedef struct { |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
159 stream_type type; ///< stream type |
25080 | 160 const GUID* majortype; ///< GUID of major mediatype (video/audio/vbi) |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
161 const GUID* pin_category; ///< pin category (pointer to one of PIN_CATEGORY_*) |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
162 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
163 IBaseFilter *pCaptureFilter; ///< capture device filter |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
164 IAMStreamConfig *pStreamConfig; ///< for configuring stream |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
165 ISampleGrabber *pSG; ///< ISampleGrabber interface of SampleGrabber filter |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
166 IBaseFilter *pSGF; ///< IBaseFilter interface of SampleGrabber filter |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
167 IPin *pCapturePin; ///< output capture pin |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
168 IPin *pSGIn; ///< input pin of SampleGrabber filter |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
169 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
170 grabber_ringbuffer_t *rbuf; ///< sample frabber data |
25086
e91503fbf524
Move pointer to SampleGrabber filter into chain structure.
voroshil
parents:
25085
diff
changeset
|
171 CSampleGrabberCB* pCSGCB; ///< callback object |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
172 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
173 AM_MEDIA_TYPE *pmt; ///< stream properties. |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
174 int nFormatUsed; ///< index of used format |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
175 AM_MEDIA_TYPE **arpmt; ///< available formats |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
176 void** arStreamCaps; ///< VIDEO_STREAM_CONFIG_CAPS or AUDIO_STREAM_CONFIG_CAPS |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
177 } chain_t; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
178 |
31322
016194f71de3
Fix function pointer types in tvi_functions struct
reimar
parents:
30702
diff
changeset
|
179 typedef struct priv { |
24744 | 180 int dev_index; ///< capture device index in device list (defaul: 0, first available device) |
181 int adev_index; ///< audio capture device index in device list (default: -1, not used) | |
182 int immediate_mode; ///< immediate mode (no sound capture) | |
183 int state; ///< state: 1-filter graph running, 0-filter graph stopped | |
184 int direct_setfreq_call; ///< 0-find nearest channels from system channel list(workaround),1-direct call to set frequency | |
185 int direct_getfreq_call; ///< 0-find frequncy from frequency table (workaround),1-direct call to get frequency | |
186 | |
187 int fcc; ///< used video format code (FourCC) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
188 int width; ///< picture width (default: auto) |
24744 | 189 int height; ///< picture height (default: auto) |
190 | |
191 int channels; ///< number of audio channels (default: auto) | |
192 int samplerate; ///< audio samplerate (default: auto) | |
193 | |
194 long *freq_table; ///< frequency table (in Hz) | |
195 int freq_table_len; ///< length of freq table | |
196 int first_channel; ///< channel number of first entry in freq table | |
197 int input; ///< used input | |
198 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
199 chain_t* chains[3]; ///< chains' data (0-video, 1-audio, 2-vbi) |
24744 | 200 |
201 IAMTVTuner *pTVTuner; ///< interface for tuner device | |
202 IGraphBuilder *pGraph; ///< filter graph | |
203 ICaptureGraphBuilder2 *pBuilder; ///< graph builder | |
204 IMediaControl *pMediaControl; ///< interface for controlling graph (start, stop,...) | |
205 IAMVideoProcAmp *pVideoProcAmp; ///< for adjusting hue,saturation,etc | |
206 IAMCrossbar *pCrossbar; ///< for selecting input (Tuner,Composite,S-Video,...) | |
207 DWORD dwRegister; ///< allow graphedit to connect to our graph | |
208 void *priv_vbi; ///< private VBI data structure | |
209 tt_stream_props tsp; ///< data for VBI initialization | |
210 | |
211 tv_param_t* tv_param; ///< TV parameters | |
212 } priv_t; | |
213 | |
214 #include "tvi_def.h" | |
215 | |
216 /** | |
217 country table entry structure (for loading freq table stored in kstvtuner.ax | |
218 | |
219 \note | |
220 structure have to be 2-byte aligned and have 10-byte length!! | |
221 */ | |
222 typedef struct __attribute__((__packed__)) { | |
223 WORD CountryCode; ///< Country code | |
224 WORD CableFreqTable; ///< index of resource with frequencies for cable channels | |
225 WORD BroadcastFreqTable; ///< index of resource with frequencies for broadcast channels | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
226 DWORD VideoStandard; ///< used video standard |
24744 | 227 } TRCCountryList; |
228 /** | |
229 information about image formats | |
230 */ | |
231 typedef struct { | |
232 uint32_t fmt; ///< FourCC | |
233 const GUID *subtype; ///< DirectShow's subtype | |
234 int nBits; ///< number of bits | |
235 int nCompression; ///< complression | |
236 int tail; ///< number of additional bytes followed VIDEOINFOHEADER structure | |
237 } img_fmt; | |
238 | |
239 /* | |
240 *--------------------------------------------------------------------------------------- | |
241 * | |
242 * Methods forward declaration | |
243 * | |
244 *--------------------------------------------------------------------------------------- | |
245 */ | |
246 static HRESULT init_ringbuffer(grabber_ringbuffer_t * rb, int buffersize, | |
247 int blocksize); | |
248 static HRESULT show_filter_info(IBaseFilter * pFilter); | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
249 #if 0 |
24744 | 250 //defined in current MinGW release |
251 HRESULT STDCALL GetRunningObjectTable(DWORD, IRunningObjectTable **); | |
252 HRESULT STDCALL CreateItemMoniker(LPCOLESTR, LPCOLESTR, IMoniker **); | |
253 #endif | |
254 static CSampleGrabberCB *CSampleGrabberCB_Create(grabber_ringbuffer_t * | |
255 pbuf); | |
256 static int set_crossbar_input(priv_t * priv, int input); | |
257 static int subtype2imgfmt(const GUID * subtype); | |
258 | |
259 /* | |
260 *--------------------------------------------------------------------------------------- | |
261 * | |
262 * Global constants and variables | |
263 * | |
264 *--------------------------------------------------------------------------------------- | |
265 */ | |
266 /** | |
267 lookup tables for physical connector types | |
268 */ | |
269 static const struct { | |
270 long type; | |
271 char *name; | |
272 } tv_physcon_types[]={ | |
273 {PhysConn_Video_Tuner, "Tuner" }, | |
274 {PhysConn_Video_Composite, "Composite" }, | |
275 {PhysConn_Video_SVideo, "S-Video" }, | |
276 {PhysConn_Video_RGB, "RGB" }, | |
277 {PhysConn_Video_YRYBY, "YRYBY" }, | |
278 {PhysConn_Video_SerialDigital, "SerialDigital" }, | |
279 {PhysConn_Video_ParallelDigital, "ParallelDigital"}, | |
280 {PhysConn_Video_VideoDecoder, "VideoDecoder" }, | |
281 {PhysConn_Video_VideoEncoder, "VideoEncoder" }, | |
282 {PhysConn_Video_SCART, "SCART" }, | |
283 {PhysConn_Video_Black, "Blaack" }, | |
284 {PhysConn_Audio_Tuner, "Tuner" }, | |
285 {PhysConn_Audio_Line, "Line" }, | |
286 {PhysConn_Audio_Mic, "Mic" }, | |
287 {PhysConn_Audio_AESDigital, "AESDiital" }, | |
288 {PhysConn_Audio_SPDIFDigital, "SPDIFDigital" }, | |
289 {PhysConn_Audio_AudioDecoder, "AudioDecoder" }, | |
290 {PhysConn_Audio_SCSI, "SCSI" }, | |
291 {PhysConn_Video_SCSI, "SCSI" }, | |
292 {PhysConn_Audio_AUX, "AUX" }, | |
293 {PhysConn_Video_AUX, "AUX" }, | |
294 {PhysConn_Audio_1394, "1394" }, | |
295 {PhysConn_Video_1394, "1394" }, | |
296 {PhysConn_Audio_USB, "USB" }, | |
297 {PhysConn_Video_USB, "USB" }, | |
298 {-1, NULL } | |
299 }; | |
300 | |
301 static const struct { | |
302 char *chanlist_name; | |
303 int country_code; | |
304 } tv_chanlist2country[]={ | |
305 {"us-bcast", 1}, | |
306 {"russia", 7}, | |
307 {"argentina", 54}, | |
308 {"japan-bcast", 81}, | |
309 {"china-bcast", 86}, | |
310 {"southafrica", 27}, | |
311 {"australia", 61}, | |
312 {"ireland", 353}, | |
313 {"france", 33}, | |
314 {"italy", 39}, | |
315 {"newzealand", 64}, | |
316 //directshow table uses eastern europe freq table for russia | |
317 {"europe-east", 7}, | |
318 //directshow table uses western europe freq table for germany | |
319 {"europe-west", 49}, | |
320 /* cable channels */ | |
321 {"us-cable", 1}, | |
322 {"us-cable-hrc", 1}, | |
323 {"japan-cable", 81}, | |
324 //default is USA | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
325 {NULL, 1} |
24744 | 326 }; |
327 | |
328 /** | |
329 array, contains information about various supported (i hope) image formats | |
330 */ | |
331 static const img_fmt img_fmt_list[] = { | |
25054 | 332 {IMGFMT_YUY2, &MEDIASUBTYPE_YUY2, 16, IMGFMT_YUY2, 0}, |
333 {IMGFMT_YV12, &MEDIASUBTYPE_YV12, 12, IMGFMT_YV12, 0}, | |
334 {IMGFMT_IYUV, &MEDIASUBTYPE_IYUV, 12, IMGFMT_IYUV, 0}, | |
335 {IMGFMT_I420, &MEDIASUBTYPE_I420, 12, IMGFMT_I420, 0}, | |
336 {IMGFMT_UYVY, &MEDIASUBTYPE_UYVY, 16, IMGFMT_UYVY, 0}, | |
337 {IMGFMT_YVYU, &MEDIASUBTYPE_YVYU, 16, IMGFMT_YVYU, 0}, | |
338 {IMGFMT_YVU9, &MEDIASUBTYPE_YVU9, 9, IMGFMT_YVU9, 0}, | |
339 {IMGFMT_BGR32, &MEDIASUBTYPE_RGB32, 32, 0, 0}, | |
340 {IMGFMT_BGR24, &MEDIASUBTYPE_RGB24, 24, 0, 0}, | |
341 {IMGFMT_BGR16, &MEDIASUBTYPE_RGB565, 16, 3, 12}, | |
342 {IMGFMT_BGR15, &MEDIASUBTYPE_RGB555, 16, 3, 12}, | |
343 {0, &GUID_NULL, 0, 0, 0} | |
24744 | 344 }; |
345 | |
346 #define TV_NORMS_COUNT 19 | |
347 static const struct { | |
348 long index; | |
349 char *name; | |
350 } tv_norms[TV_NORMS_COUNT] = { | |
351 { | |
352 AnalogVideo_NTSC_M, "ntsc-m"}, { | |
353 AnalogVideo_NTSC_M_J, "ntsc-mj"}, { | |
354 AnalogVideo_NTSC_433, "ntsc-433"}, { | |
355 AnalogVideo_PAL_B, "pal-b"}, { | |
356 AnalogVideo_PAL_D, "pal-d"}, { | |
357 AnalogVideo_PAL_G, "pal-g"}, { | |
358 AnalogVideo_PAL_H, "pal-h"}, { | |
359 AnalogVideo_PAL_I, "pal-i"}, { | |
360 AnalogVideo_PAL_M, "pal-m"}, { | |
361 AnalogVideo_PAL_N, "pal-n"}, { | |
362 AnalogVideo_PAL_60, "pal-60"}, { | |
363 AnalogVideo_SECAM_B, "secam-b"}, { | |
364 AnalogVideo_SECAM_D, "secam-d"}, { | |
365 AnalogVideo_SECAM_G, "secam-g"}, { | |
366 AnalogVideo_SECAM_H, "secam-h"}, { | |
367 AnalogVideo_SECAM_K, "secam-k"}, { | |
368 AnalogVideo_SECAM_K1, "secam-k1"}, { | |
369 AnalogVideo_SECAM_L, "secam-l"}, { | |
370 AnalogVideo_SECAM_L1, "secam-l1"} | |
371 }; | |
372 static long tv_available_norms[TV_NORMS_COUNT]; | |
373 static int tv_available_norms_count = 0; | |
374 | |
375 | |
376 static long *tv_available_inputs; | |
377 static int tv_available_inputs_count = 0; | |
378 | |
379 /* | |
380 *--------------------------------------------------------------------------------------- | |
381 * | |
382 * Various GUID definitions | |
383 * | |
384 *--------------------------------------------------------------------------------------- | |
385 */ | |
30305
fd0de0336717
Add hack to fix tvi_dshow compilation with 64-bit MinGW
reimar
parents:
30300
diff
changeset
|
386 // selectany can not be used with "static", fixes compilation with mingw-w64 |
fd0de0336717
Add hack to fix tvi_dshow compilation with 64-bit MinGW
reimar
parents:
30300
diff
changeset
|
387 #undef DECLSPEC_SELECTANY |
fd0de0336717
Add hack to fix tvi_dshow compilation with 64-bit MinGW
reimar
parents:
30300
diff
changeset
|
388 #define DECLSPEC_SELECTANY |
24744 | 389 /// CLSID definitions (used for CoCreateInstance call) |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
390 #define CLSID_SampleGrabber MP_CLSID_SampleGrabber |
34115 | 391 MP_DEFINE_LOCAL_GUID(CLSID_SampleGrabber, 0xC1F400A0, 0x3F08, 0x11d3, 0x9F, 0x0B, |
24744 | 392 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
393 #define CLSID_NullRenderer MP_CLSID_NullRenderer |
34115 | 394 MP_DEFINE_LOCAL_GUID(CLSID_NullRenderer, 0xC1F400A4, 0x3F08, 0x11d3, 0x9F, 0x0B, |
24744 | 395 0x00, 0x60, 0x08, 0x03, 0x9E, 0x37); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
396 #define CLSID_SystemDeviceEnum MP_CLSID_SystemDeviceEnum |
34115 | 397 MP_DEFINE_LOCAL_GUID(CLSID_SystemDeviceEnum, 0x62BE5D10, 0x60EB, 0x11d0, 0xBD, 0x3B, |
24744 | 398 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
399 #define CLSID_CaptureGraphBuilder2 MP_CLSID_CaptureGraphBuilder2 |
34115 | 400 MP_DEFINE_LOCAL_GUID(CLSID_CaptureGraphBuilder2, 0xBF87B6E1, 0x8C27, 0x11d0, 0xB3, |
24744 | 401 0xF0, 0x00, 0xAA, 0x00, 0x37, 0x61, 0xC5); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
402 #define CLSID_VideoInputDeviceCategory MP_CLSID_VideoInputDeviceCategory |
34115 | 403 MP_DEFINE_LOCAL_GUID(CLSID_VideoInputDeviceCategory, 0x860BB310, 0x5D01, 0x11d0, |
24744 | 404 0xBD, 0x3B, 0x00, 0xA0, 0xC9, 0x11, 0xCE, 0x86); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
405 #define CLSID_AudioInputDeviceCategory MP_CLSID_AudioInputDeviceCategory |
34115 | 406 MP_DEFINE_LOCAL_GUID(CLSID_AudioInputDeviceCategory, 0x33d9a762, 0x90c8, 0x11d0, |
24744 | 407 0xbd, 0x43, 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
408 #define CLSID_FilterGraph MP_CLSID_FilterGraph |
34115 | 409 MP_DEFINE_LOCAL_GUID(CLSID_FilterGraph, 0xe436ebb3, 0x524f, 0x11ce, 0x9f, 0x53, |
24744 | 410 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
411 #define CLSID_SystemClock MP_CLSID_SystemClock |
34115 | 412 MP_DEFINE_LOCAL_GUID(CLSID_SystemClock, 0xe436ebb1, 0x524f, 0x11ce, 0x9f, 0x53, |
24744 | 413 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
414 #ifdef NOT_USED | |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
415 #define CLSID_CaptureGraphBuilder MP_CLSID_CaptureGraphBuilder |
34115 | 416 MP_DEFINE_LOCAL_GUID(CLSID_CaptureGraphBuilder, 0xBF87B6E0, 0x8C27, 0x11d0, 0xB3, |
24744 | 417 0xF0, 0x00, 0xAA, 0x00, 0x37, 0x61, 0xC5); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
418 #define CLSID_VideoPortManager MP_CLSID_VideoPortManager |
34115 | 419 MP_DEFINE_LOCAL_GUID(CLSID_VideoPortManager, 0x6f26a6cd, 0x967b, 0x47fd, 0x87, 0x4a, |
24744 | 420 0x7a, 0xed, 0x2c, 0x9d, 0x25, 0xa2); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
421 #define IID_IPin MP_IID_IPin |
34115 | 422 MP_DEFINE_LOCAL_GUID(IID_IPin, 0x56a86891, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, 0x20, |
24744 | 423 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
424 #define IID_ICaptureGraphBuilder MP_IID_ICaptureGraphBuilder |
34115 | 425 MP_DEFINE_LOCAL_GUID(IID_ICaptureGraphBuilder, 0xbf87b6e0, 0x8c27, 0x11d0, 0xb3, |
24744 | 426 0xf0, 0x00, 0xaa, 0x00, 0x37, 0x61, 0xc5); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
427 #define IID_IFilterGraph MP_IID_IFilterGraph |
34115 | 428 MP_DEFINE_LOCAL_GUID(IID_IFilterGraph, 0x56a8689f, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, |
24744 | 429 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
430 #define PIN_CATEGORY_PREVIEW MP_PIN_CATEGORY_PREVIEW |
34115 | 431 MP_DEFINE_LOCAL_GUID(PIN_CATEGORY_PREVIEW, 0xfb6c4282, 0x0353, 0x11d1, 0x90, 0x5f, |
24744 | 432 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); |
433 #endif | |
434 | |
435 /// IID definitions (used for QueryInterface call) | |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
436 #define IID_IReferenceClock MP_IID_IReferenceClock |
34115 | 437 MP_DEFINE_LOCAL_GUID(IID_IReferenceClock, 0x56a86897, 0x0ad4, 0x11ce, 0xb0, 0x3a, |
24744 | 438 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
439 #define IID_IAMBufferNegotiation MP_IID_IAMBufferNegotiation |
34115 | 440 MP_DEFINE_LOCAL_GUID(IID_IAMBufferNegotiation, 0x56ED71A0, 0xAF5F, 0x11D0, 0xB3, 0xF0, |
24744 | 441 0x00, 0xAA, 0x00, 0x37, 0x61, 0xC5); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
442 #define IID_IKsPropertySet MP_IID_IKsPropertySet |
34115 | 443 MP_DEFINE_LOCAL_GUID(IID_IKsPropertySet, 0x31efac30, 0x515c, 0x11d0, 0xa9, 0xaa, |
24744 | 444 0x00, 0xaa, 0x00, 0x61, 0xbe, 0x93); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
445 #define IID_ISampleGrabber MP_IID_ISampleGrabber |
34115 | 446 MP_DEFINE_LOCAL_GUID(IID_ISampleGrabber, 0x6B652FFF, 0x11FE, 0x4fce, 0x92, 0xAD, |
24744 | 447 0x02, 0x66, 0xB5, 0xD7, 0xC7, 0x8F); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
448 #define IID_ISampleGrabberCB MP_IID_ISampleGrabberCB |
34115 | 449 MP_DEFINE_LOCAL_GUID(IID_ISampleGrabberCB, 0x0579154A, 0x2B53, 0x4994, 0xB0, 0xD0, |
24744 | 450 0xE7, 0x73, 0x14, 0x8E, 0xFF, 0x85); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
451 #define IID_ICaptureGraphBuilder2 MP_IID_ICaptureGraphBuilder2 |
34115 | 452 MP_DEFINE_LOCAL_GUID(IID_ICaptureGraphBuilder2, 0x93e5a4e0, 0x2d50, 0x11d2, 0xab, |
24744 | 453 0xfa, 0x00, 0xa0, 0xc9, 0xc6, 0xe3, 0x8d); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
454 #define IID_ICreateDevEnum MP_IID_ICreateDevEnum |
34115 | 455 MP_DEFINE_LOCAL_GUID(IID_ICreateDevEnum, 0x29840822, 0x5b84, 0x11d0, 0xbd, 0x3b, |
24744 | 456 0x00, 0xa0, 0xc9, 0x11, 0xce, 0x86); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
457 #define IID_IGraphBuilder MP_IID_IGraphBuilder |
34115 | 458 MP_DEFINE_LOCAL_GUID(IID_IGraphBuilder, 0x56a868a9, 0x0ad4, 0x11ce, 0xb0, 0x3a, |
24744 | 459 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
460 #define IID_IAMVideoProcAmp MP_IID_IAMVideoProcAmp |
34115 | 461 MP_DEFINE_LOCAL_GUID(IID_IAMVideoProcAmp, 0xC6E13360, 0x30AC, 0x11d0, 0xA1, 0x8C, |
24744 | 462 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
463 #define IID_IVideoWindow MP_IID_IVideoWindow |
34115 | 464 MP_DEFINE_LOCAL_GUID(IID_IVideoWindow, 0x56a868b4, 0x0ad4, 0x11ce, 0xb0, 0x3a, 0x00, |
24744 | 465 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
466 #define IID_IMediaControl MP_IID_IMediaControl |
34115 | 467 MP_DEFINE_LOCAL_GUID(IID_IMediaControl, 0x56a868b1, 0x0ad4, 0x11ce, 0xb0, 0x3a, |
24744 | 468 0x00, 0x20, 0xaf, 0x0b, 0xa7, 0x70); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
469 #define IID_IAMTVTuner MP_IID_IAMTVTuner |
34115 | 470 MP_DEFINE_LOCAL_GUID(IID_IAMTVTuner, 0x211A8766, 0x03AC, 0x11d1, 0x8D, 0x13, 0x00, |
24744 | 471 0xAA, 0x00, 0xBD, 0x83, 0x39); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
472 #define IID_IAMCrossbar MP_IID_IAMCrossbar |
34115 | 473 MP_DEFINE_LOCAL_GUID(IID_IAMCrossbar, 0xc6e13380, 0x30ac, 0x11d0, 0xa1, 0x8c, 0x00, |
24744 | 474 0xa0, 0xc9, 0x11, 0x89, 0x56); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
475 #define IID_IAMStreamConfig MP_IID_IAMStreamConfig |
34115 | 476 MP_DEFINE_LOCAL_GUID(IID_IAMStreamConfig, 0xc6e13340, 0x30ac, 0x11d0, 0xa1, 0x8c, |
24744 | 477 0x00, 0xa0, 0xc9, 0x11, 0x89, 0x56); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
478 #define IID_IAMAudioInputMixer MP_IID_IAMAudioInputMixer |
34115 | 479 MP_DEFINE_LOCAL_GUID(IID_IAMAudioInputMixer, 0x54C39221, 0x8380, 0x11d0, 0xB3, 0xF0, |
24744 | 480 0x00, 0xAA, 0x00, 0x37, 0x61, 0xC5); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
481 #define IID_IAMTVAudio MP_IID_IAMTVAudio |
34115 | 482 MP_DEFINE_LOCAL_GUID(IID_IAMTVAudio, 0x83EC1C30, 0x23D1, 0x11d1, 0x99, 0xE6, 0x00, |
24744 | 483 0xA0, 0xC9, 0x56, 0x02, 0x66); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
484 #define IID_IAMAnalogVideoDecoder MP_IID_IAMAnalogVideoDecoder |
34115 | 485 MP_DEFINE_LOCAL_GUID(IID_IAMAnalogVideoDecoder, 0xC6E13350, 0x30AC, 0x11d0, 0xA1, |
24744 | 486 0x8C, 0x00, 0xA0, 0xC9, 0x11, 0x89, 0x56); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
487 #define IID_IPropertyBag MP_IID_IPropertyBag |
34115 | 488 MP_DEFINE_LOCAL_GUID(IID_IPropertyBag, 0x55272a00, 0x42cb, 0x11ce, 0x81, 0x35, 0x00, |
24744 | 489 0xaa, 0x00, 0x4b, 0xb8, 0x51); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
490 #define PIN_CATEGORY_CAPTURE MP_PIN_CATEGORY_CAPTURE |
34115 | 491 MP_DEFINE_LOCAL_GUID(PIN_CATEGORY_CAPTURE, 0xfb6c4281, 0x0353, 0x11d1, 0x90, 0x5f, |
24744 | 492 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
493 #define PIN_CATEGORY_VIDEOPORT MP_PIN_CATEGORY_VIDEOPORT |
34115 | 494 MP_DEFINE_LOCAL_GUID(PIN_CATEGORY_VIDEOPORT, 0xfb6c4285, 0x0353, 0x11d1, 0x90, 0x5f, |
24744 | 495 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
496 #define PIN_CATEGORY_PREVIEW MP_PIN_CATEGORY_PREVIEW |
34115 | 497 MP_DEFINE_LOCAL_GUID(PIN_CATEGORY_PREVIEW, 0xfb6c4282, 0x0353, 0x11d1, 0x90, 0x5f, |
24744 | 498 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
499 #define PIN_CATEGORY_VBI MP_PIN_CATEGORY_VBI |
34115 | 500 MP_DEFINE_LOCAL_GUID(PIN_CATEGORY_VBI, 0xfb6c4284, 0x0353, 0x11d1, 0x90, 0x5f, |
24744 | 501 0x00, 0x00, 0xc0, 0xcc, 0x16, 0xba); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
502 #define PROPSETID_TUNER MP_PROPSETID_TUNER |
34115 | 503 MP_DEFINE_LOCAL_GUID(PROPSETID_TUNER, 0x6a2e0605, 0x28e4, 0x11d0, 0xa1, 0x8c, 0x00, |
24744 | 504 0xa0, 0xc9, 0x11, 0x89, 0x56); |
30300
191571148d95
Change GUID declarations in tvi_dshow so they are not exported and thus
reimar
parents:
30127
diff
changeset
|
505 #define MEDIATYPE_VBI MP_MEDIATYPE_VBI |
34115 | 506 MP_DEFINE_LOCAL_GUID(MEDIATYPE_VBI, 0xf72a76e1, 0xeb0a, 0x11d0, 0xac, 0xe4, 0x00, |
24744 | 507 0x00, 0xc0, 0xcc, 0x16, 0xba); |
508 | |
509 #define INSTANCEDATA_OF_PROPERTY_PTR(x) (((KSPROPERTY*)(x)) + 1) | |
510 #define INSTANCEDATA_OF_PROPERTY_SIZE(x) (sizeof((x)) - sizeof(KSPROPERTY)) | |
511 | |
512 #define DEVICE_NAME_MAX_LEN 2000 | |
513 | |
514 /*--------------------------------------------------------------------------------------- | |
515 * Methods, called only from this file | |
516 *---------------------------------------------------------------------------------------*/ | |
517 | |
33618
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
518 static void set_buffer_preference(int nDiv, WAVEFORMATEX *pWF, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
519 IPin *pOutPin, IPin *pInPin) |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
520 { |
24744 | 521 ALLOCATOR_PROPERTIES prop; |
522 IAMBufferNegotiation* pBN; | |
523 HRESULT hr; | |
524 | |
525 prop.cbAlign = -1; | |
526 prop.cbBuffer = pWF->nAvgBytesPerSec/nDiv; | |
527 if (!prop.cbBuffer) | |
528 prop.cbBuffer = 1; | |
529 prop.cbBuffer += pWF->nBlockAlign - 1; | |
530 prop.cbBuffer -= prop.cbBuffer % pWF->nBlockAlign; | |
531 prop.cbPrefix = -1; | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
532 prop.cBuffers = -1; |
24744 | 533 |
534 hr=OLE_QUERYINTERFACE(pOutPin,IID_IAMBufferNegotiation,pBN); | |
535 if(FAILED(hr)) | |
536 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: pOutPin->QueryInterface(IID_IAMBufferNegotiation) Error: 0x%x\n",(unsigned int)hr); | |
537 else{ | |
538 hr=OLE_CALL_ARGS(pBN,SuggestAllocatorProperties,&prop); | |
539 if(FAILED(hr)) | |
540 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow:pOutPin->SuggestAllocatorProperties Error:0x%x\n",(unsigned int)hr); | |
541 OLE_RELEASE_SAFE(pBN); | |
542 } | |
543 hr=OLE_QUERYINTERFACE(pInPin,IID_IAMBufferNegotiation,pBN); | |
544 if(FAILED(hr)) | |
545 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: pInPin->QueryInterface(IID_IAMBufferNegotiation) Error: 0x%x",(unsigned int)hr); | |
546 else{ | |
547 hr=OLE_CALL_ARGS(pBN,SuggestAllocatorProperties,&prop); | |
548 if(FAILED(hr)) | |
549 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: pInPit->SuggestAllocatorProperties Error:0x%x\n",(unsigned int)hr); | |
550 OLE_RELEASE_SAFE(pBN); | |
551 } | |
552 } | |
553 /* | |
554 *--------------------------------------------------------------------------------------- | |
555 * | |
556 * CSampleGrabberCD class. Used for receiving samples from DirectShow. | |
557 * | |
558 *--------------------------------------------------------------------------------------- | |
559 */ | |
560 /// CSampleGrabberCD destructor | |
561 static void CSampleGrabberCB_Destroy(CSampleGrabberCB * This) | |
562 { | |
563 free(This->lpVtbl); | |
564 free(This); | |
565 } | |
566 | |
567 /// CSampleGrabberCD IUnknown interface methods implementation | |
568 static long STDCALL CSampleGrabberCB_QueryInterface(ISampleGrabberCB * | |
569 This, | |
570 const GUID * riid, | |
571 void **ppvObject) | |
572 { | |
573 CSampleGrabberCB *me = (CSampleGrabberCB *) This; | |
574 GUID *r; | |
575 unsigned int i = 0; | |
576 Debug printf("CSampleGrabberCB_QueryInterface(%p) called\n", This); | |
577 if (!ppvObject) | |
578 return E_POINTER; | |
579 for (r = me->interfaces; | |
580 i < sizeof(me->interfaces) / sizeof(me->interfaces[0]); r++, i++) | |
581 if (!memcmp(r, riid, sizeof(*r))) { | |
582 OLE_CALL(This, AddRef); | |
583 *ppvObject = This; | |
584 return 0; | |
585 } | |
586 Debug printf("Query failed! (GUID: 0x%x)\n", *(unsigned int *) riid); | |
587 return E_NOINTERFACE; | |
588 } | |
589 | |
590 static long STDCALL CSampleGrabberCB_AddRef(ISampleGrabberCB * This) | |
591 { | |
592 CSampleGrabberCB *me = (CSampleGrabberCB *) This; | |
593 Debug printf("CSampleGrabberCB_AddRef(%p) called (ref:%d)\n", This, | |
594 me->refcount); | |
595 return ++(me->refcount); | |
596 } | |
597 | |
598 static long STDCALL CSampleGrabberCB_Release(ISampleGrabberCB * This) | |
599 { | |
600 CSampleGrabberCB *me = (CSampleGrabberCB *) This; | |
601 Debug printf("CSampleGrabberCB_Release(%p) called (new ref:%d)\n", | |
602 This, me->refcount - 1); | |
603 if (--(me->refcount) == 0) | |
604 CSampleGrabberCB_Destroy(me); | |
605 return 0; | |
606 } | |
607 | |
608 | |
33618
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
609 static HRESULT STDCALL CSampleGrabberCB_BufferCB(ISampleGrabberCB *This, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
610 double SampleTime, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
611 BYTE *pBuffer, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
612 long lBufferLen) |
24744 | 613 { |
614 CSampleGrabberCB *this = (CSampleGrabberCB *) This; | |
615 grabber_ringbuffer_t *rb = this->pbuf; | |
616 | |
617 if (!lBufferLen) | |
618 return E_FAIL; | |
619 | |
620 if (!rb->ringbuffer) { | |
621 rb->buffersize /= lBufferLen; | |
622 if (init_ringbuffer(rb, rb->buffersize, lBufferLen) != S_OK) | |
623 return E_FAIL; | |
624 } | |
625 mp_msg(MSGT_TV, MSGL_DBG4, | |
626 "tvi_dshow: BufferCB(%p): len=%ld ts=%f\n", This, lBufferLen, SampleTime); | |
627 EnterCriticalSection(rb->pMutex); | |
628 if (rb->count >= rb->buffersize) { | |
629 rb->head = (rb->head + 1) % rb->buffersize; | |
630 rb->count--; | |
631 } | |
632 | |
633 memcpy(rb->ringbuffer[rb->tail], pBuffer, | |
634 lBufferLen < rb->blocksize ? lBufferLen : rb->blocksize); | |
635 rb->dpts[rb->tail] = SampleTime; | |
636 rb->tail = (rb->tail + 1) % rb->buffersize; | |
637 rb->count++; | |
638 LeaveCriticalSection(rb->pMutex); | |
639 | |
640 return S_OK; | |
641 } | |
642 | |
643 /// wrapper. directshow does the same when BufferCB callback is requested | |
33618
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
644 static HRESULT STDCALL CSampleGrabberCB_SampleCB(ISampleGrabberCB *This, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
645 double SampleTime, |
bdfb1aeb4b41
tvi_dshow: Mark functions not used outside of the file as static.
diego
parents:
32511
diff
changeset
|
646 LPMEDIASAMPLE pSample) |
24744 | 647 { |
648 char* buf; | |
649 long len; | |
650 long long tStart,tEnd; | |
651 HRESULT hr; | |
652 grabber_ringbuffer_t *rb = ((CSampleGrabberCB*)This)->pbuf; | |
653 | |
654 len=OLE_CALL(pSample,GetSize); | |
655 tStart=tEnd=0; | |
656 hr=OLE_CALL_ARGS(pSample,GetTime,&tStart,&tEnd); | |
657 if(FAILED(hr)){ | |
658 return hr; | |
659 } | |
660 mp_msg(MSGT_TV, MSGL_DBG4,"tvi_dshow: SampleCB(%p): %d/%d %f\n", This,rb->count,rb->buffersize,1e-7*tStart); | |
661 hr=OLE_CALL_ARGS(pSample,GetPointer,(void*)&buf); | |
662 if(FAILED(hr)){ | |
663 return hr; | |
664 } | |
665 hr=CSampleGrabberCB_BufferCB(This,1e-7*tStart,buf,len); | |
666 return hr; | |
667 | |
668 } | |
669 | |
670 /// main grabbing routine | |
671 static CSampleGrabberCB *CSampleGrabberCB_Create(grabber_ringbuffer_t * | |
672 pbuf) | |
673 { | |
674 CSampleGrabberCB *This = malloc(sizeof(CSampleGrabberCB)); | |
675 if (!This) | |
676 return NULL; | |
677 | |
678 This->lpVtbl = malloc(sizeof(ISampleGrabberVtbl)); | |
679 if (!This->lpVtbl) { | |
680 CSampleGrabberCB_Destroy(This); | |
681 return NULL; | |
682 } | |
683 This->refcount = 1; | |
684 This->lpVtbl->QueryInterface = CSampleGrabberCB_QueryInterface; | |
685 This->lpVtbl->AddRef = CSampleGrabberCB_AddRef; | |
686 This->lpVtbl->Release = CSampleGrabberCB_Release; | |
687 This->lpVtbl->SampleCB = CSampleGrabberCB_SampleCB; | |
688 This->lpVtbl->BufferCB = CSampleGrabberCB_BufferCB; | |
689 | |
690 This->interfaces[0] = IID_IUnknown; | |
691 This->interfaces[1] = IID_ISampleGrabberCB; | |
692 | |
693 This->pbuf = pbuf; | |
694 | |
695 return This; | |
696 } | |
697 | |
698 /* | |
699 *--------------------------------------------------------------------------------------- | |
700 * | |
701 * ROT related methods (register, unregister) | |
702 * | |
703 *--------------------------------------------------------------------------------------- | |
704 */ | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
705 /** |
24744 | 706 Registering graph in ROT. User will be able to connect to graph from GraphEdit. |
707 */ | |
708 static HRESULT AddToRot(IUnknown * pUnkGraph, DWORD * pdwRegister) | |
709 { | |
710 IMoniker *pMoniker; | |
711 IRunningObjectTable *pROT; | |
712 WCHAR wsz[256]; | |
713 HRESULT hr; | |
714 | |
715 if (FAILED(GetRunningObjectTable(0, &pROT))) { | |
716 return E_FAIL; | |
717 } | |
718 wsprintfW(wsz, L"FilterGraph %08x pid %08x", (DWORD_PTR) pUnkGraph, | |
719 GetCurrentProcessId()); | |
720 hr = CreateItemMoniker(L"!", wsz, &pMoniker); | |
721 if (SUCCEEDED(hr)) { | |
722 hr = OLE_CALL_ARGS(pROT, Register, ROTFLAGS_REGISTRATIONKEEPSALIVE, | |
723 pUnkGraph, pMoniker, pdwRegister); | |
724 OLE_RELEASE_SAFE(pMoniker); | |
725 } | |
726 OLE_RELEASE_SAFE(pROT); | |
727 return hr; | |
728 } | |
729 | |
730 /// Unregistering graph in ROT | |
731 static void RemoveFromRot(DWORD dwRegister) | |
732 { | |
733 IRunningObjectTable *pROT; | |
734 if (SUCCEEDED(GetRunningObjectTable(0, &pROT))) { | |
735 OLE_CALL_ARGS(pROT, Revoke, dwRegister); | |
736 OLE_RELEASE_SAFE(pROT); | |
737 } | |
738 } | |
739 | |
740 /* | |
741 *--------------------------------------------------------------------------------------- | |
742 * | |
743 * ringbuffer related methods (init, destroy) | |
744 * | |
745 *--------------------------------------------------------------------------------------- | |
746 */ | |
747 /** | |
748 * \brief ringbuffer destroying routine | |
749 * | |
750 * \param rb pointer to empty (just allocated) ringbuffer structure | |
751 * | |
752 * \note routine does not frees memory, allocated for grabber_rinbuffer_s structure | |
753 */ | |
754 static void destroy_ringbuffer(grabber_ringbuffer_t * rb) | |
755 { | |
756 int i; | |
757 | |
758 if (!rb) | |
759 return; | |
760 | |
761 if (rb->ringbuffer) { | |
762 for (i = 0; i < rb->buffersize; i++) | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
763 free(rb->ringbuffer[i]); |
24744 | 764 free(rb->ringbuffer); |
765 rb->ringbuffer = NULL; | |
766 } | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
767 free(rb->dpts); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
768 rb->dpts = NULL; |
24744 | 769 if (rb->pMutex) { |
770 DeleteCriticalSection(rb->pMutex); | |
771 free(rb->pMutex); | |
772 rb->pMutex = NULL; | |
773 } | |
774 | |
775 rb->blocksize = 0; | |
776 rb->buffersize = 0; | |
777 rb->head = 0; | |
778 rb->tail = 0; | |
779 rb->count = 0; | |
780 } | |
781 | |
782 /** | |
783 * \brief ringbuffer initialization | |
784 * | |
785 * \param rb pointer to empty (just allocated) ringbuffer structure | |
786 * \param buffersize size of buffer in blocks | |
787 * \param blocksize size of buffer's block | |
788 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
789 * \return S_OK if success |
24744 | 790 * \return E_OUTOFMEMORY not enough memory |
791 * | |
792 * \note routine does not allocates memory for grabber_rinbuffer_s structure | |
793 */ | |
794 static HRESULT init_ringbuffer(grabber_ringbuffer_t * rb, int buffersize, | |
795 int blocksize) | |
796 { | |
797 int i; | |
798 | |
799 if (!rb) | |
800 return E_OUTOFMEMORY; | |
801 | |
802 rb->buffersize = buffersize < 2 ? 2 : buffersize; | |
803 rb->blocksize = blocksize; | |
804 | |
805 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Capture buffer: %d blocks of %d bytes.\n", | |
806 rb->buffersize, rb->blocksize); | |
807 | |
30702 | 808 rb->ringbuffer = malloc(rb->buffersize * sizeof(char *)); |
24744 | 809 if (!rb) |
810 return E_POINTER; | |
811 memset(rb->ringbuffer, 0, rb->buffersize * sizeof(char *)); | |
812 | |
813 for (i = 0; i < rb->buffersize; i++) { | |
30702 | 814 rb->ringbuffer[i] = malloc(rb->blocksize * sizeof(char)); |
24744 | 815 if (!rb->ringbuffer[i]) { |
816 destroy_ringbuffer(rb); | |
817 return E_OUTOFMEMORY; | |
818 } | |
819 } | |
30702 | 820 rb->dpts = malloc(rb->buffersize * sizeof(double)); |
24744 | 821 if (!rb->dpts) { |
822 destroy_ringbuffer(rb); | |
823 return E_OUTOFMEMORY; | |
824 } | |
825 rb->head = 0; | |
826 rb->tail = 0; | |
827 rb->count = 0; | |
828 rb->tStart = -1; | |
30702 | 829 rb->pMutex = malloc(sizeof(CRITICAL_SECTION)); |
24744 | 830 if (!rb->pMutex) { |
831 destroy_ringbuffer(rb); | |
832 return E_OUTOFMEMORY; | |
833 } | |
834 InitializeCriticalSection(rb->pMutex); | |
835 return S_OK; | |
836 } | |
837 | |
838 /* | |
839 *--------------------------------------------------------------------------------------- | |
840 * | |
841 * Tuner related methods (frequency, capabilities, etc | |
842 * | |
843 *--------------------------------------------------------------------------------------- | |
844 */ | |
845 /** | |
846 * \brief returns string with name for givend PsysCon_* constant | |
847 * | |
848 * \param lPhysicalType constant from PhysicalConnectorType enumeration | |
849 * | |
850 * \return pointer to string with apropriate name | |
851 * | |
852 * \note | |
853 * Caller should not free returned pointer | |
854 */ | |
855 static char *physcon2str(const long lPhysicalType) | |
856 { | |
857 int i; | |
858 for(i=0; tv_physcon_types[i].name; i++) | |
859 if(tv_physcon_types[i].type==lPhysicalType) | |
860 return tv_physcon_types[i].name; | |
861 return "Unknown"; | |
862 }; | |
863 | |
864 /** | |
865 * \brief converts MPlayer's chanlist to system country code. | |
866 * | |
867 * \param chanlist MPlayer's chanlist name | |
868 * | |
869 * \return system country code | |
870 * | |
871 * \remarks | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
872 * After call to IAMTVTuner::put_CountryCode with returned value tuner switches to frequency table used in specified |
24744 | 873 * country (which is usually larger then MPlayer's one, so workaround will work fine). |
874 * | |
875 * \todo | |
876 * Resolve trouble with cable channels (DirectShow's tuners must be switched between broadcast and cable channels modes. | |
877 */ | |
878 static int chanlist2country(char *chanlist) | |
879 { | |
880 int i; | |
881 for(i=0; tv_chanlist2country[i].chanlist_name; i++) | |
882 if (!strcmp(chanlist, tv_chanlist2country[i].chanlist_name)) | |
883 break; | |
884 return tv_chanlist2country[i].country_code; | |
885 } | |
886 | |
887 /** | |
888 * \brief loads specified resource from module and return pointer to it | |
889 * | |
890 * \param hDLL valid module desriptor | |
891 * \param index index of resource. resource with name "#<index>" will be loaded | |
892 * | |
893 * \return pointer to loader resource or NULL if error occured | |
894 */ | |
895 static void *GetRC(HMODULE hDLL, int index) | |
896 { | |
897 char szRCDATA[10]; | |
898 char szName[10]; | |
899 HRSRC hRes; | |
900 HGLOBAL hTable; | |
901 | |
902 snprintf(szRCDATA, 10, "#%d", (int)RT_RCDATA); | |
903 snprintf(szName, 10, "#%d", index); | |
904 | |
905 hRes = FindResource(hDLL, szName, szRCDATA); | |
906 if (!hRes) { | |
907 return NULL; | |
908 } | |
909 hTable = LoadResource(hDLL, hRes); | |
910 if (!hTable) { | |
911 return NULL; | |
912 } | |
913 return LockResource(hTable); | |
914 } | |
915 | |
916 /** | |
917 * \brief loads frequency table for given country from kstvtune.ax | |
918 * | |
919 * \param[in] nCountry - country code | |
920 * \param[in] nInputType (TunerInputCable or TunerInputAntenna) | |
921 * \param[out] pplFreqTable - address of variable that receives pointer to array, containing frequencies | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
922 * \param[out] pnLen length of array |
24744 | 923 * \param[out] pnFirst - channel number of first entry in array (nChannelMax) |
924 * | |
925 * \return S_OK if success | |
926 * \return E_POINTER pplFreqTable==NULL || plFirst==NULL || pnLen==NULL | |
927 * \return E_FAIL error occured during load | |
928 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
929 * \remarks |
24744 | 930 * - array must be freed by caller |
931 * - MSDN says that it is not neccessery to unlock or free resource. It will be done after unloading DLL | |
932 */ | |
933 static HRESULT load_freq_table(int nCountry, int nInputType, | |
934 long **pplFreqTable, int *pnLen, | |
935 int *pnFirst) | |
936 { | |
937 HMODULE hDLL; | |
938 long *plFreqTable; | |
939 TRCCountryList *pCountryList; | |
940 int i, index; | |
941 | |
27630
6fe56f6147ea
Add debug message about loaded frequency tables.
voroshil
parents:
27629
diff
changeset
|
942 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: load_freq_table called %d (%s)\n",nCountry,nInputType == TunerInputAntenna ? "broadcast" : "cable"); |
24744 | 943 /* ASSERT(sizeof(TRCCountryList)==10); // need properly aligned structure */ |
944 | |
945 if (!pplFreqTable || !pnFirst || !pnLen) | |
946 return E_POINTER; | |
947 if (!nCountry) | |
948 return E_FAIL; | |
949 | |
950 hDLL = LoadLibrary("kstvtune.ax"); | |
951 if (!hDLL) { | |
952 return E_FAIL; | |
953 } | |
954 pCountryList = GetRC(hDLL, 9999); | |
955 if (!pCountryList) { | |
956 FreeLibrary(hDLL); | |
957 return E_FAIL; | |
958 } | |
959 for (i = 0; pCountryList[i].CountryCode != 0; i++) | |
960 if (pCountryList[i].CountryCode == nCountry) | |
961 break; | |
962 if (pCountryList[i].CountryCode == 0) { | |
963 FreeLibrary(hDLL); | |
964 return E_FAIL; | |
965 } | |
966 if (nInputType == TunerInputCable) | |
967 index = pCountryList[i].CableFreqTable; | |
968 else | |
969 index = pCountryList[i].BroadcastFreqTable; | |
970 | |
971 plFreqTable = GetRC(hDLL, index); //First element is number of first channel, second - number of last channel | |
972 if (!plFreqTable) { | |
973 FreeLibrary(hDLL); | |
974 return E_FAIL; | |
975 } | |
976 *pnFirst = plFreqTable[0]; | |
977 *pnLen = (int) (plFreqTable[1] - plFreqTable[0] + 1); | |
30702 | 978 *pplFreqTable = malloc((*pnLen) * sizeof(long)); |
24744 | 979 if (!*pplFreqTable) { |
980 FreeLibrary(hDLL); | |
981 return E_FAIL; | |
982 } | |
983 for (i = 0; i < *pnLen; i++) { | |
984 (*pplFreqTable)[i] = plFreqTable[i + 2]; | |
27630
6fe56f6147ea
Add debug message about loaded frequency tables.
voroshil
parents:
27629
diff
changeset
|
985 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: load_freq_table #%d => (%ld)\n",i+*pnFirst,(*pplFreqTable)[i]); |
24744 | 986 } |
987 FreeLibrary(hDLL); | |
988 return S_OK; | |
989 } | |
990 | |
991 /** | |
992 * \brief tunes to given frequency through IKsPropertySet call | |
993 * | |
994 * \param pTVTuner IAMTVTuner interface of capture device | |
995 * \param lFreq frequency to tune (in Hz) | |
996 * | |
997 * \return S_OK success | |
998 * \return apropriate error code otherwise | |
999 * | |
1000 * \note | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1001 * Due to either bug in driver or error in following code calll to IKsProperty::Set |
24744 | 1002 * in this methods always fail with error 0x8007007a. |
1003 * | |
1004 * \todo test code on other machines and an error | |
1005 */ | |
1006 static HRESULT set_frequency_direct(IAMTVTuner * pTVTuner, long lFreq) | |
1007 { | |
1008 HRESULT hr; | |
1009 DWORD dwSupported = 0; | |
1010 DWORD cbBytes = 0; | |
1011 KSPROPERTY_TUNER_MODE_CAPS_S mode_caps; | |
1012 KSPROPERTY_TUNER_FREQUENCY_S frequency; | |
1013 IKsPropertySet *pKSProp; | |
1014 | |
1015 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: set_frequency_direct called\n"); | |
1016 | |
1017 memset(&mode_caps, 0, sizeof(mode_caps)); | |
1018 memset(&frequency, 0, sizeof(frequency)); | |
1019 | |
1020 hr = OLE_QUERYINTERFACE(pTVTuner, IID_IKsPropertySet, pKSProp); | |
1021 if (FAILED(hr)) | |
1022 return hr; //no IKsPropertySet interface | |
1023 | |
1024 mode_caps.Mode = AMTUNER_MODE_TV; | |
1025 hr = OLE_CALL_ARGS(pKSProp, QuerySupported, &PROPSETID_TUNER, | |
1026 KSPROPERTY_TUNER_MODE_CAPS, &dwSupported); | |
1027 if (FAILED(hr)) { | |
1028 OLE_RELEASE_SAFE(pKSProp); | |
1029 return hr; | |
1030 } | |
1031 | |
1032 if (!dwSupported & KSPROPERTY_SUPPORT_GET) { | |
1033 OLE_RELEASE_SAFE(pKSProp); | |
1034 return E_FAIL; //PROPSETID_TINER not supported | |
1035 } | |
1036 | |
1037 hr = OLE_CALL_ARGS(pKSProp, Get, &PROPSETID_TUNER, | |
1038 KSPROPERTY_TUNER_MODE_CAPS, | |
1039 INSTANCEDATA_OF_PROPERTY_PTR(&mode_caps), | |
1040 INSTANCEDATA_OF_PROPERTY_SIZE(mode_caps), | |
1041 &mode_caps, sizeof(mode_caps), &cbBytes); | |
1042 | |
1043 frequency.Frequency = lFreq; | |
1044 | |
1045 if (mode_caps.Strategy == KS_TUNER_STRATEGY_DRIVER_TUNES) | |
1046 frequency.TuningFlags = KS_TUNER_TUNING_FINE; | |
1047 else | |
1048 frequency.TuningFlags = KS_TUNER_TUNING_EXACT; | |
1049 | |
1050 if (lFreq < mode_caps.MinFrequency || lFreq > mode_caps.MaxFrequency) { | |
1051 OLE_RELEASE_SAFE(pKSProp); | |
1052 return E_FAIL; | |
1053 } | |
1054 | |
1055 hr = OLE_CALL_ARGS(pKSProp, Set, &PROPSETID_TUNER, | |
1056 KSPROPERTY_TUNER_FREQUENCY, | |
1057 INSTANCEDATA_OF_PROPERTY_PTR(&frequency), | |
1058 INSTANCEDATA_OF_PROPERTY_SIZE(frequency), | |
1059 &frequency, sizeof(frequency)); | |
1060 if (FAILED(hr)) { | |
1061 OLE_RELEASE_SAFE(pKSProp); | |
1062 return hr; | |
1063 } | |
1064 | |
1065 OLE_RELEASE_SAFE(pKSProp); | |
1066 | |
1067 return S_OK; | |
1068 } | |
1069 | |
1070 /** | |
1071 * \brief find channel with nearest frequency and set it | |
1072 * | |
1073 * \param priv driver's private data | |
1074 * \param lFreq frequency in Hz | |
1075 * | |
1076 * \return S_OK if success | |
1077 * \return E_FAIL if error occured | |
1078 */ | |
1079 static HRESULT set_nearest_freq(priv_t * priv, long lFreq) | |
1080 { | |
1081 HRESULT hr; | |
1082 int i; | |
1083 long lFreqDiff=-1; | |
1084 int nChannel; | |
1085 TunerInputType tunerInput; | |
1086 long lInput; | |
1087 | |
27629
d04568721d39
Make output messages of frequency selection code more useful by
voroshil
parents:
27628
diff
changeset
|
1088 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: set_nearest_freq called: %ld\n", lFreq); |
24744 | 1089 if(priv->freq_table_len == -1 && !priv->freq_table) { |
1090 | |
1091 hr = OLE_CALL_ARGS(priv->pTVTuner, get_ConnectInput, &lInput); | |
1092 if(FAILED(hr)){ //Falling back to 0 | |
1093 lInput=0; | |
1094 } | |
1095 | |
1096 hr = OLE_CALL_ARGS(priv->pTVTuner, get_InputType, lInput, &tunerInput); | |
1097 | |
1098 if (load_freq_table(chanlist2country(priv->tv_param->chanlist), tunerInput, &(priv->freq_table), &(priv->freq_table_len), &(priv->first_channel)) != S_OK) {//FIXME | |
1099 priv->freq_table_len=0; | |
1100 priv->freq_table=NULL; | |
1101 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableExtractFreqTable); | |
1102 return E_FAIL; | |
1103 }; | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1104 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: loaded system (%s) frequency table for country id=%d (channels:%d).\n", tunerInput == TunerInputAntenna ? "broadcast" : "cable", |
24744 | 1105 chanlist2country(priv->tv_param->chanlist), priv->freq_table_len); |
1106 } | |
1107 | |
1108 if (priv->freq_table_len <= 0) | |
1109 return E_FAIL; | |
1110 | |
1111 //FIXME: rewrite search algo | |
1112 nChannel = -1; | |
1113 for (i = 0; i < priv->freq_table_len; i++) { | |
1114 if (nChannel == -1 || labs(lFreq - priv->freq_table[i]) < lFreqDiff) { | |
1115 nChannel = priv->first_channel + i; | |
1116 lFreqDiff = labs(lFreq - priv->freq_table[i]); | |
1117 } | |
27629
d04568721d39
Make output messages of frequency selection code more useful by
voroshil
parents:
27628
diff
changeset
|
1118 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: set_nearest_freq #%d (%ld) => %d (%ld)\n",i+priv->first_channel,priv->freq_table[i], nChannel,lFreqDiff); |
24744 | 1119 } |
1120 if (nChannel == -1) { | |
1121 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_UnableFindNearestChannel); | |
1122 return E_FAIL; | |
1123 } | |
27629
d04568721d39
Make output messages of frequency selection code more useful by
voroshil
parents:
27628
diff
changeset
|
1124 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: set_nearest_freq #%d (%ld)\n",nChannel,priv->freq_table[nChannel - priv->first_channel]); |
24744 | 1125 hr = OLE_CALL_ARGS(priv->pTVTuner, put_Channel, nChannel, |
1126 AMTUNER_SUBCHAN_DEFAULT, AMTUNER_SUBCHAN_DEFAULT); | |
1127 if (FAILED(hr)) { | |
1128 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableToSetChannel, (unsigned int)hr); | |
1129 return E_FAIL; | |
1130 } | |
1131 return S_OK; | |
1132 } | |
1133 | |
1134 /** | |
1135 * \brief setting frequency. decides whether use direct call/workaround | |
1136 * | |
1137 * \param priv driver's private data | |
1138 * \param lFreq frequency in Hz | |
1139 * | |
1140 * \return TVI_CONTROL_TRUE if success | |
1141 * \return TVI_CONTROL_FALSE if error occured | |
1142 * | |
1143 * \todo check for freq boundary | |
1144 */ | |
1145 static int set_frequency(priv_t * priv, long lFreq) | |
1146 { | |
1147 HRESULT hr; | |
1148 | |
27629
d04568721d39
Make output messages of frequency selection code more useful by
voroshil
parents:
27628
diff
changeset
|
1149 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: set_frequency called: %ld\n", lFreq); |
24744 | 1150 if (!priv->pTVTuner) |
1151 return TVI_CONTROL_FALSE; | |
1152 if (priv->direct_setfreq_call) { //using direct call to set frequency | |
1153 hr = set_frequency_direct(priv->pTVTuner, lFreq); | |
1154 if (FAILED(hr)) { | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1155 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: Unable to set frequency directly. OS built-in channels table will be used.\n"); |
24744 | 1156 priv->direct_setfreq_call = 0; |
1157 } | |
1158 } | |
1159 if (!priv->direct_setfreq_call) { | |
1160 hr = set_nearest_freq(priv, lFreq); | |
1161 } | |
1162 if (FAILED(hr)) | |
1163 return TVI_CONTROL_FALSE; | |
1164 #ifdef DEPRECATED | |
1165 priv->pGrabber->ClearBuffer(priv->pGrabber); | |
1166 #endif | |
1167 return TVI_CONTROL_TRUE; | |
1168 } | |
1169 | |
1170 /** | |
1171 * \brief return current frequency from tuner (in Hz) | |
1172 * | |
1173 * \param pTVTuner IAMTVTuner interface of tuner | |
1174 * \param plFreq address of variable that receives current frequency | |
1175 * | |
1176 * \return S_OK success | |
1177 * \return E_POINTER pTVTuner==NULL || plFreq==NULL | |
1178 * \return apropriate error code otherwise | |
1179 */ | |
1180 static HRESULT get_frequency_direct(IAMTVTuner * pTVTuner, long *plFreq) | |
1181 { | |
1182 HRESULT hr; | |
1183 KSPROPERTY_TUNER_STATUS_S TunerStatus; | |
1184 DWORD cbBytes; | |
1185 IKsPropertySet *pKSProp; | |
1186 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: get_frequency_direct called\n"); | |
1187 | |
1188 if (!plFreq) | |
1189 return E_POINTER; | |
1190 | |
1191 hr = OLE_QUERYINTERFACE(pTVTuner, IID_IKsPropertySet, pKSProp); | |
1192 if (FAILED(hr)) { | |
1193 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Get freq QueryInterface failed\n"); | |
1194 return hr; | |
1195 } | |
1196 | |
1197 hr = OLE_CALL_ARGS(pKSProp, Get, &PROPSETID_TUNER, | |
1198 KSPROPERTY_TUNER_STATUS, | |
1199 INSTANCEDATA_OF_PROPERTY_PTR(&TunerStatus), | |
1200 INSTANCEDATA_OF_PROPERTY_SIZE(TunerStatus), | |
1201 &TunerStatus, sizeof(TunerStatus), &cbBytes); | |
1202 if (FAILED(hr)) { | |
1203 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Get freq Get failure\n"); | |
1204 return hr; | |
1205 } | |
1206 *plFreq = TunerStatus.CurrentFrequency; | |
1207 return S_OK; | |
1208 } | |
1209 | |
1210 /** | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1211 * \brief gets current frequency |
24744 | 1212 * |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1213 * \param priv driver's private data structure |
24744 | 1214 * \param plFreq - pointer to long int to store frequency to (in Hz) |
1215 * | |
1216 * \return TVI_CONTROL_TRUE if success, TVI_CONTROL_FALSE otherwise | |
1217 */ | |
1218 static int get_frequency(priv_t * priv, long *plFreq) | |
1219 { | |
1220 HRESULT hr; | |
1221 | |
1222 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: get_frequency called\n"); | |
1223 | |
1224 if (!plFreq || !priv->pTVTuner) | |
1225 return TVI_CONTROL_FALSE; | |
1226 | |
1227 if (priv->direct_getfreq_call) { //using direct call to get frequency | |
1228 hr = get_frequency_direct(priv->pTVTuner, plFreq); | |
1229 if (FAILED(hr)) { | |
1230 mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_DirectGetFreqFailed); | |
1231 priv->direct_getfreq_call = 0; | |
1232 } | |
1233 } | |
1234 if (!priv->direct_getfreq_call) { | |
1235 hr=OLE_CALL_ARGS(priv->pTVTuner, get_VideoFrequency, plFreq); | |
1236 if (FAILED(hr)) | |
1237 return TVI_CONTROL_FALSE; | |
1238 | |
1239 } | |
1240 return TVI_CONTROL_TRUE; | |
1241 } | |
1242 | |
1243 /** | |
1244 * \brief get tuner capabilities | |
1245 * | |
1246 * \param priv driver's private data | |
1247 */ | |
1248 static void get_capabilities(priv_t * priv) | |
1249 { | |
1250 long lAvailableFormats; | |
1251 HRESULT hr; | |
1252 int i; | |
1253 long lInputPins, lOutputPins, lRelated, lPhysicalType; | |
1254 IEnumPins *pEnum; | |
1255 char tmp[200]; | |
1256 IPin *pPin = 0; | |
1257 PIN_DIRECTION ThisPinDir; | |
1258 PIN_INFO pi; | |
1259 IAMAudioInputMixer *pIAMixer; | |
1260 | |
1261 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: get_capabilities called\n"); | |
1262 if (priv->pTVTuner) { | |
1263 | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1264 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: supported norms:"); |
24744 | 1265 hr = OLE_CALL_ARGS(priv->pTVTuner, get_AvailableTVFormats, |
1266 &lAvailableFormats); | |
1267 if (FAILED(hr)) | |
1268 tv_available_norms_count = 0; | |
1269 else { | |
1270 for (i = 0; i < TV_NORMS_COUNT; i++) { | |
1271 if (lAvailableFormats & tv_norms[i].index) { | |
1272 tv_available_norms[tv_available_norms_count] = i; | |
1273 mp_msg(MSGT_TV, MSGL_V, " %d=%s;", | |
1274 tv_available_norms_count + 1, tv_norms[i].name); | |
1275 tv_available_norms_count++; | |
1276 } | |
1277 } | |
1278 } | |
1279 mp_msg(MSGT_TV, MSGL_INFO, "\n"); | |
1280 } | |
1281 if (priv->pCrossbar) { | |
1282 OLE_CALL_ARGS(priv->pCrossbar, get_PinCounts, &lOutputPins, | |
1283 &lInputPins); | |
1284 | |
30702 | 1285 tv_available_inputs = malloc(sizeof(long) * lInputPins); |
24744 | 1286 tv_available_inputs_count = 0; |
1287 | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1288 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: available video inputs:"); |
24744 | 1289 for (i = 0; i < lInputPins; i++) { |
1290 OLE_CALL_ARGS(priv->pCrossbar, get_CrossbarPinInfo, 1, i, | |
1291 &lRelated, &lPhysicalType); | |
1292 | |
1293 if (lPhysicalType < 0x1000) { | |
1294 tv_available_inputs[tv_available_inputs_count++] = i; | |
1295 mp_msg(MSGT_TV, MSGL_V, " %d=%s;", | |
1296 tv_available_inputs_count - 1, | |
1297 physcon2str(lPhysicalType)); | |
1298 } | |
1299 } | |
1300 mp_msg(MSGT_TV, MSGL_INFO, "\n"); | |
1301 | |
1302 set_crossbar_input(priv, 0); | |
1303 } | |
1304 | |
1305 if (priv->adev_index != -1) { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
1306 hr = OLE_CALL_ARGS(priv->chains[1]->pCaptureFilter, EnumPins, &pEnum); |
24744 | 1307 if (FAILED(hr)) |
1308 return; | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1309 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: available audio inputs:"); |
24744 | 1310 i = 0; |
1311 while (OLE_CALL_ARGS(pEnum, Next, 1, &pPin, NULL) == S_OK) { | |
1312 memset(&pi, 0, sizeof(pi)); | |
1313 memset(tmp, 0, 200); | |
1314 OLE_CALL_ARGS(pPin, QueryDirection, &ThisPinDir); | |
1315 if (ThisPinDir == PINDIR_INPUT) { | |
1316 OLE_CALL_ARGS(pPin, QueryPinInfo, &pi); | |
1317 wtoa(pi.achName, tmp, 200); | |
1318 OLE_RELEASE_SAFE(pi.pFilter); | |
1319 mp_msg(MSGT_TV, MSGL_V, " %d=%s", i, tmp); | |
1320 mp_msg(MSGT_TV, MSGL_DBG3, " (%p)", pPin); | |
1321 hr = OLE_QUERYINTERFACE(pPin, IID_IAMAudioInputMixer,pIAMixer); | |
1322 if (SUCCEEDED(hr)) { | |
1323 if (i == priv->tv_param->audio_id) { | |
1324 OLE_CALL_ARGS(pIAMixer, put_Enable, TRUE); | |
1325 if(priv->tv_param->volume>0) | |
1326 OLE_CALL_ARGS(pIAMixer, put_MixLevel, 0.01 * priv->tv_param->volume); | |
1327 #if 0 | |
1328 else | |
1329 OLE_CALL_ARGS(pIAMixer, put_MixLevel, 1.0); | |
1330 #endif | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
1331 mp_msg(MSGT_TV, MSGL_V, "(selected)"); |
24744 | 1332 } else { |
1333 OLE_CALL_ARGS(pIAMixer, put_Enable, FALSE); | |
1334 #if 0 | |
1335 OLE_CALL_ARGS(pIAMixer, put_MixLevel, 0.0); | |
1336 #endif | |
1337 } | |
1338 OLE_RELEASE_SAFE(pIAMixer); | |
1339 } | |
1340 mp_msg(MSGT_TV, MSGL_V, ";"); | |
1341 OLE_RELEASE_SAFE(pPin); | |
1342 i++; | |
1343 } | |
1344 } | |
1345 mp_msg(MSGT_TV, MSGL_INFO, "\n"); | |
1346 OLE_RELEASE_SAFE(pEnum); | |
1347 } | |
1348 } | |
1349 | |
1350 /* | |
1351 *--------------------------------------------------------------------------------------- | |
1352 * | |
1353 * Filter related methods | |
1354 * | |
1355 *--------------------------------------------------------------------------------------- | |
1356 */ | |
1357 /** | |
1358 * \brief building in graph audio/video capture chain | |
1359 * | |
1360 * \param priv driver's private data | |
1361 * \param pCaptureFilter pointer to capture device's IBaseFilter interface | |
1362 * \param pbuf ringbuffer data structure | |
1363 * \param pmt media type for chain (AM_MEDIA_TYPE) | |
1364 * | |
1365 * \note routine does not frees memory, allocated for grabber_rinbuffer_s structure | |
1366 */ | |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1367 static HRESULT build_sub_graph(priv_t * priv, chain_t * chain, const GUID* ppin_category) |
24744 | 1368 { |
1369 HRESULT hr; | |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1370 int nFormatProbed = 0; |
25029
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1371 |
24744 | 1372 IPin *pSGOut; |
1373 IPin *pNRIn=NULL; | |
1374 | |
1375 IBaseFilter *pNR = NULL; | |
1376 | |
1377 hr=S_OK; | |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1378 |
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1379 //No supported formats |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1380 if(!chain->arpmt[0]) |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1381 return E_FAIL; |
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1382 |
24744 | 1383 do{ |
1384 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, | |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1385 (IUnknown *) chain->pCaptureFilter, |
24744 | 1386 PINDIR_OUTPUT, ppin_category, |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1387 chain->majortype, FALSE, 0, &chain->pCapturePin); |
24744 | 1388 if(FAILED(hr)){ |
1389 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: FindPin(pCapturePin) call failed. Error:0x%x\n", (unsigned int)hr); | |
1390 break; | |
1391 } | |
1392 /* Addinf SampleGrabber filter for video stream */ | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1393 hr = CoCreateInstance((GUID *) & CLSID_SampleGrabber, NULL,CLSCTX_INPROC_SERVER, &IID_IBaseFilter,(void *) &chain->pSGF); |
24744 | 1394 if(FAILED(hr)){ |
1395 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: CoCreateInstance(SampleGrabber) call failed. Error:0x%x\n", (unsigned int)hr); | |
1396 break; | |
1397 } | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1398 hr = OLE_CALL_ARGS(priv->pGraph, AddFilter, chain->pSGF, L"Sample Grabber"); |
24744 | 1399 if(FAILED(hr)){ |
1400 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: AddFilter(SampleGrabber) call failed. Error:0x%x\n", (unsigned int)hr); | |
1401 break; | |
1402 } | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1403 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, (IUnknown *) chain->pSGF,PINDIR_INPUT, NULL, NULL, FALSE, 0, &chain->pSGIn); |
24744 | 1404 if(FAILED(hr)){ |
1405 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: FindPin(pSGIn) call failed. Error:0x%x\n", (unsigned int)hr); | |
1406 break; | |
1407 } | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1408 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, (IUnknown *) chain->pSGF,PINDIR_OUTPUT, NULL, NULL, FALSE, 0, &pSGOut); |
24744 | 1409 if(FAILED(hr)){ |
1410 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: FindPin(pSGOut) call failed. Error:0x%x\n", (unsigned int)hr); | |
1411 break; | |
1412 } | |
1413 | |
1414 /* creating ringbuffer for video samples */ | |
25086
e91503fbf524
Move pointer to SampleGrabber filter into chain structure.
voroshil
parents:
25085
diff
changeset
|
1415 chain->pCSGCB = CSampleGrabberCB_Create(chain->rbuf); |
e91503fbf524
Move pointer to SampleGrabber filter into chain structure.
voroshil
parents:
25085
diff
changeset
|
1416 if(!chain->pCSGCB){ |
24744 | 1417 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: CSampleGrabberCB_Create(pbuf) call failed. Error:0x%x\n", (unsigned int)E_OUTOFMEMORY); |
1418 break; | |
1419 } | |
1420 | |
1421 /* initializing SampleGrabber filter */ | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1422 hr = OLE_QUERYINTERFACE(chain->pSGF, IID_ISampleGrabber, chain->pSG); |
24744 | 1423 if(FAILED(hr)){ |
1424 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: QueryInterface(IID_ISampleGrabber) call failed. Error:0x%x\n", (unsigned int)hr); | |
1425 break; | |
1426 } | |
1427 // hr = OLE_CALL_ARGS(pSG, SetCallback, (ISampleGrabberCB *) pCSGCB, 1); //we want to receive copy of sample's data | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1428 hr = OLE_CALL_ARGS(chain->pSG, SetCallback, (ISampleGrabberCB *) chain->pCSGCB, 0); //we want to receive sample |
24744 | 1429 |
1430 if(FAILED(hr)){ | |
1431 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetCallback(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | |
1432 break; | |
1433 } | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1434 hr = OLE_CALL_ARGS(chain->pSG, SetOneShot, FALSE); //... for all frames |
24744 | 1435 if(FAILED(hr)){ |
1436 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetOneShot(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | |
1437 break; | |
1438 } | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1439 hr = OLE_CALL_ARGS(chain->pSG, SetBufferSamples, FALSE); //... do not buffer samples in sample grabber |
24744 | 1440 if(FAILED(hr)){ |
1441 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetBufferSamples(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | |
1442 break; | |
1443 } | |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1444 |
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1445 if(priv->tv_param->normalize_audio_chunks && chain->type==audio){ |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1446 set_buffer_preference(20,(WAVEFORMATEX*)(chain->arpmt[nFormatProbed]->pbFormat),chain->pCapturePin,chain->pSGIn); |
25048 | 1447 } |
24744 | 1448 |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1449 for(nFormatProbed=0; chain->arpmt[nFormatProbed]; nFormatProbed++) |
25065 | 1450 { |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1451 DisplayMediaType("Probing format", chain->arpmt[nFormatProbed]); |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1452 hr = OLE_CALL_ARGS(chain->pSG, SetMediaType, chain->arpmt[nFormatProbed]); //set desired mediatype |
25066 | 1453 if(FAILED(hr)){ |
1454 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: SetMediaType(pSG) call failed. Error:0x%x\n", (unsigned int)hr); | |
1455 continue; | |
1456 } | |
1457 /* connecting filters together: VideoCapture --> SampleGrabber */ | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1458 hr = OLE_CALL_ARGS(priv->pGraph, Connect, chain->pCapturePin, chain->pSGIn); |
25066 | 1459 if(FAILED(hr)){ |
1460 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pCapturePin<->pSGIn connection. Error:0x%x\n", (unsigned int)hr); | |
1461 continue; | |
1462 } | |
25065 | 1463 break; |
1464 } | |
1465 | |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
1466 if(!chain->arpmt[nFormatProbed]) |
25065 | 1467 { |
1468 mp_msg(MSGT_TV, MSGL_WARN, "tvi_dshow: Unable to negotiate media format\n"); | |
1469 hr = E_FAIL; | |
24744 | 1470 break; |
1471 } | |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1472 |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1473 hr = OLE_CALL_ARGS(chain->pCapturePin, ConnectionMediaType, chain->pmt); |
25029
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1474 if(FAILED(hr)) |
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1475 { |
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1476 mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_GetActualMediatypeFailed, (unsigned int)hr); |
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1477 } |
24744 | 1478 |
1479 if(priv->tv_param->hidden_video_renderer){ | |
1480 IEnumFilters* pEnum; | |
1481 IBaseFilter* pFilter; | |
1482 | |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
1483 hr=OLE_CALL_ARGS(priv->pBuilder,RenderStream,NULL,NULL,(IUnknown*)chain->pCapturePin,NULL,NULL); |
24744 | 1484 |
1485 OLE_CALL_ARGS(priv->pGraph, EnumFilters, &pEnum); | |
1486 while (OLE_CALL_ARGS(pEnum, Next, 1, &pFilter, NULL) == S_OK) { | |
1487 LPVIDEOWINDOW pVideoWindow; | |
1488 hr = OLE_QUERYINTERFACE(pFilter, IID_IVideoWindow, pVideoWindow); | |
1489 if (SUCCEEDED(hr)) | |
1490 { | |
1491 OLE_CALL_ARGS(pVideoWindow,put_Visible,/* OAFALSE*/ 0); | |
1492 OLE_CALL_ARGS(pVideoWindow,put_AutoShow,/* OAFALSE*/ 0); | |
1493 OLE_RELEASE_SAFE(pVideoWindow); | |
1494 } | |
1495 OLE_RELEASE_SAFE(pFilter); | |
1496 } | |
1497 OLE_RELEASE_SAFE(pEnum); | |
1498 }else | |
1499 { | |
25052
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1500 #if 0 |
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1501 /* |
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1502 Code below is disabled, because terminating chain with NullRenderer leads to jerky video. |
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1503 Perhaps, this happens because NullRenderer filter discards each received |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1504 frame while discarded frames causes live source filter to dramatically reduce frame rate. |
25052
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1505 */ |
24744 | 1506 /* adding sink for video stream */ |
1507 hr = CoCreateInstance((GUID *) & CLSID_NullRenderer, NULL,CLSCTX_INPROC_SERVER, &IID_IBaseFilter,(void *) &pNR); | |
1508 if(FAILED(hr)){ | |
1509 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: CoCreateInstance(NullRenderer) call failed. Error:0x%x\n", (unsigned int)hr); | |
1510 break; | |
1511 } | |
1512 hr = OLE_CALL_ARGS(priv->pGraph, AddFilter, pNR, L"Null Renderer"); | |
1513 if(FAILED(hr)){ | |
1514 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: AddFilter(NullRenderer) call failed. Error:0x%x\n", (unsigned int)hr); | |
1515 break; | |
1516 } | |
1517 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, (IUnknown *) pNR,PINDIR_INPUT, NULL, NULL, FALSE, 0, &pNRIn); | |
1518 if(FAILED(hr)){ | |
1519 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: FindPin(pNRIn) call failed. Error:0x%x\n", (unsigned int)hr); | |
1520 break; | |
1521 } | |
1522 /* | |
1523 Prevent ending VBI chain with NullRenderer filter, because this causes VBI pin disconnection | |
1524 */ | |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
1525 if(memcmp(&(arpmt[nFormatProbed]->majortype),&MEDIATYPE_VBI,16)){ |
24744 | 1526 /* connecting filters together: SampleGrabber --> NullRenderer */ |
1527 hr = OLE_CALL_ARGS(priv->pGraph, Connect, pSGOut, pNRIn); | |
1528 if(FAILED(hr)){ | |
1529 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Unable to create pSGOut<->pNRIn connection. Error:0x%x\n", (unsigned int)hr); | |
1530 break; | |
1531 } | |
1532 } | |
25052
7b2b17b57cf7
Disable terminating directshow chains with NullRenderer filter,
voroshil
parents:
25051
diff
changeset
|
1533 #endif |
24744 | 1534 } |
1535 | |
1536 hr = S_OK; | |
1537 } while(0); | |
25029
c9f20e41bc13
Make sure that mplayer will receive actual media type
voroshil
parents:
25028
diff
changeset
|
1538 |
24744 | 1539 OLE_RELEASE_SAFE(pSGOut); |
1540 OLE_RELEASE_SAFE(pNR); | |
1541 OLE_RELEASE_SAFE(pNRIn); | |
1542 | |
1543 return hr; | |
1544 } | |
1545 | |
1546 /** | |
1547 * \brief configures crossbar for grabbing video stream from given input | |
1548 * | |
1549 * \param priv driver's private data | |
1550 * \param input index of available video input to get data from | |
1551 * | |
1552 * \return TVI_CONTROL_TRUE success | |
1553 * \return TVI_CONTROL_FALSE error | |
1554 */ | |
1555 static int set_crossbar_input(priv_t * priv, int input) | |
1556 { | |
1557 HRESULT hr; | |
1558 int i, nVideoDecoder, nAudioDecoder; | |
1559 long lInput, lInputRelated, lRelated, lPhysicalType, lOutputPins, | |
1560 lInputPins; | |
1561 | |
1562 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: Configuring crossbar\n"); | |
1563 if (!priv->pCrossbar || input < 0 | |
1564 || input >= tv_available_inputs_count) | |
1565 return TVI_CONTROL_FALSE; | |
1566 | |
1567 OLE_CALL_ARGS(priv->pCrossbar, get_PinCounts, &lOutputPins, &lInputPins); | |
1568 | |
1569 lInput = tv_available_inputs[input]; | |
1570 | |
1571 if (lInput < 0 || lInput >= lInputPins) | |
1572 return TVI_CONTROL_FALSE; | |
1573 | |
1574 OLE_CALL_ARGS(priv->pCrossbar, get_CrossbarPinInfo, 1 /* input */ , lInput, | |
1575 &lInputRelated, &lPhysicalType); | |
1576 | |
1577 nVideoDecoder = nAudioDecoder = -1; | |
1578 for (i = 0; i < lOutputPins; i++) { | |
1579 OLE_CALL_ARGS(priv->pCrossbar, get_CrossbarPinInfo, 0 /*output */ , i, | |
1580 &lRelated, &lPhysicalType); | |
1581 if (lPhysicalType == PhysConn_Video_VideoDecoder) | |
1582 nVideoDecoder = i; | |
1583 if (lPhysicalType == PhysConn_Audio_AudioDecoder) | |
1584 nAudioDecoder = i; | |
1585 } | |
1586 if (nVideoDecoder >= 0) { | |
1587 //connecting given input with video decoder | |
1588 hr = OLE_CALL_ARGS(priv->pCrossbar, Route, nVideoDecoder, lInput); | |
1589 if (hr != S_OK) { | |
1590 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableConnectInputVideoDecoder, (unsigned int)hr); | |
1591 return TVI_CONTROL_FALSE; | |
1592 } | |
1593 } | |
1594 if (nAudioDecoder >= 0 && lInputRelated >= 0) { | |
1595 hr = OLE_CALL_ARGS(priv->pCrossbar, Route, nAudioDecoder, | |
1596 lInputRelated); | |
1597 if (hr != S_OK) { | |
1598 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableConnectInputAudioDecoder, (unsigned int)hr); | |
1599 return TVI_CONTROL_FALSE; | |
1600 } | |
1601 } | |
1602 return TVI_CONTROL_TRUE; | |
1603 } | |
1604 | |
1605 /** | |
1606 * \brief adjusts video control (hue,saturation,contrast,brightess) | |
1607 * | |
1608 * \param priv driver's private data | |
1609 * \param control which control to adjust | |
1610 * \param value new value for control (0-100) | |
1611 * | |
1612 * \return TVI_CONTROL_TRUE success | |
1613 * \return TVI_CONTROL_FALSE error | |
1614 */ | |
1615 static int set_control(priv_t * priv, int control, int value) | |
1616 { | |
1617 long lMin, lMax, lStepping, lDefault, lFlags, lValue; | |
1618 HRESULT hr; | |
1619 | |
1620 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: set_control called\n"); | |
1621 if (value < -100 || value > 100 || !priv->pVideoProcAmp) | |
1622 return TVI_CONTROL_FALSE; | |
1623 | |
1624 hr = OLE_CALL_ARGS(priv->pVideoProcAmp, GetRange, control, | |
1625 &lMin, &lMax, &lStepping, &lDefault, &lFlags); | |
1626 if (FAILED(hr) || lFlags != VideoProcAmp_Flags_Manual) | |
1627 return TVI_CONTROL_FALSE; | |
1628 | |
1629 lValue = lMin + (value + 100) * (lMax - lMin) / 200; | |
1630 /* | |
1631 Workaround for ATI AIW 7500. The driver reports: max=255, stepping=256 | |
1632 */ | |
1633 if (lStepping > lMax) { | |
1634 mp_msg(MSGT_TV, MSGL_DBG3, | |
1635 "tvi_dshow: Stepping (%ld) is bigger than max value (%ld) for control %d. Assuming 1\n", | |
1636 lStepping, lMax,control); | |
1637 lStepping = 1; | |
1638 } | |
1639 lValue -= lValue % lStepping; | |
1640 hr = OLE_CALL_ARGS(priv->pVideoProcAmp, Set, control, lValue, | |
1641 VideoProcAmp_Flags_Manual); | |
1642 if (FAILED(hr)) | |
1643 return TVI_CONTROL_FALSE; | |
1644 | |
1645 return TVI_CONTROL_TRUE; | |
1646 } | |
1647 | |
1648 /** | |
1649 * \brief get current value of video control (hue,saturation,contrast,brightess) | |
1650 * | |
1651 * \param priv driver's private data | |
1652 * \param control which control to adjust | |
1653 * \param pvalue address of variable thar receives current value | |
1654 * | |
1655 * \return TVI_CONTROL_TRUE success | |
1656 * \return TVI_CONTROL_FALSE error | |
1657 */ | |
1658 static int get_control(priv_t * priv, int control, int *pvalue) | |
1659 { | |
1660 long lMin, lMax, lStepping, lDefault, lFlags, lValue; | |
1661 HRESULT hr; | |
1662 | |
1663 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: get_control called\n"); | |
1664 if (!pvalue || !priv->pVideoProcAmp) | |
1665 return TVI_CONTROL_FALSE; | |
1666 | |
1667 hr = OLE_CALL_ARGS(priv->pVideoProcAmp, GetRange, control, | |
1668 &lMin, &lMax, &lStepping, &lDefault, &lFlags); | |
1669 if (FAILED(hr)) | |
1670 return TVI_CONTROL_FALSE; | |
1671 if (lMin == lMax) { | |
1672 *pvalue = lMin; | |
1673 return TVI_CONTROL_TRUE; | |
1674 } | |
1675 | |
1676 hr = OLE_CALL_ARGS(priv->pVideoProcAmp, Get, control, &lValue, &lFlags); | |
1677 if (FAILED(hr)) | |
1678 return TVI_CONTROL_FALSE; | |
1679 | |
1680 *pvalue = 200 * (lValue - lMin) / (lMax - lMin) - 100; | |
1681 | |
1682 return TVI_CONTROL_TRUE; | |
1683 } | |
1684 | |
1685 /** | |
25053
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1686 * \brief create AM_MEDIA_TYPE structure, corresponding to given FourCC code and width/height/fps |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1687 * \param fcc FourCC code for video format |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1688 * \param width picture width |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1689 * \param height pciture height |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1690 * \param fps frames per second (required for bitrate calculation) |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1691 * |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1692 * \return pointer to AM_MEDIA_TYPE structure if success, NULL - otherwise |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1693 */ |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1694 static AM_MEDIA_TYPE* create_video_format(int fcc, int width, int height, int fps) |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1695 { |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1696 int i; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1697 AM_MEDIA_TYPE mt; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1698 VIDEOINFOHEADER vHdr; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1699 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1700 /* Check given fcc in lookup table*/ |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1701 for(i=0; img_fmt_list[i].fmt && img_fmt_list[i].fmt!=fcc; i++) /* NOTHING */; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1702 if(!img_fmt_list[i].fmt) |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1703 return NULL; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1704 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1705 memset(&mt, 0, sizeof(AM_MEDIA_TYPE)); |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1706 memset(&vHdr, 0, sizeof(VIDEOINFOHEADER)); |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1707 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1708 vHdr.bmiHeader.biSize = sizeof(vHdr.bmiHeader); |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1709 vHdr.bmiHeader.biWidth = width; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1710 vHdr.bmiHeader.biHeight = height; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1711 //FIXME: is biPlanes required too? |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1712 //vHdr.bmiHeader.biPlanes = img_fmt_list[i].nPlanes; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1713 vHdr.bmiHeader.biBitCount = img_fmt_list[i].nBits; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1714 vHdr.bmiHeader.biCompression = img_fmt_list[i].nCompression; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1715 vHdr.bmiHeader.biSizeImage = width * height * img_fmt_list[i].nBits / 8; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1716 vHdr.dwBitRate = vHdr.bmiHeader.biSizeImage * 8 * fps; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1717 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1718 mt.pbFormat = (char*)&vHdr; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1719 mt.cbFormat = sizeof(vHdr); |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1720 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1721 mt.majortype = MEDIATYPE_Video; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1722 mt.subtype = *img_fmt_list[i].subtype; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1723 mt.formattype = FORMAT_VideoInfo; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1724 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1725 mt.bFixedSizeSamples = 1; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1726 mt.bTemporalCompression = 0; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1727 mt.lSampleSize = vHdr.bmiHeader.biSizeImage; |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1728 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1729 return CreateMediaType(&mt); |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1730 } |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1731 |
086c2accaaa2
Service routine for constructing AM_MEDIA_TYPE structure from
voroshil
parents:
25052
diff
changeset
|
1732 /** |
24744 | 1733 * \brief extracts fcc,width,height from AM_MEDIA_TYPE |
1734 * | |
1735 * \param pmt pointer to AM_MEDIA_TYPE to extract data from | |
1736 * \param pfcc address of variable that receives FourCC | |
1737 * \param pwidth address of variable that receives width | |
1738 * \param pheight address of variable that recevies height | |
1739 * | |
1740 * \return 1 if data extracted successfully, 0 - otherwise | |
1741 */ | |
1742 static int extract_video_format(AM_MEDIA_TYPE * pmt, int *pfcc, | |
1743 int *pwidth, int *pheight) | |
1744 { | |
1745 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: extract_video_format called\n"); | |
1746 if (!pmt) | |
1747 return 0; | |
1748 if (!pmt->pbFormat) | |
1749 return 0; | |
1750 if (memcmp(&(pmt->formattype), &FORMAT_VideoInfo, 16) != 0) | |
1751 return 0; | |
1752 if (pfcc) | |
1753 *pfcc = subtype2imgfmt(&(pmt->subtype)); | |
1754 if (pwidth) | |
1755 *pwidth = ((VIDEOINFOHEADER *) pmt->pbFormat)->bmiHeader.biWidth; | |
1756 if (pheight) | |
1757 *pheight = ((VIDEOINFOHEADER *) pmt->pbFormat)->bmiHeader.biHeight; | |
1758 return 1; | |
1759 } | |
1760 | |
1761 /** | |
1762 * \brief extracts samplerate,bits,channels from AM_MEDIA_TYPE | |
1763 * | |
1764 * \param pmt pointer to AM_MEDIA_TYPE to extract data from | |
1765 * \param pfcc address of variable that receives samplerate | |
1766 * \param pwidth address of variable that receives number of bits per sample | |
1767 * \param pheight address of variable that recevies number of channels | |
1768 * | |
1769 * \return 1 if data extracted successfully, 0 - otherwise | |
1770 */ | |
1771 static int extract_audio_format(AM_MEDIA_TYPE * pmt, int *psamplerate, | |
1772 int *pbits, int *pchannels) | |
1773 { | |
1774 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: extract_audio_format called\n"); | |
1775 if (!pmt) | |
1776 return 0; | |
1777 if (!pmt->pbFormat) | |
1778 return 0; | |
1779 if (memcmp(&(pmt->formattype), &FORMAT_WaveFormatEx, 16) != 0) | |
1780 return 0; | |
1781 if (psamplerate) | |
1782 *psamplerate = ((WAVEFORMATEX *) pmt->pbFormat)->nSamplesPerSec; | |
1783 if (pbits) | |
1784 *pbits = ((WAVEFORMATEX *) pmt->pbFormat)->wBitsPerSample; | |
1785 if (pchannels) | |
1786 *pchannels = ((WAVEFORMATEX *) pmt->pbFormat)->nChannels; | |
1787 return 1; | |
1788 } | |
1789 | |
1790 /** | |
1791 * \brief checks if AM_MEDIA_TYPE compatible with given samplerate,bits,channels | |
1792 * | |
1793 * \param pmt pointer to AM_MEDIA_TYPE for check | |
1794 * \param samplerate audio samplerate | |
1795 * \param bits bits per sample | |
1796 * \param channels number of audio channels | |
1797 * | |
1798 * \return 1 if AM_MEDIA_TYPE compatible | |
1799 * \return 0 if not | |
1800 */ | |
1801 static int check_audio_format(AM_MEDIA_TYPE * pmt, int samplerate, | |
1802 int bits, int channels) | |
1803 { | |
1804 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: check_audio_format called\n"); | |
1805 if (!pmt) | |
1806 return 0; | |
1807 if (memcmp(&(pmt->majortype), &MEDIATYPE_Audio, 16) != 0) | |
1808 return 0; | |
1809 if (memcmp(&(pmt->subtype), &MEDIASUBTYPE_PCM, 16) != 0) | |
1810 return 0; | |
1811 if (memcmp(&(pmt->formattype), &FORMAT_WaveFormatEx, 16) != 0) | |
1812 return 0; | |
1813 if (!pmt->pbFormat) | |
1814 return 0; | |
1815 if (((WAVEFORMATEX *) pmt->pbFormat)->nSamplesPerSec != samplerate) | |
1816 return 0; | |
1817 if (((WAVEFORMATEX *) pmt->pbFormat)->wBitsPerSample != bits) | |
1818 return 0; | |
1819 if (channels > 0 | |
1820 && ((WAVEFORMATEX *) pmt->pbFormat)->nChannels != channels) | |
1821 return 0; | |
1822 | |
1823 return 1; | |
1824 } | |
1825 | |
1826 /** | |
1827 * \brief checks if AM_MEDIA_TYPE compatible with given fcc,width,height | |
1828 * | |
1829 * \param pmt pointer to AM_MEDIA_TYPE for check | |
1830 * \param fcc FourCC (compression) | |
1831 * \param width width of picture | |
1832 * \param height height of picture | |
1833 * | |
1834 * \return 1 if AM_MEDIA_TYPE compatible | |
1835 & \return 0 if not | |
1836 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1837 * \note |
24744 | 1838 * width and height are currently not used |
1839 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1840 * \todo |
24744 | 1841 * add width/height check |
1842 */ | |
1843 static int check_video_format(AM_MEDIA_TYPE * pmt, int fcc, int width, | |
1844 int height) | |
1845 { | |
1846 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: check_video_format called\n"); | |
1847 if (!pmt) | |
1848 return 0; | |
1849 if (memcmp(&(pmt->majortype), &MEDIATYPE_Video, 16) != 0) | |
1850 return 0; | |
1851 if (subtype2imgfmt(&(pmt->subtype)) != fcc) | |
1852 return 0; | |
1853 return 1; | |
1854 } | |
1855 | |
1856 /** | |
1857 * \brief converts DirectShow subtype to MPlayer's IMGFMT | |
1858 * | |
1859 * \param subtype DirectShow subtype for video format | |
1860 * | |
1861 * \return MPlayer's IMGFMT or 0 if error occured | |
1862 */ | |
1863 static int subtype2imgfmt(const GUID * subtype) | |
1864 { | |
1865 int i; | |
1866 for (i = 0; img_fmt_list[i].fmt; i++) { | |
1867 if (memcmp(subtype, img_fmt_list[i].subtype, 16) == 0) | |
1868 return img_fmt_list[i].fmt; | |
1869 } | |
1870 return 0; | |
1871 } | |
1872 | |
1873 /** | |
1874 * \brief prints filter name and it pins | |
1875 * | |
1876 * \param pFilter - IBaseFilter to get data from | |
1877 * | |
1878 * \return S_OK if success, error code otherwise | |
1879 */ | |
1880 static HRESULT show_filter_info(IBaseFilter * pFilter) | |
1881 { | |
1882 char tmp[200]; | |
1883 FILTER_INFO fi; | |
1884 LPENUMPINS pEnum = 0; | |
1885 IPin *pPin = 0; | |
1886 PIN_DIRECTION ThisPinDir; | |
1887 PIN_INFO pi; | |
1888 HRESULT hr; | |
1889 int i; | |
1890 | |
1891 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: show_filter_info called\n"); | |
1892 memset(&fi, 0, sizeof(fi)); | |
1893 memset(tmp, 0, 200); | |
1894 | |
1895 OLE_CALL_ARGS(pFilter, QueryFilterInfo, &fi); | |
1896 OLE_RELEASE_SAFE(fi.pGraph); | |
1897 wtoa(fi.achName, tmp, 200); | |
1898 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: BaseFilter (%p): Name=%s, Graph=%p output pins:", | |
1899 pFilter, tmp, fi.pGraph); | |
1900 hr = OLE_CALL_ARGS(pFilter, EnumPins, &pEnum); | |
1901 if (FAILED(hr)) | |
1902 return hr; | |
1903 i = 0; | |
1904 while (OLE_CALL_ARGS(pEnum, Next, 1, &pPin, NULL) == S_OK) { | |
1905 memset(&pi, 0, sizeof(pi)); | |
1906 memset(tmp, 0, 200); | |
1907 OLE_CALL_ARGS(pPin, QueryDirection, &ThisPinDir); | |
1908 if (ThisPinDir == PINDIR_OUTPUT) { | |
1909 OLE_CALL_ARGS(pPin, QueryPinInfo, &pi); | |
1910 wtoa(pi.achName, tmp, 200); | |
1911 OLE_RELEASE_SAFE(pi.pFilter); | |
1912 mp_msg(MSGT_TV, MSGL_DBG2, " %d=%s", i, tmp); | |
1913 mp_msg(MSGT_TV, MSGL_DBG3, " (%p)", pPin); | |
1914 mp_msg(MSGT_TV, MSGL_DBG2, ";"); | |
1915 OLE_RELEASE_SAFE(pPin); | |
1916 i++; | |
1917 } | |
1918 } | |
1919 mp_msg(MSGT_TV, MSGL_DBG2, "\n"); | |
1920 OLE_RELEASE_SAFE(pEnum); | |
1921 return S_OK; | |
1922 } | |
1923 | |
1924 /** | |
1925 * \brief gets device's frendly in ANSI encoding | |
1926 * | |
1927 * \param pM IMoniker interface, got in enumeration process | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1928 * \param category device category |
24744 | 1929 * |
1930 * \return TVI_CONTROL_TRUE if operation succeded, TVI_CONTROL_FALSE - otherwise | |
1931 */ | |
1932 static int get_device_name(IMoniker * pM, char *pBuf, int nLen) | |
1933 { | |
1934 HRESULT hr; | |
1935 VARIANT var; | |
1936 IPropertyBag *pPropBag; | |
1937 hr = OLE_CALL_ARGS(pM, BindToStorage, 0, 0, &IID_IPropertyBag,(void *) &pPropBag); | |
1938 if (FAILED(hr)) { | |
1939 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Call to BindToStorage failed\n"); | |
1940 return TVI_CONTROL_FALSE; | |
1941 } | |
1942 var.vt = VT_BSTR; | |
1943 hr = OLE_CALL_ARGS(pPropBag, Read, L"Description", (LPVARIANT) & var, | |
1944 NULL); | |
1945 if (FAILED(hr)) { | |
1946 hr = OLE_CALL_ARGS(pPropBag, Read, L"FriendlyName", (LPVARIANT) & var, | |
1947 NULL); | |
1948 } | |
1949 OLE_RELEASE_SAFE(pPropBag); | |
1950 if (SUCCEEDED(hr)) { | |
1951 wtoa(var.bstrVal, pBuf, nLen); | |
1952 return TVI_CONTROL_TRUE; | |
1953 } | |
1954 return TVI_CONTROL_FALSE; | |
1955 } | |
1956 | |
1957 /** | |
1958 * \brief find capture device at given index | |
1959 * | |
1960 * \param index device index to search for (-1 mean only print available) | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1961 * \param category device category |
24744 | 1962 * |
1963 * \return IBaseFilter interface for capture device with given index | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
1964 * |
24744 | 1965 * Sample values for category: |
1966 * CLSID_VideoInputDeviceCategory - Video Capture Sources | |
1967 * CLSID_AudioInputDeviceCategory - Audio Capture Sources | |
1968 * See DirectShow SDK documentation for other possible values | |
1969 */ | |
1970 static IBaseFilter *find_capture_device(int index, REFCLSID category) | |
1971 { | |
1972 IBaseFilter *pFilter = NULL; | |
1973 ICreateDevEnum *pDevEnum = NULL; | |
1974 IEnumMoniker *pClassEnum = NULL; | |
1975 IMoniker *pM; | |
1976 HRESULT hr; | |
1977 ULONG cFetched; | |
1978 int i; | |
1979 char tmp[DEVICE_NAME_MAX_LEN + 1]; | |
1980 hr = CoCreateInstance((GUID *) & CLSID_SystemDeviceEnum, NULL, | |
1981 CLSCTX_INPROC_SERVER, &IID_ICreateDevEnum, | |
1982 (void *) &pDevEnum); | |
1983 if (FAILED(hr)) { | |
1984 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Unable to create device enumerator\n"); | |
1985 return NULL; | |
1986 } | |
1987 | |
1988 hr = OLE_CALL_ARGS(pDevEnum, CreateClassEnumerator, category, &pClassEnum, 0); | |
1989 OLE_RELEASE_SAFE(pDevEnum); | |
1990 if (FAILED(hr)) { | |
1991 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Unable to create class enumerator\n"); | |
1992 return NULL; | |
1993 } | |
1994 if (hr == S_FALSE) { | |
1995 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: No capture devices found\n"); | |
1996 return NULL; | |
1997 } | |
1998 | |
1999 OLE_CALL(pClassEnum,Reset); | |
2000 for (i = 0; OLE_CALL_ARGS(pClassEnum, Next, 1, &pM, &cFetched) == S_OK; i++) { | |
2001 if(get_device_name(pM, tmp, DEVICE_NAME_MAX_LEN)!=TVI_CONTROL_TRUE) | |
2002 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableGetDeviceName, i); | |
2003 else | |
33827
277ec491a8a7
Do not translate console messages of verbosity level MSGL_V and above.
diego
parents:
33622
diff
changeset
|
2004 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: Device #%d: %s\n", i, tmp); |
24744 | 2005 if (index != -1 && i == index) { |
2006 mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_UsingDevice, index, tmp); | |
2007 hr = OLE_CALL_ARGS(pM, BindToObject, 0, 0, &IID_IBaseFilter,(void *) &pFilter); | |
2008 if (FAILED(hr)) | |
2009 pFilter = NULL; | |
2010 } | |
2011 OLE_RELEASE_SAFE(pM); | |
2012 } | |
2013 if (index != -1 && !pFilter) { | |
2014 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_DeviceNotFound, | |
2015 index); | |
2016 } | |
2017 OLE_RELEASE_SAFE(pClassEnum); | |
2018 | |
2019 return pFilter; | |
2020 } | |
2021 | |
2022 /** | |
2023 * \brief get array of available formats through call to IAMStreamConfig::GetStreamCaps | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2024 * |
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2025 * \praram[in] chain chain data structure |
24744 | 2026 * |
2027 * \return S_OK success | |
2028 * \return E_POINTER one of parameters is NULL | |
2029 * \return E_FAIL required size of buffer is unknown for given media type | |
2030 * \return E_OUTOFMEMORY not enough memory | |
2031 * \return other error code from called methods | |
2032 * | |
2033 * \remarks | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2034 * last items of chain->arpmt and chain->arStreamCaps will be NULL |
24744 | 2035 */ |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2036 static HRESULT get_available_formats_stream(chain_t *chain) |
24744 | 2037 { |
2038 AM_MEDIA_TYPE **arpmt; | |
2039 void **pBuf=NULL; | |
2040 | |
2041 HRESULT hr; | |
2042 int i, count, size; | |
2043 int done; | |
2044 | |
2045 mp_msg(MSGT_TV, MSGL_DBG4, | |
2046 "tvi_dshow: get_available_formats_stream called\n"); | |
2047 | |
25090 | 2048 if (!chain->pStreamConfig) |
24744 | 2049 return E_POINTER; |
2050 | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2051 hr=OLE_CALL_ARGS(chain->pStreamConfig, GetNumberOfCapabilities, &count, &size); |
24744 | 2052 if (FAILED(hr)) { |
2053 mp_msg(MSGT_TV, MSGL_DBG4, | |
2054 "tvi_dshow: Call to GetNumberOfCapabilities failed (get_available_formats_stream)\n"); | |
2055 return hr; | |
2056 } | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2057 if (chain->type == video){ |
24744 | 2058 if (size != sizeof(VIDEO_STREAM_CONFIG_CAPS)) { |
2059 mp_msg(MSGT_TV, MSGL_DBG4, | |
2060 "tvi_dshow: Wrong video structure size for GetNumberOfCapabilities (get_available_formats_stream)\n"); | |
2061 return E_FAIL; | |
25089
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2062 } |
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2063 } else if (chain->type == audio){ |
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2064 if (size != sizeof(AUDIO_STREAM_CONFIG_CAPS)) { |
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2065 mp_msg(MSGT_TV, MSGL_DBG4, |
24744 | 2066 "tvi_dshow: Wrong audio structure size for GetNumberOfCapabilities (get_available_formats_stream)\n"); |
25089
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2067 return E_FAIL; |
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2068 } |
791f867d0124
Fix totally wrong (due to mess of brackets) structures size check.
voroshil
parents:
25088
diff
changeset
|
2069 } else { |
24744 | 2070 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnsupportedMediaType,"get_available_formats_stream"); |
2071 return E_FAIL; | |
2072 } | |
2073 done = 0; | |
2074 | |
30702 | 2075 arpmt = malloc((count + 1) * sizeof(AM_MEDIA_TYPE *)); |
24744 | 2076 if (arpmt) { |
2077 memset(arpmt, 0, (count + 1) * sizeof(AM_MEDIA_TYPE *)); | |
2078 | |
30702 | 2079 pBuf = malloc((count + 1) * sizeof(void *)); |
24744 | 2080 if (pBuf) { |
2081 memset(pBuf, 0, (count + 1) * sizeof(void *)); | |
2082 | |
2083 for (i = 0; i < count; i++) { | |
25127
6e039dd0b5d8
Revert r25089 (Ignore video formats which are supported by device
voroshil
parents:
25126
diff
changeset
|
2084 pBuf[i] = malloc(size); |
6e039dd0b5d8
Revert r25089 (Ignore video formats which are supported by device
voroshil
parents:
25126
diff
changeset
|
2085 |
6e039dd0b5d8
Revert r25089 (Ignore video formats which are supported by device
voroshil
parents:
25126
diff
changeset
|
2086 if (!pBuf[i]) |
24744 | 2087 break; |
2088 | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2089 hr = OLE_CALL_ARGS(chain->pStreamConfig, GetStreamCaps, i, |
25127
6e039dd0b5d8
Revert r25089 (Ignore video formats which are supported by device
voroshil
parents:
25126
diff
changeset
|
2090 &(arpmt[i]), pBuf[i]); |
24744 | 2091 if (FAILED(hr)) |
2092 break; | |
2093 } | |
2094 if (i == count) { | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2095 chain->arpmt = arpmt; |
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2096 chain->arStreamCaps = pBuf; |
24744 | 2097 done = 1; |
2098 } | |
2099 } | |
2100 } | |
2101 if (!done) { | |
2102 for (i = 0; i < count; i++) { | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
2103 if (pBuf) |
24744 | 2104 free(pBuf[i]); |
2105 if (arpmt && arpmt[i]) | |
2106 DeleteMediaType(arpmt[i]); | |
2107 } | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
2108 free(pBuf); |
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
2109 free(arpmt); |
24744 | 2110 if (hr != S_OK) { |
2111 mp_msg(MSGT_TV, MSGL_DBG4, "tvi_dshow: Call to GetStreamCaps failed (get_available_formats_stream)\n"); | |
2112 return hr; | |
2113 } else | |
2114 return E_OUTOFMEMORY; | |
2115 } | |
2116 return S_OK; | |
2117 } | |
2118 | |
2119 /** | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2120 * \brief returns allocates an array and store available media formats for given pin type to it |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2121 * |
24744 | 2122 * \param pBuilder ICaptureGraphBuilder2 interface of graph builder |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2123 * \param chain chain data structure |
24744 | 2124 * |
2125 * \return S_OK success | |
2126 * \return E_POINTER one of given pointers is null | |
2127 * \return apropriate error code otherwise | |
2128 */ | |
2129 static HRESULT get_available_formats_pin(ICaptureGraphBuilder2 * pBuilder, | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2130 chain_t *chain) |
24744 | 2131 { |
2132 IEnumMediaTypes *pEnum; | |
2133 int i, count, size; | |
2134 ULONG cFetched; | |
2135 AM_MEDIA_TYPE *pmt; | |
2136 HRESULT hr; | |
2137 void **pBuf; | |
2138 AM_MEDIA_TYPE **arpmt; //This will be real array | |
2139 VIDEO_STREAM_CONFIG_CAPS *pVideoCaps; | |
2140 AUDIO_STREAM_CONFIG_CAPS *pAudioCaps; | |
2141 int p1, p2, p3; | |
2142 | |
2143 mp_msg(MSGT_TV, MSGL_DBG4, | |
2144 "tvi_dshow: get_available_formats_pin called\n"); | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2145 if (!pBuilder || !chain->pCaptureFilter) |
24744 | 2146 return E_POINTER; |
2147 | |
25093 | 2148 if (!chain->pCapturePin) |
2149 { | |
2150 hr = OLE_CALL_ARGS(pBuilder, FindPin, | |
2151 (IUnknown *) chain->pCaptureFilter, | |
2152 PINDIR_OUTPUT, &PIN_CATEGORY_CAPTURE, | |
2153 chain->majortype, FALSE, 0, &chain->pCapturePin); | |
2154 | |
2155 if (!chain->pCapturePin) | |
2156 return E_POINTER; | |
2157 } | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2158 if (chain->type == video) { |
24744 | 2159 size = sizeof(VIDEO_STREAM_CONFIG_CAPS); |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2160 } else if (chain->type == audio) { |
24744 | 2161 size = sizeof(AUDIO_STREAM_CONFIG_CAPS); |
2162 } else { | |
2163 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnsupportedMediaType,"get_available_formats_pin"); | |
2164 return E_FAIL; | |
2165 } | |
2166 | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2167 hr = OLE_CALL_ARGS(chain->pCapturePin, EnumMediaTypes, &pEnum); |
24744 | 2168 if (FAILED(hr)) { |
2169 mp_msg(MSGT_TV, MSGL_DBG4, | |
2170 "tvi_dshow: Call to EnumMediaTypes failed (get_available_formats_pin)\n"); | |
2171 return hr; | |
2172 } | |
2173 for (i = 0; OLE_CALL_ARGS(pEnum, Next, 1, &pmt, &cFetched) == S_OK; i++) { | |
2174 if (!pmt) | |
2175 break; | |
2176 } | |
2177 OLE_CALL(pEnum,Reset); | |
2178 | |
2179 count = i; | |
30702 | 2180 arpmt = malloc((count + 1) * sizeof(AM_MEDIA_TYPE *)); |
24744 | 2181 if (!arpmt) |
2182 return E_OUTOFMEMORY; | |
2183 memset(arpmt, 0, (count + 1) * sizeof(AM_MEDIA_TYPE *)); | |
2184 | |
2185 for (i = 0; | |
2186 i < count | |
2187 && OLE_CALL_ARGS(pEnum, Next, 1, &(arpmt[i]), &cFetched) == S_OK; | |
2188 i++); | |
2189 | |
2190 OLE_RELEASE_SAFE(pEnum); | |
2191 | |
2192 | |
30702 | 2193 pBuf = malloc((count + 1) * sizeof(void *)); |
24744 | 2194 if (!pBuf) { |
2195 for (i = 0; i < count; i++) | |
2196 if (arpmt[i]) | |
2197 DeleteMediaType(arpmt[i]); | |
2198 free(arpmt); | |
2199 return E_OUTOFMEMORY; | |
2200 } | |
2201 memset(pBuf, 0, (count + 1) * sizeof(void *)); | |
2202 | |
2203 for (i = 0; i < count; i++) { | |
2204 pBuf[i] = malloc(size); | |
2205 if (!pBuf[i]) | |
2206 break; | |
2207 memset(pBuf[i], 0, size); | |
2208 | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2209 if (chain->type == video) { |
24744 | 2210 pVideoCaps = (VIDEO_STREAM_CONFIG_CAPS *) pBuf[i]; |
2211 extract_video_format(arpmt[i], NULL, &p1, &p2); | |
2212 pVideoCaps->MaxOutputSize.cx = pVideoCaps->MinOutputSize.cx = | |
2213 p1; | |
2214 pVideoCaps->MaxOutputSize.cy = pVideoCaps->MinOutputSize.cy = | |
2215 p2; | |
2216 } else { | |
2217 pAudioCaps = (AUDIO_STREAM_CONFIG_CAPS *) pBuf[i]; | |
2218 extract_audio_format(arpmt[i], &p1, &p2, &p3); | |
2219 pAudioCaps->MaximumSampleFrequency = | |
2220 pAudioCaps->MinimumSampleFrequency = p1; | |
2221 pAudioCaps->MaximumBitsPerSample = | |
2222 pAudioCaps->MinimumBitsPerSample = p2; | |
2223 pAudioCaps->MaximumChannels = pAudioCaps->MinimumChannels = p3; | |
2224 } | |
2225 | |
2226 } | |
2227 if (i != count) { | |
2228 for (i = 0; i < count; i++) { | |
2229 if (arpmt[i]) | |
2230 DeleteMediaType(arpmt[i]); | |
32511
b39155e98ac3
Remove some useless NULL pointer checks before invoking free() on the pointer.
diego
parents:
32141
diff
changeset
|
2231 free(pBuf[i]); |
24744 | 2232 } |
2233 free(arpmt); | |
2234 free(pBuf); | |
2235 return E_OUTOFMEMORY; | |
2236 } | |
25088
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2237 chain->arpmt = arpmt; |
554bbb45a2f2
Replace several parameters for get_available_formats_stream
voroshil
parents:
25087
diff
changeset
|
2238 chain->arStreamCaps = pBuf; |
24744 | 2239 |
2240 return S_OK; | |
2241 } | |
2242 | |
2243 /* | |
2244 *--------------------------------------------------------------------------------------- | |
2245 * | |
2246 * Public methods | |
2247 * | |
2248 *--------------------------------------------------------------------------------------- | |
2249 */ | |
2250 /** | |
2251 * \brief fills given buffer with audio data (usually one block) | |
2252 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2253 * \param priv driver's private data structure |
24744 | 2254 * \param buffer buffer to store data to |
2255 * \param len buffer's size in bytes (usually one block size) | |
2256 * | |
2257 * \return audio pts if audio present, 1 - otherwise | |
2258 */ | |
2259 static double grab_audio_frame(priv_t * priv, char *buffer, int len) | |
2260 { | |
2261 int bytes = 0; | |
2262 int i; | |
2263 double pts; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2264 grabber_ringbuffer_t *rb = priv->chains[1]->rbuf; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2265 grabber_ringbuffer_t *vrb = priv->chains[0]->rbuf; |
24744 | 2266 |
2267 if (!rb || !rb->ringbuffer) | |
2268 return 1; | |
2269 | |
2270 if(vrb && vrb->tStart<0){ | |
2271 memset(buffer,0,len); | |
2272 return 0; | |
2273 } | |
2274 if(vrb && rb->tStart<0) | |
2275 rb->tStart=vrb->tStart; | |
2276 | |
2277 if (len < rb->blocksize) | |
2278 bytes = len; | |
2279 else | |
2280 bytes = rb->blocksize; | |
2281 | |
2282 mp_msg(MSGT_TV, MSGL_DBG3,"tvi_dshow: FillBuffer (audio) called. %d blocks in buffer, %d bytes requested\n", | |
2283 rb->count, len); | |
2284 if(!rb->count){ | |
2285 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: waiting for frame\n"); | |
2286 for(i=0;i<1000 && !rb->count;i++) usec_sleep(1000); | |
2287 if(!rb->count){ | |
2288 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: waiting timeout\n"); | |
2289 return 0; | |
2290 } | |
2291 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: got frame!\n"); | |
2292 } | |
2293 | |
2294 EnterCriticalSection(rb->pMutex); | |
2295 pts=rb->dpts[rb->head]-rb->tStart; | |
2296 memcpy(buffer, rb->ringbuffer[rb->head], bytes); | |
2297 rb->head = (rb->head + 1) % rb->buffersize; | |
2298 rb->count--; | |
2299 LeaveCriticalSection(rb->pMutex); | |
2300 return pts; | |
2301 } | |
2302 | |
2303 /** | |
2304 * \brief returns audio frame size | |
2305 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2306 * \param priv driver's private data structure |
24744 | 2307 * |
2308 * \return audio block size if audio enabled and 1 - otherwise | |
2309 */ | |
2310 static int get_audio_framesize(priv_t * priv) | |
2311 { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2312 if (!priv->chains[1]->rbuf) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2313 return 1; //no audio |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2314 mp_msg(MSGT_TV,MSGL_DBG3,"get_audio_framesize: %d\n",priv->chains[1]->rbuf->blocksize); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2315 return priv->chains[1]->rbuf->blocksize; |
24744 | 2316 } |
2317 | |
2318 static int vbi_get_props(priv_t* priv,tt_stream_props* ptsp) | |
2319 { | |
2320 if(!priv || !ptsp) | |
2321 return TVI_CONTROL_FALSE; | |
2322 | |
2323 //STUBS!!! | |
2324 ptsp->interlaced=0; | |
2325 ptsp->offset=256; | |
2326 | |
2327 ptsp->sampling_rate=27e6; | |
2328 ptsp->samples_per_line=720; | |
2329 | |
2330 ptsp->count[0]=16; | |
2331 ptsp->count[1]=16; | |
2332 //END STUBS!!! | |
2333 ptsp->bufsize = ptsp->samples_per_line * (ptsp->count[0] + ptsp->count[1]); | |
2334 | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2335 mp_msg(MSGT_TV,MSGL_V,"vbi_get_props: sampling_rate=%d,offset:%d,samples_per_line: %d\n interlaced:%s, count=[%d,%d]\n", |
24744 | 2336 ptsp->sampling_rate, |
2337 ptsp->offset, | |
2338 ptsp->samples_per_line, | |
2339 ptsp->interlaced?"Yes":"No", | |
2340 ptsp->count[0], | |
2341 ptsp->count[1]); | |
2342 | |
2343 return TVI_CONTROL_TRUE; | |
2344 } | |
2345 | |
2346 static void vbi_grabber(priv_t* priv) | |
2347 { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2348 grabber_ringbuffer_t *rb = priv->chains[2]->rbuf; |
24744 | 2349 int i; |
2350 unsigned char* buf; | |
2351 if (!rb || !rb->ringbuffer) | |
2352 return; | |
2353 | |
2354 buf=calloc(1,rb->blocksize); | |
2355 for(i=0; i<23 && rb->count; i++){ | |
2356 memcpy(buf,rb->ringbuffer[rb->head],rb->blocksize); | |
2357 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_DECODE_PAGE,&buf); | |
2358 rb->head = (rb->head + 1) % rb->buffersize; | |
2359 rb->count--; | |
2360 } | |
2361 free(buf); | |
2362 } | |
2363 | |
2364 /** | |
2365 * \brief fills given buffer with video data (usually one frame) | |
2366 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2367 * \param priv driver's private data structure |
24744 | 2368 * \param buffer buffer to store data to |
2369 * \param len buffer's size in bytes (usually one frame size) | |
2370 * | |
2371 * \return frame size if video present, 0 - otherwise | |
2372 */ | |
2373 static double grab_video_frame(priv_t * priv, char *buffer, int len) | |
2374 { | |
2375 int bytes = 0; | |
2376 int i; | |
2377 double pts; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2378 grabber_ringbuffer_t *rb = priv->chains[0]->rbuf; |
24744 | 2379 |
2380 if (!rb || !rb->ringbuffer) | |
2381 return 1; | |
2382 if (len < rb->blocksize) | |
2383 bytes = len; | |
2384 else | |
2385 bytes = rb->blocksize; | |
2386 | |
2387 mp_msg(MSGT_TV, MSGL_DBG3,"tvi_dshow: FillBuffer (video) called. %d blocks in buffer, %d bytes requested\n", | |
2388 rb->count, len); | |
2389 if(!rb->count){ | |
2390 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: waiting for frame\n"); | |
2391 for(i=0;i<1000 && !rb->count;i++) usec_sleep(1000); | |
2392 if(!rb->count){ | |
2393 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: waiting timeout\n"); | |
2394 return 0; | |
2395 } | |
2396 mp_msg(MSGT_TV,MSGL_DBG4,"tvi_dshow: got frame!\n"); | |
2397 } | |
2398 EnterCriticalSection(rb->pMutex); | |
2399 if(rb->tStart<0) | |
2400 rb->tStart=rb->dpts[rb->head]; | |
2401 pts=rb->dpts[rb->head]-rb->tStart; | |
2402 memcpy(buffer, rb->ringbuffer[rb->head], bytes); | |
2403 rb->head = (rb->head + 1) % rb->buffersize; | |
2404 rb->count--; | |
2405 LeaveCriticalSection(rb->pMutex); | |
2406 | |
2407 vbi_grabber(priv); | |
2408 return pts; | |
2409 } | |
2410 | |
2411 /** | |
2412 * \brief returns frame size | |
2413 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2414 * \param priv driver's private data structure |
24744 | 2415 * |
2416 * \return frame size if video present, 0 - otherwise | |
2417 */ | |
2418 static int get_video_framesize(priv_t * priv) | |
2419 { | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2420 // if(!priv->pmtVideo) return 1; //no video |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
2421 // return priv->pmtVideo->lSampleSize; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2422 if (!priv->chains[0]->rbuf) |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2423 return 1; //no video |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2424 mp_msg(MSGT_TV,MSGL_DBG3,"geT_video_framesize: %d\n",priv->chains[0]->rbuf->blocksize); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2425 return priv->chains[0]->rbuf->blocksize; |
24744 | 2426 } |
2427 | |
2428 /** | |
2429 * \brief calculate audio buffer size | |
2430 * \param video_buf_size size of video buffer in bytes | |
2431 * \param video_bitrate video bit rate | |
2432 * \param audio_bitrate audio bit rate | |
2433 * \return audio buffer isze in bytes | |
2434 * | |
2435 * \remarks length of video buffer and resulted audio buffer calculated in | |
2436 * seconds will be the same. | |
2437 */ | |
2438 static inline int audio_buf_size_from_video(int video_buf_size, int video_bitrate, int audio_bitrate) | |
2439 { | |
2440 int audio_buf_size = audio_bitrate * (video_buf_size / video_bitrate); | |
2441 mp_msg(MSGT_TV,MSGL_DBG2,"tvi_dshow: Audio capture buffer: %d * %d / %d = %d\n", | |
2442 audio_bitrate,video_buf_size,video_bitrate,audio_buf_size); | |
2443 return audio_buf_size; | |
2444 } | |
2445 | |
2446 /** | |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2447 * \brief common chain initialization routine |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2448 * \param chain chain data structure |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2449 * |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2450 * \note pCaptureFilter member should be initialized before call to this routine |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2451 */ |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2452 static HRESULT init_chain_common(ICaptureGraphBuilder2 *pBuilder, chain_t *chain) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2453 { |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2454 HRESULT hr; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2455 int i; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2456 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2457 if(!chain->pCaptureFilter) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2458 return E_POINTER; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2459 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2460 show_filter_info(chain->pCaptureFilter); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2461 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2462 hr = OLE_CALL_ARGS(pBuilder, FindPin, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2463 (IUnknown *) chain->pCaptureFilter, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2464 PINDIR_OUTPUT, chain->pin_category, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2465 chain->majortype, FALSE, 0, &chain->pCapturePin); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2466 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2467 if (FAILED(hr)) { |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2468 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: FindPin(pCapturePin) call failed. Error:0x%x\n", (unsigned int)hr); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2469 return hr; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2470 } |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2471 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2472 hr = OLE_CALL_ARGS(pBuilder, FindInterface, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2473 chain->pin_category, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2474 chain->majortype, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2475 chain->pCaptureFilter, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2476 &IID_IAMStreamConfig, |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2477 (void **) &(chain->pStreamConfig)); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2478 if (FAILED(hr)) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2479 chain->pStreamConfig = NULL; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2480 |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2481 /* |
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2482 Getting available video formats (last pointer in array will be NULL) |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2483 First tryin to call IAMStreamConfig::GetStreamCaos. this will give us additional information such as |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2484 min/max picture dimensions, etc. If this call fails trying IPIn::EnumMediaTypes with default |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2485 min/max values. |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2486 */ |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2487 hr = get_available_formats_stream(chain); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2488 if (FAILED(hr)) { |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2489 mp_msg(MSGT_TV, MSGL_DBG2, "Unable to use IAMStreamConfig for retriving available formats (Error:0x%x). Using EnumMediaTypes instead\n", (unsigned int)hr); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2490 hr = get_available_formats_pin(pBuilder, chain); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2491 if(FAILED(hr)){ |
25125
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2492 return hr; |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2493 } |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2494 } |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2495 chain->nFormatUsed = 0; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2496 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2497 //If argument to CreateMediaType is NULL then result will be NULL too. |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2498 chain->pmt = CreateMediaType(chain->arpmt[0]); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2499 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2500 for (i = 0; chain->arpmt[i]; i++) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2501 DisplayMediaType("Available format", chain->arpmt[i]); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2502 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2503 return S_OK; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2504 } |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2505 /** |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2506 * \brief build video stream chain in graph |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2507 * \param priv private data structure |
24744 | 2508 * |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2509 * \return S_OK if chain was built successfully, apropriate error code otherwise |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2510 */ |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2511 static HRESULT build_video_chain(priv_t *priv) |
24744 | 2512 { |
2513 HRESULT hr; | |
2514 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2515 if(priv->chains[0]->rbuf) |
25059 | 2516 return S_OK; |
2517 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2518 if (priv->chains[0]->pStreamConfig) { |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2519 hr = OLE_CALL_ARGS(priv->chains[0]->pStreamConfig, SetFormat, priv->chains[0]->pmt); |
24744 | 2520 if (FAILED(hr)) { |
2521 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableSelectVideoFormat, (unsigned int)hr); | |
2522 } | |
2523 } | |
2524 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2525 priv->chains[0]->rbuf=calloc(1,sizeof(grabber_ringbuffer_t)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2526 if(!priv->chains[0]->rbuf) |
25058 | 2527 return E_OUTOFMEMORY; |
24744 | 2528 |
2529 if (priv->tv_param->buffer_size >= 0) { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2530 priv->chains[0]->rbuf->buffersize = priv->tv_param->buffer_size; |
24744 | 2531 } else { |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2532 priv->chains[0]->rbuf->buffersize = 16; |
24744 | 2533 } |
2534 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2535 priv->chains[0]->rbuf->buffersize *= 1024 * 1024; |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
2536 hr=build_sub_graph(priv, priv->chains[0], &PIN_CATEGORY_CAPTURE); |
24744 | 2537 if(FAILED(hr)){ |
2538 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVideoSubGraph,(unsigned int)hr); | |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2539 return hr; |
24744 | 2540 } |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2541 return S_OK; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2542 } |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2543 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2544 /** |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2545 * \brief build audio stream chain in graph |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2546 * \param priv private data structure |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2547 * |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2548 * \return S_OK if chain was built successfully, apropriate error code otherwise |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2549 */ |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2550 static HRESULT build_audio_chain(priv_t *priv) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2551 { |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2552 HRESULT hr; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2553 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2554 if(priv->chains[1]->rbuf) |
25059 | 2555 return S_OK; |
2556 | |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2557 if(priv->immediate_mode) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2558 return S_OK; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2559 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2560 if (priv->chains[1]->pStreamConfig) { |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2561 hr = OLE_CALL_ARGS(priv->chains[1]->pStreamConfig, SetFormat, |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2562 priv->chains[1]->pmt); |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2563 if (FAILED(hr)) { |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2564 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableSelectAudioFormat, (unsigned int)hr); |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2565 } |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2566 } |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2567 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2568 if(priv->chains[1]->pmt){ |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2569 priv->chains[1]->rbuf=calloc(1,sizeof(grabber_ringbuffer_t)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2570 if(!priv->chains[1]->rbuf) |
25058 | 2571 return E_OUTOFMEMORY; |
24744 | 2572 |
2573 /* let the audio buffer be the same size (in seconds) than video one */ | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2574 priv->chains[1]->rbuf->buffersize=audio_buf_size_from_video( |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2575 priv->chains[0]->rbuf->buffersize, |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2576 (((VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat)->dwBitRate), |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2577 (((WAVEFORMATEX *) (priv->chains[1]->pmt->pbFormat))->nAvgBytesPerSec)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2578 |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
2579 hr=build_sub_graph(priv, priv->chains[1],&PIN_CATEGORY_CAPTURE); |
24744 | 2580 if(FAILED(hr)){ |
2581 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildAudioSubGraph,(unsigned int)hr); | |
2582 return 0; | |
2583 } | |
2584 } | |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2585 return S_OK; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2586 } |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2587 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2588 /** |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2589 * \brief build VBI stream chain in graph |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2590 * \param priv private data structure |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2591 * |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2592 * \return S_OK if chain was built successfully, apropriate error code otherwise |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2593 */ |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2594 static HRESULT build_vbi_chain(priv_t *priv) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2595 { |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2596 HRESULT hr; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2597 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2598 if(priv->chains[2]->rbuf) |
25059 | 2599 return S_OK; |
2600 | |
29806 | 2601 if(priv->tv_param->teletext.device) |
24744 | 2602 { |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2603 priv->chains[2]->rbuf=calloc(1,sizeof(grabber_ringbuffer_t)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2604 if(!priv->chains[2]->rbuf) |
25058 | 2605 return E_OUTOFMEMORY; |
2606 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2607 init_ringbuffer(priv->chains[2]->rbuf,24,priv->tsp.bufsize); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2608 |
25084
f72ebba1e6d1
pass chain structure instead of several variables to build_sub_graph
voroshil
parents:
25083
diff
changeset
|
2609 hr=build_sub_graph(priv, priv->chains[2],&PIN_CATEGORY_VBI); |
24744 | 2610 if(FAILED(hr)){ |
2611 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_UnableBuildVBISubGraph,(unsigned int)hr); | |
2612 return 0; | |
2613 } | |
2614 } | |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2615 return S_OK; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2616 } |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2617 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2618 /** |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2619 * \brief playback/capture real start |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2620 * |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2621 * \param priv driver's private data structure |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2622 * |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2623 * \return 1 if success, 0 - otherwise |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2624 * |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2625 * TODO: move some code from init() here |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2626 */ |
25057
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2627 static int start(priv_t * priv) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2628 { |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2629 HRESULT hr; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2630 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2631 hr = build_video_chain(priv); |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2632 if(FAILED(hr)) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2633 return 0; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2634 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2635 hr = build_audio_chain(priv); |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2636 if(FAILED(hr)) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2637 return 0; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2638 |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2639 hr = build_vbi_chain(priv); |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2640 if(FAILED(hr)) |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2641 return 0; |
7d74c1a2c840
Move chains building code into separate routines.
voroshil
parents:
25054
diff
changeset
|
2642 |
24744 | 2643 /* |
2644 Graph is ready to capture. Starting graph. | |
2645 */ | |
2646 if (mp_msg_test(MSGT_TV, MSGL_DBG2)) { | |
2647 mp_msg(MSGT_TV, MSGL_DBG2, "Debug pause 10sec\n"); | |
2648 usec_sleep(10000000); | |
2649 mp_msg(MSGT_TV, MSGL_DBG2, "Debug pause end\n"); | |
2650 } | |
2651 if (!priv->pMediaControl) { | |
2652 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableGetMediaControlInterface,(unsigned int)E_POINTER); | |
2653 return 0; | |
2654 } | |
2655 hr = OLE_CALL(priv->pMediaControl, Run); | |
2656 if (FAILED(hr)) { | |
2657 mp_msg(MSGT_TV,MSGL_ERR,MSGTR_TVI_DS_UnableStartGraph, (unsigned int)hr); | |
2658 return 0; | |
2659 } | |
2660 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Graph is started.\n"); | |
2661 priv->state = 1; | |
2662 | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
2663 return 1; |
24744 | 2664 } |
2665 | |
2666 /** | |
2667 * \brief driver initialization | |
2668 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2669 * \param priv driver's private data structure |
24744 | 2670 * |
2671 * \return 1 if success, 0 - otherwise | |
2672 */ | |
2673 static int init(priv_t * priv) | |
2674 { | |
2675 HRESULT hr; | |
2676 int result = 0; | |
2677 long lInput, lTunerInput; | |
2678 IEnumFilters *pEnum; | |
2679 IBaseFilter *pFilter; | |
2680 IPin *pVPOutPin; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2681 int i; |
24744 | 2682 |
2683 priv->state=0; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2684 |
24744 | 2685 CoInitialize(NULL); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2686 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2687 for(i=0; i<3;i++) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2688 priv->chains[i] = calloc(1, sizeof(chain_t)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2689 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2690 priv->chains[0]->type=video; |
25080 | 2691 priv->chains[0]->majortype=&MEDIATYPE_Video; |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2692 priv->chains[0]->pin_category=&PIN_CATEGORY_CAPTURE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2693 priv->chains[1]->type=audio; |
25080 | 2694 priv->chains[1]->majortype=&MEDIATYPE_Audio; |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2695 priv->chains[1]->pin_category=&PIN_CATEGORY_CAPTURE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2696 priv->chains[2]->type=vbi; |
25080 | 2697 priv->chains[2]->majortype=&MEDIATYPE_VBI; |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2698 priv->chains[2]->pin_category=&PIN_CATEGORY_VBI; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2699 |
24744 | 2700 do{ |
2701 hr = CoCreateInstance((GUID *) & CLSID_FilterGraph, NULL, | |
2702 CLSCTX_INPROC_SERVER, &IID_IGraphBuilder, | |
2703 (void **) &priv->pGraph); | |
2704 if(FAILED(hr)){ | |
2705 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: CoCreateInstance(FilterGraph) call failed. Error:0x%x\n", (unsigned int)hr); | |
2706 break; | |
2707 } | |
2708 //Debug | |
2709 if (mp_msg_test(MSGT_TV, MSGL_DBG2)) { | |
2710 AddToRot((IUnknown *) priv->pGraph, &(priv->dwRegister)); | |
2711 } | |
2712 | |
2713 hr = CoCreateInstance((GUID *) & CLSID_CaptureGraphBuilder2, NULL, | |
2714 CLSCTX_INPROC_SERVER, &IID_ICaptureGraphBuilder2, | |
2715 (void **) &priv->pBuilder); | |
2716 if(FAILED(hr)){ | |
2717 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: CoCreateInstance(CaptureGraphBuilder) call failed. Error:0x%x\n", (unsigned int)hr); | |
2718 break; | |
2719 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2720 |
24744 | 2721 hr = OLE_CALL_ARGS(priv->pBuilder, SetFiltergraph, priv->pGraph); |
2722 if(FAILED(hr)){ | |
2723 mp_msg(MSGT_TV,MSGL_ERR, "tvi_dshow: SetFiltergraph call failed. Error:0x%x\n",(unsigned int)hr); | |
2724 break; | |
2725 } | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
2726 |
24744 | 2727 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Searching for available video capture devices\n"); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2728 priv->chains[0]->pCaptureFilter = find_capture_device(priv->dev_index, &CLSID_VideoInputDeviceCategory); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2729 if(!priv->chains[0]->pCaptureFilter){ |
24744 | 2730 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_NoVideoCaptureDevice); |
2731 break; | |
2732 } | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2733 hr = OLE_CALL_ARGS(priv->pGraph, AddFilter, priv->chains[0]->pCaptureFilter, NULL); |
24744 | 2734 if(FAILED(hr)){ |
2735 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Unable to add video capture device to Directshow graph. Error:0x%x\n", (unsigned int)hr); | |
2736 break; | |
2737 } | |
2738 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Searching for available audio capture devices\n"); | |
2739 if (priv->adev_index != -1) { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2740 priv->chains[1]->pCaptureFilter = find_capture_device(priv->adev_index, &CLSID_AudioInputDeviceCategory); //output available audio edevices |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2741 if(!priv->chains[1]->pCaptureFilter){ |
24744 | 2742 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_NoAudioCaptureDevice); |
2743 break; | |
2744 } | |
2745 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2746 hr = OLE_CALL_ARGS(priv->pGraph, AddFilter, priv->chains[1]->pCaptureFilter, NULL); |
24744 | 2747 if(FAILED(hr)){ |
2748 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: Unable to add audio capture device to Directshow graph. Error:0x%x\n", (unsigned int)hr); | |
2749 break; | |
2750 } | |
2751 } else | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2752 hr = OLE_QUERYINTERFACE(priv->chains[0]->pCaptureFilter, IID_IBaseFilter, priv->chains[1]->pCaptureFilter); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2753 |
25082
b63b4b599cbe
Add capture filter's pointer to vbi chain structure too.
voroshil
parents:
25081
diff
changeset
|
2754 /* increase refrence counter for capture filter ad store pointer into vbi chain structure too */ |
b63b4b599cbe
Add capture filter's pointer to vbi chain structure too.
voroshil
parents:
25081
diff
changeset
|
2755 hr = OLE_QUERYINTERFACE(priv->chains[0]->pCaptureFilter, IID_IBaseFilter, priv->chains[2]->pCaptureFilter); |
b63b4b599cbe
Add capture filter's pointer to vbi chain structure too.
voroshil
parents:
25081
diff
changeset
|
2756 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2757 hr = OLE_QUERYINTERFACE(priv->chains[0]->pCaptureFilter, IID_IAMVideoProcAmp,priv->pVideoProcAmp); |
24744 | 2758 if (FAILED(hr) && hr != E_NOINTERFACE) |
2759 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Get IID_IAMVideoProcAmp failed (0x%x).\n", (unsigned int)hr); | |
2760 | |
2761 if (hr != S_OK) { | |
2762 mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_VideoAdjustigNotSupported); | |
2763 priv->pVideoProcAmp = NULL; | |
2764 } | |
2765 | |
2766 hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, | |
2767 &PIN_CATEGORY_CAPTURE, | |
25080 | 2768 priv->chains[0]->majortype, |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2769 priv->chains[0]->pCaptureFilter, |
24744 | 2770 &IID_IAMCrossbar, (void **) &(priv->pCrossbar)); |
2771 if (FAILED(hr)) { | |
2772 mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_SelectingInputNotSupported); | |
2773 priv->pCrossbar = NULL; | |
2774 } | |
2775 | |
2776 if (priv->tv_param->amode >= 0) { | |
2777 IAMTVAudio *pTVAudio; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2778 hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, NULL, NULL,priv->chains[0]->pCaptureFilter,&IID_IAMTVAudio, (void *) &pTVAudio); |
24744 | 2779 if (hr == S_OK) { |
2780 switch (priv->tv_param->amode) { | |
2781 case 0: | |
2782 hr = OLE_CALL_ARGS(pTVAudio, put_TVAudioMode, AMTVAUDIO_MODE_MONO); | |
2783 break; | |
2784 case 1: | |
2785 hr = OLE_CALL_ARGS(pTVAudio, put_TVAudioMode, AMTVAUDIO_MODE_STEREO); | |
2786 break; | |
2787 case 2: | |
2788 hr = OLE_CALL_ARGS(pTVAudio, put_TVAudioMode, | |
2789 AMTVAUDIO_MODE_LANG_A); | |
2790 break; | |
2791 case 3: | |
2792 hr = OLE_CALL_ARGS(pTVAudio, put_TVAudioMode, | |
2793 AMTVAUDIO_MODE_LANG_B); | |
2794 break; | |
2795 } | |
2796 OLE_RELEASE_SAFE(pTVAudio); | |
2797 if (FAILED(hr)) | |
2798 mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_UnableSetAudioMode, priv->tv_param->amode,(unsigned int)hr); | |
2799 } | |
2800 } | |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2801 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2802 // Video chain initialization |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2803 hr = init_chain_common(priv->pBuilder, priv->chains[0]); |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2804 if(FAILED(hr)) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2805 break; |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2806 |
25125
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2807 /* |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2808 Audio chain initialization |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2809 Since absent audio stream is not fatal, |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2810 at least one NULL pointer should be kept in format arrays |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2811 (to avoid another additional check everywhere for array presence). |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2812 */ |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2813 hr = init_chain_common(priv->pBuilder, priv->chains[1]); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2814 if(FAILED(hr)) |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2815 { |
33622
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2816 mp_msg(MSGT_TV, MSGL_V, |
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2817 "tvi_dshow: Unable to initialize audio chain (Error:0x%lx). Audio disabled\n", |
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2818 (unsigned long)hr); |
25125
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2819 priv->chains[1]->arpmt=calloc(1, sizeof(AM_MEDIA_TYPE*)); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2820 priv->chains[1]->arStreamCaps=calloc(1, sizeof(void*)); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2821 } |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2822 |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2823 /* |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2824 VBI chain initialization |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2825 Since absent VBI stream is not fatal, |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2826 at least one NULL pointer should be kept in format arrays |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2827 (to avoid another additional check everywhere for array presence). |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2828 */ |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2829 hr = init_chain_common(priv->pBuilder, priv->chains[2]); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2830 if(FAILED(hr)) |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2831 { |
33622
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2832 mp_msg(MSGT_TV, MSGL_V, |
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2833 "tvi_dshow: Unable to initialize VBI chain (Error:0x%lx). Teletext disabled\n", |
27f7a3196e18
tvi_dshow: Adjust mp_msg printf conversion specifier to avoid warnings.
diego
parents:
33618
diff
changeset
|
2834 (unsigned long)hr); |
25125
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2835 priv->chains[2]->arpmt=calloc(1, sizeof(AM_MEDIA_TYPE*)); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2836 priv->chains[2]->arStreamCaps=calloc(1, sizeof(void*)); |
a1e6345207a1
§³reate empty format arrays in case of error in init_chain_common.
voroshil
parents:
25105
diff
changeset
|
2837 } |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2838 |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2839 if (!priv->chains[0]->pStreamConfig) |
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2840 mp_msg(MSGT_TV, MSGL_INFO, MSGTR_TVI_DS_ChangingWidthHeightNotSupported); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2841 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2842 if (!priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed] |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2843 || !extract_video_format(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed], |
24744 | 2844 &(priv->fcc), &(priv->width), |
2845 &(priv->height))) { | |
2846 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_ErrorParsingVideoFormatStruct); | |
2847 break; | |
2848 } | |
25094
e27cb70d2302
Move code related to chain initialization and similar
voroshil
parents:
25093
diff
changeset
|
2849 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2850 if (priv->chains[1]->arpmt[priv->chains[1]->nFormatUsed]) { |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2851 if (!extract_audio_format(priv->chains[1]->pmt, &(priv->samplerate), NULL, NULL)) { |
24744 | 2852 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_ErrorParsingAudioFormatStruct); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2853 DisplayMediaType("audio format failed",priv->chains[1]->arpmt[priv->chains[1]->nFormatUsed]); |
24744 | 2854 break; |
2855 } | |
2856 } | |
2857 | |
2858 hr = OLE_QUERYINTERFACE(priv->pGraph, IID_IMediaControl,priv->pMediaControl); | |
2859 if(FAILED(hr)){ | |
2860 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_UnableGetMediaControlInterface,(unsigned int)hr); | |
2861 break; | |
2862 } | |
2863 hr = OLE_CALL_ARGS(priv->pBuilder, FindInterface, | |
2864 &PIN_CATEGORY_CAPTURE, NULL, | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2865 priv->chains[0]->pCaptureFilter, |
24744 | 2866 &IID_IAMTVTuner, (void **) &(priv->pTVTuner)); |
2867 | |
2868 if (!priv->pTVTuner) { | |
2869 mp_msg(MSGT_TV, MSGL_DBG2, "tvi_dshow: Unable to access IAMTVTuner (0x%x)\n", (unsigned int)hr); | |
2870 } | |
2871 | |
2872 // shows Tuner capabilities | |
2873 get_capabilities(priv); | |
2874 | |
2875 if (priv->pTVTuner) { | |
2876 hr = OLE_CALL_ARGS(priv->pTVTuner, put_CountryCode, | |
2877 chanlist2country(priv->tv_param->chanlist)); | |
2878 if(FAILED(hr)){ | |
2879 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: Call to put_CountryCode failed. Error:0x%x\n",(unsigned int)hr); | |
2880 } | |
2881 | |
2882 hr = OLE_CALL_ARGS(priv->pTVTuner, put_Mode, AMTUNER_MODE_TV); | |
2883 if(FAILED(hr)){ | |
2884 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: Call to put_Mode failed. Error:0x%x\n",(unsigned int)hr); | |
2885 break; | |
2886 } | |
2887 | |
2888 hr = OLE_CALL_ARGS(priv->pTVTuner, get_ConnectInput, &lInput); | |
2889 if(FAILED(hr)){ | |
2890 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: Call to get_ConnectInput failed. Error:0x%x\n",(unsigned int)hr); | |
2891 break; | |
2892 } | |
2893 | |
2894 /* small hack */ | |
2895 lTunerInput = strstr(priv->tv_param->chanlist, "cable") ? TunerInputCable : TunerInputAntenna; | |
2896 | |
2897 hr = OLE_CALL_ARGS(priv->pTVTuner, put_InputType, lInput, lTunerInput); | |
2898 if(FAILED(hr)){ | |
2899 mp_msg(MSGT_TV,MSGL_DBG2, "tvi_dshow: Call to put_InputType failed. Error:0x%x\n",(unsigned int)hr); | |
2900 break; | |
2901 } | |
2902 | |
2903 } | |
2904 | |
2905 /** | |
2906 for VIVO cards we should check if preview pin is available on video capture device. | |
2907 If it is not, we have to connect Video Port Manager filter to VP pin of capture device filter. | |
2908 Otherwise we will get 0x8007001f (Device is not functioning properly) when attempting to start graph | |
2909 */ | |
2910 hr = OLE_CALL_ARGS(priv->pBuilder, FindPin, | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
2911 (IUnknown *) priv->chains[0]->pCaptureFilter, |
24744 | 2912 PINDIR_OUTPUT, |
2913 &PIN_CATEGORY_VIDEOPORT, NULL, FALSE, | |
2914 0, (IPin **) & pVPOutPin); | |
2915 if (SUCCEEDED(hr)) { | |
2916 hr = OLE_CALL_ARGS(priv->pGraph, Render, pVPOutPin); | |
2917 OLE_RELEASE_SAFE(pVPOutPin); | |
2918 | |
2919 if (FAILED(hr)) { | |
2920 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_UnableTerminateVPPin, (unsigned int)hr); | |
2921 break; | |
2922 } | |
2923 } | |
2924 | |
2925 OLE_CALL_ARGS(priv->pGraph, EnumFilters, &pEnum); | |
2926 while (OLE_CALL_ARGS(pEnum, Next, 1, &pFilter, NULL) == S_OK) { | |
2927 LPVIDEOWINDOW pVideoWindow; | |
2928 hr = OLE_QUERYINTERFACE(pFilter, IID_IVideoWindow, pVideoWindow); | |
2929 if (SUCCEEDED(hr)) | |
2930 { | |
2931 if(priv->tv_param->hidden_vp_renderer){ | |
2932 OLE_CALL_ARGS(pVideoWindow,put_Visible,/* OAFALSE*/ 0); | |
2933 OLE_CALL_ARGS(pVideoWindow,put_AutoShow,/* OAFALSE*/ 0); | |
2934 }else | |
2935 { | |
2936 OLE_CALL_ARGS(priv->pGraph, RemoveFilter, pFilter); | |
2937 } | |
2938 OLE_RELEASE_SAFE(pVideoWindow); | |
2939 } | |
2940 OLE_RELEASE_SAFE(pFilter); | |
2941 } | |
2942 OLE_RELEASE_SAFE(pEnum); | |
2943 if(priv->tv_param->system_clock) | |
2944 { | |
2945 LPREFERENCECLOCK rc; | |
2946 IBaseFilter* pBF; | |
2947 hr = CoCreateInstance((GUID *) & CLSID_SystemClock, NULL, | |
2948 CLSCTX_INPROC_SERVER, &IID_IReferenceClock, | |
2949 (void *) &rc); | |
2950 | |
2951 OLE_QUERYINTERFACE(priv->pBuilder,IID_IBaseFilter,pBF); | |
2952 OLE_CALL_ARGS(pBF,SetSyncSource,rc); | |
2953 } | |
2954 if(vbi_get_props(priv,&(priv->tsp))!=TVI_CONTROL_TRUE) | |
2955 break; | |
2956 result = 1; | |
2957 } while(0); | |
2958 | |
2959 if (!result){ | |
2960 mp_msg(MSGT_TV,MSGL_ERR, MSGTR_TVI_DS_GraphInitFailure); | |
2961 uninit(priv); | |
2962 } | |
2963 return result; | |
2964 } | |
2965 | |
2966 /** | |
25085
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2967 * \brief chain uninitialization |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2968 * \param chain chain data structure |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2969 */ |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2970 static void destroy_chain(chain_t *chain) |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2971 { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2972 int i; |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2973 |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2974 if(!chain) |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2975 return; |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2976 |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2977 OLE_RELEASE_SAFE(chain->pStreamConfig); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2978 OLE_RELEASE_SAFE(chain->pCaptureFilter); |
25086
e91503fbf524
Move pointer to SampleGrabber filter into chain structure.
voroshil
parents:
25085
diff
changeset
|
2979 OLE_RELEASE_SAFE(chain->pCSGCB); |
25087
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
2980 OLE_RELEASE_SAFE(chain->pCapturePin); |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
2981 OLE_RELEASE_SAFE(chain->pSGIn); |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
2982 OLE_RELEASE_SAFE(chain->pSG); |
edc7391db7f5
New routine for reconnecting two pins with new media type
voroshil
parents:
25086
diff
changeset
|
2983 OLE_RELEASE_SAFE(chain->pSGF); |
25086
e91503fbf524
Move pointer to SampleGrabber filter into chain structure.
voroshil
parents:
25085
diff
changeset
|
2984 |
25085
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2985 if (chain->pmt) |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2986 DeleteMediaType(chain->pmt); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2987 |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2988 if (chain->arpmt) { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2989 for (i = 0; chain->arpmt[i]; i++) { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2990 DeleteMediaType(chain->arpmt[i]); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2991 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2992 free(chain->arpmt); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2993 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2994 |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2995 if (chain->arStreamCaps) { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2996 for (i = 0; chain->arStreamCaps[i]; i++) { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2997 free(chain->arStreamCaps[i]); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2998 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
2999 free(chain->arStreamCaps); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3000 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3001 |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3002 if (chain->rbuf) { |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3003 destroy_ringbuffer(chain->rbuf); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3004 free(chain->rbuf); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3005 chain->rbuf = NULL; |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3006 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3007 free(chain); |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3008 } |
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3009 /** |
24744 | 3010 * \brief driver uninitialization |
3011 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
3012 * \param priv driver's private data structure |
24744 | 3013 * |
3014 * \return always 1 | |
3015 */ | |
3016 static int uninit(priv_t * priv) | |
3017 { | |
3018 int i; | |
3019 if (!priv) | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3020 return 1; |
24744 | 3021 //Debug |
3022 if (priv->dwRegister) { | |
3023 RemoveFromRot(priv->dwRegister); | |
3024 } | |
3025 teletext_control(priv->priv_vbi,TV_VBI_CONTROL_STOP,(void*)1); | |
3026 //stop audio grabber thread | |
3027 | |
3028 if (priv->state && priv->pMediaControl) { | |
3029 OLE_CALL(priv->pMediaControl, Stop); | |
3030 } | |
3031 OLE_RELEASE_SAFE(priv->pMediaControl); | |
3032 priv->state = 0; | |
3033 | |
3034 if (priv->pGraph) { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3035 if (priv->chains[0]->pCaptureFilter) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3036 OLE_CALL_ARGS(priv->pGraph, RemoveFilter, priv->chains[0]->pCaptureFilter); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3037 if (priv->chains[1]->pCaptureFilter) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3038 OLE_CALL_ARGS(priv->pGraph, RemoveFilter, priv->chains[1]->pCaptureFilter); |
24744 | 3039 } |
3040 OLE_RELEASE_SAFE(priv->pCrossbar); | |
3041 OLE_RELEASE_SAFE(priv->pVideoProcAmp); | |
3042 OLE_RELEASE_SAFE(priv->pGraph); | |
3043 OLE_RELEASE_SAFE(priv->pBuilder); | |
3044 if(priv->freq_table){ | |
3045 priv->freq_table_len=-1; | |
3046 free(priv->freq_table); | |
3047 priv->freq_table=NULL; | |
3048 } | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3049 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3050 for(i=0; i<3;i++) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3051 { |
25085
da7c8d1b7a36
Move common chain uninit code into separate routine.
voroshil
parents:
25084
diff
changeset
|
3052 destroy_chain(priv->chains[i]); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3053 priv->chains[i] = NULL; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3054 } |
24744 | 3055 CoUninitialize(); |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3056 return 1; |
24744 | 3057 } |
3058 | |
3059 /** | |
3060 * \brief driver pre-initialization | |
3061 * | |
3062 * \param device string, containing device name in form "x[.y]", where x is video capture device | |
3063 * (default: 0, first available); y (if given) sets audio capture device | |
3064 * | |
3065 * \return 1 if success,0 - otherwise | |
3066 */ | |
3067 static tvi_handle_t *tvi_init_dshow(tv_param_t* tv_param) | |
3068 { | |
3069 tvi_handle_t *h; | |
3070 priv_t *priv; | |
3071 int a; | |
3072 | |
32141
2802b8095bf7
Move TV input new_handle static function to tv.c and make it non-static.
diego
parents:
32090
diff
changeset
|
3073 h = tv_new_handle(sizeof(priv_t), &functions); |
24744 | 3074 if (!h) |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3075 return NULL; |
24744 | 3076 |
3077 priv = h->priv; | |
3078 | |
3079 memset(priv, 0, sizeof(priv_t)); | |
3080 priv->direct_setfreq_call = 1; //first using direct call. if it fails, workaround will be enabled | |
3081 priv->direct_getfreq_call = 1; //first using direct call. if it fails, workaround will be enabled | |
3082 priv->adev_index = -1; | |
3083 priv->freq_table_len=-1; | |
3084 priv->tv_param=tv_param; | |
3085 | |
3086 if (tv_param->device) { | |
3087 if (sscanf(tv_param->device, "%d", &a) == 1) { | |
3088 priv->dev_index = a; | |
3089 } else { | |
3090 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_WrongDeviceParam, tv_param->device); | |
32090
535ebcd085e4
Move TV input free_handle static function to tv.c and make it non-static.
diego
parents:
31322
diff
changeset
|
3091 tv_free_handle(h); |
24744 | 3092 return NULL; |
3093 } | |
3094 if (priv->dev_index < 0) { | |
3095 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_WrongDeviceIndex, a); | |
32090
535ebcd085e4
Move TV input free_handle static function to tv.c and make it non-static.
diego
parents:
31322
diff
changeset
|
3096 tv_free_handle(h); |
24744 | 3097 return NULL; |
3098 } | |
3099 } | |
3100 if (tv_param->adevice) { | |
3101 if (sscanf(tv_param->adevice, "%d", &a) == 1) { | |
3102 priv->adev_index = a; | |
3103 } else { | |
3104 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_WrongADeviceParam, tv_param->adevice); | |
32090
535ebcd085e4
Move TV input free_handle static function to tv.c and make it non-static.
diego
parents:
31322
diff
changeset
|
3105 tv_free_handle(h); |
24744 | 3106 return NULL; |
3107 } | |
3108 if (priv->dev_index < 0) { | |
3109 mp_msg(MSGT_TV, MSGL_ERR, MSGTR_TVI_DS_WrongADeviceIndex, a); | |
32090
535ebcd085e4
Move TV input free_handle static function to tv.c and make it non-static.
diego
parents:
31322
diff
changeset
|
3110 tv_free_handle(h); |
24744 | 3111 return NULL; |
3112 } | |
3113 } | |
3114 return h; | |
3115 } | |
3116 | |
3117 /** | |
3118 * \brief driver's ioctl handler | |
3119 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
3120 * \param priv driver's private data structure |
24744 | 3121 * \param cmd ioctl command |
3122 * \param arg ioct command's parameter | |
3123 * | |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
3124 * \return TVI_CONTROL_TRUE if success |
24744 | 3125 * \return TVI_CONTROL_FALSE if failure |
3126 * \return TVI_CONTROL_UNKNOWN if unknowm cmd called | |
3127 */ | |
3128 static int control(priv_t * priv, int cmd, void *arg) | |
3129 { | |
3130 switch (cmd) { | |
3131 /* need rewrite */ | |
3132 case TVI_CONTROL_VID_SET_FORMAT: | |
3133 { | |
25126
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3134 int fcc, i,j; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3135 void* tmp,*tmp2; |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3136 int result = TVI_CONTROL_TRUE; |
25063
29260745e4fa
Pass all available formats to chain building routine and
voroshil
parents:
25061
diff
changeset
|
3137 |
24744 | 3138 if (priv->state) |
3139 return TVI_CONTROL_FALSE; | |
3140 fcc = *(int *) arg; | |
3141 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3142 if(!priv->chains[0]->arpmt) |
24744 | 3143 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3144 for (i = 0; priv->chains[0]->arpmt[i]; i++) |
24744 | 3145 if (check_video_format |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3146 (priv->chains[0]->arpmt[i], fcc, priv->width, priv->height)) |
24744 | 3147 break; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3148 if (!priv->chains[0]->arpmt[i]) |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3149 { |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3150 int fps = 0; |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3151 VIDEOINFOHEADER* Vhdr = NULL; |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3152 AM_MEDIA_TYPE *pmt; |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3153 |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3154 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: will try also use undeclared video format: %dx%d, %s\n",priv->width, priv->height, vo_format_name(fcc)); |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3155 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3156 if (priv->chains[0]->arpmt[0]) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3157 Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->arpmt[0]->pbFormat; |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3158 |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3159 if(Vhdr && Vhdr->bmiHeader.biSizeImage) |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3160 fps = Vhdr->dwBitRate / (8 * Vhdr->bmiHeader.biSizeImage); |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3161 |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3162 pmt=create_video_format(fcc, priv->width, priv->height, fps); |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3163 if(!pmt) |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3164 { |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3165 mp_msg(MSGT_TV, MSGL_V, "tvi_dshow: Unable to create AM_MEDIA_TYPE structure for given format\n"); |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3166 return TVI_CONTROL_FALSE; |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3167 } |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3168 priv->chains[0]->arpmt=realloc(priv->chains[0]->arpmt, (i+2)*sizeof(AM_MEDIA_TYPE*)); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3169 priv->chains[0]->arpmt[i+1] = NULL; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3170 priv->chains[0]->arpmt[i] = pmt; |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3171 |
25105 | 3172 priv->chains[0]->arStreamCaps=realloc(priv->chains[0]->arStreamCaps, (i+2)*sizeof(void*)); |
25096 | 3173 priv->chains[0]->arpmt[i+1] = NULL; |
3174 | |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3175 result = TVI_CONTROL_FALSE; |
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3176 } |
24744 | 3177 |
25126
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3178 |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3179 tmp=priv->chains[0]->arpmt[i]; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3180 tmp2=priv->chains[0]->arStreamCaps[i]; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3181 for(j=i; j>0; j--) |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3182 { |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3183 priv->chains[0]->arpmt[j] = priv->chains[0]->arpmt[j-1]; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3184 priv->chains[0]->arStreamCaps[j] = priv->chains[0]->arStreamCaps[j-1]; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3185 } |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3186 priv->chains[0]->arpmt[0] = tmp; |
8152446e42b1
Move requested format at top and shift all oters down
voroshil
parents:
25125
diff
changeset
|
3187 priv->chains[0]->arStreamCaps[0] = tmp2; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3188 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3189 priv->chains[0]->nFormatUsed = 0; |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3190 |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3191 if (priv->chains[0]->pmt) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3192 DeleteMediaType(priv->chains[0]->pmt); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3193 priv->chains[0]->pmt = |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3194 CreateMediaType(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed]); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3195 DisplayMediaType("VID_SET_FORMAT", priv->chains[0]->pmt); |
24744 | 3196 /* |
3197 Setting width & height to preferred by driver values | |
3198 */ | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3199 extract_video_format(priv->chains[0]->arpmt[priv->chains[0]->nFormatUsed], |
24744 | 3200 &(priv->fcc), &(priv->width), |
3201 &(priv->height)); | |
25068
4b14d188ed34
Add all passed to VID_SET_FORMAT formats to the end of
voroshil
parents:
25067
diff
changeset
|
3202 return result; |
24744 | 3203 } |
3204 case TVI_CONTROL_VID_GET_FORMAT: | |
3205 { | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3206 if(!priv->chains[0]->pmt) |
24744 | 3207 return TVI_CONTROL_FALSE; |
25067
5abe2c29b7d8
Ensure that when VID_GET_FORMAT ioctl is called,
voroshil
parents:
25066
diff
changeset
|
3208 /* |
5abe2c29b7d8
Ensure that when VID_GET_FORMAT ioctl is called,
voroshil
parents:
25066
diff
changeset
|
3209 Build video chain (for video format negotiation). |
5abe2c29b7d8
Ensure that when VID_GET_FORMAT ioctl is called,
voroshil
parents:
25066
diff
changeset
|
3210 If this was done before, routine will do nothing. |
5abe2c29b7d8
Ensure that when VID_GET_FORMAT ioctl is called,
voroshil
parents:
25066
diff
changeset
|
3211 */ |
5abe2c29b7d8
Ensure that when VID_GET_FORMAT ioctl is called,
voroshil
parents:
25066
diff
changeset
|
3212 build_video_chain(priv); |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3213 DisplayMediaType("VID_GET_FORMAT", priv->chains[0]->pmt); |
24744 | 3214 if (priv->fcc) { |
3215 *(int *) arg = priv->fcc; | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3216 return TVI_CONTROL_TRUE; |
24744 | 3217 } else |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3218 return TVI_CONTROL_FALSE; |
24744 | 3219 } |
3220 case TVI_CONTROL_VID_SET_WIDTH: | |
3221 { | |
3222 VIDEO_STREAM_CONFIG_CAPS *pCaps; | |
3223 VIDEOINFOHEADER *Vhdr; | |
3224 int width = *(int *) arg; | |
3225 if (priv->state) | |
3226 return TVI_CONTROL_FALSE; | |
3227 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3228 pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; |
24744 | 3229 if (!pCaps) |
3230 return TVI_CONTROL_FALSE; | |
3231 if (width < pCaps->MinOutputSize.cx | |
3232 || width > pCaps->MaxOutputSize.cx) | |
3233 return TVI_CONTROL_FALSE; | |
3234 | |
3235 if (width % pCaps->OutputGranularityX) | |
3236 return TVI_CONTROL_FALSE; | |
3237 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3238 if (!priv->chains[0]->pmt || !priv->chains[0]->pmt->pbFormat) |
24744 | 3239 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3240 Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat; |
24744 | 3241 Vhdr->bmiHeader.biWidth = width; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3242 priv->chains[0]->pmt->lSampleSize = Vhdr->bmiHeader.biSizeImage = |
24744 | 3243 labs(Vhdr->bmiHeader.biBitCount * Vhdr->bmiHeader.biWidth * |
3244 Vhdr->bmiHeader.biHeight) >> 3; | |
3245 | |
3246 priv->width = width; | |
3247 | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3248 return TVI_CONTROL_TRUE; |
24744 | 3249 } |
3250 case TVI_CONTROL_VID_GET_WIDTH: | |
3251 { | |
3252 if (priv->width) { | |
3253 *(int *) arg = priv->width; | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3254 return TVI_CONTROL_TRUE; |
24744 | 3255 } else |
3256 return TVI_CONTROL_FALSE; | |
3257 } | |
3258 case TVI_CONTROL_VID_CHK_WIDTH: | |
3259 { | |
3260 VIDEO_STREAM_CONFIG_CAPS *pCaps; | |
3261 int width = *(int *) arg; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3262 pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; |
24744 | 3263 if (!pCaps) |
3264 return TVI_CONTROL_FALSE; | |
3265 if (width < pCaps->MinOutputSize.cx | |
3266 || width > pCaps->MaxOutputSize.cx) | |
3267 return TVI_CONTROL_FALSE; | |
3268 | |
3269 if (width % pCaps->OutputGranularityX) | |
3270 return TVI_CONTROL_FALSE; | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3271 return TVI_CONTROL_TRUE; |
24744 | 3272 } |
3273 case TVI_CONTROL_VID_SET_HEIGHT: | |
3274 { | |
3275 VIDEO_STREAM_CONFIG_CAPS *pCaps; | |
3276 VIDEOINFOHEADER *Vhdr; | |
3277 int height = *(int *) arg; | |
3278 if (priv->state) | |
3279 return TVI_CONTROL_FALSE; | |
3280 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3281 pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; |
24744 | 3282 if (!pCaps) |
3283 return TVI_CONTROL_FALSE; | |
3284 if (height < pCaps->MinOutputSize.cy | |
3285 || height > pCaps->MaxOutputSize.cy) | |
3286 return TVI_CONTROL_FALSE; | |
3287 | |
3288 if (height % pCaps->OutputGranularityY) | |
3289 return TVI_CONTROL_FALSE; | |
3290 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3291 if (!priv->chains[0]->pmt || !priv->chains[0]->pmt->pbFormat) |
24744 | 3292 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3293 Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat; |
24744 | 3294 |
3295 if (Vhdr->bmiHeader.biHeight < 0) | |
3296 Vhdr->bmiHeader.biHeight = -height; | |
3297 else | |
3298 Vhdr->bmiHeader.biHeight = height; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3299 priv->chains[0]->pmt->lSampleSize = Vhdr->bmiHeader.biSizeImage = |
24744 | 3300 labs(Vhdr->bmiHeader.biBitCount * Vhdr->bmiHeader.biWidth * |
3301 Vhdr->bmiHeader.biHeight) >> 3; | |
3302 | |
3303 priv->height = height; | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3304 return TVI_CONTROL_TRUE; |
24744 | 3305 } |
3306 case TVI_CONTROL_VID_GET_HEIGHT: | |
3307 { | |
3308 if (priv->height) { | |
3309 *(int *) arg = priv->height; | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3310 return TVI_CONTROL_TRUE; |
24744 | 3311 } else |
3312 return TVI_CONTROL_FALSE; | |
3313 } | |
3314 case TVI_CONTROL_VID_CHK_HEIGHT: | |
3315 { | |
3316 VIDEO_STREAM_CONFIG_CAPS *pCaps; | |
3317 int height = *(int *) arg; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3318 pCaps = priv->chains[0]->arStreamCaps[priv->chains[0]->nFormatUsed]; |
24744 | 3319 if (!pCaps) |
3320 return TVI_CONTROL_FALSE; | |
3321 if (height < pCaps->MinOutputSize.cy | |
3322 || height > pCaps->MaxOutputSize.cy) | |
3323 return TVI_CONTROL_FALSE; | |
3324 | |
3325 if (height % pCaps->OutputGranularityY) | |
3326 return TVI_CONTROL_FALSE; | |
3327 | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3328 return TVI_CONTROL_TRUE; |
24744 | 3329 } |
3330 case TVI_CONTROL_IS_AUDIO: | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3331 if (!priv->chains[1]->pmt) |
24744 | 3332 return TVI_CONTROL_FALSE; |
3333 else | |
3334 return TVI_CONTROL_TRUE; | |
3335 case TVI_CONTROL_IS_VIDEO: | |
3336 return TVI_CONTROL_TRUE; | |
3337 case TVI_CONTROL_AUD_GET_FORMAT: | |
3338 { | |
3339 *(int *) arg = AF_FORMAT_S16_LE; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3340 if (!priv->chains[1]->pmt) |
24744 | 3341 return TVI_CONTROL_FALSE; |
3342 else | |
3343 return TVI_CONTROL_TRUE; | |
3344 } | |
3345 case TVI_CONTROL_AUD_GET_CHANNELS: | |
3346 { | |
3347 *(int *) arg = priv->channels; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3348 if (!priv->chains[1]->pmt) |
24744 | 3349 return TVI_CONTROL_FALSE; |
3350 else | |
3351 return TVI_CONTROL_TRUE; | |
3352 } | |
3353 case TVI_CONTROL_AUD_SET_SAMPLERATE: | |
3354 { | |
3355 int i, samplerate; | |
3356 if (priv->state) | |
3357 return TVI_CONTROL_FALSE; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3358 if (!priv->chains[1]->arpmt[0]) |
24744 | 3359 return TVI_CONTROL_FALSE; |
3360 | |
28576 | 3361 samplerate = *(int *) arg; |
24744 | 3362 |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3363 for (i = 0; priv->chains[1]->arpmt[i]; i++) |
24744 | 3364 if (check_audio_format |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3365 (priv->chains[1]->arpmt[i], samplerate, 16, priv->channels)) |
24744 | 3366 break; |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
3367 if (!priv->chains[1]->arpmt[i]) { |
24744 | 3368 //request not found. failing back to first available |
3369 mp_msg(MSGT_TV, MSGL_WARN, MSGTR_TVI_DS_SamplerateNotsupported, samplerate); | |
3370 i = 0; | |
3371 } | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3372 if (priv->chains[1]->pmt) |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3373 DeleteMediaType(priv->chains[1]->pmt); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3374 priv->chains[1]->pmt = CreateMediaType(priv->chains[1]->arpmt[i]); |
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3375 extract_audio_format(priv->chains[1]->arpmt[i], &(priv->samplerate), |
24744 | 3376 NULL, &(priv->channels)); |
3377 return TVI_CONTROL_TRUE; | |
3378 } | |
3379 case TVI_CONTROL_AUD_GET_SAMPLERATE: | |
3380 { | |
3381 *(int *) arg = priv->samplerate; | |
3382 if (!priv->samplerate) | |
3383 return TVI_CONTROL_FALSE; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3384 if (!priv->chains[1]->pmt) |
24744 | 3385 return TVI_CONTROL_FALSE; |
3386 else | |
3387 return TVI_CONTROL_TRUE; | |
3388 } | |
3389 case TVI_CONTROL_AUD_GET_SAMPLESIZE: | |
3390 { | |
3391 WAVEFORMATEX *pWF; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3392 if (!priv->chains[1]->pmt) |
24744 | 3393 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3394 if (!priv->chains[1]->pmt->pbFormat) |
24744 | 3395 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3396 pWF = (WAVEFORMATEX *) priv->chains[1]->pmt->pbFormat; |
24744 | 3397 *(int *) arg = pWF->wBitsPerSample / 8; |
3398 return TVI_CONTROL_TRUE; | |
3399 } | |
3400 case TVI_CONTROL_IS_TUNER: | |
3401 { | |
3402 if (!priv->pTVTuner) | |
3403 return TVI_CONTROL_FALSE; | |
3404 | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3405 return TVI_CONTROL_TRUE; |
24744 | 3406 } |
3407 case TVI_CONTROL_TUN_SET_NORM: | |
3408 { | |
3409 IAMAnalogVideoDecoder *pVD; | |
3410 long lAnalogFormat; | |
3411 int i; | |
3412 HRESULT hr; | |
3413 | |
3414 i = *(int *) arg; | |
3415 i--; | |
3416 if (i < 0 || i >= tv_available_norms_count) | |
3417 return TVI_CONTROL_FALSE; | |
3418 lAnalogFormat = tv_norms[tv_available_norms[i]].index; | |
3419 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3420 hr = OLE_QUERYINTERFACE(priv->chains[0]->pCaptureFilter,IID_IAMAnalogVideoDecoder, pVD); |
29263
0f1b5b68af32
whitespace cosmetics: Remove all trailing whitespace.
diego
parents:
28576
diff
changeset
|
3421 if (hr != S_OK) |
24744 | 3422 return TVI_CONTROL_FALSE; |
25077 | 3423 hr = OLE_CALL_ARGS(pVD, put_TVFormat, lAnalogFormat); |
24744 | 3424 OLE_RELEASE_SAFE(pVD); |
3425 if (FAILED(hr)) | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3426 return TVI_CONTROL_FALSE; |
24744 | 3427 else |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3428 return TVI_CONTROL_TRUE; |
24744 | 3429 } |
3430 case TVI_CONTROL_TUN_GET_NORM: | |
3431 { | |
3432 long lAnalogFormat; | |
3433 int i; | |
3434 HRESULT hr; | |
3435 IAMAnalogVideoDecoder *pVD; | |
3436 | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3437 hr = OLE_QUERYINTERFACE(priv->chains[0]->pCaptureFilter,IID_IAMAnalogVideoDecoder, pVD); |
24744 | 3438 if (hr == S_OK) { |
3439 hr = OLE_CALL_ARGS(pVD, get_TVFormat, &lAnalogFormat); | |
3440 OLE_RELEASE_SAFE(pVD); | |
3441 } | |
3442 | |
3443 if (FAILED(hr)) { //trying another method | |
3444 if (!priv->pTVTuner) | |
3445 return TVI_CONTROL_FALSE; | |
3446 hr=OLE_CALL_ARGS(priv->pTVTuner, get_TVFormat, &lAnalogFormat); | |
3447 if (FAILED(hr)) | |
3448 return TVI_CONTROL_FALSE; | |
3449 } | |
3450 for (i = 0; i < tv_available_norms_count; i++) { | |
3451 if (tv_norms[tv_available_norms[i]].index == lAnalogFormat) { | |
3452 *(int *) arg = i + 1; | |
3453 return TVI_CONTROL_TRUE; | |
3454 } | |
3455 } | |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3456 return TVI_CONTROL_FALSE; |
24744 | 3457 } |
3458 case TVI_CONTROL_SPC_GET_NORMID: | |
3459 { | |
3460 int i; | |
3461 if (!priv->pTVTuner) | |
3462 return TVI_CONTROL_FALSE; | |
3463 for (i = 0; i < tv_available_norms_count; i++) { | |
3464 if (!strcasecmp | |
3465 (tv_norms[tv_available_norms[i]].name, (char *) arg)) { | |
3466 *(int *) arg = i + 1; | |
3467 return TVI_CONTROL_TRUE; | |
3468 } | |
3469 } | |
3470 return TVI_CONTROL_FALSE; | |
3471 } | |
3472 case TVI_CONTROL_SPC_SET_INPUT: | |
3473 { | |
3474 return set_crossbar_input(priv, *(int *) arg); | |
3475 } | |
3476 case TVI_CONTROL_TUN_GET_FREQ: | |
3477 { | |
3478 unsigned long lFreq; | |
3479 int ret; | |
3480 if (!priv->pTVTuner) | |
3481 return TVI_CONTROL_FALSE; | |
3482 | |
3483 ret = get_frequency(priv, &lFreq); | |
27628
1779bbc0733a
Fix overflow in frequency conversion code inside tvi_dshow.
voroshil
parents:
27370
diff
changeset
|
3484 lFreq = lFreq / (1000000/16); //convert from Hz to 1/16 MHz units |
24744 | 3485 |
3486 *(unsigned long *) arg = lFreq; | |
3487 return ret; | |
3488 } | |
3489 case TVI_CONTROL_TUN_SET_FREQ: | |
3490 { | |
3491 unsigned long nFreq = *(unsigned long *) arg; | |
3492 if (!priv->pTVTuner) | |
3493 return TVI_CONTROL_FALSE; | |
3494 //convert to Hz | |
27628
1779bbc0733a
Fix overflow in frequency conversion code inside tvi_dshow.
voroshil
parents:
27370
diff
changeset
|
3495 nFreq = (1000000/16) * nFreq; //convert from 1/16 MHz units to Hz |
24744 | 3496 return set_frequency(priv, nFreq); |
3497 } | |
3498 case TVI_CONTROL_VID_SET_HUE: | |
3499 return set_control(priv, VideoProcAmp_Hue, *(int *) arg); | |
3500 case TVI_CONTROL_VID_GET_HUE: | |
3501 return get_control(priv, VideoProcAmp_Hue, (int *) arg); | |
3502 case TVI_CONTROL_VID_SET_CONTRAST: | |
3503 return set_control(priv, VideoProcAmp_Contrast, *(int *) arg); | |
3504 case TVI_CONTROL_VID_GET_CONTRAST: | |
3505 return get_control(priv, VideoProcAmp_Contrast, (int *) arg); | |
3506 case TVI_CONTROL_VID_SET_SATURATION: | |
3507 return set_control(priv, VideoProcAmp_Saturation, *(int *) arg); | |
3508 case TVI_CONTROL_VID_GET_SATURATION: | |
3509 return get_control(priv, VideoProcAmp_Saturation, (int *) arg); | |
3510 case TVI_CONTROL_VID_SET_BRIGHTNESS: | |
3511 return set_control(priv, VideoProcAmp_Brightness, *(int *) arg); | |
3512 case TVI_CONTROL_VID_GET_BRIGHTNESS: | |
3513 return get_control(priv, VideoProcAmp_Brightness, (int *) arg); | |
3514 | |
3515 case TVI_CONTROL_VID_GET_FPS: | |
3516 { | |
3517 VIDEOINFOHEADER *Vhdr; | |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3518 if (!priv->chains[0]->pmt) |
24744 | 3519 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3520 if (!priv->chains[0]->pmt->pbFormat) |
24744 | 3521 return TVI_CONTROL_FALSE; |
25079
3dcf8e3e65d9
One step of code cleanup: move all variables, related
voroshil
parents:
25077
diff
changeset
|
3522 Vhdr = (VIDEOINFOHEADER *) priv->chains[0]->pmt->pbFormat; |
24744 | 3523 *(float *) arg = |
25028
2cae9470f53b
Fix FPS from bitrate calculation (was 8 times larger than real value).
voroshil
parents:
25019
diff
changeset
|
3524 (1.0 * Vhdr->dwBitRate) / (Vhdr->bmiHeader.biSizeImage * 8); |
24744 | 3525 return TVI_CONTROL_TRUE; |
3526 } | |
3527 case TVI_CONTROL_IMMEDIATE: | |
3528 priv->immediate_mode = 1; | |
3529 return TVI_CONTROL_TRUE; | |
3530 case TVI_CONTROL_VBI_INIT: | |
3531 { | |
3532 void* ptr; | |
3533 ptr=&(priv->tsp); | |
29760
1cc8a20520e8
Add MSGT_TELETEXT, rename TVI_CONTROL as VBI_CONTROL and fix some paths
cehoyos
parents:
29759
diff
changeset
|
3534 if(teletext_control(NULL,TV_VBI_CONTROL_START,&ptr)==VBI_CONTROL_TRUE) |
24744 | 3535 priv->priv_vbi=ptr; |
3536 else | |
3537 priv->priv_vbi=NULL; | |
3538 return TVI_CONTROL_TRUE; | |
3539 } | |
29806 | 3540 case TVI_CONTROL_GET_VBI_PTR: |
3541 *(void **)arg=priv->priv_vbi; | |
3542 return TVI_CONTROL_TRUE; | |
24744 | 3543 } |
26756
c43ce7268677
cosmetics: Remove useless parentheses from return statements.
diego
parents:
26737
diff
changeset
|
3544 return TVI_CONTROL_UNKNOWN; |
24744 | 3545 } |