~ubuntu-branches/ubuntu/quantal/gst-plugins-bad-multiverse0.10/quantal

« back to all changes in this revision

Viewing changes to gst/real/gstrealvideodec.c

  • Committer: Bazaar Package Importer
  • Author(s): Onkar Shinde
  • Date: 2009-02-23 02:23:58 UTC
  • mfrom: (1.1.11 upstream)
  • Revision ID: james.westby@ubuntu.com-20090223022358-9yhx5izc7dz60yc8
Tags: 0.10.10-0ubuntu1
* New upstream release.
* debian/rules
  - Disable some plugins which get built by default but we do not ship in 
    multiverse package.
  - Do not build docs as there is no multiverse-doc package.

Show diffs side-by-side

added added

removed removed

Lines of Context:
65
65
    GST_TYPE_ELEMENT);
66
66
 
67
67
static gboolean open_library (GstRealVideoDec * dec,
68
 
    GstRealVideoDecHooks * hooks, GstRealVideoDecVersion version);
69
 
static void close_library (GstRealVideoDecHooks hooks);
 
68
    GstRealVideoDecVersion version, GstRVDecLibrary * lib);
 
69
static void close_library (GstRealVideoDec * dec, GstRVDecLibrary * lib);
70
70
 
71
71
typedef struct
72
72
{
103
103
 
104
104
  dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
105
105
 
106
 
  if (G_UNLIKELY (dec->hooks.transform == NULL || dec->hooks.module == NULL))
 
106
  if (G_UNLIKELY (dec->lib.Transform == NULL || dec->lib.module == NULL))
107
107
    goto not_negotiated;
108
108
 
109
109
  data = GST_BUFFER_DATA (in);
162
162
  /* jump over the frag table to the fragments */
163
163
  data += frag_size;
164
164
 
165
 
  result = dec->hooks.transform (
 
165
  result = dec->lib.Transform (
166
166
      (gchar *) data,
167
 
      (gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->hooks.context);
 
167
      (gchar *) GST_BUFFER_DATA (out), &tin, &tout, dec->lib.context);
168
168
  if (result)
169
169
    goto could_not_transform;
170
170
 
243
243
  }
244
244
}
245
245
 
246
 
static gboolean
247
 
gst_real_video_dec_activate_push (GstPad * pad, gboolean active)
 
246
static GstCaps *
 
247
gst_real_video_dec_getcaps (GstPad * pad)
248
248
{
249
 
  return TRUE;
 
249
  GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (GST_PAD_PARENT (pad));
 
250
  GstCaps *res;
 
251
 
 
252
  if (dec->checked_modules) {
 
253
    GValue versions = { 0 };
 
254
    GValue version = { 0 };
 
255
 
 
256
    GST_LOG_OBJECT (dec, "constructing caps");
 
257
    res = gst_caps_new_empty ();
 
258
 
 
259
    g_value_init (&versions, GST_TYPE_LIST);
 
260
    g_value_init (&version, G_TYPE_INT);
 
261
 
 
262
    if (dec->valid_rv20) {
 
263
      g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_2);
 
264
      gst_value_list_append_value (&versions, &version);
 
265
    }
 
266
    if (dec->valid_rv30) {
 
267
      g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_3);
 
268
      gst_value_list_append_value (&versions, &version);
 
269
    }
 
270
    if (dec->valid_rv40) {
 
271
      g_value_set_int (&version, GST_REAL_VIDEO_DEC_VERSION_4);
 
272
      gst_value_list_append_value (&versions, &version);
 
273
    }
 
274
 
 
275
    if (gst_value_list_get_size (&versions) > 0) {
 
276
      res = gst_caps_new_simple ("video/x-pn-realvideo", NULL);
 
277
      gst_structure_set_value (gst_caps_get_structure (res, 0),
 
278
          "rmversion", &versions);
 
279
    } else {
 
280
      res = gst_caps_new_empty ();
 
281
    }
 
282
    g_value_unset (&versions);
 
283
    g_value_unset (&version);
 
284
  } else {
 
285
    GST_LOG_OBJECT (dec, "returning padtemplate caps");
 
286
    res = gst_caps_copy (gst_pad_get_pad_template_caps (pad));
 
287
  }
 
