OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [libjava/] [classpath/] [native/] [jni/] [gstreamer-peer/] [gst_native_pipeline.c] - Blame information for rev 774

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 774 jeremybenn
/*gst_native_pipeline.c - Header file for the GstClasspathPlugin
2
 Copyright (C) 2007 Free Software Foundation, Inc.
3
 
4
This file is part of GNU Classpath.
5
 
6
GNU Classpath is free software; you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8
the Free Software Foundation; either version 2, or (at your option)
9
any later version.
10
 
11
GNU Classpath is distributed in the hope that it will be useful, but
12
WITHOUT ANY WARRANTY; without even the implied warranty of
13
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14
General Public License for more details.
15
 
16
You should have received a copy of the GNU General Public License
17
along with GNU Classpath; see the file COPYING.  If not, write to the
18
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19
02110-1301 USA.
20
 
21
Linking this library statically or dynamically with other modules is
22
making a combined work based on this library.  Thus, the terms and
23
conditions of the GNU General Public License cover the whole
24
combination.
25
 
26
As a special exception, the copyright holders of this library give you
27
permission to link this library with independent modules to produce an
28
executable, regardless of the license terms of these independent
29
modules, and to copy and distribute the resulting executable under
30
terms of your choice, provided that you also meet, for each linked
31
independent module, the terms and conditions of the license of that
32
module.  An independent module is a module which is not derived from
33
or based on this library.  If you modify this library, you may extend
34
this exception to your version of the library, but you are not
35
obligated to do so.  If you do not wish to do so, delete this
36
exception statement from your version. */
37
 
38
#include <jni.h>
39
#include <jcl.h>
40
 
41
#include <string.h>
42
#include <stdlib.h>
43
 
44
#include <sys/types.h>
45
#include <sys/stat.h>
46
#include <sys/wait.h>
47
 
48
#include <unistd.h>
49
 
50
#ifdef HAVE_FCNTL_H
51
#include <fcntl.h>
52
#endif /* HAVE_FCNTL_H */
53
 
54
#if defined(HAVE_SYS_IOCTL_H)
55
#define BSD_COMP /* Get FIONREAD on Solaris2 */
56
#include <sys/ioctl.h>
57
#endif
58
#if defined(HAVE_SYS_FILIO_H) /* Get FIONREAD on Solaris 2.5 */
59
#include <sys/filio.h>
60
#endif
61
 
62
#include <gdk/gdk.h>
63
#include <glib.h>
64
 
65
#include <gst/gst.h>
66
 
67
#include "cpio.h"
68
#include "gst_peer.h"
69
 
70
#include "gnu_javax_sound_sampled_gstreamer_lines_GstPipeline.h"
71
#include "gst_native_pipeline.h"
72
 
73
static jmethodID pointerConstructorMID = NULL;
74
 
75
static jfieldID pipelineFID = NULL;
76
static jfieldID pointerDataFID = NULL;
77
static jfieldID nameFID = NULL;
78
static jfieldID capacityFID = NULL;
79
 
80
/*
81
 * Needed to compute the size of the data still available for processing in the
82
 * pipeline. We give a default here but this will be overwritten by the
83
 * detection routines.
84
 */
85
static long GST_DETECTED_PIPE_CAPACITY = 65536;
86
 
87
/*
88
 * Note: the Java code uses enum classes, these are not mapped into constants
89
 * by the javah tool, changes to these values should be reflected in the Java
90
 * side.
91
 */
92
enum
93
{
94
  PLAY,
95
  PAUSE,
96
  STOP
97
};
98
 
99
/*
100
 * Defined as constants in the Java code, hence mapped by javah.
101
 */
102
enum
103
{
104
  READ = gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_READ,
105
  WRITE = gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_WRITE
106
};
107
 
108
struct _GstNativePipelinePrivate
109
{
110
  JavaVM *vm;
111
  jclass GstPipelineClass;
112
  jclass PointerClass;
113
 
114
  jobject jni_pipeline;
115
 
116
  char *name;
117
  int fd;
118
 
119
  GstElement *pipeline;
120
};
121
 
122
/* ************************************************************************** */
123
/*
124
static void gst_native_pipeline_clean (GstNativePipeline *self);*/
125
static char *create_name (void);
126
static void init_pointer_IDs (JNIEnv* env);
127
static jint get_free_space (int fd);
128
static void detect_pipe_max (void);
129
 
