~oah-dev/oah/gst-plugins-bad

« back to all changes in this revision

Viewing changes to sys/winks/ksvideohelpers.c

  • Committer: Haakon Sporsheim
  • Date: 2009-03-12 13:52:03 UTC
  • Revision ID: haakon.sporsheim@tandberg.com-20090312135203-i5k294hgkushb0mt
Initial import of git repository: git://anongit.freedesktop.org/gstreamer/gst-plugins-bad (tag: RELEASE-0_10_10)

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2007 Haakon Sporsheim <hakon.sporsheim@tandberg.com>
 
3
 *               2008 Ole Andr� Vadla Ravn�s <ole.andre.ravnas@tandberg.com>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License as published by the Free Software Foundation; either
 
8
 * version 2 of the License, or (at your option) any later version.
 
9
 *
 
10
 * This library is distributed in the hope that it will be useful,
 
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
13
 * Library General Public License for more details.
 
14
 *
 
15
 * You should have received a copy of the GNU Library General Public
 
16
 * License along with this library; if not, write to the
 
17
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 
18
 * Boston, MA 02111-1307, USA.
 
19
 */
 
20
 
 
21
#include "ksvideohelpers.h"
 
22
 
 
23
#include <uuids.h>
 
24
#include "kshelpers.h"
 
25
 
 
26
GST_DEBUG_CATEGORY_EXTERN (gst_ks_debug);
 
27
#define GST_CAT_DEFAULT gst_ks_debug
 
28
 
 
29
static const GUID MEDIASUBTYPE_FOURCC =
 
30
    { 0x0 /* FourCC here */ , 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00,
 
31
    0x38, 0x9B, 0x71}
 
32
};
 
33
 
 
34
extern const GUID MEDIASUBTYPE_I420 =
 
35
    { 0x30323449, 0x0000, 0x0010, {0x80, 0x00, 0x00, 0xAA, 0x00, 0x38, 0x9B,
 
36
    0x71}
 
37
};
 
38
 
 
39
static GstStructure *
 
40
ks_video_format_to_structure (GUID subtype_guid, GUID format_guid)
 
41
{
 
42
  GstStructure *structure = NULL;
 
43
 
 
44
  if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_MJPG) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_TVMJ) ||     /* FIXME: NOT tested */
 
45
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_WAKE) ||        /* FIXME: NOT tested */
 
46
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_CFCC) ||        /* FIXME: NOT tested */
 
47
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_IJPG)) {        /* FIXME: NOT tested */
 
48
    structure = gst_structure_new ("image/jpeg", NULL);
 
49
  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555) ||       /* FIXME: NOT tested */
 
50
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565) ||      /* FIXME: NOT tested */
 
51
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24) || IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32) ||   /* FIXME: NOT tested */
 
52
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555) ||    /* FIXME: NOT tested */
 
53
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32) ||      /* FIXME: NOT tested */
 
