static u_char* hds_muxer_write_codec_config(u_char* p, hds_muxer_state_t* state, uint64_t cur_frame_dts) { media_track_t* cur_track; hds_muxer_stream_state_t* cur_stream; uint32_t packet_size; u_char* packet_start; for (cur_stream = state->first_stream; cur_stream < state->last_stream; cur_stream++) { cur_track = cur_stream->track; packet_start = p; switch (cur_track->media_info.media_type) { case MEDIA_TYPE_VIDEO: p = hds_write_video_tag_header( p, cur_track->media_info.extra_data_size, cur_frame_dts, FRAME_TYPE_KEY_FRAME, AVC_PACKET_TYPE_SEQUENCE_HEADER, 0); break; case MEDIA_TYPE_AUDIO: p = hds_write_audio_tag_header( p, cur_track->media_info.extra_data_size, cur_frame_dts, cur_stream->sound_info, AAC_PACKET_TYPE_SEQUENCE_HEADER); break; } p = vod_copy(p, cur_track->media_info.extra_data, cur_track->media_info.extra_data_size); packet_size = p - packet_start; write_be32(p, packet_size); } return p; }
static u_char* hds_muxer_write_codec_config(u_char* p, hds_muxer_state_t* state, uint64_t cur_frame_dts) { mpeg_stream_metadata_t* cur_stream; hds_muxer_stream_state_t* stream_state; size_t packet_size; for (stream_state = state->first_stream; stream_state < state->last_stream; stream_state++) { cur_stream = stream_state->metadata; packet_size = sizeof(adobe_mux_packet_header_t)+cur_stream->media_info.extra_data_size; switch (cur_stream->media_info.media_type) { case MEDIA_TYPE_VIDEO: p = hds_write_video_tag_header( p, cur_stream->media_info.extra_data_size, cur_frame_dts, FRAME_TYPE_KEY_FRAME, AVC_PACKET_TYPE_SEQUENCE_HEADER, 0); packet_size += sizeof(video_tag_header_avc); break; case MEDIA_TYPE_AUDIO: p = hds_write_audio_tag_header( p, cur_stream->media_info.extra_data_size, cur_frame_dts, stream_state->sound_info, AAC_PACKET_TYPE_SEQUENCE_HEADER); packet_size += sizeof(audio_tag_header_aac); break; } p = vod_copy(p, cur_stream->media_info.extra_data, cur_stream->media_info.extra_data_size); write_dword(p, packet_size); } 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; }