in src/gstreamer/gstkvssink.cpp [317:397]
void create_kinesis_video_stream(GstKvsSink *kvssink) {
auto data = kvssink->data;
map<string, string> *p_stream_tags = nullptr;
map<string, string> stream_tags;
if (kvssink->stream_tags) {
gboolean ret;
ret = kvs_sink_util::gstructToMap(kvssink->stream_tags, &stream_tags);
if (!ret) {
LOG_WARN("Failed to parse stream tags");
} else {
p_stream_tags = &stream_tags;
}
}
// If doing offline mode file uploading, and the user wants to use a specific file start time,
// then switch to use abosolute fragment time. Since we will be adding the file_start_time to the timestamp
// of each frame to make each frame's timestamp absolute. Assuming each frame's timestamp is relative
// (i.e. starting from 0)
if (kvssink->streaming_type == STREAMING_TYPE_OFFLINE && kvssink->file_start_time != 0) {
kvssink->absolute_fragment_times = TRUE;
data->pts_base = (uint64_t) duration_cast<nanoseconds>(seconds(kvssink->file_start_time)).count();
}
switch (data->media_type) {
case AUDIO_VIDEO:
kvssink->framerate = MAX(kvssink->framerate, DEFAULT_STREAM_FRAMERATE_HIGH_DENSITY);
break;
case AUDIO_ONLY:
g_free(kvssink->codec_id);
kvssink->codec_id = kvssink->audio_codec_id;
g_free(kvssink->track_name);
kvssink->track_name = g_strdup(DEFAULT_AUDIO_TRACK_NAME);
kvssink->track_info_type = MKV_TRACK_INFO_TYPE_AUDIO;
kvssink->key_frame_fragmentation = FALSE;
kvssink->framerate = MAX(kvssink->framerate, DEFAULT_STREAM_FRAMERATE_HIGH_DENSITY);
break;
case VIDEO_ONLY:
// no-op because default setup is for video only
break;
}
unique_ptr<StreamDefinition> stream_definition(new StreamDefinition(kvssink->stream_name,
hours(kvssink->retention_period_hours),
p_stream_tags,
kvssink->kms_key_id,
kvssink->streaming_type,
kvssink->content_type,
duration_cast<milliseconds> (seconds(kvssink->max_latency_seconds)),
milliseconds(kvssink->fragment_duration_miliseconds),
milliseconds(kvssink->timecode_scale_milliseconds),
kvssink->key_frame_fragmentation,//Construct a fragment at each key frame
kvssink->frame_timecodes,//Use provided frame timecode
kvssink->absolute_fragment_times,//Relative timecode
kvssink->fragment_acks,//Ack on fragment is enabled
kvssink->restart_on_error,//SDK will restart when error happens
kvssink->recalculate_metrics,//recalculate_metrics
0,
kvssink->framerate,
kvssink->avg_bandwidth_bps,
seconds(kvssink->buffer_duration_seconds),
seconds(kvssink->replay_duration_seconds),
seconds(kvssink->connection_staleness_seconds),
kvssink->codec_id,
kvssink->track_name,
nullptr,
0,
kvssink->track_info_type,
vector<uint8_t>(),
KVS_SINK_DEFAULT_TRACKID));
if (data->media_type == AUDIO_VIDEO) {
stream_definition->addTrack(KVS_SINK_DEFAULT_AUDIO_TRACKID, DEFAULT_AUDIO_TRACK_NAME, kvssink->audio_codec_id, MKV_TRACK_INFO_TYPE_AUDIO);
// Need to reorder frames to avoid fragment overlap error.
stream_definition->setFrameOrderMode(FRAME_ORDERING_MODE_MULTI_TRACK_AV_COMPARE_PTS_ONE_MS_COMPENSATE_EOFR);
}
data->kinesis_video_stream = data->kinesis_video_producer->createStreamSync(move(stream_definition));
data->frame_count = 0;
cout << "Stream is ready" << endl;
}