54
      IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {    /* FIXME: NOT tested */
 
55
    guint depth = 0, bpp = 0;
 
56
    gint endianness = 0;
 
57
    guint32 r_mask = 0, b_mask = 0, g_mask = 0;
 
58
 
 
59
    if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB555)) {
 
60
      bpp = 16;
 
61
      depth = 15;
 
62
      endianness = G_BIG_ENDIAN;
 
63
      r_mask = 0x7c00;
 
64
      g_mask = 0x03e0;
 
65
      b_mask = 0x001f;
 
66
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB565)) {
 
67
      bpp = depth = 16;
 
68
      endianness = G_BIG_ENDIAN;
 
69
      r_mask = 0xf800;
 
70
      g_mask = 0x07e0;
 
71
      b_mask = 0x001f;
 
72
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB24)) {
 
73
      bpp = depth = 24;
 
74
      endianness = G_BIG_ENDIAN;
 
75
      r_mask = 0x0000ff;
 
76
      g_mask = 0x00ff00;
 
77
      b_mask = 0xff0000;
 
78
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_RGB32)) {
 
79
      bpp = 32;
 
80
      depth = 24;
 
81
      endianness = G_BIG_ENDIAN;
 
82
      r_mask = 0x000000ff;
 
83
      g_mask = 0x0000ff00;
 
84
      b_mask = 0x00ff0000;
 
85
      /* FIXME: check
 
86
       *r_mask = 0xff000000;
 
87
       *g_mask = 0x00ff0000;
 
88
       *b_mask = 0x0000ff00;
 
89
       */
 
90
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB1555)) {
 
91
      bpp = 16;
 
92
      depth = 15;
 
93
      endianness = G_BIG_ENDIAN;
 
94
      r_mask = 0x7c00;
 
95
      g_mask = 0x03e0;
 
96
      b_mask = 0x001f;
 
97
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB32)) {
 
98
      bpp = depth = 32;
 
99
      endianness = G_BIG_ENDIAN;
 
100
      r_mask = 0x000000ff;
 
101
      g_mask = 0x0000ff00;
 
102
      b_mask = 0x00ff0000;
 
103
      /* FIXME: check
 
104
       *r_mask = 0xff000000;
 
105
       *g_mask = 0x00ff0000;
 
106
       *b_mask = 0x0000ff00;
 
107
       */
 
108
    } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_ARGB4444)) {
 
109
      bpp = 16;
 
110
      depth = 12;
 
111
      endianness = G_BIG_ENDIAN;
 
112
      r_mask = 0x0f00;
 
113
      g_mask = 0x00f0;
 
114
      b_mask = 0x000f;
 
115
      //r_mask = 0x000f;
 
116
      //g_mask = 0x00f0;
 
117
      //b_mask = 0x0f00;
 
118
    } else {
 
119
      g_assert_not_reached ();
 
120
    }
 
121
 
 
122
    structure = gst_structure_new ("video/x-raw-rgb",
 
123
        "bpp", G_TYPE_INT, bpp,
 
124
        "depth", G_TYPE_INT, depth,
 
125
        "red_mask", G_TYPE_INT, r_mask,
 
126
        "green_mask", G_TYPE_INT, g_mask,
 
127
        "blue_mask", G_TYPE_INT, b_mask,
 
128
        "endianness", G_TYPE_INT, endianness, NULL);
 
129
  } else if (IsEqualGUID (&subtype_guid, &MEDIASUBTYPE_dvsd)) {
 
130
    if (IsEqualGUID (&format_guid, &FORMAT_DvInfo)) {
 
131
      structure = gst_structure_new ("video/x-dv",
 
132
          "systemstream", G_TYPE_BOOLEAN, TRUE, NULL);
 
133
    } else if (IsEqualGUID (&format_guid, &FORMAT_VideoInfo)) {
 
134
      structure = gst_structure_new ("video/x-dv",
 
135
          "systemstream", G_TYPE_BOOLEAN, FALSE,
 
136
          "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('d', 'v', 's', 'd'),
 
137
          NULL);
 
138
    }
 
139
  } else if (memcmp (&subtype_guid.Data2, &MEDIASUBTYPE_FOURCC.Data2,
 
140
          sizeof (subtype_guid) - sizeof (subtype_guid.Data1)) == 0) {
 
141
    guint8 *p = (guint8 *) & subtype_guid.Data1;
 
142
 
 
143
    structure = gst_structure_new ("video/x-raw-yuv",
 
144
        "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC (p[0], p[1], p[2], p[3]),
 
145
        NULL);
 
146
  }
 
147
 
 
148
  if (!structure) {
 
149
    GST_DEBUG ("Unknown DirectShow Video GUID %08x-%04x-%04x-%04x-%08x%04x",
 
150
        subtype_guid.Data1, subtype_guid.Data2, subtype_guid.Data3,
 
151
        *(WORD *) subtype_guid.Data4, *(DWORD *) & subtype_guid.Data4[2],
 
152
        *(WORD *) & subtype_guid.Data4[6]);
 
153
  }
 
154
 
 
155
  return structure;
 
156
}
 
157
 
 
158
static gboolean
 
159
ks_video_append_video_stream_cfg_fields (GstStructure * structure,
 
160
    const KS_VIDEO_STREAM_CONFIG_CAPS * vscc)
 
