static GstFlowReturn new_sample_callback (GstAppSink * sink, gpointer user_data) { GstBuffer *buffer; GstSample *sample; Encoder *encoder = (Encoder *)user_data; *(encoder->output->heartbeat) = gst_clock_get_time (encoder->system_clock); sample = gst_app_sink_pull_sample (GST_APP_SINK (sink)); buffer = gst_sample_get_buffer (sample); sem_wait (encoder->output->semaphore); (*(encoder->output->total_count)) += gst_buffer_get_size (buffer); /* update head_addr, free enough memory for current buffer. */ while (cache_free (encoder) < gst_buffer_get_size (buffer) + 12) { /* timestamp + gop size = 12 */ move_head (encoder); } if (!GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) { /* * random access point found. * write previous gop size to 4 bytes reservation, * write current gop timestamp, * reserve 4 bytes for size of current gop, */ if (encoder->mqdes == -1) { /* no m3u8 output */ move_last_rap (encoder, buffer); } else if (GST_BUFFER_PTS (buffer) == encoder->last_running_time) { gchar *msg; move_last_rap (encoder, buffer); msg = g_strdup_printf ("%lu", encoder->last_segment_duration); if (mq_send (encoder->mqdes, msg, strlen (msg), 1) == -1) { GST_ERROR ("mq_send error: %s", g_strerror (errno)); } g_free (msg); encoder->last_running_time = GST_CLOCK_TIME_NONE; } } /* udpstreaming? */ if (encoder->udpstreaming) { udp_streaming (encoder, buffer); } /* * copy buffer to cache. * update tail_addr */ copy_buffer (encoder, buffer); sem_post (encoder->output->semaphore); gst_sample_unref (sample); return GST_FLOW_OK; }
static GstFlowReturn new_sample_callback (GstAppSink * sink, gpointer user_data) { GstBuffer *buffer; GstSample *sample; Encoder *encoder = (Encoder *)user_data; *(encoder->output->heartbeat) = gst_clock_get_time (encoder->system_clock); sample = gst_app_sink_pull_sample (GST_APP_SINK (sink)); buffer = gst_sample_get_buffer (sample); if (sem_wait (encoder->output->semaphore) == -1) { GST_ERROR ("new_sample_callback sem_wait failure: %s", g_strerror (errno)); gst_sample_unref (sample); return GST_FLOW_OK; } (*(encoder->output->total_count)) += gst_buffer_get_size (buffer); /* update head_addr, free enough memory for current buffer. */ while (cache_free (encoder) <= gst_buffer_get_size (buffer) + 12) { /* timestamp + gop size = 12 */ move_head (encoder); } if (encoder->has_tssegment && encoder->has_m3u8_output) { if ((encoder->duration_accumulation >= encoder->segment_duration) || ((encoder->segment_duration - encoder->duration_accumulation) < 500000000)) { encoder->last_segment_duration = encoder->duration_accumulation; encoder->last_running_time = GST_BUFFER_PTS (buffer); encoder->duration_accumulation = 0; } encoder->duration_accumulation += GST_BUFFER_DURATION (buffer); } /* * random access point found. * 1. with video encoder and IDR found; * 2. audio only encoder and current pts >= last_running_time; * 3. tssegment out every buffer with random access point. */ if ((encoder->has_video && !GST_BUFFER_FLAG_IS_SET (buffer, GST_BUFFER_FLAG_DELTA_UNIT)) || (encoder->has_audio_only && (GST_BUFFER_PTS (buffer) >= encoder->last_running_time)) || (encoder->has_tssegment && (GST_BUFFER_PTS (buffer) >= encoder->last_running_time))) { if (encoder->has_m3u8_output == FALSE) { /* no m3u8 output */ move_last_rap (encoder, buffer); } else if (GST_BUFFER_PTS (buffer) >= encoder->last_running_time) { move_last_rap (encoder, buffer); send_msg (encoder); } else if (encoder->is_first_key) { /* move_last_rap if its first key even if has m3u8 output */ move_last_rap (encoder, buffer); send_msg (encoder); encoder->is_first_key = FALSE; } } /* udpstreaming? */ if (encoder->udpstreaming) { udp_streaming (encoder, buffer); } /* * copy buffer to cache. * update tail_addr */ copy_buffer (encoder, buffer); sem_post (encoder->output->semaphore); gst_sample_unref (sample); return GST_FLOW_OK; }