288
  GST_LOG_OBJECT (dec, "returning caps %" GST_PTR_FORMAT, res);
 
289
 
 
290
  return res;
250
291
}
251
292
 
252
293
static gboolean
259
300
  gchar data[36];
260
301
  gboolean bres;
261
302
  const GValue *v;
262
 
  GstRealVideoDecHooks hooks = { 0, 0, 0, 0, 0, 0 };
263
303
 
264
304
  if (!gst_structure_get_int (s, "rmversion", &version) ||
265
305
      !gst_structure_get_int (s, "width", (gint *) & width) ||
272
312
 
273
313
  GST_LOG_OBJECT (dec, "Setting version to %d", version);
274
314
 
275
 
  if (!open_library (dec, &hooks, version))
276
 
    return FALSE;
 
315
  close_library (dec, &dec->lib);
 
316
 
 
317
  if (!open_library (dec, version, &dec->lib))
 
318
    goto open_failed;
277
319
 
278
320
  /* Initialize REAL driver. */
279
321
  GST_WRITE_UINT16_LE (data + 0, 11);
285
327
  GST_WRITE_UINT32_LE (data + 16, 1);
286
328
  GST_WRITE_UINT32_LE (data + 20, format);
287
329
 
288
 
  res = hooks.init (&data, &hooks.context);
289
 
  if (res)
 
330
  if ((res = dec->lib.Init (&data, &dec->lib.context)))
290
331
    goto could_not_initialize;
291
332
 
292
333
  if ((v = gst_structure_get_value (s, "codec_data"))) {
328
369
    for (i = 0; i < bufsize; i++)
329
370
      msgdata[i + 2] = 4 * (guint32) bufdata[i];
330
371
 
331
 
    res = hooks.custom_message (&msg, hooks.context);
 
372
    res = dec->lib.Message (&msg, dec->lib.context);
332
373
 
333
374
    g_free (msgdata);
334
375
    if (res)
339
380
      "format", GST_TYPE_FOURCC, GST_MAKE_FOURCC ('I', '4', '2', '0'),
340
381
      "framerate", GST_TYPE_FRACTION, framerate_num, framerate_denom,
341
382
      "width", G_TYPE_INT, width, "height", G_TYPE_INT, height, NULL);
 
383
 
 
384
  /* set PAR if one was specified in the sink caps */
 
385
  if ((v = gst_structure_get_value (s, "pixel-aspect-ratio"))) {
 
386
    gst_structure_set_value (gst_caps_get_structure (caps, 0),
 
387
        "pixel-aspect-ratio", v);
 
388
  }
 
389
 
342
390
  bres = gst_pad_set_caps (GST_PAD (dec->src), caps);
343
391
  gst_caps_unref (caps);
344
392
  if (!bres)
345
393
    goto could_not_set_caps;
346
394
 
347
 
  close_library (dec->hooks);
348
 
  dec->hooks = hooks;
349
395
  dec->version = version;
350
396
  dec->width = width;
351
397
  dec->height = height;
361
407
    GST_ERROR_OBJECT (dec, "Could not find all necessary keys in structure.");
362
408
    return FALSE;
363
409
  }
364
 
 
 
410
open_failed:
 
411
  {
 
412
    GST_ERROR_OBJECT (dec, "failed to open library");
 
413
    return FALSE;
 
414
  }
365
415
could_not_initialize:
366
416
  {
367
 
    close_library (hooks);
368
417
    GST_ERROR_OBJECT (dec, "Initialization of REAL driver failed (%i).", res);
 
418
    close_library (dec, &dec->lib);
369
419
    return FALSE;
370
420
  }
371
 
 
372
421
could_not_allocate:
373
422
  {
374
 
    close_library (hooks);
375
423
    GST_ERROR_OBJECT (dec, "Could not allocate memory.");
 
424
    close_library (dec, &dec->lib);
376
425
    return FALSE;
377
426
  }
378
 
 
379
427
could_not_send_message:
380
428
  {
381
 
    close_library (hooks);
382
429
    GST_ERROR_OBJECT (dec, "Failed to send custom message needed for "
383
430
        "initialization (%i).", res);
 
431
    close_library (dec, &dec->lib);
384
432
    return FALSE;
385
433
  }