161
{
 
162
  g_return_val_if_fail (structure, FALSE);
 
163
  g_return_val_if_fail (vscc, FALSE);
 
164
 
 
165
  /* width */
 
166
  if (vscc->MinOutputSize.cx == vscc->MaxOutputSize.cx) {
 
167
    gst_structure_set (structure,
 
168
        "width", G_TYPE_INT, vscc->MaxOutputSize.cx, NULL);
 
169
  } else {
 
170
    gst_structure_set (structure,
 
171
        "width", GST_TYPE_INT_RANGE,
 
172
        vscc->MinOutputSize.cx, vscc->MaxOutputSize.cx, NULL);
 
173
  }
 
174
 
 
175
  /* height */
 
176
  if (vscc->MinOutputSize.cy == vscc->MaxOutputSize.cy) {
 
177
    gst_structure_set (structure,
 
178
        "height", G_TYPE_INT, vscc->MaxOutputSize.cy, NULL);
 
179
  } else {
 
180
    gst_structure_set (structure,
 
181
        "height", GST_TYPE_INT_RANGE,
 
182
        vscc->MinOutputSize.cy, vscc->MaxOutputSize.cy, NULL);
 
183
  }
 
184
 
 
185
  /* framerate */
 
186
  if (vscc->MinFrameInterval == vscc->MaxFrameInterval) {
 
187
    gst_structure_set (structure,
 
188
        "framerate", GST_TYPE_FRACTION,
 
189
        (gint) (10000000 / vscc->MaxFrameInterval), 1, NULL);
 
190
  } else {
 
191
    gst_structure_set (structure,
 
192
        "framerate", GST_TYPE_FRACTION_RANGE,
 
193
        (gint) (10000000 / vscc->MaxFrameInterval), 1,
 
194
        (gint) (10000000 / vscc->MinFrameInterval), 1, NULL);
 
195
  }
 
196
 
 
197
  return TRUE;
 
198
}
 
199
 
 
200
KsVideoMediaType *
 
201
ks_video_media_type_dup (KsVideoMediaType * media_type)
 
202
{
 
203
  KsVideoMediaType *result = g_new (KsVideoMediaType, 1);
 
204
 
 
205
  memcpy (result, media_type, sizeof (KsVideoMediaType));
 
206
 
 
207
  result->range = g_malloc (media_type->range->FormatSize);
 
208
  memcpy ((gpointer) result->range, media_type->range,
 
209
      media_type->range->FormatSize);
 
210
 
 
211
  result->format = g_malloc (media_type->format_size);
 
212
  memcpy (result->format, media_type->format, media_type->format_size);
 
213
 
 
214
  result->translated_caps = gst_caps_ref (media_type->translated_caps);
 
215
 
 
216
  return result;
 
217
}
 
218
 
 
219
void
 
220
ks_video_media_type_free (KsVideoMediaType * media_type)
 
221
{
 
222
  if (media_type == NULL)
 
223
    return;
 
224
 
 
225
  g_free ((gpointer) media_type->range);
 
226
 
 
227
  g_free (media_type->format);
 
228
 
 
229
  if (media_type->translated_caps != NULL)
 
230
    gst_caps_unref (media_type->translated_caps);
 
231
 
 
232
  g_free (media_type);
 
233
}
 
234
 
 
235
static GList *
 
236
ks_video_media_type_list_remove_duplicates (GList * media_types)
 
