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