コード例 #1
0
ファイル: job.c プロジェクト: bbshocking/gstreamill
static gchar * render_master_m3u8_playlist (Job *job)
{
        GString *master_m3u8_playlist;
        gchar *p, *value;
        gint i;

        master_m3u8_playlist = g_string_new ("");
        g_string_append_printf (master_m3u8_playlist, M3U8_HEADER_TAG);
        if (jobdesc_m3u8streaming_version (job->description) == 0) {
                g_string_append_printf (master_m3u8_playlist, M3U8_VERSION_TAG, 3);

        } else {
                g_string_append_printf (master_m3u8_playlist, M3U8_VERSION_TAG, jobdesc_m3u8streaming_version (job->description));
        }

        for (i = 0; i < job->output->encoder_count; i++) {
                p = g_strdup_printf ("encoder.%d.elements.x264enc.property.bitrate", i);
                value = jobdesc_element_property_value (job->description, p);
                if (value != NULL) {
                        GST_INFO ("job %s with m3u8 output, append end tag", job->name);
                        g_string_append_printf (master_m3u8_playlist, M3U8_STREAM_INF_TAG, 1, value);
                        g_string_append_printf (master_m3u8_playlist, "encoder/%d/playlist.m3u8<%%parameters%%>\n", i);
                        g_free (value);
                }
                g_free (p);
        }

        p = master_m3u8_playlist->str;
        g_string_free (master_m3u8_playlist, FALSE);

        return p;
}
コード例 #2
0
ファイル: gstreamill.c プロジェクト: bbshocking/gstreamill
static void job_check_func (gpointer data, gpointer user_data)
{
        Job *job = (Job *)data;
        Gstreamill *gstreamill = (Gstreamill *)user_data;

        if (gstreamill->stop) {
                GST_ERROR ("waitting %s stopped", job->name);
                return;
        }

        /* stat report. */
        if (gstreamill->daemon && (job->worker_pid != 0)) {
                job_stat_update (job);
                GST_INFO ("Job %s's average cpu: %d%%, cpu: %d%%, rss: %lu",
                                job->name,
                                job->cpu_average,
                                job->cpu_current,
                                job->memory);
        }

        if (*(job->output->state) != JOB_STATE_PLAYING) {
                return;
        }

        source_check (gstreamill, job);

        encoders_check (gstreamill, job);

        if (job->is_live) {
                sync_check (gstreamill, job);
        }

        /* check non live job eos */
        if (!job->is_live) {
                gint i;
                gboolean eos = TRUE;

                for (i = 0; i < job->output->encoder_count; i++) {
                        if (!(*(job->output->encoders[i].eos))) {
                                eos = FALSE;
                                break;

                        } else {
                                /* add #EXT-X-ENDLIST to playlist if output is m3u8 */
                                gchar *location, *property, *playlist1, *playlist2;

                                property = g_strdup_printf ("encoder.%d.elements.hlssink.property.playlist-location", i);
                                location = jobdesc_element_property_value (job->description, property);
                                g_free (property);
                                if (location != NULL) {
                                        g_file_get_contents (location, &playlist1, NULL, NULL);
                                        playlist2 = g_strdup_printf ("%s#EXT-X-ENDLIST\n",  playlist1);
                                        g_file_set_contents (location, playlist2, strlen(playlist2), NULL);
                                        g_free (playlist1);
                                        g_free (playlist2);
                                        g_free (location);
                                }
                        }
                }

                if (eos) {
                        stop_job (job, SIGTERM);
                        job->eos = TRUE;
                }
        }
}
コード例 #3
0
ファイル: encoder.c プロジェクト: yan5845hao/gstreamill
guint encoder_initialize (GArray *earray, gchar *job, EncoderOutput *encoders, Source *source)
{
    gint i, j, k;
    gchar *job_name, *pipeline;
    Encoder *encoder;
    EncoderStream *estream;
    SourceStream *sstream;
    gchar **bins;
    gsize count;

    job_name = jobdesc_get_name (job);
    count = jobdesc_encoders_count (job);
    for (i = 0; i < count; i++) {
        pipeline = g_strdup_printf ("encoder.%d", i);
        encoder = encoder_new ("name", pipeline, NULL);
        encoder->job_name = g_strdup (job_name);
        encoder->id = i;
        encoder->last_running_time = GST_CLOCK_TIME_NONE;
        encoder->output = &(encoders[i]);
        encoder->segment_duration = jobdesc_m3u8streaming_segment_duration (job);
        encoder->duration_accumulation = 0;
        encoder->last_segment_duration = 0;
        encoder->force_key_count = 0;
        encoder->has_video = FALSE;
        encoder->has_audio_only = FALSE;
        encoder->has_tssegment = FALSE;

        bins = jobdesc_bins (job, pipeline);
        if (encoder_extract_streams (encoder, bins) != 0) {
            GST_ERROR ("extract encoder %s streams failure", encoder->name);
            g_free (job_name);
            g_free (pipeline);
            g_strfreev (bins);
            return 1;
        }
        g_strfreev (bins);

        for (j = 0; j < encoder->streams->len; j++) {
            estream = g_array_index (encoder->streams, gpointer, j);
            estream->state = &(encoders[i].streams[j]);
            g_strlcpy (encoders[i].streams[j].name, estream->name, STREAM_NAME_LEN);
            estream->encoder = encoder;
            estream->source = NULL;
            for (k = 0; k < source->streams->len; k++) {
                sstream = g_array_index (source->streams, gpointer, k);
                if (g_strcmp0 (sstream->name, estream->name) == 0) {
                    estream->source = sstream;
                    estream->current_position = -1;
                    estream->system_clock = encoder->system_clock;
                    g_array_append_val (sstream->encoders, estream);
                    break;
                }
            }
            if (estream->source == NULL) {
                GST_ERROR ("cant find job %s source %s.", job_name, estream->name);
                g_free (job_name);
                g_free (pipeline);
                return 1;
            }
        }

        /* mkdir for transcode job. */
        if (!jobdesc_is_live (job)) {
            gchar *locations[] = {"%s.elements.filesink.property.location", "%s.elements.hlssink.property.location", NULL};
            gchar *p, *value, **location;

            location = locations;
            while (*location != NULL) {
                p = g_strdup_printf (*location, pipeline);
                value = jobdesc_element_property_value (job, p);
                g_free (p);
                if (value != NULL) {
                    break;
                }
                location += 1;
            }
            if (*location == NULL) {
                GST_ERROR ("No location found for transcode");
                return 1;
            }
            p = g_path_get_dirname (value);
            g_free (value);
            if (g_mkdir_with_parents (p, 0755) != 0) {
                GST_ERROR ("Can't open or create directory: %s.", p);
                g_free (p);
                return 1;
            }
            g_free (p);
        }

        /* parse bins and create pipeline. */
        encoder->bins = bins_parse (job, pipeline);
        if (encoder->bins == NULL) {
            GST_ERROR ("parse job %s bins error", job_name);
            g_free (job_name);
            g_free (pipeline);
            return 1;
        }
        complete_request_element (encoder->bins);
        if (create_encoder_pipeline (encoder) != 0) {
            GST_ERROR ("create encoder %s pipeline failure", encoder->name);
            g_free (job_name);
            g_free (pipeline);
            return 1;
        }

        /* parse udpstreaming */
        udpstreaming_parse (job, encoder);

        /* m3u8 playlist */
        encoder->is_first_key = TRUE;
        if (jobdesc_m3u8streaming (job)) {
            memset (&(encoder->msg_sock_addr), 0, sizeof (struct sockaddr_un));
            encoder->msg_sock_addr.sun_family = AF_UNIX;
            strncpy (encoder->msg_sock_addr.sun_path, MSG_SOCK_PATH, sizeof (encoder->msg_sock_addr.sun_path) - 1);
            encoder->msg_sock = socket(AF_UNIX, SOCK_DGRAM | SOCK_NONBLOCK, 0);
            encoder->has_m3u8_output = TRUE;

        } else {
            encoder->has_m3u8_output = FALSE;
        }

        g_free (pipeline);
        g_array_append_val (earray, encoder);
    }
    g_free (job_name);

    return 0;
}