237
{
 
238
  GList *master, *duplicates;
 
239
 
 
240
  do {
 
241
    GList *entry;
 
242
 
 
243
    master = duplicates = NULL;
 
244
 
 
245
    /* Find the first set of duplicates and their master */
 
246
    for (entry = media_types; entry != NULL && duplicates == NULL;
 
247
        entry = entry->next) {
 
248
      KsVideoMediaType *mt = entry->data;
 
249
      GList *other_entry;
 
250
 
 
251
      for (other_entry = media_types; other_entry != NULL;
 
252
          other_entry = other_entry->next) {
 
253
        KsVideoMediaType *other_mt = other_entry->data;
 
254
 
 
255
        if (other_mt == mt)
 
256
          continue;
 
257
 
 
258
        if (gst_caps_is_equal (mt->translated_caps, other_mt->translated_caps))
 
259
          duplicates = g_list_prepend (duplicates, other_mt);
 
260
      }
 
261
 
 
262
      if (duplicates != NULL)
 
263
        master = entry;
 
264
    }
 
265
 
 
266
    if (duplicates != NULL) {
 
267
      KsVideoMediaType *selected_mt = master->data;
 
268
 
 
269
      /*
 
270
       * Pick a FORMAT_VideoInfo2 if present, if not we just stay with the
 
271
       * first entry
 
272
       */
 
273
      for (entry = duplicates; entry != NULL; entry = entry->next) {
 
274
        KsVideoMediaType *mt = entry->data;
 
275
 
 
276
        if (IsEqualGUID (&mt->range->Specifier, &FORMAT_VideoInfo2)) {
 
277
          ks_video_media_type_free (selected_mt);
 
278
          selected_mt = mt;
 
279
        } else {
 
280
          ks_video_media_type_free (mt);
 
281
        }
 
282
 
 
283
        /* Remove the dupe from the main list */
 
284
        media_types = g_list_remove (media_types, mt);
 
285
      }
 
286
 
 
287
      /* Update master node with the selected MediaType */
 
288
      master->data = selected_mt;
 
289
 
 
290
      g_list_free (duplicates);
 
291
    }
 
292
  }
 
293
  while (master != NULL);
 
294
 
 
295
  return media_types;
 
296
}
 
297
 
 
298
GList *
 
299
ks_video_probe_filter_for_caps (HANDLE filter_handle)
 
300
{
 
301
  GList *ret = NULL;
 
302
  gulong pin_count;
 
303
  guint pin_id;
 
304
 
 
305
  if (!ks_filter_get_pin_property (filter_handle, 0, KSPROPSETID_Pin,
 
306
          KSPROPERTY_PIN_CTYPES, &pin_count, sizeof (pin_count)))
 
307
    goto beach;
 
308
 
 
309
  GST_DEBUG ("pin_count = %d", pin_count);
 
310
 
 
311
  for (pin_id = 0; pin_id < pin_count; pin_id++) {
 
312
    KSPIN_COMMUNICATION pin_comm;
 
313
    KSPIN_DATAFLOW pin_flow;
 
314
    GUID pin_cat;
 
315
 
 
316
    if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
 
317
            KSPROPERTY_PIN_COMMUNICATION, &pin_comm, sizeof (pin_comm)))
 
318
      continue;
 
319
 
 
320
    if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
 
321
            KSPROPERTY_PIN_DATAFLOW, &pin_flow, sizeof (pin_flow)))
 
322
      continue;
 
323
 
 
324
    if (!ks_filter_get_pin_property (filter_handle, pin_id, KSPROPSETID_Pin,
 
325
            KSPROPERTY_PIN_CATEGORY, &pin_cat, sizeof (pin_cat)))
 
326
      continue;
 
327
 
 
328
    GST_DEBUG ("pin[%d]: pin_comm=%d, pin_flow=%d", pin_id, pin_comm, pin_flow);
 