130
/* ************************************************************************** */
131
 
132
/* JNI Methods */
133
 
134
JNIEXPORT void JNICALL
135
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1id_1cache
136
  (JNIEnv *env, jclass clazz)
137
{
138
  pipelineFID = (*env)->GetFieldID (env, clazz, "pipeline",
139
                                    "Lgnu/classpath/Pointer;");
140
  nameFID = (*env)->GetFieldID (env, clazz, "name", "Ljava/lang/String;");
141
  capacityFID = (*env)->GetFieldID (env, clazz, "capacity", "J");
142
 
143
  init_pointer_IDs (env);
144
}
145
 
146
JNIEXPORT void JNICALL
147
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_init_1instance
148
  (JNIEnv *env, jobject pipeline)
149
{
150
  GstNativePipeline *_pipeline = NULL;
151
 
152
  jclass localGstPipelineClass = NULL;
153
  jclass localPointerClass = NULL;
154
  jobject _pointer = NULL;
155
 
156
  _pipeline =
157
    (GstNativePipeline *) JCL_malloc (env, sizeof (GstNativePipeline));
158
  if (_pipeline == NULL)
159
    return;
160
 
161
  _pipeline->priv = (GstNativePipelinePrivate *)
162
    JCL_malloc (env, sizeof (GstNativePipelinePrivate));
163
  if (_pipeline->priv == NULL)
164
    {
165
      JCL_free (env, _pipeline);
166
      return;
167
    }
168
 
169
#if SIZEOF_VOID_P == 8
170
  localPointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
171
#else
172
# if SIZEOF_VOID_P == 4
173
  localPointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
174
# else
175
#   error "Pointer size is not supported."
176
# endif /* SIZEOF_VOID_P == 4 */
177
#endif /* SIZEOF_VOID_P == 8 */
178
 
179
  localGstPipelineClass = (*env)->GetObjectClass(env, pipeline);
180
  if (localGstPipelineClass == NULL || localGstPipelineClass == NULL)
181
    {
182
      JCL_free (env, _pipeline->priv);
183
      JCL_free (env, _pipeline);
184
      JCL_ThrowException (env, "java/lang/InternalError",
185
                               "Class Initialization failed.");
186
      return;
187
    }
188
 
189
  GST_DETECTED_PIPE_CAPACITY = (long) (*env)->GetLongField(env, pipeline,
190
                                                           capacityFID);
191
 
192
  /* fill the object */
193
  (*env)->GetJavaVM(env, &_pipeline->priv->vm);
194
  _pipeline->priv->jni_pipeline = (*env)->NewGlobalRef(env, pipeline);
195
  _pipeline->priv->GstPipelineClass =
196
    (*env)->NewGlobalRef(env, localGstPipelineClass);
197
  _pipeline->priv->PointerClass = (*env)->NewGlobalRef(env, localPointerClass);
198
  _pipeline->priv->pipeline = NULL;
199
 
200
  _pointer = (*env)->GetObjectField(env, pipeline, pipelineFID);
201
 
202
  if (_pointer == NULL)
203
    {
204
#if SIZEOF_VOID_P == 8
205
      _pointer = (*env)->NewObject(env, _pipeline->priv->PointerClass,
206
                                   pointerConstructorMID, (jlong) _pipeline);
207
#else
208
      _pointer = (*env)->NewObject(env, _pipeline->priv->PointerClass,
209
                                   pointerConstructorMID, (jint) _pipeline);
210
#endif
211
    }
212
  else
213
    {
214
#if SIZEOF_VOID_P == 8
215
      (*env)->SetLongField(env, pipeline, pipelineFID, (jlong) _pipeline);
216
#else
217
      (*env)->SetIntField(env, pipeline, pipelineFID, (jint) _pipeline);
218
#endif
219
    }
220
 
221
  /* store back our pointer into the calling class */
222
  (*env)->SetObjectField(env, pipeline, pipelineFID, _pointer);
223
}
224
 
225
JNIEXPORT jboolean JNICALL
226
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_set_1state
227
  (JNIEnv *env, jclass clazz, jobject pointer, jint state)
