1 |
//------------------------------------------------------------------------------
|
2 |
// File: DVDMedia.h
|
3 |
//
|
4 |
// Desc: Contains typedefs and defines necessary for user mode (ring 3) DVD
|
5 |
// filters and applications.
|
6 |
//
|
7 |
// This should be included in the DirectShow SDK for user mode filters.
|
8 |
// The types defined here should be kept in synch with ksmedia.h WDM
|
9 |
// DDK for kernel mode filters.
|
10 |
//
|
11 |
// Copyright (c) 1997 - 2000, Microsoft Corporation. All rights reserved.
|
12 |
//------------------------------------------------------------------------------
|
13 |
|
14 |
|
15 |
#ifndef __DVDMEDIA_H__
|
16 |
#define __DVDMEDIA_H__
|
17 |
|
18 |
#ifdef __cplusplus
|
19 |
extern "C" {
|
20 |
#endif // __cplusplus
|
21 |
|
22 |
// -----------------------------------------------------------------------
|
23 |
// AC-3 definition for the AM_KSPROPSETID_AC3 property set
|
24 |
// -----------------------------------------------------------------------
|
25 |
|
26 |
typedef enum {
|
27 |
AM_PROPERTY_AC3_ERROR_CONCEALMENT = 1,
|
28 |
AM_PROPERTY_AC3_ALTERNATE_AUDIO = 2,
|
29 |
AM_PROPERTY_AC3_DOWNMIX = 3,
|
30 |
AM_PROPERTY_AC3_BIT_STREAM_MODE = 4,
|
31 |
AM_PROPERTY_AC3_DIALOGUE_LEVEL = 5,
|
32 |
AM_PROPERTY_AC3_LANGUAGE_CODE = 6,
|
33 |
AM_PROPERTY_AC3_ROOM_TYPE = 7
|
34 |
} AM_PROPERTY_AC3;
|
35 |
|
36 |
typedef struct {
|
37 |
BOOL fRepeatPreviousBlock;
|
38 |
BOOL fErrorInCurrentBlock;
|
39 |
} AM_AC3_ERROR_CONCEALMENT, *PAM_AC3_ERROR_CONCEALMENT;
|
40 |
|
41 |
typedef struct {
|
42 |
BOOL fStereo;
|
43 |
ULONG DualMode;
|
44 |
} AM_AC3_ALTERNATE_AUDIO, *PAM_AC3_ALTERNATE_AUDIO;
|
45 |
|
46 |
#define AM_AC3_ALTERNATE_AUDIO_1 1
|
47 |
#define AM_AC3_ALTERNATE_AUDIO_2 2
|
48 |
#define AM_AC3_ALTERNATE_AUDIO_BOTH 3
|
49 |
|
50 |
typedef struct {
|
51 |
BOOL fDownMix;
|
52 |
BOOL fDolbySurround;
|
53 |
} AM_AC3_DOWNMIX, *PAM_AC3_DOWNMIX;
|
54 |
|
55 |
typedef struct {
|
56 |
LONG BitStreamMode;
|
57 |
} AM_AC3_BIT_STREAM_MODE, *PAM_AC3_BIT_STREAM_MODE;
|
58 |
|
59 |
#define AM_AC3_SERVICE_MAIN_AUDIO 0
|
60 |
#define AM_AC3_SERVICE_NO_DIALOG 1
|
61 |
#define AM_AC3_SERVICE_VISUALLY_IMPAIRED 2
|
62 |
#define AM_AC3_SERVICE_HEARING_IMPAIRED 3
|
63 |
#define AM_AC3_SERVICE_DIALOG_ONLY 4
|
64 |
#define AM_AC3_SERVICE_COMMENTARY 5
|
65 |
#define AM_AC3_SERVICE_EMERGENCY_FLASH 6
|
66 |
#define AM_AC3_SERVICE_VOICE_OVER 7
|
67 |
|
68 |
typedef struct {
|
69 |
ULONG DialogueLevel;
|
70 |
} AM_AC3_DIALOGUE_LEVEL, *PAM_AC3_DIALOGUE_LEVEL;
|
71 |
|
72 |
typedef struct {
|
73 |
BOOL fLargeRoom;
|
74 |
} AM_AC3_ROOM_TYPE, *PAM_AC3_ROOM_TYPE;
|
75 |
|
76 |
|
77 |
// -----------------------------------------------------------------------
|
78 |
// subpicture definition for the AM_KSPROPSETID_DvdSubPic property set
|
79 |
// -----------------------------------------------------------------------
|
80 |
|
81 |
typedef enum {
|
82 |
AM_PROPERTY_DVDSUBPIC_PALETTE = 0,
|
83 |
AM_PROPERTY_DVDSUBPIC_HLI = 1,
|
84 |
AM_PROPERTY_DVDSUBPIC_COMPOSIT_ON = 2 // TRUE for subpicture is displayed
|
85 |
} AM_PROPERTY_DVDSUBPIC;
|
86 |
|
87 |
typedef struct _AM_DVD_YUV {
|
88 |
UCHAR Reserved;
|
89 |
UCHAR Y;
|
90 |
UCHAR U;
|
91 |
UCHAR V;
|
92 |
} AM_DVD_YUV, *PAM_DVD_YUV;
|
93 |
|
94 |
typedef struct _AM_PROPERTY_SPPAL {
|
95 |
AM_DVD_YUV sppal[16];
|
96 |
} AM_PROPERTY_SPPAL, *PAM_PROPERTY_SPPAL;
|
97 |
|
98 |
typedef struct _AM_COLCON {
|
99 |
UCHAR emph1col:4;
|
100 |
UCHAR emph2col:4;
|
101 |
UCHAR backcol:4;
|
102 |
UCHAR patcol:4;
|
103 |
UCHAR emph1con:4;
|
104 |
UCHAR emph2con:4;
|
105 |
UCHAR backcon:4;
|
106 |
UCHAR patcon:4;
|
107 |
|
108 |
} AM_COLCON, *PAM_COLCON;
|
109 |
|
110 |
typedef struct _AM_PROPERTY_SPHLI {
|
111 |
USHORT HLISS; //
|
112 |
USHORT Reserved;
|
113 |
ULONG StartPTM; // start presentation time in x/90000
|
114 |
ULONG EndPTM; // end PTM in x/90000
|
115 |
USHORT StartX;
|
116 |
USHORT StartY;
|
117 |
USHORT StopX;
|
118 |
USHORT StopY;
|
119 |
AM_COLCON ColCon; // color contrast description (4 bytes as given in HLI)
|
120 |
} AM_PROPERTY_SPHLI, *PAM_PROPERTY_SPHLI;
|
121 |
|
122 |
typedef BOOL AM_PROPERTY_COMPOSIT_ON, *PAM_PROPERTY_COMPOSIT_ON;
|
123 |
|
124 |
|
125 |
|
126 |
// -----------------------------------------------------------------------
|
127 |
// copy protection definitions
|
128 |
// -----------------------------------------------------------------------
|
129 |
|
130 |
// AM_UseNewCSSKey for the dwTypeSpecificFlags in IMediaSample2 to indicate
|
131 |
// the exact point in a stream after which to start applying a new CSS key.
|
132 |
// This is typically sent on an empty media sample just before attempting
|
133 |
// to renegotiate a CSS key.
|
134 |
#define AM_UseNewCSSKey 0x1
|
135 |
|
136 |
//
|
137 |
// AM_KSPROPSETID_CopyProt property set definitions
|
138 |
//
|
139 |
typedef enum {
|
140 |
AM_PROPERTY_DVDCOPY_CHLG_KEY = 0x01,
|
141 |
AM_PROPERTY_DVDCOPY_DVD_KEY1 = 0x02,
|
142 |
AM_PROPERTY_DVDCOPY_DEC_KEY2 = 0x03,
|
143 |
AM_PROPERTY_DVDCOPY_TITLE_KEY = 0x04,
|
144 |
AM_PROPERTY_COPY_MACROVISION = 0x05,
|
145 |
AM_PROPERTY_DVDCOPY_REGION = 0x06,
|
146 |
AM_PROPERTY_DVDCOPY_SET_COPY_STATE = 0x07,
|
147 |
AM_PROPERTY_DVDCOPY_DISC_KEY = 0x80
|
148 |
} AM_PROPERTY_DVDCOPYPROT;
|
149 |
|
150 |
typedef struct _AM_DVDCOPY_CHLGKEY {
|
151 |
BYTE ChlgKey[10];
|
152 |
BYTE Reserved[2];
|
153 |
} AM_DVDCOPY_CHLGKEY, *PAM_DVDCOPY_CHLGKEY;
|
154 |
|
155 |
typedef struct _AM_DVDCOPY_BUSKEY {
|
156 |
BYTE BusKey[5];
|
157 |
BYTE Reserved[1];
|
158 |
} AM_DVDCOPY_BUSKEY, *PAM_DVDCOPY_BUSKEY;
|
159 |
|
160 |
typedef struct _AM_DVDCOPY_DISCKEY {
|
161 |
BYTE DiscKey[2048];
|
162 |
} AM_DVDCOPY_DISCKEY, *PAM_DVDCOPY_DISCKEY;
|
163 |
|
164 |
typedef struct AM_DVDCOPY_TITLEKEY {
|
165 |
ULONG KeyFlags;
|
166 |
ULONG Reserved1[2];
|
167 |
UCHAR TitleKey[6];
|
168 |
UCHAR Reserved2[2];
|
169 |
} AM_DVDCOPY_TITLEKEY, *PAM_DVDCOPY_TITLEKEY;
|
170 |
|
171 |
typedef struct _AM_COPY_MACROVISION {
|
172 |
ULONG MACROVISIONLevel;
|
173 |
} AM_COPY_MACROVISION, *PAM_COPY_MACROVISION;
|
174 |
|
175 |
typedef struct AM_DVDCOPY_SET_COPY_STATE {
|
176 |
ULONG DVDCopyState;
|
177 |
} AM_DVDCOPY_SET_COPY_STATE, *PAM_DVDCOPY_SET_COPY_STATE;
|
178 |
|
179 |
typedef enum {
|
180 |
AM_DVDCOPYSTATE_INITIALIZE = 0,
|
181 |
AM_DVDCOPYSTATE_INITIALIZE_TITLE = 1, // indicates we are starting a title
|
182 |
// key copy protection sequence
|
183 |
AM_DVDCOPYSTATE_AUTHENTICATION_NOT_REQUIRED = 2,
|
184 |
AM_DVDCOPYSTATE_AUTHENTICATION_REQUIRED = 3,
|
185 |
AM_DVDCOPYSTATE_DONE = 4
|
186 |
} AM_DVDCOPYSTATE;
|
187 |
|
188 |
typedef enum {
|
189 |
AM_MACROVISION_DISABLED = 0,
|
190 |
AM_MACROVISION_LEVEL1 = 1,
|
191 |
AM_MACROVISION_LEVEL2 = 2,
|
192 |
AM_MACROVISION_LEVEL3 = 3
|
193 |
} AM_COPY_MACROVISION_LEVEL, *PAM_COPY_MACROVISION_LEVEL;
|
194 |
|
195 |
|
196 |
// CSS region stucture
|
197 |
typedef struct _DVD_REGION {
|
198 |
UCHAR CopySystem;
|
199 |
UCHAR RegionData;
|
200 |
UCHAR SystemRegion;
|
201 |
UCHAR Reserved;
|
202 |
} DVD_REGION, *PDVD_REGION;
|
203 |
|
204 |
//
|
205 |
// CGMS Copy Protection Flags
|
206 |
//
|
207 |
|
208 |
#define AM_DVD_CGMS_RESERVED_MASK 0x00000078
|
209 |
|
210 |
#define AM_DVD_CGMS_COPY_PROTECT_MASK 0x00000018
|
211 |
#define AM_DVD_CGMS_COPY_PERMITTED 0x00000000
|
212 |
#define AM_DVD_CGMS_COPY_ONCE 0x00000010
|
213 |
#define AM_DVD_CGMS_NO_COPY 0x00000018
|
214 |
|
215 |
#define AM_DVD_COPYRIGHT_MASK 0x00000040
|
216 |
#define AM_DVD_NOT_COPYRIGHTED 0x00000000
|
217 |
#define AM_DVD_COPYRIGHTED 0x00000040
|
218 |
|
219 |
#define AM_DVD_SECTOR_PROTECT_MASK 0x00000020
|
220 |
#define AM_DVD_SECTOR_NOT_PROTECTED 0x00000000
|
221 |
#define AM_DVD_SECTOR_PROTECTED 0x00000020
|
222 |
|
223 |
|
224 |
// -----------------------------------------------------------------------
|
225 |
// video format blocks
|
226 |
// -----------------------------------------------------------------------
|
227 |
|
228 |
enum AM_MPEG2Level {
|
229 |
AM_MPEG2Level_Low = 1,
|
230 |
AM_MPEG2Level_Main = 2,
|
231 |
AM_MPEG2Level_High1440 = 3,
|
232 |
AM_MPEG2Level_High = 4
|
233 |
};
|
234 |
|
235 |
enum AM_MPEG2Profile {
|
236 |
AM_MPEG2Profile_Simple = 1,
|
237 |
AM_MPEG2Profile_Main = 2,
|
238 |
AM_MPEG2Profile_SNRScalable = 3,
|
239 |
AM_MPEG2Profile_SpatiallyScalable = 4,
|
240 |
AM_MPEG2Profile_High = 5
|
241 |
};
|
242 |
|
243 |
#define AMINTERLACE_IsInterlaced 0x00000001 // if 0, other interlace bits are irrelevent
|
244 |
#define AMINTERLACE_1FieldPerSample 0x00000002 // else 2 fields per media sample
|
245 |
#define AMINTERLACE_Field1First 0x00000004 // else Field 2 is first; top field in PAL is field 1, top field in NTSC is field 2?
|
246 |
#define AMINTERLACE_UNUSED 0x00000008 //
|
247 |
#define AMINTERLACE_FieldPatternMask 0x00000030 // use this mask with AMINTERLACE_FieldPat*
|
248 |
#define AMINTERLACE_FieldPatField1Only 0x00000000 // stream never contains a Field2
|
249 |
#define AMINTERLACE_FieldPatField2Only 0x00000010 // stream never contains a Field1
|
250 |
#define AMINTERLACE_FieldPatBothRegular 0x00000020 // There will be a Field2 for every Field1 (required for Weave?)
|
251 |
#define AMINTERLACE_FieldPatBothIrregular 0x00000030 // Random pattern of Field1s and Field2s
|
252 |
#define AMINTERLACE_DisplayModeMask 0x000000c0
|
253 |
#define AMINTERLACE_DisplayModeBobOnly 0x00000000
|
254 |
#define AMINTERLACE_DisplayModeWeaveOnly 0x00000040
|
255 |
#define AMINTERLACE_DisplayModeBobOrWeave 0x00000080
|
256 |
|
257 |
#define AMCOPYPROTECT_RestrictDuplication 0x00000001 // duplication of this stream should be restricted
|
258 |
|
259 |
#define AMMPEG2_DoPanScan 0x00000001 //if set, the MPEG-2 video decoder should crop output image
|
260 |
// based on pan-scan vectors in picture_display_extension
|
261 |
// and change the picture aspect ratio accordingly.
|
262 |
#define AMMPEG2_DVDLine21Field1 0x00000002 //if set, the MPEG-2 decoder must be able to produce an output
|
263 |
// pin for DVD style closed caption data found in GOP layer of field 1
|
264 |
#define AMMPEG2_DVDLine21Field2 0x00000004 //if set, the MPEG-2 decoder must be able to produce an output
|
265 |
// pin for DVD style closed caption data found in GOP layer of field 2
|
266 |
#define AMMPEG2_SourceIsLetterboxed 0x00000008 //if set, indicates that black bars have been encoded in the top
|
267 |
// and bottom of the video.
|
268 |
#define AMMPEG2_FilmCameraMode 0x00000010 //if set, indicates "film mode" used for 625/50 content. If cleared,
|
269 |
// indicates that "camera mode" was used.
|
270 |
#define AMMPEG2_LetterboxAnalogOut 0x00000020 //if set and this stream is sent to an analog output, it should
|
271 |
// be letterboxed. Streams sent to VGA should be letterboxed only by renderers.
|
272 |
|
273 |
|
274 |
typedef struct tagVIDEOINFOHEADER2 {
|
275 |
RECT rcSource;
|
276 |
RECT rcTarget;
|
277 |
DWORD dwBitRate;
|
278 |
DWORD dwBitErrorRate;
|
279 |
REFERENCE_TIME AvgTimePerFrame;
|
280 |
DWORD dwInterlaceFlags; // use AMINTERLACE_* defines. Reject connection if undefined bits are not 0
|
281 |
DWORD dwCopyProtectFlags; // use AMCOPYPROTECT_* defines. Reject connection if undefined bits are not 0
|
282 |
DWORD dwPictAspectRatioX; // X dimension of picture aspect ratio, e.g. 16 for 16x9 display
|
283 |
DWORD dwPictAspectRatioY; // Y dimension of picture aspect ratio, e.g. 9 for 16x9 display
|
284 |
DWORD dwReserved1; // must be 0; reject connection otherwise
|
285 |
DWORD dwReserved2; // must be 0; reject connection otherwise
|
286 |
BITMAPINFOHEADER bmiHeader;
|
287 |
} VIDEOINFOHEADER2;
|
288 |
|
289 |
typedef struct tagMPEG2VIDEOINFO {
|
290 |
VIDEOINFOHEADER2 hdr;
|
291 |
DWORD dwStartTimeCode; // ?? not used for DVD ??
|
292 |
DWORD cbSequenceHeader; // is 0 for DVD (no sequence header)
|
293 |
DWORD dwProfile; // use enum MPEG2Profile
|
294 |
DWORD dwLevel; // use enum MPEG2Level
|
295 |
DWORD dwFlags; // use AMMPEG2_* defines. Reject connection if undefined bits are not 0
|
296 |
DWORD dwSequenceHeader[1]; // DWORD instead of Byte for alignment purposes
|
297 |
// For MPEG-2, if a sequence_header is included, the sequence_extension
|
298 |
// should also be included
|
299 |
} MPEG2VIDEOINFO;
|
300 |
|
301 |
#define SIZE_MPEG2VIDEOINFO(pv) (FIELD_OFFSET(MPEG2VIDEOINFO, dwSequenceHeader[0]) + (pv)->cbSequenceHeader)
|
302 |
|
303 |
// do not use
|
304 |
#define MPEG1_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->bSequenceHeader)
|
305 |
|
306 |
// use this macro instead, the previous only works for MPEG1VIDEOINFO structures
|
307 |
#define MPEG2_SEQUENCE_INFO(pv) ((const BYTE *)(pv)->dwSequenceHeader)
|
308 |
|
309 |
|
310 |
//===================================================================================
|
311 |
// flags for dwTypeSpecificFlags in AM_SAMPLE2_PROPERTIES which define type specific
|
312 |
// data in IMediaSample2
|
313 |
//===================================================================================
|
314 |
|
315 |
#define AM_VIDEO_FLAG_FIELD_MASK 0x0003L // use this mask to check whether the sample is field1 or field2 or frame
|
316 |
#define AM_VIDEO_FLAG_INTERLEAVED_FRAME 0x0000L // the sample is a frame (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
|
317 |
#define AM_VIDEO_FLAG_FIELD1 0x0001L // the sample is field1 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
|
318 |
#define AM_VIDEO_FLAG_FIELD2 0x0002L // the sample is the field2 (remember to use AM_VIDEO_FLAG_FIELD_MASK when using this)
|
319 |
#define AM_VIDEO_FLAG_FIELD1FIRST 0x0004L // if set means display field1 first, else display field2 first.
|
320 |
// this bit is irrelavant for 1FieldPerSample mode
|
321 |
#define AM_VIDEO_FLAG_WEAVE 0x0008L // if set use bob display mode else weave
|
322 |
#define AM_VIDEO_FLAG_IPB_MASK 0x0030L // use this mask to check whether the sample is I, P or B
|
323 |
#define AM_VIDEO_FLAG_I_SAMPLE 0x0000L // I Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
|
324 |
#define AM_VIDEO_FLAG_P_SAMPLE 0x0010L // P Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
|
325 |
#define AM_VIDEO_FLAG_B_SAMPLE 0x0020L // B Sample (remember to use AM_VIDEO_FLAG_IPB_MASK when using this)
|
326 |
#define AM_VIDEO_FLAG_REPEAT_FIELD 0x0040L // if set means display the field which has been displayed first again after displaying
|
327 |
// both fields first. This bit is irrelavant for 1FieldPerSample mode
|
328 |
|
329 |
// -----------------------------------------------------------------------
|
330 |
// AM_KSPROPSETID_DvdKaraoke property set definitions
|
331 |
// -----------------------------------------------------------------------
|
332 |
|
333 |
typedef struct tagAM_DvdKaraokeData
|
334 |
{
|
335 |
DWORD dwDownmix; // bitwise OR of AM_DvdKaraoke_Downmix flags
|
336 |
DWORD dwSpeakerAssignment; // AM_DvdKaraoke_SpeakerAssignment
|
337 |
} AM_DvdKaraokeData;
|
338 |
|
339 |
typedef enum {
|
340 |
AM_PROPERTY_DVDKARAOKE_ENABLE = 0, // BOOL
|
341 |
AM_PROPERTY_DVDKARAOKE_DATA = 1,
|
342 |
} AM_PROPERTY_DVDKARAOKE;
|
343 |
|
344 |
// -----------------------------------------------------------------------
|
345 |
// AM_KSPROPSETID_TSRateChange property set definitions for time stamp
|
346 |
// rate changes.
|
347 |
// -----------------------------------------------------------------------
|
348 |
|
349 |
typedef enum {
|
350 |
AM_RATE_SimpleRateChange = 1, // rw, use AM_SimpleRateChange
|
351 |
AM_RATE_ExactRateChange = 2, // rw, use AM_ExactRateChange
|
352 |
AM_RATE_MaxFullDataRate = 3, // r, use AM_MaxFullDataRate
|
353 |
AM_RATE_Step = 4 // w, use AM_Step
|
354 |
} AM_PROPERTY_TS_RATE_CHANGE;
|
355 |
|
356 |
// -------------------------------------------------------------------
|
357 |
// AM_KSPROPSETID_DVD_RateChange property set definitions for new DVD
|
358 |
// rate change scheme.
|
359 |
// -------------------------------------------------------------------
|
360 |
|
361 |
typedef enum {
|
362 |
AM_RATE_ChangeRate = 1, // w, use AM_DVD_ChangeRate
|
363 |
AM_RATE_FullDataRateMax = 2, // r, use AM_MaxFullDataRate
|
364 |
AM_RATE_ReverseDecode = 3, // r, use LONG
|
365 |
AM_RATE_DecoderPosition = 4, // r, use AM_DVD_DecoderPosition
|
366 |
AM_RATE_DecoderVersion = 5 // r, use LONG
|
367 |
} AM_PROPERTY_DVD_RATE_CHANGE;
|
368 |
|
369 |
typedef struct {
|
370 |
// this is the simplest mechanism to set a time stamp rate change on
|
371 |
// a filter (simplest for the person setting the rate change, harder
|
372 |
// for the filter doing the rate change).
|
373 |
REFERENCE_TIME StartTime; //stream time at which to start this rate
|
374 |
LONG Rate; //new rate * 10000 (decimal)
|
375 |
} AM_SimpleRateChange;
|
376 |
|
377 |
typedef struct {
|
378 |
REFERENCE_TIME OutputZeroTime; //input TS that maps to zero output TS
|
379 |
LONG Rate; //new rate * 10000 (decimal)
|
380 |
} AM_ExactRateChange;
|
381 |
|
382 |
typedef LONG AM_MaxFullDataRate; //rate * 10000 (decimal)
|
383 |
|
384 |
typedef DWORD AM_Step; // number of frame to step
|
385 |
|
386 |
// New rate change property set, structs. enums etc.
|
387 |
typedef struct {
|
388 |
REFERENCE_TIME StartInTime; // stream time (input) at which to start decoding at this rate
|
389 |
REFERENCE_TIME StartOutTime; // reference time (output) at which to start showing at this rate
|
390 |
LONG Rate; // new rate * 10000 (decimal)
|
391 |
} AM_DVD_ChangeRate ;
|
392 |
|
393 |
typedef LONGLONG AM_DVD_DecoderPosition ;
|
394 |
|
395 |
typedef enum {
|
396 |
DVD_DIR_FORWARD = 0,
|
397 |
DVD_DIR_BACKWARD = 1
|
398 |
} DVD_PLAY_DIRECTION ;
|
399 |
|
400 |
#ifdef __cplusplus
|
401 |
}
|
402 |
#endif // __cplusplus
|
403 |
#endif // __DVDMEDIA_H__
|