|
|
Chromium Code Reviews|
Created:
4 years, 11 months ago by chcunningham Modified:
4 years, 11 months ago CC:
chromium-reviews, posciak+watch_chromium.org, jam, mcasas+watch_chromium.org, feature-media-reviews_chromium.org, darin-cc_chromium.org, piman+watch_chromium.org, sandersd (OOO until July 31) Base URL:
https://chromium.googlesource.com/chromium/src.git@master Target Ref:
refs/pending/heads/master Project:
chromium Visibility:
Public. |
DescriptionFix MP4 mid-stream resolution changes for MSE on android spitzer.
ANDROID CONTEXT:
Android'S MediaCodec does not support mid-stream resolution changes prior
to Kitkat. See b/7093648 and FEATURE_AdaptivePlayback.
The workaround for earlier versions of Android is to call
MediaCodec.flush() before starting to decode the new resolution. Flush
has some gotchas:
1) All output buffers are immediately revoked at the point of the flush,
so you'll want to signal then wait for end-of-stream before flushing
to decode the last frames before the config change.
2) Buuut, flush does not work reliably after EOS before JB-MR2. So
we need to completely Stop and reset MediaCodec for earlier
versions (SDK_INT < 18). See b/8125974, b/8347958.
CHROME CONTEXT:
In WebRTC, the backward compatable workaround for the above Android
bugs is to have the call Reset on the VDA whenever the
client becomes aware of a config change. https://crrev.com/47123002
THIS CHANGE:
For MSE, we can take advantage of the fact that every config change
is preceeded by an EOS signal to drain the decoder [0]. This leaves
MediaCodec in the "End of Stream" state, which is recovered from
by calling flush. This change adds the flush call after EOS makes
its way through the decoder, which conveniently prepares MediaCodec
to recieve new buffers of a potentially different resolution.
MediaCodec.flush() appears as MediaCodecBridge.reset() thanks to JNI
and some confusing naming.
To continue working around the broken flush for android < JB-MR2, we
still stop and reconfigure MediaCodec when SDK_INT < 18.
[0] https://code.google.com/p/chromium/codesearch#chromium/src/media/filters/decoder_stream.cc&rcl=1452025768&l=488
RUNNING THE TESTS:
Tests must be run with additional command line flags to pass.
--enable-unified-media-pipeline to enable spitzer
--use-gl=egl to override using mesa (used in tests). Mesa is not
compatible with SurfaceTextures used in HW accelerated decoding.
BUG=555703
Committed: https://crrev.com/9e5ca6716a7d19b8f605c256251b80a6ae49eaa0
Cr-Commit-Position: refs/heads/master@{#368507}
Patch Set 1 #
Total comments: 20
Patch Set 2 : Rebase #Patch Set 3 : CL feedback round 1 #Patch Set 4 : Rebase + TODO comment in ResetCodecState #
Messages
Total messages: 19 (7 generated)
chcunningham@chromium.org changed reviewers: + liberato@chromium.org, watk@chromium.org
This makes all of the resolution change tests pass! I'll do a follow up cl to add a VirtualTestSuite that uses the necessary spitzer + gl command line flags and updates test expectations. Visually things look good. I occasionally see the frames render upside down, but watk expects this to be fixed by an upcoming change from liberato (fixing existing race condition).
nice. -fl https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.cc (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:373: ResetOutputState(); we don't know that this is eos. we might not have the bitstream buffer for the presentation timestamp. we don't want to ResetOutputState unless it's eos. something like if(eos) { do this stuff } else if(it!=end) { do the else existing clause } else should_try_again = true; https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:543: void AndroidVideoDecodeAccelerator::ResetOutputState() { maybe ResetCodecState, or maybe ResetOrReplaceCodec? https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:546: strategy_->DismissOnePictureBuffer(it->second); this will immediately make the images undrawable, including the most recent frame. DismissOnePictureBuffer disconnects the image from the texture, so all future draw requests will fail even if they are in the SurfaceTexture's front buffer already. you might want to do two things: Remove the call to SetImageForPicture in deferred::DismissOnePictureBuffer. This will keep the SurfaceTexture's front buffer attached. The codec buffer will still be released immediately, however, which is good. Second, you might want to count how many of these picture buffers still have codec buffers attached in DismissOne. that gives us an idea of how many frames are being affected. This doesn't have to be part of the CL, but it would be nice to have some measurement. You can just count it in ReleaseCodecBufferForPicture, but be sure to only count calls from DismissOne. There is a call to ReleaseCodecBufferForPicture from ReuseOnePictureBuffer that we don't want to count. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:562: if (state_ == NO_ERROR && not sure that it matters if |state_| is NO_ERROR or not. or, conversely, if it does matter, it's unclear that ConfigureMediaCodec would fix it while Reset would not. from a quick check, i think that it's okay to ignore |state_| and unconditionally set it to NO_ERROR. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:571: ConfigureMediaCodec(); is this going to be deferred as part of sandersd@ work? i don't think that we want to re-allocate the codec if we don't know if another bitstream buffer is coming. as in, release it here and allocate it later. for this CL, it's fine as it is. just making sure we're all in sync.
I only had minor comments. I'll leave the rest up to you and Frank. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.cc (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:544: for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); Range based for-loop opportunity! https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:553: CHECK(free_picture_ids_.empty()); Heh, this is a paranoid check. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.h (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.h:177: void ResetOutputState(); My naming suggestions: PrepareForNewConfig? PrepareForReinitialization? ResetMediaCodec? https://codereview.chromium.org/1560983002/diff/1/media/filters/gpu_video_dec... File media/filters/gpu_video_decoder.cc (right): https://codereview.chromium.org/1560983002/diff/1/media/filters/gpu_video_dec... media/filters/gpu_video_decoder.cc:295: DVLOG(3) << __FUNCTION__ << " Initiating Flush for EOS()"; parens after EOS?
https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.cc (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:373: ResetOutputState(); On 2016/01/06 18:06:32, liberato wrote: > we don't know that this is eos. we might not have the bitstream buffer for the > presentation timestamp. we don't want to ResetOutputState unless it's eos. > > something like if(eos) { do this stuff } else if(it!=end) { do the else existing > clause } else should_try_again = true; Done. Added a log and made sure to ReleaseOutputBuffer whenever we don't find the timestamp. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:543: void AndroidVideoDecodeAccelerator::ResetOutputState() { On 2016/01/06 18:06:32, liberato wrote: > maybe ResetCodecState, or maybe ResetOrReplaceCodec? Made this ResetCodecState https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:544: for (OutputBufferMap::iterator it = output_picture_buffers_.begin(); On 2016/01/06 20:05:51, watk wrote: > Range based for-loop opportunity! Done. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:546: strategy_->DismissOnePictureBuffer(it->second); On 2016/01/06 18:06:32, liberato wrote: > this will immediately make the images undrawable, including the most recent > frame. DismissOnePictureBuffer disconnects the image from the texture, so all > future draw requests will fail even if they are in the SurfaceTexture's front > buffer already. you might want to do two things: > > Remove the call to SetImageForPicture in deferred::DismissOnePictureBuffer. > This will keep the SurfaceTexture's front buffer attached. The codec buffer > will still be released immediately, however, which is good. SetImageForPicture appears to be a no-op whenever the image is 0. I don't see that it actually unhooks anything? But lets say it does do some unhooking and I stop calling it so that it can remain attached to SurfaceTexture's front buffer... potentially n00b question: how can we be sure that MediaCodec won't write to this front texture while we're actively showing the frame? We've Released the ID to the codec, so shouldn't it feel free to re-use the texture associated with that ID? Is there a potential for graphics glitches if this occurs? Dan and I hashed this out a bunch (I've still got a ton to learn about GL and the gpu parts of our pipeline). His feeling is that this is that this is unlikely to be a problem because Android likely does some ref counting on this memory and will find that SurfaceTexture still holds a ref (front buffer) and will not truly free it for writing until all refs are detached. This makes sense to me, but I'm nervous and haven't seen mention of this in the docs. Going back to our design chat, we were worried that waiting for AVDA::ReusePictureBuffer for all buffers would block forever as someone (not sure who?) is likely to hold onto one. Questions: 1) Shouldn't AVDA reporting NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE mean we can expect to get them all back? Tracing this code path isn't trivial... can you point me at the component you think may hold onto buffers? 2) If we really don't get all the PictureBuffers back, Dan mentioned we might be able to do something like post a task whenever we UpdateTheSurfaceTexture and basically wait for all the PictureBuffer's to be *used* before MediaCodec.flush/Reset. WDYT > Second, you might want to count how many of these picture buffers still have > codec buffers attached in DismissOne. that gives us an idea of how many frames > are being affected. This doesn't have to be part of the CL, but it would be > nice to have some measurement. You can just count it in > ReleaseCodecBufferForPicture, but be sure to only count calls from DismissOne. > There is a call to ReleaseCodecBufferForPicture from ReuseOnePictureBuffer that > we don't want to count. Happy to count. Do you just want a dvlog everytime this occurs? https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:553: CHECK(free_picture_ids_.empty()); On 2016/01/06 20:05:51, watk wrote: > Heh, this is a paranoid check. Are you suggesting a downgrade to DCHECK? https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:562: if (state_ == NO_ERROR && On 2016/01/06 18:06:32, liberato wrote: > not sure that it matters if |state_| is NO_ERROR or not. or, conversely, if it > does matter, it's unclear that ConfigureMediaCodec would fix it while Reset > would not. > > from a quick check, i think that it's okay to ignore |state_| and > unconditionally set it to NO_ERROR. My thinking here comes from the state diagram in the MediaCodec docs. When we hit an error we enter the "Stopped" mega-state and we need to call MediaCodec.reset() to make the codec usable again... flush() won't cut it. I think the ConfigureMediaCodec probably effectively resets things in that it makes a completely new one. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:571: ConfigureMediaCodec(); On 2016/01/06 18:06:32, liberato wrote: > is this going to be deferred as part of sandersd@ work? i don't think that we > want to re-allocate the codec if we don't know if another bitstream buffer is > coming. as in, release it here and allocate it later. > > for this CL, it's fine as it is. just making sure we're all in sync. sanders@, comment on your plans? Agree, lazy would be better. https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.h (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.h:177: void ResetOutputState(); On 2016/01/06 20:05:51, watk wrote: > My naming suggestions: PrepareForNewConfig? PrepareForReinitialization? > ResetMediaCodec? Acknowledged. https://codereview.chromium.org/1560983002/diff/1/media/filters/gpu_video_dec... File media/filters/gpu_video_decoder.cc (right): https://codereview.chromium.org/1560983002/diff/1/media/filters/gpu_video_dec... media/filters/gpu_video_decoder.cc:295: DVLOG(3) << __FUNCTION__ << " Initiating Flush for EOS()"; On 2016/01/06 20:05:51, watk wrote: > parens after EOS? Done.
lgtm. regardless of whether we're trashing lots of codec buffers or not, it's still a pretty big improvement over where we are. a fix, if needed, can be a separate CL. thanks -fl https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.cc (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:546: strategy_->DismissOnePictureBuffer(it->second); On 2016/01/07 02:14:48, chcunningham wrote: > On 2016/01/06 18:06:32, liberato wrote: > > this will immediately make the images undrawable, including the most recent > > frame. DismissOnePictureBuffer disconnects the image from the texture, so all > > future draw requests will fail even if they are in the SurfaceTexture's front > > buffer already. you might want to do two things: > > > > Remove the call to SetImageForPicture in deferred::DismissOnePictureBuffer. > > This will keep the SurfaceTexture's front buffer attached. The codec buffer > > will still be released immediately, however, which is good. > > SetImageForPicture appears to be a no-op whenever the image is 0. I don't see > that it actually unhooks anything? > > But lets say it does do some unhooking and I stop calling it so that it can > remain attached to SurfaceTexture's front buffer... potentially n00b question: > how can we be sure that MediaCodec won't write to this front texture while we're > actively showing the frame? We've Released the ID to the codec, so shouldn't it > feel free to re-use the texture associated with that ID? Is there a potential > for graphics glitches if this occurs? > > Dan and I hashed this out a bunch (I've still got a ton to learn about GL and > the gpu parts of our pipeline). His feeling is that this is that this is > unlikely to be a problem because Android likely does some ref counting on this > memory and will find that SurfaceTexture still holds a ref (front buffer) and > will not truly free it for writing until all refs are detached. This makes sense > to me, but I'm nervous and haven't seen mention of this in the docs. > > Going back to our design chat, we were worried that waiting for > AVDA::ReusePictureBuffer for all buffers would block forever as someone (not > sure who?) is likely to hold onto one. Questions: > > 1) Shouldn't AVDA reporting NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE mean we can > expect to get them all back? Tracing this code path isn't trivial... can you > point me at the component you think may hold onto buffers? > > 2) If we really don't get all the PictureBuffers back, Dan mentioned we might be > able to do something like post a task whenever we UpdateTheSurfaceTexture and > basically wait for all the PictureBuffer's to be *used* before > MediaCodec.flush/Reset. WDYT > > > Second, you might want to count how many of these picture buffers still have > > codec buffers attached in DismissOne. that gives us an idea of how many > frames > > are being affected. This doesn't have to be part of the CL, but it would be > > nice to have some measurement. You can just count it in > > ReleaseCodecBufferForPicture, but be sure to only count calls from DismissOne. > > > There is a call to ReleaseCodecBufferForPicture from ReuseOnePictureBuffer > that > > we don't want to count. > > Happy to count. Do you just want a dvlog everytime this occurs? doesn't do anything for null: wow! well then, i'd not worry about it. good catch. not sure if it's a mistake or there's some subtle reason that i'm forgetting. probably best not to touch it. front buffer issues: luckily, there's no issue. the front buffer isn't accessible to media codec. i can go into more detail if you like next time i'm in seattle (probably friday). getting back picture buffers: i'm not sure if the last buffer is subject to this, or how long it might take. i think that VideoFrameCompositor might latch it. i'm really not sure though. 1) Personally, i wouldn't bother. i think that your current approach of 'keep the front buffer valid' is probably fine -- that's why i suggested counting the number of unused decoder buffers. it will give us an idea of whether we really have a problem. if we do, then we can figure out why. but my first guesses would be VideoFrameCompositor or VideoRendererAlgorithm, to answer your question. 2) Yes -- i was thinking about this too, and i also believe that checking for used is sufficient. however, i'm not sure that it's necessary that we do anything.
Thanks guys! https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... File content/common/gpu/media/android_video_decode_accelerator.cc (right): https://codereview.chromium.org/1560983002/diff/1/content/common/gpu/media/an... content/common/gpu/media/android_video_decode_accelerator.cc:546: strategy_->DismissOnePictureBuffer(it->second); On 2016/01/07 14:48:55, liberato wrote: > On 2016/01/07 02:14:48, chcunningham wrote: > > On 2016/01/06 18:06:32, liberato wrote: > > > this will immediately make the images undrawable, including the most recent > > > frame. DismissOnePictureBuffer disconnects the image from the texture, so > all > > > future draw requests will fail even if they are in the SurfaceTexture's > front > > > buffer already. you might want to do two things: > > > > > > Remove the call to SetImageForPicture in deferred::DismissOnePictureBuffer. > > > This will keep the SurfaceTexture's front buffer attached. The codec buffer > > > will still be released immediately, however, which is good. > > > > SetImageForPicture appears to be a no-op whenever the image is 0. I don't see > > that it actually unhooks anything? > > > > But lets say it does do some unhooking and I stop calling it so that it can > > remain attached to SurfaceTexture's front buffer... potentially n00b question: > > how can we be sure that MediaCodec won't write to this front texture while > we're > > actively showing the frame? We've Released the ID to the codec, so shouldn't > it > > feel free to re-use the texture associated with that ID? Is there a potential > > for graphics glitches if this occurs? > > > > Dan and I hashed this out a bunch (I've still got a ton to learn about GL and > > the gpu parts of our pipeline). His feeling is that this is that this is > > unlikely to be a problem because Android likely does some ref counting on this > > memory and will find that SurfaceTexture still holds a ref (front buffer) and > > will not truly free it for writing until all refs are detached. This makes > sense > > to me, but I'm nervous and haven't seen mention of this in the docs. > > > > Going back to our design chat, we were worried that waiting for > > AVDA::ReusePictureBuffer for all buffers would block forever as someone (not > > sure who?) is likely to hold onto one. Questions: > > > > 1) Shouldn't AVDA reporting NEEDS_ALL_PICTURE_BUFFERS_TO_DECODE mean we can > > expect to get them all back? Tracing this code path isn't trivial... can you > > point me at the component you think may hold onto buffers? > > > > 2) If we really don't get all the PictureBuffers back, Dan mentioned we might > be > > able to do something like post a task whenever we UpdateTheSurfaceTexture and > > basically wait for all the PictureBuffer's to be *used* before > > MediaCodec.flush/Reset. WDYT > > > > > Second, you might want to count how many of these picture buffers still have > > > codec buffers attached in DismissOne. that gives us an idea of how many > > frames > > > are being affected. This doesn't have to be part of the CL, but it would be > > > nice to have some measurement. You can just count it in > > > ReleaseCodecBufferForPicture, but be sure to only count calls from > DismissOne. > > > > > There is a call to ReleaseCodecBufferForPicture from ReuseOnePictureBuffer > > that > > > we don't want to count. > > > > Happy to count. Do you just want a dvlog everytime this occurs? > > doesn't do anything for null: wow! well then, i'd not worry about it. good > catch. not sure if it's a mistake or there's some subtle reason that i'm > forgetting. probably best not to touch it. > > front buffer issues: luckily, there's no issue. the front buffer isn't > accessible to media codec. i can go into more detail if you like next time i'm > in seattle (probably friday). > > getting back picture buffers: i'm not sure if the last buffer is subject to > this, or how long it might take. i think that VideoFrameCompositor might latch > it. i'm really not sure though. > > 1) Personally, i wouldn't bother. i think that your current approach of 'keep > the front buffer valid' is probably fine -- that's why i suggested counting the > number of unused decoder buffers. it will give us an idea of whether we really > have a problem. if we do, then we can figure out why. but my first guesses > would be VideoFrameCompositor or VideoRendererAlgorithm, to answer your > question. > > 2) Yes -- i was thinking about this too, and i also believe that checking for > used is sufficient. however, i'm not sure that it's necessary that we do > anything. SGTM. I added a temporary count of dismissed-frames-in-use and found the count is consistently 4 frames for both JB and K. Added a TODO in ResetCodecState to describe potential future work.
The CQ bit was checked by chcunningham@chromium.org
The patchset sent to the CQ was uploaded after l-g-t-m from liberato@chromium.org Link to the patchset: https://codereview.chromium.org/1560983002/#ps60001 (title: "Rebase + TODO comment in ResetCodecState")
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1560983002/60001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1560983002/60001
The CQ bit was unchecked by commit-bot@chromium.org
Try jobs failed on following builders: chromium_presubmit on tryserver.chromium.linux (JOB_FAILED, http://build.chromium.org/p/tryserver.chromium.linux/builders/chromium_presub...)
sandersd@chromium.org changed reviewers: + sandersd@chromium.org
RS LGTM
The CQ bit was checked by chcunningham@chromium.org
CQ is trying da patch. Follow status at https://chromium-cq-status.appspot.com/patch-status/1560983002/60001 View timeline at https://chromium-cq-status.appspot.com/patch-timeline/1560983002/60001
Message was sent while issue was closed.
Committed patchset #4 (id:60001)
Message was sent while issue was closed.
Description was changed from ========== Fix MP4 mid-stream resolution changes for MSE on android spitzer. ANDROID CONTEXT: Android'S MediaCodec does not support mid-stream resolution changes prior to Kitkat. See b/7093648 and FEATURE_AdaptivePlayback. The workaround for earlier versions of Android is to call MediaCodec.flush() before starting to decode the new resolution. Flush has some gotchas: 1) All output buffers are immediately revoked at the point of the flush, so you'll want to signal then wait for end-of-stream before flushing to decode the last frames before the config change. 2) Buuut, flush does not work reliably after EOS before JB-MR2. So we need to completely Stop and reset MediaCodec for earlier versions (SDK_INT < 18). See b/8125974, b/8347958. CHROME CONTEXT: In WebRTC, the backward compatable workaround for the above Android bugs is to have the call Reset on the VDA whenever the client becomes aware of a config change. https://crrev.com/47123002 THIS CHANGE: For MSE, we can take advantage of the fact that every config change is preceeded by an EOS signal to drain the decoder [0]. This leaves MediaCodec in the "End of Stream" state, which is recovered from by calling flush. This change adds the flush call after EOS makes its way through the decoder, which conveniently prepares MediaCodec to recieve new buffers of a potentially different resolution. MediaCodec.flush() appears as MediaCodecBridge.reset() thanks to JNI and some confusing naming. To continue working around the broken flush for android < JB-MR2, we still stop and reconfigure MediaCodec when SDK_INT < 18. [0] https://code.google.com/p/chromium/codesearch#chromium/src/media/filters/deco... RUNNING THE TESTS: Tests must be run with additional command line flags to pass. --enable-unified-media-pipeline to enable spitzer --use-gl=egl to override using mesa (used in tests). Mesa is not compatible with SurfaceTextures used in HW accelerated decoding. BUG=555703 ========== to ========== Fix MP4 mid-stream resolution changes for MSE on android spitzer. ANDROID CONTEXT: Android'S MediaCodec does not support mid-stream resolution changes prior to Kitkat. See b/7093648 and FEATURE_AdaptivePlayback. The workaround for earlier versions of Android is to call MediaCodec.flush() before starting to decode the new resolution. Flush has some gotchas: 1) All output buffers are immediately revoked at the point of the flush, so you'll want to signal then wait for end-of-stream before flushing to decode the last frames before the config change. 2) Buuut, flush does not work reliably after EOS before JB-MR2. So we need to completely Stop and reset MediaCodec for earlier versions (SDK_INT < 18). See b/8125974, b/8347958. CHROME CONTEXT: In WebRTC, the backward compatable workaround for the above Android bugs is to have the call Reset on the VDA whenever the client becomes aware of a config change. https://crrev.com/47123002 THIS CHANGE: For MSE, we can take advantage of the fact that every config change is preceeded by an EOS signal to drain the decoder [0]. This leaves MediaCodec in the "End of Stream" state, which is recovered from by calling flush. This change adds the flush call after EOS makes its way through the decoder, which conveniently prepares MediaCodec to recieve new buffers of a potentially different resolution. MediaCodec.flush() appears as MediaCodecBridge.reset() thanks to JNI and some confusing naming. To continue working around the broken flush for android < JB-MR2, we still stop and reconfigure MediaCodec when SDK_INT < 18. [0] https://code.google.com/p/chromium/codesearch#chromium/src/media/filters/deco... RUNNING THE TESTS: Tests must be run with additional command line flags to pass. --enable-unified-media-pipeline to enable spitzer --use-gl=egl to override using mesa (used in tests). Mesa is not compatible with SurfaceTextures used in HW accelerated decoding. BUG=555703 Committed: https://crrev.com/9e5ca6716a7d19b8f605c256251b80a6ae49eaa0 Cr-Commit-Position: refs/heads/master@{#368507} ==========
Message was sent while issue was closed.
Patchset 4 (id:??) landed as https://crrev.com/9e5ca6716a7d19b8f605c256251b80a6ae49eaa0 Cr-Commit-Position: refs/heads/master@{#368507} |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
