示例#1
0
static u_char* 
hds_calculate_output_offsets_and_write_afra_entries(
	hds_muxer_state_t* state, 
	uint32_t initial_value, 
	uint32_t afra_entries_base, 
	u_char* p)
{
	hds_muxer_stream_state_t* selected_stream;
	hds_muxer_stream_state_t* cur_stream;
	uint32_t cur_offset = initial_value;

	for (;;)
	{
		// choose a stream
		selected_stream = hds_muxer_choose_stream(state);
		if (selected_stream == NULL)
		{
			break;
		}

		// video key frames start with the codec info
		if (selected_stream->media_type == MEDIA_TYPE_VIDEO && selected_stream->cur_frame->key_frame)
		{
			p = hds_write_afra_atom_entry(p, 
				rescale_time(selected_stream->next_frame_dts, selected_stream->timescale, HDS_TIMESCALE),
				cur_offset + afra_entries_base);
			cur_offset += state->codec_config_size;
		}

		// skip the tag size
		cur_offset += tag_size_by_media_type[selected_stream->media_type];

		// set the offset (points to the beginning of the actual data)
		*selected_stream->cur_frame_output_offset = cur_offset;
		selected_stream->cur_frame_output_offset++;

		// move to the end of the frame
		cur_offset += selected_stream->cur_frame->size;
		cur_offset += sizeof(uint32_t);

		// move to the next frame
		selected_stream->next_frame_time_offset += selected_stream->cur_frame->duration;
		selected_stream->next_frame_dts = rescale_time(selected_stream->next_frame_time_offset, selected_stream->timescale, HDS_TIMESCALE);
		selected_stream->cur_frame++;
	}

	// reset the state
	for (cur_stream = state->first_stream; cur_stream < state->last_stream; cur_stream++)
	{
		cur_stream->cur_frame = cur_stream->first_frame;
		cur_stream->cur_frame_output_offset = cur_stream->first_frame_output_offset;
		cur_stream->next_frame_time_offset = cur_stream->first_frame_time_offset;
		cur_stream->next_frame_dts = rescale_time(cur_stream->next_frame_time_offset, cur_stream->timescale, HDS_TIMESCALE);
	}

	return p;
}
static vod_status_t
hds_muxer_start_frame(hds_muxer_state_t* state)
{
	hds_muxer_stream_state_t* selected_stream;
	uint64_t cur_frame_offset;
	uint64_t cur_frame_dts;
	size_t alloc_size;
	u_char* p;
	vod_status_t rc;

	rc = hds_muxer_choose_stream(state, &selected_stream);
	if (rc != VOD_OK)
	{
		return rc;
	}

	// init the frame
	state->cur_frame = selected_stream->cur_frame;
	state->frames_source = selected_stream->frames_source;
	state->frames_source_context = selected_stream->frames_source_context;
	selected_stream->cur_frame++;
	cur_frame_offset = *selected_stream->cur_frame_input_offset;
	selected_stream->cur_frame_input_offset++;
	selected_stream->cur_frame_output_offset++;

	selected_stream->next_frame_time_offset += state->cur_frame->duration;
	cur_frame_dts = selected_stream->next_frame_dts + selected_stream->clip_start_time;
	selected_stream->next_frame_dts = rescale_time(selected_stream->next_frame_time_offset, selected_stream->timescale, HDS_TIMESCALE);

	state->cache_slot_id = selected_stream->media_type;

	// allocate room for the mux packet header
	state->frame_header_size = tag_size_by_media_type[selected_stream->media_type];

	alloc_size = state->frame_header_size;
	if (selected_stream->media_type == MEDIA_TYPE_VIDEO && state->cur_frame->key_frame)
	{
		alloc_size += state->codec_config_size;
	}

	rc = write_buffer_get_bytes(&state->write_buffer_state, alloc_size, NULL, &p);
	if (rc != VOD_OK)
	{
		vod_log_debug1(VOD_LOG_DEBUG_LEVEL, state->request_context->log, 0,
			"hds_muxer_start_frame: write_buffer_get_bytes failed %i", rc);
		return rc;
	}

	// write the mux packet header and optionally codec config
	if (selected_stream->media_type == MEDIA_TYPE_VIDEO && state->cur_frame->key_frame)
	{
		p = hds_muxer_write_codec_config(p, state, cur_frame_dts);
	}

	switch (selected_stream->media_type)
	{
	case MEDIA_TYPE_VIDEO:
		hds_write_video_tag_header(
			p,
			state->cur_frame->size,
			cur_frame_dts,
			state->cur_frame->key_frame ? FRAME_TYPE_KEY_FRAME : FRAME_TYPE_INTER_FRAME,
			AVC_PACKET_TYPE_NALU,
			rescale_time(state->cur_frame->pts_delay, selected_stream->timescale, HDS_TIMESCALE));
		break;

	case MEDIA_TYPE_AUDIO:
		hds_write_audio_tag_header(
			p,
			state->cur_frame->size,
			cur_frame_dts,
			selected_stream->sound_info,
			AAC_PACKET_TYPE_RAW);
	}

	rc = state->frames_source->start_frame(state->frames_source_context, state->cur_frame, cur_frame_offset);
	if (rc != VOD_OK)
	{
		return rc;
	}

	return VOD_OK;
}
static vod_status_t
hds_calculate_output_offsets_and_write_afra_entries(
	hds_muxer_state_t* state, 
	uint32_t initial_value, 
	uint32_t afra_entries_base, 
	u_char** p)
{
	hds_muxer_stream_state_t* selected_stream;
	hds_muxer_stream_state_t* cur_stream;
	uint32_t cur_offset = initial_value;
	vod_status_t rc;

	for (;;)
	{
		// choose a stream
		rc = hds_muxer_choose_stream(state, &selected_stream);
		if (rc != VOD_OK)
		{
			if (rc == VOD_NOT_FOUND)
			{
				break;		// done
			}
			return rc;
		}

		// video key frames start with the codec info
		if (selected_stream->cur_frame->key_frame && selected_stream->media_type == MEDIA_TYPE_VIDEO && p != NULL)
		{
			*p = hds_write_afra_atom_entry(
				*p, 
				selected_stream->next_frame_dts + selected_stream->clip_start_time, 
				cur_offset + afra_entries_base);
			cur_offset += state->codec_config_size;
		}

		// skip the tag size
		cur_offset += tag_size_by_media_type[selected_stream->media_type];

		// set the offset (points to the beginning of the actual data)
		*selected_stream->cur_frame_output_offset = cur_offset;
		selected_stream->cur_frame_output_offset++;

		// move to the end of the frame
		cur_offset += selected_stream->cur_frame->size;
		cur_offset += sizeof(uint32_t);

		// move to the next frame
		selected_stream->next_frame_time_offset += selected_stream->cur_frame->duration;
		selected_stream->next_frame_dts = rescale_time(selected_stream->next_frame_time_offset, selected_stream->timescale, HDS_TIMESCALE);
		selected_stream->cur_frame++;
	}

	// reset the state
	if (state->clips_end > state->clips_start + 1)
	{
		state->cur_clip = state->clips_start;
		rc = hds_muxer_reinit_tracks(state);
		if (rc != VOD_OK)
		{
			vod_log_error(VOD_LOG_ERR, state->request_context->log, 0,
				"hds_calculate_output_offsets_and_write_afra_entries: unexpected - hds_muxer_reinit_tracks failed %i", rc);
			return rc;
		}

		for (cur_stream = state->first_stream; cur_stream < state->last_stream; cur_stream++)
		{
			cur_stream->cur_frame_output_offset = cur_stream->first_frame_output_offset;
		}
	}
	else
	{
		for (cur_stream = state->first_stream; cur_stream < state->last_stream; cur_stream++)
		{
			cur_stream->cur_frame = cur_stream->first_frame;
			cur_stream->cur_frame_output_offset = cur_stream->first_frame_output_offset;
			cur_stream->next_frame_time_offset = cur_stream->first_frame_time_offset;
			cur_stream->next_frame_dts = rescale_time(cur_stream->next_frame_time_offset, cur_stream->timescale, HDS_TIMESCALE);
		}
	}

	return VOD_OK;
}