386
 
 
387
434
could_not_set_caps:
388
435
  {
389
 
    close_library (hooks);
390
436
    GST_ERROR_OBJECT (dec, "Could not convince peer to accept dimensions "
391
437
        "%i x %i.", dec->width, dec->height);
 
438
    close_library (dec, &dec->lib);
392
439
    return FALSE;
393
440
  }
394
441
}
396
443
/* Attempts to open the correct library for the configured version */
397
444
 
398
445
static gboolean
399
 
open_library (GstRealVideoDec * dec, GstRealVideoDecHooks * hooks,
400
 
    GstRealVideoDecVersion version)
 
446
open_library (GstRealVideoDec * dec, GstRealVideoDecVersion version,
 
447
    GstRVDecLibrary * lib)
401
448
{
402
449
  gpointer rv_custom_msg, rv_free, rv_init, rv_transform;
403
450
  GModule *module = NULL;
432
479
    for (j = 0; split_names[j]; j++) {
433
480
      gchar *codec = g_strconcat (split_path[i], "/", split_names[j], NULL);
434
481
 
 
482
      GST_DEBUG_OBJECT (dec, "trying %s", codec);
435
483
      module = g_module_open (codec, G_MODULE_BIND_LAZY);
436
484
      g_free (codec);
437
485
      if (module)
446
494
  if (module == NULL)
447
495
    goto could_not_open;
448
496
 
 
497
  GST_DEBUG_OBJECT (dec, "module opened, finding symbols");
 
498
 
449
499
  /* First try opening legacy symbols, if that fails try loading new symbols */
450
500
  if (g_module_symbol (module, "RV20toYUV420Init", &rv_init) &&
451
501
      g_module_symbol (module, "RV20toYUV420Free", &rv_free) &&
461
511
    goto could_not_load;
462
512
  }
463
513
 
464
 
  hooks->init = (GstRealVideoDecInitFunc) rv_init;
465
 
  hooks->free = (GstRealVideoDecFreeFunc) rv_free;
466
 
  hooks->transform = (GstRealVideoDecTransformFunc) rv_transform;
467
 
  hooks->custom_message = (GstRealVideoDecMessageFunc) rv_custom_msg;
468
 
  hooks->module = module;
 
514
  lib->Init = (guint32 (*)(gpointer, gpointer)) rv_init;
 
515
  lib->Free = (guint32 (*)(gpointer)) rv_free;
 
516
  lib->Transform = (guint32 (*)(gchar *, gchar *, gpointer, gpointer, gpointer))
 
517
      rv_transform;
 
518
  lib->Message = (guint32 (*)(gpointer, gpointer)) rv_custom_msg;
 
519
  lib->module = module;
469
520
 
470
521
  dec->error_count = 0;
471
522
 
476
527
    GST_ERROR_OBJECT (dec, "Cannot handle version %i.", version);
477
528
    return FALSE;
478
529
  }
479
 
 
480
530
could_not_open:
481
531
  {
482
532
    GST_ERROR_OBJECT (dec, "Could not open library '%s' in '%s': %s", names,
483
533
        path, g_module_error ());
484
534
    return FALSE;
485
535
  }
486
 
 
487
536
could_not_load:
488
537
  {
489
 
    close_library (*hooks);
 
538
    close_library (dec, lib);
490
539
    GST_ERROR_OBJECT (dec, "Could not load all symbols: %s", g_module_error ());
491
540
    return FALSE;
492
541
  }
493
542
}
494
543
 
495
544
static void
496
 
close_library (GstRealVideoDecHooks hooks)
497
 