228
{
229
  GstNativePipeline *jpipeline = NULL;
230
  jboolean result = JNI_FALSE;
231
 
232
  if (pointer == NULL)
233
    {
234
      JCL_ThrowException (env, "javax/sound/sampled/LineUnavailableException",
235
                               "Can't change pipeline state: " \
236
                               "pipeline not initialized");
237
      return result;
238
    }
239
 
240
  jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
241
                                                             pointerDataFID);
242
  if (jpipeline == NULL)
243
    return JNI_FALSE;
244
 
245
  switch (state)
246
    {
247
      case (PLAY):
248
        gst_element_set_state(GST_ELEMENT(jpipeline->priv->pipeline),
249
                              GST_STATE_PLAYING);
250
        result = JNI_TRUE;
251
        break;
252
 
253
      case (PAUSE):
254
        gst_element_set_state(GST_ELEMENT(jpipeline->priv->pipeline),
255
                              GST_STATE_PAUSED);
256
        result = JNI_TRUE;
257
        break;
258
 
259
      case (STOP):
260
#ifndef WITHOUT_FILESYSTEM
261
        /* clean the pipeline and kill named pipe */
262
        if (jpipeline->priv->name)
263
          {
264
            cpio_removeFile (jpipeline->priv->name);
265
            g_free (jpipeline->priv->name);
266
            jpipeline->priv->name = NULL;
267
          }
268
#endif /* WITHOUT_FILESYSTEM */
269
 
270
        if (jpipeline->priv->pipeline != NULL)
271
          gst_object_unref (GST_OBJECT(jpipeline->priv->pipeline));
272
        result = JNI_TRUE;
273
        break;
274
 
275
      default:
276
        /* nothing */
277
        result = JNI_FALSE;
278
        break;
279
    }
280
 
281
  return result;
282
}
283
 
284
JNIEXPORT void JNICALL
285
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_open_1native_1pipe
286
  (JNIEnv *env, jclass clazz, jobject pointer, jint mode)
287
{
288
  GstNativePipeline *jpipeline = NULL;
289
 
290
  jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
291
                                                             pointerDataFID);
292
  switch (mode)
293
    {
294
      case (READ):
295
        jpipeline->priv->fd =
296
            open (jpipeline->priv->name, O_RDONLY | O_NONBLOCK);
297
        break;
298
 
299
      case (WRITE):
300
        /* TODO: no-op currently */
301
        break;
302
    }
303
}
304
 
305
JNIEXPORT void JNICALL
306
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_close_1native_1pipe
307
  (JNIEnv *env, jclass clazz, jobject pointer)
308
{
309
#ifndef WITHOUT_FILESYSTEM
310
  GstNativePipeline *jpipeline = NULL;
311
  jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
312
                                                             pointerDataFID);
313
  /* kill the named pipe */
314
  if (jpipeline->priv->name)
315
    {
316
      cpio_removeFile (jpipeline->priv->name);
317
      g_free (jpipeline->priv->name);
318
      jpipeline->priv->name = NULL;
319
    }
320
#endif /* WITHOUT_FILESYSTEM */
321
}
322
 
323
JNIEXPORT jboolean JNICALL
324
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_create_1named_1pipe
325
  (JNIEnv *env, jobject GstPipeline, jobject pointer)
326
{
327
#ifndef WITHOUT_FILESYSTEM
328
  /*
329
   * We get a temp name for the named pipe, create the named pipe and then
330
   * set the relative field in the java class.
331
   */
332
  GstNativePipeline *jpipeline = NULL;
333
  jstring *name = NULL;
334
 
335
  jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
336
                                                             pointerDataFID);
337
  if (jpipeline == NULL)
338
    return JNI_FALSE;
339
 
340
  jpipeline->priv->name = create_name ();
341
  if (jpipeline->priv->name == NULL)
342
    return JNI_FALSE;
343
 
344
  if (mkfifo (jpipeline->priv->name, 0600) < 0)
345
    {
346
      if (jpipeline->priv->name != NULL)
347
        free (jpipeline->priv->name);
348
      return JNI_FALSE;
349
    }
350
 
351
  /* now set the String field */
352
  name = (*env)->NewStringUTF(env, jpipeline->priv->name);