329
 
 
330
    if (pin_flow == KSPIN_DATAFLOW_OUT &&
 
331
        memcmp (&pin_cat, &PINNAME_CAPTURE, sizeof (GUID)) == 0) {
 
332
      KSMULTIPLE_ITEM *items;
 
333
 
 
334
      if (ks_filter_get_pin_property_multi (filter_handle, pin_id,
 
335
              KSPROPSETID_Pin, KSPROPERTY_PIN_DATARANGES, &items)) {
 
336
        KSDATARANGE *range = (KSDATARANGE *) (items + 1);
 
337
        guint i;
 
338
 
 
339
        for (i = 0; i < items->Count; i++) {
 
340
          if (IsEqualGUID (&range->MajorFormat, &KSDATAFORMAT_TYPE_VIDEO)) {
 
341
            KsVideoMediaType *entry;
 
342
            gpointer src_vscc, src_format;
 
343
            GstStructure *media_structure;
 
344
 
 
345
            entry = g_new0 (KsVideoMediaType, 1);
 
346
            entry->pin_id = pin_id;
 
347
 
 
348
            entry->range = g_malloc (range->FormatSize);
 
349
            memcpy ((gpointer) entry->range, range, range->FormatSize);
 
350
 
 
351
            if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo)) {
 
352
              KS_DATARANGE_VIDEO *vr = (KS_DATARANGE_VIDEO *) entry->range;
 
353
 
 
354
              src_vscc = &vr->ConfigCaps;
 
355
              src_format = &vr->VideoInfoHeader;
 
356
 
 
357
              entry->format_size = sizeof (vr->VideoInfoHeader);
 
358
              entry->sample_size = vr->VideoInfoHeader.bmiHeader.biSizeImage;
 
359
            } else if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo2)) {
 
360
              KS_DATARANGE_VIDEO2 *vr = (KS_DATARANGE_VIDEO2 *) entry->range;
 
361
 
 
362
              src_vscc = &vr->ConfigCaps;
 
363
              src_format = &vr->VideoInfoHeader;
 
364
 
 
365
              entry->format_size = sizeof (vr->VideoInfoHeader);
 
366
              entry->sample_size = vr->VideoInfoHeader.bmiHeader.biSizeImage;
 
367
            } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEGVideo)) {
 
368
              /* Untested and probably wrong... */
 
369
              KS_DATARANGE_MPEG1_VIDEO *vr =
 
370
                  (KS_DATARANGE_MPEG1_VIDEO *) entry->range;
 
371
 
 
372
              src_vscc = &vr->ConfigCaps;
 
373
              src_format = &vr->VideoInfoHeader;
 
374
 
 
375
              entry->format_size = sizeof (vr->VideoInfoHeader);
 
376
              entry->sample_size =
 
377
                  vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
 
378
            } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) {
 
379
              /* Untested and probably wrong... */
 
380
              KS_DATARANGE_MPEG2_VIDEO *vr =
 
381
                  (KS_DATARANGE_MPEG2_VIDEO *) entry->range;
 
382
 
 
383
              src_vscc = &vr->ConfigCaps;
 
384
              src_format = &vr->VideoInfoHeader;
 
385
 
 
386
              entry->format_size = sizeof (vr->VideoInfoHeader);
 
387
              entry->sample_size =
 
388
                  vr->VideoInfoHeader.hdr.bmiHeader.biSizeImage;
 
389
            } else
 
390
              g_assert_not_reached ();
 
391
 
 
392
            g_assert (entry->sample_size != 0);
 
393
 
 
394
            memcpy ((gpointer) & entry->vscc, src_vscc, sizeof (entry->vscc));
 
395
 
 
396
            entry->format = g_malloc (entry->format_size);
 
397
            memcpy (entry->format, src_format, entry->format_size);
 
398
 
 
399
            media_structure =
 
400
                ks_video_format_to_structure (range->SubFormat,
 
401
                range->MajorFormat);
 
402
 
 
403
            if (media_structure == NULL) {
 
404
              g_warning ("ks_video_format_to_structure returned NULL");
 
405
              ks_video_media_type_free (entry);
 
406
              entry = NULL;
 
407
            } else if (ks_video_append_video_stream_cfg_fields (media_structure,
 
408
                    &entry->vscc)) {
 
409
              entry->translated_caps = gst_caps_new_empty ();
 
410
              gst_caps_append_structure (entry->translated_caps,
 
411
                  media_structure);
 
412
            } else {
 
413
              gst_structure_free (media_structure);
 
414
              ks_video_media_type_free (entry);
 
415
              entry = NULL;
 
416
            }
 
417
 
 
418
            if (entry != NULL)
 
419
              ret = g_list_prepend (ret, entry);
 
420
          }
 
421
 
 
422
          /* REVISIT: Each KSDATARANGE should start on a 64-bit boundary */
 
