static GstClockTime send_chunk (EncoderOutput *encoder_output, RequestData *request_data) { RequestDataUserData *request_user_data; gint64 current_gop_end_addr, tail_addr; gint32 ret; request_user_data = request_data->user_data; sem_wait (request_user_data->encoder->mutex); tail_addr = *(encoder_output->tail_addr); current_gop_end_addr = get_current_gop_end (encoder_output, request_user_data); if (request_user_data->send_count == request_user_data->chunk_size + request_user_data->chunk_size_str_len + 2) { /* completly send a chunk, prepare next. */ request_user_data->current_send_position += request_user_data->send_count - request_user_data->chunk_size_str_len - 2; if (request_user_data->current_send_position == encoder_output->cache_size) { request_user_data->current_send_position = 0; } g_free (request_user_data->chunk_size_str); request_user_data->chunk_size_str_len = 0; request_user_data->chunk_size = 0; } if (request_user_data->current_send_position == current_gop_end_addr) { /* next gop. */ request_user_data->current_rap_addr = current_gop_end_addr; if (request_user_data->current_send_position + 12 < encoder_output->cache_size) { request_user_data->current_send_position += 12; } else { request_user_data->current_send_position = request_user_data->current_send_position + 12 - encoder_output->cache_size; } current_gop_end_addr = get_current_gop_end (encoder_output, request_user_data); } sem_post (request_user_data->encoder->mutex); if (request_user_data->chunk_size == 0) { if (current_gop_end_addr == -1) { /* current output gop. */ if ((tail_addr - request_user_data->current_send_position) > 16384) { request_user_data->chunk_size = 16384; } else if (tail_addr > request_user_data->current_send_position) { /* send to tail. */ request_user_data->chunk_size = tail_addr - request_user_data->current_send_position; } else if (tail_addr == request_user_data->current_send_position) { /* no data available, wait a while. */ return 10 * GST_MSECOND + g_random_int_range (1, 1000000); } else if ((encoder_output->cache_size - request_user_data->current_send_position) > 16384) { request_user_data->chunk_size = 16384; } else { request_user_data->chunk_size = encoder_output->cache_size - request_user_data->current_send_position; } } else { /* completely output gop. */ if ((current_gop_end_addr - request_user_data->current_send_position) > 16384) { request_user_data->chunk_size = 16384; } else if (current_gop_end_addr > request_user_data->current_send_position) { /* send to gop end. */ request_user_data->chunk_size = current_gop_end_addr - request_user_data->current_send_position; } else if (current_gop_end_addr == request_user_data->current_send_position) { /* no data available, wait a while. */ return 10 * GST_MSECOND + g_random_int_range (1, 1000000); //FIXME FIXME } else { /* send to cache end. */ request_user_data->chunk_size = encoder_output->cache_size - request_user_data->current_send_position; } } request_user_data->chunk_size_str = g_strdup_printf("%x\r\n", request_user_data->chunk_size); request_user_data->chunk_size_str_len = strlen (request_user_data->chunk_size_str); request_user_data->send_count = 0; } /* send data. */ ret = send_data (encoder_output, request_data); if (ret == -1) { return GST_CLOCK_TIME_NONE; } else { request_user_data->send_count += ret; request_data->bytes_send += ret; } if (request_user_data->send_count == request_user_data->chunk_size + request_user_data->chunk_size_str_len + 2) { /* send complete, wait 10 ms. */ return 10 * GST_MSECOND + g_random_int_range (1, 1000000); } else { /* not send complete, blocking, wait 200 ms. */ return 200 * GST_MSECOND + g_random_int_range (1, 1000000); } }
static GstClockTime send_chunk (EncoderOutput *encoder_output, RequestData *request_data) { HTTPStreamingPrivateData *priv_data; gint64 current_gop_end_addr, tail_addr; gint32 ret; priv_data = request_data->priv_data; if (sem_wait (encoder_output->semaphore) == -1) { GST_WARNING ("send_chunk sem_wait failure: %s", g_strerror (errno)); /* sem_wait failure, wait a while. */ return 100 * GST_MSECOND + g_random_int_range (1, 1000000); } tail_addr = *(encoder_output->tail_addr); current_gop_end_addr = get_current_gop_end (encoder_output, priv_data); if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) { /* completly send a chunk, prepare next. */ priv_data->send_position += priv_data->send_count - priv_data->chunk_size_str_len - 2; if (priv_data->send_position == encoder_output->cache_size) { priv_data->send_position = 0; } g_free (priv_data->chunk_size_str); priv_data->chunk_size_str_len = 0; priv_data->chunk_size = 0; } if (priv_data->send_position == current_gop_end_addr) { /* next gop. */ priv_data->rap_addr = current_gop_end_addr; if (priv_data->send_position + 12 < encoder_output->cache_size) { priv_data->send_position += 12; } else { priv_data->send_position = priv_data->send_position + 12 - encoder_output->cache_size; } current_gop_end_addr = get_current_gop_end (encoder_output, priv_data); } sem_post (encoder_output->semaphore); if (priv_data->chunk_size == 0) { if (current_gop_end_addr == -1) { /* current output gop. */ if ((tail_addr - priv_data->send_position) > 16384) { priv_data->chunk_size = 16384; } else if (tail_addr > priv_data->send_position) { /* send to tail. */ priv_data->chunk_size = tail_addr - priv_data->send_position; } else if (tail_addr == priv_data->send_position) { /* no data available, wait a while. */ return 100 * GST_MSECOND + g_random_int_range (1, 1000000); } else if ((encoder_output->cache_size - priv_data->send_position) > 16384) { priv_data->chunk_size = 16384; } else { priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position; } } else { /* completely output gop. */ if ((current_gop_end_addr - priv_data->send_position) > 16384) { priv_data->chunk_size = 16384; } else if (current_gop_end_addr > priv_data->send_position) { /* send to gop end. */ priv_data->chunk_size = current_gop_end_addr - priv_data->send_position; } else if (current_gop_end_addr == priv_data->send_position) { /* no data available, wait a while. */ return 100 * GST_MSECOND + g_random_int_range (1, 1000000); //FIXME FIXME } else { /* send to cache end. */ priv_data->chunk_size = encoder_output->cache_size - priv_data->send_position; } } priv_data->chunk_size_str = g_strdup_printf ("%x\r\n", priv_data->chunk_size); priv_data->chunk_size_str_len = strlen (priv_data->chunk_size_str); priv_data->send_count = 0; } /* send data. */ ret = send_data (encoder_output, request_data); if (ret == -1) { return GST_CLOCK_TIME_NONE; } else { priv_data->send_count += ret; request_data->bytes_send += ret; } if (priv_data->send_count == priv_data->chunk_size + priv_data->chunk_size_str_len + 2) { /* send complete, wait 10 ms. */ return 10 * GST_MSECOND + g_random_int_range (1, 1000000); } else { /* not send complete, blocking, wait 200 ms. */ return 200 * GST_MSECOND + g_random_int_range (1, 1000000); } }