353
  if (name == NULL)
354
    {
355
      cpio_removeFile (jpipeline->priv->name);
356
      if (jpipeline->priv->name != NULL)
357
        free (jpipeline->priv->name);
358
 
359
      return JNI_FALSE;
360
    }
361
 
362
  (*env)->SetObjectField(env, GstPipeline, nameFID, name);
363
 
364
  return JNI_TRUE;
365
 
366
#else /* not WITHOUT_FILESYSTEM */
367
  return JNI_FALSE;
368
#endif /* not WITHOUT_FILESYSTEM */
369
}
370
 
371
JNIEXPORT jint JNICALL
372
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_available
373
  (JNIEnv *env, jclass clazz, jobject pointer, jint mode)
374
{
375
  jint result = -1;
376
 
377
#ifndef WITHOUT_FILESYSTEM
378
 
379
  GstNativePipeline *jpipeline = NULL;
380
  jpipeline = (GstNativePipeline *) get_object_from_pointer (env, pointer,
381
                                                             pointerDataFID);
382
 
383
  if (mode == READ)
384
    {
385
      result = get_free_space (jpipeline->priv->fd);
386
    }
387
  else
388
    {
389
# if defined (FIONREAD)      
390
      if (ioctl (jpipeline->priv->fd, FIONREAD, &result) == -1)
391
        g_warning("IMPLEMENT ME: ioctl failed");
392
 
393
# else /* not defined (FIONREAD) */
394
      g_warning("IMPLEMENT ME: !defined (FIONREAD");
395
# endif /* defined (FIONREAD) */
396
 
397
    } /* if (mode == READ) */
398
 
399
#endif  /* not WITHOUT_FILESYSTEM */
400
 
401
  return result;
402
}
403
 
404
JNIEXPORT jlong JNICALL
405
Java_gnu_javax_sound_sampled_gstreamer_lines_GstPipeline_detect_1pipe_1size
406
  (JNIEnv *env, jobject GstPipeline)
407
{
408
  detect_pipe_max ();
409
 
410
  return GST_DETECTED_PIPE_CAPACITY;
411
}
412
 
413
/* exported library functions */
414
/*
415
static void gst_native_pipeline_clean (GstNativePipeline *self)
416
{
417
  JNIEnv *env = NULL;
418
 
419
  env = gst_get_jenv (self->priv->vm);
420
 
421
  (*env)->DeleteGlobalRef (env, self->priv->jni_pipeline);
422
  (*env)->DeleteGlobalRef (env, self->priv->GstPipelineClass);
423
  (*env)->DeleteGlobalRef (env, self->priv->PointerClass);
424
 
425
  if (self->priv->pipeline != NULL)
426
    gst_object_unref (GST_OBJECT (self->priv->pipeline));
427
 
428
  if (self->priv->name)
429
    {
430
      cpio_removeFile (self->priv->name);
431
      g_free (self->priv->name);
432
      self->priv->name = NULL;
433
    }
434
 
435
  JCL_free (env, self->priv);
436
  JCL_free (env, self);
437
}
438
*/
439
void gst_native_pipeline_set_pipeline (GstNativePipeline *self,
440
                                       GstElement *pipeline)
441
{
442
  if (self->priv->pipeline != NULL)
443
    gst_object_unref (GST_OBJECT (self->priv->pipeline));
444
 
445
  self->priv->pipeline = pipeline;
446
}
447
 
448
GstElement *gst_native_pipeline_get_pipeline (GstNativePipeline *self)
449
{
450
  return self->priv->pipeline;
451
}
452
 
453
char *gst_native_pipeline_get_pipeline_name (GstNativePipeline *self)
454
{
455
  return self->priv->name;
456
}
457
 
458
int gst_native_pipeline_get_pipeline_fd (GstNativePipeline *self)
459
{
460
  return self->priv->fd;
461
}
462
 
463
/* private functions */
464
 