423
          range = (KSDATARANGE *) (((guchar *) range) + range->FormatSize);
 
424
        }
 
425
 
 
426
        g_free (items);
 
427
      }
 
428
    }
 
429
  }
 
430
 
 
431
  if (ret != NULL) {
 
432
    ret = g_list_reverse (ret);
 
433
    ret = ks_video_media_type_list_remove_duplicates (ret);
 
434
  }
 
435
 
 
436
beach:
 
437
  return ret;
 
438
}
 
439
 
 
440
KSPIN_CONNECT *
 
441
ks_video_create_pin_conn_from_media_type (KsVideoMediaType * media_type)
 
442
{
 
443
  KSPIN_CONNECT *conn = NULL;
 
444
  KSDATAFORMAT *format = NULL;
 
445
  guint8 *vih;
 
446
 
 
447
  conn = g_malloc0 (sizeof (KSPIN_CONNECT) + sizeof (KSDATAFORMAT) +
 
448
      media_type->format_size);
 
449
 
 
450
  conn->Interface.Set = KSINTERFACESETID_Standard;
 
451
  conn->Interface.Id = KSINTERFACE_STANDARD_STREAMING;
 
452
  conn->Interface.Flags = 0;
 
453
 
 
454
  conn->Medium.Set = KSMEDIUMSETID_Standard;
 
455
  conn->Medium.Id = KSMEDIUM_TYPE_ANYINSTANCE;
 
456
  conn->Medium.Flags = 0;
 
457
 
 
458
  conn->PinId = media_type->pin_id;
 
459
  conn->PinToHandle = NULL;
 
460
  conn->Priority.PriorityClass = KSPRIORITY_NORMAL;
 
461
  conn->Priority.PrioritySubClass = 1;
 
462
 
 
463
  format = (KSDATAFORMAT *) (conn + 1);
 
464
  memcpy (format, media_type->range, sizeof (KSDATAFORMAT));
 
465
  format->FormatSize = sizeof (KSDATAFORMAT) + media_type->format_size;
 
466
 
 
467
  vih = (guint8 *) (format + 1);
 
468
  memcpy (vih, media_type->format, media_type->format_size);
 
469
 
 
470
  return conn;
 
471
}
 
472
 
 
473
gboolean
 
474
ks_video_fixate_media_type (const KSDATARANGE * range,
 
475
    guint8 * format, gint width, gint height, gint fps_n, gint fps_d)
 
476
{
 
477
  DWORD dwRate = (width * height * fps_n) / fps_d;
 
478
 
 
479
  g_return_val_if_fail (format != NULL, FALSE);
 
480
 
 
481
  if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo)) {
 
482
    KS_VIDEOINFOHEADER *vih = (KS_VIDEOINFOHEADER *) format;
 
483
 
 
484
    vih->AvgTimePerFrame = gst_util_uint64_scale_int (10000000, fps_d, fps_n);
 
485
    vih->dwBitRate = dwRate * vih->bmiHeader.biBitCount;
 
486
 
 
487
    g_assert (vih->bmiHeader.biWidth == width);
 
488
    g_assert (vih->bmiHeader.biHeight == height);
 
489
  } else if (IsEqualGUID (&range->Specifier, &FORMAT_VideoInfo2)) {
 
490
    KS_VIDEOINFOHEADER2 *vih = (KS_VIDEOINFOHEADER2 *) format;
 
491
 
 
492
    vih->AvgTimePerFrame = gst_util_uint64_scale_int (10000000, fps_d, fps_n);
 
493
    vih->dwBitRate = dwRate * vih->bmiHeader.biBitCount;
 
494
 
 
495
    g_assert (vih->bmiHeader.biWidth == width);
 
496
    g_assert (vih->bmiHeader.biHeight == height);
 
497
  } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEGVideo)) {
 
498
    KS_MPEG1VIDEOINFO *vih = (KS_MPEG1VIDEOINFO *) format;
 
499
 
 
500
    vih->hdr.AvgTimePerFrame =
 
501
        gst_util_uint64_scale_int (10000000, fps_d, fps_n);
 
502
    vih->hdr.dwBitRate = dwRate * vih->hdr.bmiHeader.biBitCount;
 
503
 
 
504
    /* FIXME: set height and width? */
 
505
    g_assert (vih->hdr.bmiHeader.biWidth == width);
 
506
    g_assert (vih->hdr.bmiHeader.biHeight == height);
 
507
  } else if (IsEqualGUID (&range->Specifier, &FORMAT_MPEG2Video)) {
 
508
    KS_MPEGVIDEOINFO2 *vih = (KS_MPEGVIDEOINFO2 *) format;
 
509
 
 
510
    vih->hdr.AvgTimePerFrame =
 
511
        gst_util_uint64_scale_int (10000000, fps_d, fps_n);
 
512
    vih->hdr.dwBitRate = dwRate * vih->hdr.bmiHeader.biBitCount;
 
513
 
 
514
    /* FIXME: set height and width? */
 
515
    g_assert (vih->hdr.bmiHeader.biWidth == width);
 
516
    g_assert (vih->hdr.bmiHeader.biHeight == height);
 
517
  } else {
 
518
    return FALSE;
 
519
  }
 
