mirror of
https://github.com/androidx/media.git
synced 2025-05-12 18:19:50 +08:00
Fix incorrect decoder non-reuse when operating rate needs clearing
This fixes a case where updateCodecOperatingRate would configure the decoder to be drained and then released, only for onInputFormatChanged to override the drain action with something else. We've not seen any reports of this issue, which suggests that either it's OK to not release the decoder in such cases, or that the case doesn't happen very often. I suspect that it's both, but let's restore the intended behaviour for now. PiperOrigin-RevId: 340909132
This commit is contained in:
parent
702e5cfb3e
commit
477eae3c57
@ -683,7 +683,7 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
if (codec != null
|
if (codec != null
|
||||||
&& codecDrainAction != DRAIN_ACTION_REINITIALIZE
|
&& codecDrainAction != DRAIN_ACTION_REINITIALIZE
|
||||||
&& getState() != STATE_DISABLED) {
|
&& getState() != STATE_DISABLED) {
|
||||||
updateCodecOperatingRate();
|
updateOperatingRateOrReinitializeCodec(codecInputFormat);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1416,33 +1416,42 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
drainAndReinitializeCodec();
|
drainAndReinitializeCodec();
|
||||||
break;
|
break;
|
||||||
case KEEP_CODEC_RESULT_YES_WITH_FLUSH:
|
case KEEP_CODEC_RESULT_YES_WITH_FLUSH:
|
||||||
codecInputFormat = newFormat;
|
if (updateOperatingRateOrReinitializeCodec(newFormat)) {
|
||||||
updateCodecOperatingRate();
|
// Codec re-initialization triggered.
|
||||||
if (drainAndUpdateCodecDrmSession) {
|
|
||||||
drainAndUpdateCodecDrmSessionV23();
|
|
||||||
} else {
|
} else {
|
||||||
drainAndFlushCodec();
|
codecInputFormat = newFormat;
|
||||||
|
if (drainAndUpdateCodecDrmSession) {
|
||||||
|
drainAndUpdateCodecDrmSessionV23();
|
||||||
|
} else {
|
||||||
|
drainAndFlushCodec();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION:
|
case KEEP_CODEC_RESULT_YES_WITH_RECONFIGURATION:
|
||||||
codecReconfigured = true;
|
if (updateOperatingRateOrReinitializeCodec(newFormat)) {
|
||||||
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
// Codec re-initialization triggered.
|
||||||
codecNeedsAdaptationWorkaroundBuffer =
|
} else {
|
||||||
codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_ALWAYS
|
codecReconfigured = true;
|
||||||
|| (codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION
|
codecReconfigurationState = RECONFIGURATION_STATE_WRITE_PENDING;
|
||||||
&& newFormat.width == codecInputFormat.width
|
codecNeedsAdaptationWorkaroundBuffer =
|
||||||
&& newFormat.height == codecInputFormat.height);
|
codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_ALWAYS
|
||||||
codecInputFormat = newFormat;
|
|| (codecAdaptationWorkaroundMode == ADAPTATION_WORKAROUND_MODE_SAME_RESOLUTION
|
||||||
updateCodecOperatingRate();
|
&& newFormat.width == codecInputFormat.width
|
||||||
if (drainAndUpdateCodecDrmSession) {
|
&& newFormat.height == codecInputFormat.height);
|
||||||
drainAndUpdateCodecDrmSessionV23();
|
codecInputFormat = newFormat;
|
||||||
|
if (drainAndUpdateCodecDrmSession) {
|
||||||
|
drainAndUpdateCodecDrmSessionV23();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION:
|
case KEEP_CODEC_RESULT_YES_WITHOUT_RECONFIGURATION:
|
||||||
codecInputFormat = newFormat;
|
if (updateOperatingRateOrReinitializeCodec(newFormat)) {
|
||||||
updateCodecOperatingRate();
|
// Codec re-initialization triggered.
|
||||||
if (drainAndUpdateCodecDrmSession) {
|
} else {
|
||||||
drainAndUpdateCodecDrmSessionV23();
|
codecInputFormat = newFormat;
|
||||||
|
if (drainAndUpdateCodecDrmSession) {
|
||||||
|
drainAndUpdateCodecDrmSessionV23();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -1598,23 +1607,30 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the codec operating rate.
|
* Updates the codec operating rate, or triggers codec release and re-initialization if a
|
||||||
|
* previously set operating rate needs to be cleared.
|
||||||
*
|
*
|
||||||
|
* @param format The {@link Format} for which the operating rate should be configured.
|
||||||
* @throws ExoPlaybackException If an error occurs releasing or initializing a codec.
|
* @throws ExoPlaybackException If an error occurs releasing or initializing a codec.
|
||||||
|
* @return Whether codec release and re-initialization was triggered, rather than the existing
|
||||||
|
* codec being updated.
|
||||||
*/
|
*/
|
||||||
private void updateCodecOperatingRate() throws ExoPlaybackException {
|
private boolean updateOperatingRateOrReinitializeCodec(Format format)
|
||||||
|
throws ExoPlaybackException {
|
||||||
if (Util.SDK_INT < 23) {
|
if (Util.SDK_INT < 23) {
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
float newCodecOperatingRate =
|
float newCodecOperatingRate =
|
||||||
getCodecOperatingRateV23(playbackSpeed, codecInputFormat, getStreamFormats());
|
getCodecOperatingRateV23(playbackSpeed, format, getStreamFormats());
|
||||||
if (codecOperatingRate == newCodecOperatingRate) {
|
if (codecOperatingRate == newCodecOperatingRate) {
|
||||||
// No change.
|
// No change.
|
||||||
|
return false;
|
||||||
} else if (newCodecOperatingRate == CODEC_OPERATING_RATE_UNSET) {
|
} else if (newCodecOperatingRate == CODEC_OPERATING_RATE_UNSET) {
|
||||||
// The only way to clear the operating rate is to instantiate a new codec instance. See
|
// The only way to clear the operating rate is to instantiate a new codec instance. See
|
||||||
// [Internal ref: b/111543954].
|
// [Internal ref: b/111543954].
|
||||||
drainAndReinitializeCodec();
|
drainAndReinitializeCodec();
|
||||||
|
return true;
|
||||||
} else if (codecOperatingRate != CODEC_OPERATING_RATE_UNSET
|
} else if (codecOperatingRate != CODEC_OPERATING_RATE_UNSET
|
||||||
|| newCodecOperatingRate > assumedMinimumCodecOperatingRate) {
|
|| newCodecOperatingRate > assumedMinimumCodecOperatingRate) {
|
||||||
// We need to set the operating rate, either because we've set it previously or because it's
|
// We need to set the operating rate, either because we've set it previously or because it's
|
||||||
@ -1623,7 +1639,10 @@ public abstract class MediaCodecRenderer extends BaseRenderer {
|
|||||||
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, newCodecOperatingRate);
|
codecParameters.putFloat(MediaFormat.KEY_OPERATING_RATE, newCodecOperatingRate);
|
||||||
codec.setParameters(codecParameters);
|
codec.setParameters(codecParameters);
|
||||||
codecOperatingRate = newCodecOperatingRate;
|
codecOperatingRate = newCodecOperatingRate;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Starts draining the codec for flush. */
|
/** Starts draining the codec for flush. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user