{
498
 
  if (hooks.context && hooks.free)
499
 
    hooks.free (hooks.context);
500
 
 
501
 
  if (hooks.module) {
502
 
    g_module_close (hooks.module);
503
 
    hooks.module = NULL;
504
 
  }
 
545
close_library (GstRealVideoDec * dec, GstRVDecLibrary * lib)
 
546
{
 
547
  if (lib->context) {
 
548
    GST_LOG_OBJECT (dec, "closing library");
 
549
    if (lib->Free)
 
550
      lib->Free (lib->context);
 
551
  }
 
552
  if (lib->module) {
 
553
    GST_LOG_OBJECT (dec, "closing library module");
 
554
    g_module_close (lib->module);
 
555
    lib->module = NULL;
 
556
  }
 
557
  memset (lib, 0, sizeof (*lib));
 
558
}
 
559
 
 
560
static void
 
561
gst_real_video_dec_probe_modules (GstRealVideoDec * dec)
 
562
{
 
563
  GstRVDecLibrary dummy = { NULL };
 
564
 
 
565
  if ((dec->valid_rv20 =
 
566
          open_library (dec, GST_REAL_VIDEO_DEC_VERSION_2, &dummy)))
 
567
    close_library (dec, &dummy);
 
568
  if ((dec->valid_rv30 =
 
569
          open_library (dec, GST_REAL_VIDEO_DEC_VERSION_3, &dummy)))
 
570
    close_library (dec, &dummy);
 
571
  if ((dec->valid_rv40 =
 
572
          open_library (dec, GST_REAL_VIDEO_DEC_VERSION_4, &dummy)))
 
573
    close_library (dec, &dummy);
 
574
}
 
575
 
 
576
static GstStateChangeReturn
 
577
gst_real_video_dec_change_state (GstElement * element,
 
578
    GstStateChange transition)
 
579
{
 
580
  GstStateChangeReturn ret;
 
581
  GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (element);
 
582
 
 
583
  switch (transition) {
 
584
    case GST_STATE_CHANGE_NULL_TO_READY:
 
585
      gst_real_video_dec_probe_modules (dec);
 
586
      dec->checked_modules = TRUE;
 
587
      break;
 
588
    default:
 
589
      break;
 
590
  }
 
591
 
 
592
  ret = GST_ELEMENT_CLASS (parent_class)->change_state (element, transition);
 
593
 
 
594
  switch (transition) {
 
595
    case GST_STATE_CHANGE_PAUSED_TO_READY:
 
596
      close_library (dec, &dec->lib);
 
597
      break;
 
598
    case GST_STATE_CHANGE_READY_TO_NULL:
 
599
      dec->checked_modules = FALSE;
 
600
      break;
 
601
    default:
 
602
      break;
 
603
  }
 
604
  return ret;
505
605
}
506
606
 
507
607
static void
508
608
gst_real_video_dec_init (GstRealVideoDec * dec, GstRealVideoDecClass * klass)
509
609
{
510
610
  dec->snk = gst_pad_new_from_static_template (&snk_t, "sink");
 
611
  gst_pad_set_getcaps_function (dec->snk,
 
612
      GST_DEBUG_FUNCPTR (gst_real_video_dec_getcaps));
511
613
  gst_pad_set_setcaps_function (dec->snk,
512
614
      GST_DEBUG_FUNCPTR (gst_real_video_dec_setcaps));
513
615
  gst_pad_set_chain_function (dec->snk,
514
616
      GST_DEBUG_FUNCPTR (gst_real_video_dec_chain));
515
 
  gst_pad_set_activatepush_function (dec->snk,
516
 
      GST_DEBUG_FUNCPTR (gst_real_video_dec_activate_push));
517
617
  gst_element_add_pad (GST_ELEMENT (dec), dec->snk);
518
618
 
519
619
  dec->src = gst_pad_new_from_static_template (&src_t, "src");
539
639
{
540
640
  GstRealVideoDec *dec = GST_REAL_VIDEO_DEC (object);
541
641
 
542
 
  close_library (dec->hooks);
543
 
  memset (&dec->hooks, 0, sizeof (dec->hooks));
 
642
  close_library (dec, &dec->lib);
544
643
 
545
644
  if (dec->real_codecs_path) {
546
645
    g_free (dec->real_codecs_path);
638
737
gst_real_video_dec_class_init (GstRealVideoDecClass * klass)
639
738
{
640
739
  GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
740
  GstElementClass *element_class = GST_ELEMENT_CLASS (klass);
641
741
 
642
742
  object_class->set_property = gst_real_video_dec_set_property;
643
743
  object_class->get_property = gst_real_video_dec_get_property;
644
744
  object_class->finalize = gst_real_video_dec_finalize;
645
745
 
 
746
  element_class->change_state = gst_real_video_dec_change_state;
 
747
 
646
748
  g_object_class_install_property (object_class, PROP_REAL_CODECS_PATH,
647
749
      g_param_spec_string ("real-codecs-path",
648
750
          "Path where to search for RealPlayer codecs",