520
 
 
521
  return TRUE;
 
522
}
 
523
 
 
524
static GstStructure *
 
525
ks_video_append_var_video_fields (GstStructure * structure)
 
526
{
 
527
  if (structure) {
 
528
    gst_structure_set (structure,
 
529
        "width", GST_TYPE_INT_RANGE, 1, G_MAXINT,
 
530
        "height", GST_TYPE_INT_RANGE, 1, G_MAXINT,
 
531
        "framerate", GST_TYPE_FRACTION_RANGE, 0, 1, G_MAXINT, 1, NULL);
 
532
  }
 
533
 
 
534
  return structure;
 
535
}
 
536
 
 
537
GstCaps *
 
538
ks_video_get_all_caps (void)
 
539
{
 
540
  static GstCaps *caps = NULL;
 
541
 
 
542
  if (caps == NULL) {
 
543
    GstStructure *structure;
 
544
    caps = gst_caps_new_empty ();
 
545
 
 
546
    /* from Windows SDK 6.0 uuids.h */
 
547
    /* RGB formats */
 
548
    structure =
 
549
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
550
        (MEDIASUBTYPE_RGB555, FORMAT_VideoInfo));
 
551
    gst_caps_append_structure (caps, structure);
 
552
 
 
553
    structure =
 
554
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
555
        (MEDIASUBTYPE_RGB565, FORMAT_VideoInfo));
 
556
    gst_caps_append_structure (caps, structure);
 
557
 
 
558
    structure =
 
559
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
560
        (MEDIASUBTYPE_RGB24, FORMAT_VideoInfo));
 
561
    gst_caps_append_structure (caps, structure);
 
562
 
 
563
    structure =
 
564
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
565
        (MEDIASUBTYPE_RGB32, FORMAT_VideoInfo));
 
566
    gst_caps_append_structure (caps, structure);
 
567
 
 
568
    /* YUV formats */
 
569
    structure =
 
570
        ks_video_append_var_video_fields (gst_structure_new ("video/x-raw-yuv",
 
571
            NULL));
 
572
    gst_caps_append_structure (caps, structure);
 
573
 
 
574
    /* Other formats */
 
575
    structure =
 
576
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
577
        (MEDIASUBTYPE_MJPG, FORMAT_VideoInfo));
 
578
    gst_caps_append_structure (caps, structure);
 
579
 
 
580
    structure =
 
581
        ks_video_append_var_video_fields (ks_video_format_to_structure
 
582
        (MEDIASUBTYPE_dvsd, FORMAT_VideoInfo));
 
583
    gst_caps_append_structure (caps, structure);
 
584
 
 
585
    structure =                 /* no variable video fields (width, height, framerate) */
 
586
        ks_video_format_to_structure (MEDIASUBTYPE_dvsd, FORMAT_DvInfo);
 
587
    gst_caps_append_structure (caps, structure);
 
588
  }
 
589
 
 
590
  return caps;
 
591
}