Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Code refactoring] remove circular dependencies #3256

Conversation

bbert
Copy link
Contributor

@bbert bbert commented May 19, 2020

to/from StreamController and StreamProcessor, as illustrated in following figure (remove red relations):

refacto_streamcontroller_CD

Thanks to this PR, responsabilities are better distributed between the classes.
It especially required to refactor the sheduling mechanism, as illustrated in the following sequence diagrams:

refacto_schedulecontroller_SD

Also, the NextFragmentRule is removed and its logic direclty integrate in the StreamProcessor, as IMO this is not really a rule.

@bbert bbert force-pushed the refactoring-circular-deps branch from db9b083 to 1f6a3b9 Compare May 19, 2020 10:22
@dsilhavy dsilhavy self-requested a review May 22, 2020 14:18
@dsilhavy dsilhavy added this to the 3.1.2 milestone May 22, 2020
Bertrand Berthelot added 8 commits May 26, 2020 15:04
- rename BufferController.switchInitData() by appendInitSegment()
- add method BufferController.replaceBuffer() for replacing buffer when switching track (replace resetBufferInProgress mechanism)
…Controller (to update fragmentDuration for example in case of SegmentTimeline)
} else {
const seekTarget = playbackController.getStreamStartTime(false);
bufferController.setSeekStartTime(seekTarget);
scheduleController.setCurrentRepresentation(getRepresentationInfo());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Before this was also set for livestreams. Might need to move this up to also be applied to livestreams

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is done in setLiveEdgeSeekTarget() method.
This is the way it was done before in ScheduleController

addDVRMetric();
if (!e.error) {
scheduleController.setCurrentRepresentation(adapter.convertDataToRepresentationInfo(e.currentRepresentation));
} else if (e.error.code !== Errors.SEGMENTS_UPDATE_FAILED_ERROR_CODE) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Compared to previous check, addDVRMetric should only be called if e.error.code === Errors.SEGMENTS_UPDATE_FAILED_ERROR_CODE

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Previous check was:
if (e.sender.getType() !== getType() || e.sender.getStreamId() !== getStreamInfo().id || !e.error || e.error.code !== Errors.SEGMENTS_UPDATE_FAILED_ERROR_CODE) return;

let representationInfo = getRepresentationInfo(e.newQuality);
scheduleController.setCurrentRepresentation(representationInfo);
dashMetrics.pushPlayListTraceMetrics(new Date(), PlayListTrace.REPRESENTATION_SWITCH_STOP_REASON);
dashMetrics.createPlaylistTraceMetrics(representationInfo.id, playbackController.getTime() * 1000, playbackController.getPlaybackRate());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might need to add (playbackRate !== null ? playbackRate.toString() : null)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This check is done in DashMetrics.createPlaylistTraceMetrics()

if (e.sender.getStreamProcessor() !== instance) return;
let manifest = manifestModel.getValue();
if (!manifest.doNotUpdateDVRWindowOnBufferUpdated) {
if (e.streamId !== streamInfo.id || e.mediaType !== type) return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We could add "dashMetrics.addBufferLevel()" at this point and remove dashMetrics from the BufferController.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, good point. I'll do it this way

@@ -296,7 +400,7 @@ function StreamProcessor(config) {
}

function setMediaSource(mediaSource) {
bufferController.setMediaSource(mediaSource, getMediaInfo());
bufferController.setMediaSource(mediaSource, getMediaInfoArr());
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to rename the variable in BufferController.setMediaSource(value,mediaInfo) to mediaInfoArr as well

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Additional suggestion: Use mediaInfoArr instead of calling the getter function

const currentRepresentation = getRepresentationInfo(quality);

// Update current representation info (to update fragmentDuration for example in case of SegmentTimeline)
scheduleController.setCurrentRepresentation(currentRepresentation);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Question: Is it possible that the fragmentDuration changed at this point? Why does the representation info change when a fragment has been loaded?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, for SegmentTimeline the segmentDuration (and thus fragmentDuration) is set and available only once a fragment has been requested (in TimelineSegmentsGetter)

}
}

function onQualityChanged(e) {
if (requiredQuality === e.newQuality || type !== e.mediaType || streamProcessor.getStreamInfo().id !== e.streamInfo.id) return;
if (e.streamInfo.id != streamInfo.id || e.mediaType !== type || requiredQuality === e.newQuality) return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use !== for comparing streamInfo ids

resetInitialSettings();
}

function initialize() {
function initialize(hasVideoTrack) {
hasVideoTrack = hasVideoTrack;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename either the outer variable of the payload of the function. Otherwise we overload the name of the variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, I missed it. It's fixed

const initCache = InitCache(context).getInstance();

describe('BufferController', function () {
describe.only('BufferController', function () {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove "only" part

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I fix it

@dsilhavy dsilhavy merged commit f7d4d7c into Dash-Industry-Forum:development Jun 3, 2020
This was referenced Jun 4, 2020
@bbert bbert deleted the refactoring-circular-deps branch June 8, 2020 12:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants