Пример #1
0
static guint64 create_job_process (Job *job)
{
        GError *error = NULL;
        gchar *argv[16], *p;
        GPid pid;
        gint i, j;

        i = 0;
        argv[i++] = g_strdup (job->exe_path);
        argv[i++] = g_strdup ("-l");
        argv[i++] = g_strdup (job->log_dir);
        argv[i++] = g_strdup ("-n");
        argv[i++] = unicode_file_name_2_shm_name (job->name);
        argv[i++] = g_strdup ("-q");
        argv[i++] = g_strdup_printf ("%ld", strlen (job->description));
        p = jobdesc_get_debug (job->description);
        if (p != NULL) {
                argv[i++] = g_strdup_printf ("--gst-debug=%s", p);
                g_free (p);
        }
        argv[i++] = NULL;
        if (!g_spawn_async (NULL, argv, NULL, G_SPAWN_DO_NOT_REAP_CHILD, NULL, NULL, &pid, &error)) {
                GST_ERROR ("Start job %s error, reason: %s.", job->name, error->message);
                for (j = 0; j < i; j++) {
                        if (argv[j] != NULL) {
                                g_free (argv[j]);
                        }
                }
                g_error_free (error);
                return JOB_STATE_START_FAILURE;
        }

        for (j = 0; j < i; j++) {
                if (argv[j] != NULL) {
                        g_free (argv[j]);
                }
        }
        job->worker_pid = pid;
        g_child_watch_add (pid, (GChildWatchFunc)child_watch_cb, job);

        while ((*(job->output->state) == JOB_STATE_READY) || (*(job->output->state) == JOB_STATE_VOID_PENDING)) {
                GST_WARNING ("waiting job process creating ... state: %s", job_state_get_name (*(job->output->state)));
                g_usleep (50000);
        }

        return *(job->output->state);
}
Пример #2
0
static void job_dispose (GObject *obj)
{
        Job *job = JOB (obj);
        GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
        JobOutput *output;
        gint i;
        gchar *name_hexstr;

        if (job->output == NULL) {
                return;
        }
        output = job->output;

        /* free semaphore */
        if (output->semaphore != NULL) {
                if (sem_close (output->semaphore) == -1) {
                        GST_ERROR ("sem_close failure: %s", g_strerror (errno));
                }
                if (sem_unlink (output->semaphore_name) == -1) {
                        GST_ERROR ("sem_unlink %s error: %s", job->name, g_strerror (errno));
                }
                g_free (output->semaphore_name);
        }

        /* free encoders output */
        if (job->is_live) {
                if (output->master_m3u8_playlist != NULL) {
                        g_free (output->master_m3u8_playlist);
                        for (i = 0; i < output->encoder_count; i++) {
                                if (output->encoders[i].record_path != NULL) {
                                        g_free (output->encoders[i].record_path);
                                }
                                m3u8playlist_free (output->encoders[i].m3u8_playlist);
                        }
                }
        }
        g_free (output->encoders);

        /* free share memory */
        if (job->output_fd != -1) {
                g_close (job->output_fd, NULL);
                if (munmap (output->job_description, job->output_size) == -1) {
                        GST_ERROR ("munmap %s error: %s", job->name, g_strerror (errno));
                }
                name_hexstr = unicode_file_name_2_shm_name (job->name);
                if (shm_unlink (name_hexstr) == -1) {
                        GST_ERROR ("shm_unlink %s error: %s", job->name, g_strerror (errno));
                }
                g_free (name_hexstr);
        }
        g_free (output);

        if (job->description != NULL) {
                g_free (job->description);
                job->description = NULL;
        }

        if (job->exe_path != NULL) {
                g_free (job->exe_path);
                job->exe_path = NULL;
        }

        if (job->name != NULL) {
                g_free (job->name);
                job->name = NULL;
        }

        G_OBJECT_CLASS (parent_class)->dispose (obj);
}
Пример #3
0
/**
 * job_initialize:
 * @job: (in): the job to be initialized.
 * @daemon: (in): is gstreamill run in background.
 *
 * Initialize the output of the job, the output of the job include the status of source and encoders and
 * the output stream.
 *
 * Returns: 0 on success.
 */