465
static void init_pointer_IDs (JNIEnv* env)
466
{
467
  jclass PointerClass = NULL;
468
 
469
#if SIZEOF_VOID_P == 8
470
  PointerClass = JCL_FindClass (env, "gnu/classpath/Pointer64");
471
  if (PointerClass != NULL)
472
    {
473
      pointerDataFID = (*env)->GetFieldID (env, PointerClass, "data", "J");
474
      pointerConstructorMID = (*env)->GetMethodID (env, PointerClass, "<init>",
475
                                                   "(J)V");
476
    }
477
#else
478
# if SIZEOF_VOID_P == 4
479
  PointerClass = JCL_FindClass (env, "gnu/classpath/Pointer32");
480
  if (PointerClass != NULL)
481
    {
482
      pointerDataFID = (*env)->GetFieldID(env, PointerClass, "data", "I");
483
      pointerConstructorMID = (*env)->GetMethodID(env, PointerClass,
484
                                                  "<init>", "(I)V");
485
    }
486
# else
487
#   error "Pointer size is not supported."
488
# endif /* SIZEOF_VOID_P == 4 */
489
#endif /* SIZEOF_VOID_P == 8 */
490
}
491
 
492
static jint get_free_space (int fd)
493
{
494
  jint result = -1;
495
 
496
#if defined (FIONSPACE)
497
 
498
  if (ioctl (fd, FIONSPACE, &result) == -1)
499
    {
500
      g_warning("IMPLEMENT ME: ioctl failed");
501
    }
502
 
503
#elif defined (FIONREAD)
504
 
505
  if (ioctl (fd, FIONREAD, &result) == -1)
506
    {
507
      g_warning("IMPLEMENT ME: ioctl failed");
508
    }
509
 
510
  result = GST_DETECTED_PIPE_CAPACITY - result;
511
 
512
#else
513
   g_warning("IMPLEMENT ME!!! - !defined (FIONSPACE), !defined (FIONREAD");
514
 
515
#endif
516
 
517
  return result;
518
}
519
 
520
static char *create_name (void)
521
{
522
  char *buffer = NULL;
523
  char *tmp = NULL;
524
 
525
  buffer = (char *) g_malloc0 (_GST_MALLOC_SIZE_);
526
  if (buffer == NULL)
527
    {
528
      /* huston, we have a problem... */
529
      return NULL;
530
    }
531
 
532
  tmp = tempnam (NULL, _GST_PIPELINE_PREFIX_);
533
  if (tmp == NULL)
534
    {
535
      g_free (buffer);
536
      return NULL;
537
    }
538
 
539
  g_snprintf (buffer, _GST_MALLOC_SIZE_, "%s%s", tmp, _GST_PIPELINE_SUFFIX_);
540
  g_free (tmp);
541
 
542
  return buffer;
543
}
544
 
545
static void detect_pipe_max (void)
546
{
547
  int read_fd;
548
  int write_fd;
549
 
550
  /* can be anything! */
551
  char *character = "a";
552
  char *pipe = NULL;
553
 
554
  gboolean available = TRUE;
555
  int w = 0;
556
  long wrote = 0;
557
 
558
  pipe = create_name ();
559
  if (pipe == NULL)
560
    {
561
      g_warning ("can't create test pipe name");
562
      return;
563
    }
564
 
565
  if (mkfifo (pipe, 0600) < 0)
566
    {
567
      g_warning ("unable to create test pipe...");
568
      g_free (pipe);
569
 
570
      return;
571
    }
572
 
573
  /* open both end of the pipe */
574
  read_fd = open (pipe, O_RDONLY | O_NONBLOCK);
575
  if (read_fd < 0)
576
    {
577
      cpio_removeFile (pipe);
578
      g_free (pipe);
579
 
580
      return;
581
    }
582
 
583
  write_fd = open (pipe, O_WRONLY | O_NONBLOCK);
584
  if (write_fd < 0)
585
    {
586
      cpio_closeFile (write_fd);
587
      cpio_removeFile (pipe);
588
      g_free (pipe);
589
 
590
      return;
591
    }
592
 
593
  while (available)
594
    {
595
      w = 0;
596
 
597
      cpio_write (write_fd, character, 1, &w);
598
      if (w < 0)
599
        available = FALSE;
600
      else
601
        wrote += w;
602
    }
603
 
604
  GST_DETECTED_PIPE_CAPACITY = wrote;
605
 
606
  cpio_closeFile (write_fd);
607
  cpio_closeFile (read_fd);
608
  cpio_removeFile (pipe);
609
 
610
  g_free (pipe);
611
}

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.