mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 18:20:34 +00:00
devices/video/decoder: fix drain+clear queue issue
Drain is cancelled by clearing either of the stream's queues. To work around a limitation in the VDA api, the output queue is cleared synchronously without going through VDA. Because of this, a drain cancellation response from VDA might fail to find the drain's AsyncCmdTag. BUG=b:170184723 TEST=android.mediastress.cts.MediaRecorderStressTest#testStressRecordVideoAndPlayback Change-Id: I1d54c9c4acfa7578addb947e1196313010a8431d Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/2535964 Reviewed-by: Chih-Yu Huang <akahuang@chromium.org> Reviewed-by: Alexandre Courbot <acourbot@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> Commit-Queue: David Stevens <stevensd@chromium.org>
This commit is contained in:
parent
f12c5ea7b4
commit
9be2c6d3c2
1 changed files with 24 additions and 12 deletions
|
@ -6,7 +6,7 @@
|
|||
|
||||
use std::collections::VecDeque;
|
||||
|
||||
use base::{error, Event, WaitContext};
|
||||
use base::{error, info, Event, WaitContext};
|
||||
use vm_memory::GuestMemory;
|
||||
|
||||
use crate::virtio::queue::{DescriptorChain, Queue};
|
||||
|
@ -14,7 +14,7 @@ use crate::virtio::resource_bridge::ResourceRequestSocket;
|
|||
use crate::virtio::video::async_cmd_desc_map::AsyncCmdDescMap;
|
||||
use crate::virtio::video::command::{QueueType, VideoCmd};
|
||||
use crate::virtio::video::device::{
|
||||
AsyncCmdResponse, Device, Token, VideoCmdResponseType, VideoEvtResponseType,
|
||||
AsyncCmdResponse, AsyncCmdTag, Device, Token, VideoCmdResponseType, VideoEvtResponseType,
|
||||
};
|
||||
use crate::virtio::video::event::{self, EvtType, VideoEvt};
|
||||
use crate::virtio::video::response::{self, Response};
|
||||
|
@ -187,17 +187,29 @@ impl Worker {
|
|||
tag,
|
||||
response: cmd_result,
|
||||
} = async_response;
|
||||
let desc = desc_map
|
||||
.remove(&tag)
|
||||
.ok_or_else(|| Error::UnexpectedResponse(tag))?;
|
||||
let cmd_response = match cmd_result {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("returning async error response: {}", &e);
|
||||
e.into()
|
||||
match desc_map.remove(&tag) {
|
||||
Some(desc) => {
|
||||
let cmd_response = match cmd_result {
|
||||
Ok(r) => r,
|
||||
Err(e) => {
|
||||
error!("returning async error response: {}", &e);
|
||||
e.into()
|
||||
}
|
||||
};
|
||||
responses.push_back((desc, cmd_response))
|
||||
}
|
||||
};
|
||||
responses.push_back((desc, cmd_response));
|
||||
None => match tag {
|
||||
// TODO(b/153406792): Drain is cancelled by clearing either of the
|
||||
// stream's queues. To work around a limitation in the VDA api, the
|
||||
// output queue is cleared synchronously without going through VDA.
|
||||
// Because of this, the cancellation response from VDA for the
|
||||
// input queue might fail to find the drain's AsyncCmdTag.
|
||||
AsyncCmdTag::Drain { stream_id: _ } => {
|
||||
info!("ignoring unknown drain response");
|
||||
}
|
||||
_ => return Err(Error::UnexpectedResponse(tag)),
|
||||
},
|
||||
}
|
||||
}
|
||||
VideoEvtResponseType::Event(evt) => {
|
||||
self.write_event(event_queue, evt)?;
|
||||
|
|
Loading…
Reference in a new issue