gint job_initialize (Job *job, gboolean daemon)
{
        gint i, fd;
        JobOutput *output;
        gchar *name, *p, *name_hexstr, *semaphore_name;
        struct timespec ts;
        sem_t *semaphore;

        job->output_size = status_output_size (job->description);
        name_hexstr = unicode_file_name_2_shm_name (job->name);
        semaphore_name = g_strdup_printf ("/%s", name_hexstr);
        semaphore = sem_open (semaphore_name, O_CREAT, 0644, 1);
        if (semaphore == SEM_FAILED) {
                GST_ERROR ("open semaphore failed: %s", g_strerror (errno));
                g_free (semaphore_name);
                return 1;
        }
        if (clock_gettime (CLOCK_REALTIME, &ts) == -1) {
                GST_ERROR ("clock_gettime error: %s", g_strerror (errno));
                g_free (semaphore_name);
                return 1;
        }
        ts.tv_sec += 2;
        while (sem_timedwait (semaphore, &ts) == -1) {
                if (errno == EINTR) {
                        continue;
                }
                GST_ERROR ("sem_timedwait failure: %s", g_strerror (errno));
                g_free (semaphore_name);
                return 1;
        }
        if (daemon) {
                /* daemon, use share memory */
                fd = shm_open (name_hexstr, O_CREAT | O_RDWR, S_IRUSR | S_IWUSR);
                if (fd == -1) {
                        GST_ERROR ("shm_open %s failure: %s", name_hexstr, g_strerror (errno));
                        job->output = NULL;
                        g_free (name_hexstr);
                        sem_post (semaphore);
                        return 1;
                }
                g_free (name_hexstr);
                if (ftruncate (fd, job->output_size) == -1) {
                        GST_ERROR ("ftruncate error: %s", g_strerror (errno));
                        job->output = NULL;
                        sem_post (semaphore);
                        return 1;
                }
                p = mmap (NULL, job->output_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
                job->output_fd = fd;

        } else {
                p = g_malloc (job->output_size);
                job->output_fd = -1;
        }
        output = (JobOutput *)g_malloc (sizeof (JobOutput));
        output->job_description = (gchar *)p;
        output->semaphore = semaphore;
        output->semaphore_name = semaphore_name;
        g_stpcpy (output->job_description, job->description);
        p += (strlen (job->description) / 8 + 1) * 8;
        output->state = (guint64 *)p;
        p += sizeof (guint64); /* state */
        output->source.duration = (gint64 *)p;
        p += sizeof (gint64); /* duration for transcode */
        output->source.sync_error_times = 0;
        output->source.stream_count = jobdesc_streams_count (job->description, "source");
        output->source.streams = (struct _SourceStreamState *)p;
        for (i = 0; i < output->source.stream_count; i++) {
                output->source.streams[i].last_heartbeat = gst_clock_get_time (job->system_clock);
        }
        p += output->source.stream_count * sizeof (struct _SourceStreamState);
        output->encoder_count = jobdesc_encoders_count (job->description);
        if (output->encoder_count == 0) {
                GST_ERROR ("Invalid job without encoders, initialize job failure");
                sem_post (semaphore);
                return 1;
        }
        output->encoders = (struct _EncoderOutput *)g_malloc (output->encoder_count * sizeof (struct _EncoderOutput));
        for (i = 0; i < output->encoder_count; i++) {
                name = g_strdup_printf ("%s.encoder.%d", job->name, i);
                g_strlcpy (output->encoders[i].name, name, STREAM_NAME_LEN);
                g_free (name);
                name = g_strdup_printf ("encoder.%d", i);
                output->encoders[i].stream_count = jobdesc_streams_count (job->description, name);
                g_free (name);
                output->encoders[i].semaphore = output->semaphore;
                output->encoders[i].heartbeat = (GstClockTime *)p;
                p += sizeof (GstClockTime); /* encoder heartbeat */
                output->encoders[i].eos = (gboolean *)p;
                p += sizeof (gboolean);
                output->encoders[i].streams = (struct _EncoderStreamState *)p;
                p += output->encoders[i].stream_count * sizeof (struct _EncoderStreamState); /* encoder state */
                output->encoders[i].total_count = (guint64 *)p;
                p += sizeof (guint64); /* total count size */

                /* non live job has no output */
                if (!job->is_live) {
                        continue;
                }

                output->encoders[i].is_first_buffer = TRUE;
                output->encoders[i].cache_addr = p;
                p += SHM_SIZE;
                output->encoders[i].cache_size = SHM_SIZE;
                output->encoders[i].head_addr = (guint64 *)p;
                p += sizeof (guint64); /* cache head */
                output->encoders[i].tail_addr = (guint64 *)p;
                p += sizeof (guint64); /* cache tail */
                output->encoders[i].last_rap_addr = (guint64 *)p;
                p += sizeof (guint64); /* last rap addr */
        }
        job->output = output;
        sem_post (semaphore);

        return 0;
}
Пример #4
0
static void job_dispose (GObject *obj)
{
        Job *job = JOB (obj);
        GObjectClass *parent_class = g_type_class_peek (G_TYPE_OBJECT);
        JobOutput *output;
        gint i;
        gchar *name, *name_hexstr;

        if (job->output == NULL) {
                return;
        }
        output = job->output;
        if (output->semaphore != NULL) {
                if (sem_close (output->semaphore) == -1) {
                        GST_ERROR ("sem_close failure: %s", g_strerror (errno));
                }
                if (sem_unlink (output->semaphore_name) == -1) {
                        GST_ERROR ("sem_unlink %s error: %s", job->name, g_strerror (errno));
                }
                g_free (output->semaphore_name);
        }
        for (i = 0; i < output->encoder_count; i++) {
                /* message queue release */
                name = g_strdup_printf ("/%s.%d", job->name, i);
                if ((output->encoders[i].mqdes != -1) && (mq_close (output->encoders[i].mqdes) == -1)) {
                        GST_ERROR ("mq_close %s error: %s", name, g_strerror (errno));
                }
                if ((output->encoders[i].mqdes != -1) && (mq_unlink (name) == -1)) {
                        GST_ERROR ("mq_unlink %s error: %s", name, g_strerror (errno));
                }
                if (job->is_live && (output->encoders[i].record_path != NULL)) {
                        g_free (output->encoders[i].record_path);
                }
                g_free (name);
        }
        /* share memory release */
        if (job->output_fd != -1) {
                g_close (job->output_fd, NULL);
                if (munmap (output->job_description, job->output_size) == -1) {
                        GST_ERROR ("munmap %s error: %s", job->name, g_strerror (errno));
                }
                name_hexstr = unicode_file_name_2_shm_name (job->name);
                if (shm_unlink (name_hexstr) == -1) {
                        GST_ERROR ("shm_unlink %s error: %s", job->name, g_strerror (errno));
                }
                g_free (name_hexstr);
        }
        g_free (output);

        if (job->name != NULL) {
                g_free (job->name);
                job->name = NULL;
        }

        if (job->description != NULL) {
                g_free (job->description);
                job->description = NULL;
        }

        if (job->exe_path != NULL) {
                g_free (job->exe_path);
                job->exe_path = NULL;
        }

        G_OBJECT_CLASS (parent_class)->dispose (obj);
}