การสร้างอุโมงค์มัลติมีเดีย

การสร้างอุโมงค์มัลติมีเดียทำให้ข้อมูลวิดีโอที่บีบอัดส่งผ่านฮาร์ดแวร์ได้ ตัวถอดรหัสวิดีโอไปยังจอแสดงผลโดยตรงโดยไม่ต้องประมวลผลโดยโค้ดของแอปหรือ โค้ดเฟรมเวิร์ก Android รหัสเฉพาะอุปกรณ์ด้านล่างสแต็ก Android กำหนดว่าจะส่งเฟรมวิดีโอใดไปยังจอแสดงผล และควรส่งเฟรมวิดีโอเมื่อใด เปรียบเทียบการประทับเวลาการนำเสนอเฟรมวิดีโอกับรายการใดรายการหนึ่งต่อไปนี้ ประเภทของนาฬิกาภายใน:

  • สำหรับการเล่นวิดีโอแบบออนดีมานด์ใน Android 5 ขึ้นไป AudioTrack นาฬิกาซิงค์กับการประทับเวลาการนำเสนอเสียง ผ่าน ในแอป

  • สำหรับการเล่นการถ่ายทอดสดใน Android 11 ขึ้นไป นาฬิกาอ้างอิงรายการ (PCR) หรือนาฬิกาเวลาของระบบ (STC) ซึ่งขับเคลื่อนโดย ตัวรับสัญญาณ

ฉากหลัง

การเล่นวิดีโอแบบดั้งเดิมใน Android แจ้งเตือน เมื่อถอดรหัสเฟรมวิดีโอที่บีบอัดแล้ว จากนั้นแอป ผลงาน เฟรมวิดีโอที่ถอดรหัสแล้วไปยังจอแสดงผลเพื่อแสดงผลที่นาฬิกาของระบบเดียวกัน ตามเฟรมเสียงที่เกี่ยวข้อง การดึงข้อมูลตามลำดับเวลา AudioTimestamps อินสแตนซ์ต่างๆ เพื่อคำนวณเวลาที่ถูกต้อง

เนื่องจากการเล่นวิดีโอ Tunnel จะข้ามโค้ดของแอปและช่วยลดจำนวน กระบวนการต่างๆ ที่ดำเนินการกับวิดีโอ ทำให้สามารถแสดงผลวิดีโอที่มีประสิทธิภาพมากขึ้น โดยขึ้นอยู่กับการใช้งาน OEM วิธีนี้ยังสามารถแสดง วิดีโอที่แม่นยำยิ่งขึ้น จังหวะและการซิงค์กับนาฬิกาที่เลือก (PRC, STC หรือเสียง) โดยหลีกเลี่ยง ปัญหาเรื่องเวลาที่เกิดจากความคลาดเคลื่อนที่อาจเกิดขึ้นในช่วงเวลาของ Android คำขอแสดงผลวิดีโอ และระยะเวลาของฮาร์ดแวร์ vsync ที่แท้จริง อย่างไรก็ตาม Tunnel ยังลดการรองรับเอฟเฟกต์ GPU อย่างเช่น การเบลอ หรือมุมโค้งมนในหน้าต่างการแสดงภาพซ้อนภาพ (PIP) เนื่องจากบัฟเฟอร์ ข้ามสแต็กกราฟิกของ Android

แผนภาพต่อไปนี้แสดงวิธีที่ Tunnel ทำให้กระบวนการเล่นวิดีโอง่ายขึ้น

การเปรียบเทียบโหมดดั้งเดิมและโหมดอุโมงค์ข้อมูล

รูปที่ 1 การเปรียบเทียบกระบวนการเล่นวิดีโอแบบดั้งเดิมและ Tunnel

สำหรับนักพัฒนาแอป

เนื่องจากนักพัฒนาแอปส่วนใหญ่ผสานรวม กับไลบรารีสำหรับการเล่น ในกรณีส่วนใหญ่ การติดตั้งใช้งานจะเพียงแค่กำหนดค่าใหม่ สำหรับการเล่น Tunnel สำหรับการใช้วิดีโอแบบ Tunnel ในระดับต่ำ ให้ทำตามคำแนะนำต่อไปนี้

สำหรับการเล่นวิดีโอแบบออนดีมานด์ใน Android 5 ขึ้นไป ให้ทำดังนี้

  1. สร้างอินสแตนซ์ SurfaceView

  2. สร้างอินสแตนซ์ audioSessionId

  3. สร้างอินสแตนซ์ AudioTrack และ MediaCodec ด้วย audioSessionId สร้างอินสแตนซ์ในขั้นตอนที่ 2

  4. จัดคิวข้อมูลเสียงไปยัง AudioTrack พร้อมการประทับเวลาการนำเสนอสำหรับ เฟรมแรกในข้อมูลเสียง

สำหรับการเล่นการถ่ายทอดสดใน Android 11 ขึ้นไป ให้ทำดังนี้

  1. สร้างอินสแตนซ์ SurfaceView

  2. รับอินสแตนซ์ avSyncHwId จาก Tuner

  3. สร้างอินสแตนซ์ AudioTrack และ MediaCodec ที่มีอินสแตนซ์ avSyncHwId ที่สร้างขึ้นในขั้นตอนที่ 2

ขั้นตอนการเรียก API จะแสดงในข้อมูลโค้ดต่อไปนี้

aab.setContentType(AudioAttributes.CONTENT_TYPE_MOVIE);

// configure for audio clock sync
aab.setFlag(AudioAttributes.FLAG_HW_AV_SYNC);
// or, for tuner clock sync (Android 11 or higher)
new tunerConfig = TunerConfiguration(0, avSyncId);
aab.setTunerConfiguration(tunerConfig);
if (codecName == null) {
  return FAILURE;
}

// configure for audio clock sync
mf.setInteger(MediaFormat.KEY_AUDIO_SESSION_ID, audioSessionId);
// or, for tuner clock sync (Android 11 or higher)
mf.setInteger(MediaFormat.KEY_HARDWARE_AV_SYNC_ID, avSyncId);

ลักษณะการทำงานของการเล่นวิดีโอแบบออนดีมานด์

เนื่องจากการเล่นวิดีโอออนดีมานด์ผ่าน Tunnel เชื่อมโยงกับ AudioTrack โดยปริยาย แต่ลักษณะการทำงานของการเล่นวิดีโอ Tunnel อาจขึ้นอยู่กับลักษณะการทำงาน ของการเล่นเสียง

  • ในอุปกรณ์ส่วนใหญ่ โดยค่าเริ่มต้น เฟรมวิดีโอจะไม่แสดงผลจนกว่าจะมีการเสียง การเริ่มเล่น แต่แอปอาจต้องแสดงผลเฟรมวิดีโอก่อน การเริ่มเล่นเสียง เป็นต้น เพื่อแสดงวิดีโอปัจจุบันต่อผู้ใช้ ขณะกรอวิดีโอ

    • เพื่อบ่งบอกว่าเฟรมวิดีโอที่อยู่ในคิวแรกควรแสดงผลโดยเร็วที่สุด ถอดรหัสแล้ว ตั้งค่า PARAMETER_KEY_TUNNEL_PEEK เป็น 1 เมื่อเรียงลำดับเฟรมวิดีโอที่บีบอัดในคิวใหม่ (เช่น เมื่อ บีเฟรม ) นั่นหมายความว่าเฟรมวิดีโอแรกที่แสดงควรเป็น iframe

    • หากไม่ต้องการให้แสดงผลเฟรมวิดีโอที่อยู่ในคิวแรกจนถึงเสียง เริ่มเล่น ให้ตั้งค่าพารามิเตอร์นี้เป็น 0

    • หากไม่ได้ตั้งค่าพารามิเตอร์นี้ OEM จะกำหนดลักษณะการทำงานของอุปกรณ์

  • เมื่อไม่ได้ให้ข้อมูลเสียงกับ AudioTrack และบัฟเฟอร์ว่างเปล่า (เสียงตกขอบ) หยุดเล่นวิดีโอจนกว่าจะมีการเขียนข้อมูลเสียงเพิ่มเติม เพราะนาฬิกาเสียงไม่ก้าวหน้าแล้ว

  • ในระหว่างการเล่น ความไม่ต่อเนื่องที่แอปไม่สามารถแก้ไขได้อาจปรากฏขึ้น การประทับเวลาการนำเสนอเสียง ในกรณีนี้ OEM จะแก้ไขค่าลบ ช่องว่างโดยการหยุดเฟรมวิดีโอปัจจุบันไว้ชั่วคราว และช่องว่างเชิงบวกที่เกิดจากการลด เฟรมของวิดีโอหรือการแทรกเฟรมเสียงเงียบ (ขึ้นอยู่กับ OEM ที่กำหนดเอง) ตำแหน่งของเฟรม AudioTimestamp ไม่เพิ่มขึ้นสำหรับ แทรกเฟรมเสียงเงียบแล้ว

สำหรับผู้ผลิตอุปกรณ์

การกำหนดค่า

OEM ควรสร้างตัวถอดรหัสวิดีโอแยกต่างหากเพื่อรองรับการเล่นวิดีโอแบบ Tunnel ตัวถอดรหัสนี้ควรโฆษณาว่าสามารถเล่น Tunnel ใน media_codecs.xml ไฟล์:

<Feature name="tunneled-playback" required="true"/>

เมื่อมีการกำหนดค่าอินสแตนซ์ MediaCodec อุโมงค์ข้อมูลด้วยรหัสเซสชันเสียง การค้นหา AudioFlinger สำหรับรหัส HW_AV_SYNC นี้:

if (entry.getKey().equals(MediaFormat.KEY_AUDIO_SESSION_ID)) {
    int sessionId = 0;
    try {
        sessionId = (Integer)entry.getValue();
    }
    catch (Exception e) {
        throw new IllegalArgumentException("Wrong Session ID Parameter!");
    }
    keys[i] = "audio-hw-sync";
    values[i] = AudioSystem.getAudioHwSyncForSession(sessionId);
}

ระหว่างคำค้นหานี้ AudioFlinger เรียกข้อมูลรหัส HW_AV_SYNC จากอุปกรณ์เสียงหลักและเชื่อมโยงกับเสียงภายใน รหัสเซสชัน:

audio_hw_device_t *dev = mPrimaryHardwareDev->hwDevice();
char *reply = dev->get_parameters(dev, AUDIO_PARAMETER_HW_AV_SYNC);
AudioParameter param = AudioParameter(String8(reply));
int hwAVSyncId;
param.getInt(String8(AUDIO_PARAMETER_HW_AV_SYNC), hwAVSyncId);

หากมีการสร้างอินสแตนซ์ AudioTrack แล้ว รหัส HW_AV_SYNC จะเป็น ไปยังสตรีมเอาต์พุตที่มีรหัสเซสชันเสียงเดียวกัน หากยังไม่มี สร้างแล้ว ระบบจะส่งรหัส HW_AV_SYNC ไปยังสตรีมเอาต์พุตระหว่าง AudioTrack ผลงาน ซึ่งดำเนินการโดยการเล่น ชุดข้อความ

mOutput->stream->common.set_parameters(&mOutput->stream->common, AUDIO_PARAMETER_STREAM_HW_AV_SYNC, hwAVSyncId);

รหัส HW_AV_SYNC จะสอดคล้องกับสตรีมเอาต์พุตเสียงหรือ Tuner จะส่งไปยังคอมโพเนนต์ OMX หรือตัวแปลงรหัส2 รหัส OEM สามารถเชื่อมโยงตัวแปลงรหัสกับสตรีมเอาต์พุตเสียงที่เกี่ยวข้อง หรือ สตรีมตัวรับสัญญาณ

ระหว่างการกำหนดค่าคอมโพเนนต์ คอมโพเนนต์ OMX หรือตัวแปลงรหัส 2 ควรแสดงผล แฮนเดิลไซด์แบนด์ที่ใช้ในการเชื่อมโยงตัวแปลงรหัสกับฮาร์ดแวร์คอมโพสเซอร์ได้ (HWC) เมื่อแอปเชื่อมโยงแพลตฟอร์มกับ MediaCodec ไซด์แบนด์นี้ แฮนเดิลจะส่งไปยัง HWC ผ่าน SurfaceFlinger ซึ่งจะกำหนดค่า เป็นเลเยอร์ แถบด้านข้าง

err = native_window_set_sideband_stream(nativeWindow.get(), sidebandHandle);
if (err != OK) {
  ALOGE("native_window_set_sideband_stream(%p) failed! (err %d).", sidebandHandle, err);
  return err;
}

HWC มีหน้าที่รับบัฟเฟอร์อิมเมจใหม่จากเอาต์พุตของตัวแปลงรหัสที่ เวลาที่เหมาะสม โดยซิงค์กับสตรีมเอาต์พุตเสียงที่เกี่ยวข้อง หรือ นาฬิกาอ้างอิงโปรแกรมจูนเนอร์ ซึ่งประกอบบัฟเฟอร์ด้วย เนื้อหาของเลเยอร์อื่นๆ และแสดงรูปภาพที่ได้ สิ่งนี้เกิดขึ้น โดยไม่ขึ้นอยู่กับรอบการเตรียมความพร้อมและกำหนดการตามปกติ เตรียมพร้อมและกำหนดการโทร จะเกิดขึ้นเฉพาะเมื่อเลเยอร์อื่นๆ เปลี่ยนแปลง หรือเมื่อคุณสมบัติของเลเยอร์ไซด์แบนด์ (เช่น ตำแหน่งหรือขนาด) เปลี่ยนแปลง

OMX

คอมโพเนนต์ตัวถอดรหัส Tunnel ควรรองรับรายการต่อไปนี้

  • การตั้งค่าแบบขยาย OMX.google.android.index.configureVideoTunnelMode ซึ่งใช้โครงสร้าง ConfigureVideoTunnelModeParams ในการส่ง ในรหัส HW_AV_SYNC ที่เชื่อมโยงกับอุปกรณ์เอาต์พุตเสียง

  • การกำหนดค่าพารามิเตอร์ OMX_IndexConfigAndroidTunnelPeek ที่บอก เพื่อแสดงผลหรือไม่แสดงเฟรมวิดีโอที่ถอดรหัสครั้งแรก โดยไม่คำนึงว่า การเล่นเสียงได้เริ่มต้นแล้วหรือไม่

  • กำลังส่งเหตุการณ์ OMX_EventOnFirstTunnelFrameReady เมื่ออุโมงค์ข้อมูลแรก เฟรมวิดีโอและพร้อมที่จะแสดงผลแล้ว

การใช้งาน AOSP กำหนดค่าโหมดอุโมงค์ข้อมูลใน ACodec ผ่าน OMXNodeInstance ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

OMX_INDEXTYPE index;
OMX_STRING name = const_cast<OMX_STRING>(
        "OMX.google.android.index.configureVideoTunnelMode");

OMX_ERRORTYPE err = OMX_GetExtensionIndex(mHandle, name, &index);

ConfigureVideoTunnelModeParams tunnelParams;
InitOMXParams(&tunnelParams);
tunnelParams.nPortIndex = portIndex;
tunnelParams.bTunneled = tunneled;
tunnelParams.nAudioHwSync = audioHwSync;
err = OMX_SetParameter(mHandle, index, &tunnelParams);
err = OMX_GetParameter(mHandle, index, &tunnelParams);
sidebandHandle = (native_handle_t*)tunnelParams.pSidebandWindow;

หากคอมโพเนนต์รองรับการกำหนดค่านี้ คอมโพเนนต์ควรจัดสรรไซด์แบนด์ จัดการกับตัวแปลงรหัสนี้และส่งกลับผ่านสมาชิก pSidebandWindow HWC สามารถระบุตัวแปลงรหัสที่เกี่ยวข้องได้ หากคอมโพเนนต์ไม่ รองรับการกำหนดค่านี้ ซึ่งควรตั้งค่า bTunneled เป็น OMX_FALSE

ตัวแปลงรหัส 2

ใน Android 11 ขึ้นไป Codec2 รองรับการเล่น Tunnel ตัวถอดรหัส คอมโพเนนต์ควรรองรับรายการต่อไปนี้

  • กำลังกำหนดค่า C2PortTunneledModeTuning ซึ่งกำหนดค่าโหมดอุโมงค์ข้อมูลและ ใน HW_AV_SYNC ที่ดึงมาจากอุปกรณ์เอาต์พุตเสียงหรือ การกำหนดค่าตัวรับสัญญาณ

  • ค้นหา C2_PARAMKEY_OUTPUT_TUNNEL_HANDLE เพื่อจัดสรรและเรียกข้อมูล แฮนเดิลของ HWC

  • การจัดการ C2_PARAMKEY_TUNNEL_HOLD_RENDER เมื่อเชื่อมต่อกับ C2Work ซึ่ง สั่งให้ตัวแปลงรหัสถอดรหัสและส่งสัญญาณว่าทำงานเสร็จแล้ว แต่ไม่แสดงผล บัฟเฟอร์เอาต์พุตจนถึง 1) ตัวแปลงรหัสจะได้รับคำแนะนำให้แสดงผลในภายหลัง หรือ 2) การเล่นเสียงเริ่มเล่น

  • กำลังจัดการ C2_PARAMKEY_TUNNEL_START_RENDER ซึ่งสั่งตัวแปลงรหัสให้ แสดงผลเฟรมที่มีเครื่องหมาย C2_PARAMKEY_TUNNEL_HOLD_RENDER แม้ว่าการเล่นเสียงยังไม่เริ่มต้นก็ตาม

  • ปล่อย debug.stagefright.ccodec_delayed_params ไว้โดยไม่มีการกำหนดค่า (แนะนำ) ถ้า ที่คุณกำหนดค่าเอง โดยตั้งค่าเป็น false

การใช้งาน AOSP กำหนดค่าโหมดอุโมงค์ข้อมูลใน CCodec ถึง C2PortTunnelModeTuning ดังที่แสดงในข้อมูลโค้ดต่อไปนี้

if (msg->findInt32("audio-hw-sync", &tunneledPlayback->m.syncId[0])) {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::AUDIO_HW_SYNC;
} else if (msg->findInt32("hw-av-sync-id", &tunneledPlayback->m.syncId[0])) {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::HW_AV_SYNC;
} else {
    tunneledPlayback->m.syncType =
            C2PortTunneledModeTuning::Struct::sync_type_t::REALTIME;
    tunneledPlayback->setFlexCount(0);
}
c2_status_t c2err = comp->config({ tunneledPlayback.get() }, C2_MAY_BLOCK,
        failures);
std::vector<std::unique_ptr<C2Param>> params;
c2err = comp->query({}, {C2PortTunnelHandleTuning::output::PARAM_TYPE},
        C2_DONT_BLOCK, &params);
if (c2err == C2_OK && params.size() == 1u) {
    C2PortTunnelHandleTuning::output *videoTunnelSideband =
            C2PortTunnelHandleTuning::output::From(params[0].get());
    return OK;
}

หากคอมโพเนนต์รองรับการกำหนดค่านี้ คอมโพเนนต์ควรจัดสรรไซด์แบนด์ จัดการตัวแปลงรหัสนี้และส่งกลับผ่าน C2PortTunnelHandlingTuning HWC สามารถระบุตัวแปลงรหัสที่เกี่ยวข้องได้

HAL เสียง

สำหรับการเล่นวิดีโอแบบออนดีมานด์ HAL ของเสียงจะได้รับการนำเสนอที่เป็นเสียง การประทับเวลาในบรรทัดที่มีข้อมูลเสียงในรูปแบบ Big-endian ภายในส่วนหัวที่พบ ที่ตอนต้นของข้อมูลเสียงแต่ละบล็อกที่แอปเขียน ดังนี้

struct TunnelModeSyncHeader {
  // The 32-bit data to identify the sync header (0x55550002)
  int32 syncWord;
  // The size of the audio data following the sync header before the next sync
  // header might be found.
  int32 sizeInBytes;
  // The presentation timestamp of the first audio sample following the sync
  // header.
  int64 presentationTimestamp;
  // The number of bytes to skip after the beginning of the sync header to find the
  // first audio sample (20 bytes for compressed audio, or larger for PCM, aligned
  // to the channel count and sample size).
  int32 offset;
}

สำหรับ HWC เพื่อแสดงผลเฟรมวิดีโอ กับเฟรมเสียงที่เกี่ยวข้อง HAL เสียงควรแยกวิเคราะห์ส่วนหัวการซิงค์และใช้การประทับเวลาการนำเสนอเพื่อ ซิงค์นาฬิกาการเล่นอีกครั้งกับการแสดงภาพเสียง หากต้องการซิงค์ข้อมูลใหม่เมื่อ กำลังเล่นเสียงที่บีบอัด เสียง HAL อาจต้องแยกวิเคราะห์ข้อมูลเมตา ภายในข้อมูลเสียงที่บีบอัดเพื่อระบุระยะเวลาการเล่น

หยุดการสนับสนุนชั่วคราว

Android 5 หรือต่ำกว่าจะไม่รวมการสนับสนุนการหยุดชั่วคราว คุณหยุด Tunnel ชั่วคราวได้ ก็เล่นด้วยการติดดาว A/V เท่านั้น แต่หากบัฟเฟอร์ภายในของวิดีโอ มีขนาดใหญ่ (เช่น มีข้อมูล 1 วินาทีในคอมโพเนนต์ OMX) ระบบจะหยุดชั่วคราว ดูไม่ตอบสนอง

ใน Android 5.1 ขึ้นไป AudioFlinger รองรับการหยุดชั่วคราวและกลับมาใช้งานต่อโดยตรง (เปิด) เอาต์พุตเสียง หาก HAL ใช้การหยุดชั่วคราวและกลับมาทำต่อ ให้ติดตามการหยุดชั่วคราว และเรซูเม่จะส่งต่อไปยัง HAL

การหยุดชั่วคราว ล้าง และลำดับการโทรต่อจะเป็นไปตามการเรียกใช้การเรียก HAL ในเธรดการเล่น (เหมือนกับการลดภาระ)

คำแนะนำการติดตั้งใช้งาน

HAL เสียง

สําหรับ Android 11 คุณสามารถใช้รหัสการซิงค์ HW จาก PCR หรือ STC สําหรับการซิงค์ A/V ได้ ดังนั้น รองรับสตรีมวิดีโอเท่านั้น

สำหรับ Android 10 หรือต่ำกว่า อุปกรณ์ที่รองรับการเล่นวิดีโอ Tunnel ควรมี โปรไฟล์สตรีมเอาต์พุตเสียงอย่างน้อย 1 โปรไฟล์ที่มี FLAG_HW_AV_SYNC และ AUDIO_OUTPUT_FLAG_DIRECT Flag ในไฟล์ audio_policy.conf แฟล็กเหล่านี้ ใช้ตั้งค่านาฬิการะบบจากนาฬิกาเสียง

OMX

ผู้ผลิตอุปกรณ์ควรมีคอมโพเนนต์ OMX แยกต่างหากสำหรับวิดีโอ Tunnel (ผู้ผลิตสามารถมีคอมโพเนนต์ OMX เพิ่มเติมสำหรับประเภทของ การเล่นเสียงและวิดีโอ เช่น การเล่นที่ปลอดภัย) คอมโพเนนต์ Tunnel ควร:

  • ระบุบัฟเฟอร์ 0 (nBufferCountMin, nBufferCountActual) ในเอาต์พุต พอร์ต

  • ใช้ส่วนขยาย OMX.google.android.index.prepareForAdaptivePlayback setParameter

  • ระบุความสามารถในไฟล์ media_codecs.xml และประกาศ ฟีเจอร์การเล่น Tunnel รวมถึงควรชี้แจงข้อจำกัดใดๆ เกี่ยวกับเฟรมด้วย ขนาด การจัดข้อความ หรืออัตราบิต ดูตัวอย่างด้านล่างนี้

    <MediaCodec name="OMX.OEM_NAME.VIDEO.DECODER.AVC.tunneled"
    type="video/avc" >
        <Feature name="adaptive-playback" />
        <Feature name="tunneled-playback" required=”true” />
        <Limit name="size" min="32x32" max="3840x2160" />
        <Limit name="alignment" value="2x2" />
        <Limit name="bitrate" range="1-20000000" />
            ...
    </MediaCodec>
    

หากใช้คอมโพเนนต์ OMX เดียวกันเพื่อรองรับการถอดรหัสแบบ Tunnel และที่ไม่ใช่การเชื่อมต่อ ควรปล่อยฟีเจอร์การเล่น Tunnel เป็น "ไม่จำเป็น" ทั้งอุโมงค์และ แล้วตัวถอดรหัสแบบ nontunneled จะมีขีดจำกัดด้านความสามารถแบบเดียวกัน ตัวอย่างเช่น แสดงอยู่ด้านล่าง

<MediaCodec name="OMX._OEM\_NAME_.VIDEO.DECODER.AVC" type="video/avc" >
    <Feature name="adaptive-playback" />
    <Feature name="tunneled-playback" />
    <Limit name="size" min="32x32" max="3840x2160" />
    <Limit name="alignment" value="2x2" />
    <Limit name="bitrate" range="1-20000000" />
        ...
</MediaCodec>

ฮาร์ดแวร์คอมโพสเซอร์ (HWC)

เมื่อมีเลเยอร์อุโมงค์ (เลเยอร์ที่มี HWC_SIDEBAND compositionType) เปิดอยู่ sidebandStream ของเลเยอร์จะเป็นแฮนเดิลแถบด้านข้างที่จัดสรรโดย คอมโพเนนต์วิดีโอ OMX

HWC จะซิงค์เฟรมวิดีโอที่ถอดรหัสแล้ว (จากคอมโพเนนต์ OMX แบบอุโมงค์ข้อมูล) เพื่อ แทร็กเสียงที่เกี่ยวข้อง (ที่มีรหัส audio-hw-sync) เมื่อเฟรมวิดีโอใหม่ HWC จะผนวกรวมกับเนื้อหาปัจจุบันของเลเยอร์ทั้งหมด ที่ได้รับในระหว่างการเตรียมหรือตั้งการโทรครั้งล่าสุด และแสดงภาพผลลัพธ์ การเตรียมพร้อมหรือกำหนดการเรียกจะเกิดขึ้นเฉพาะเมื่อเลเยอร์อื่นๆ เปลี่ยนแปลง หรือเมื่อ คุณสมบัติการเปลี่ยนแปลงของเลเยอร์ไซด์แบนด์ (เช่น ตำแหน่งหรือขนาด)

รูปต่อไปนี้แสดง HWC ที่ทำงานด้วยฮาร์ดแวร์ (หรือเคอร์เนลหรือ ไดรเวอร์) ซิงโครไนซ์ เพื่อรวมเฟรมวิดีโอ (7b) กับองค์ประกอบล่าสุด (7a) เพื่อแสดงในเวลาที่ถูกต้องตามเสียง (7c)

HWC รวมเฟรมวิดีโอตามเสียง

รูปที่ 2 เครื่องมือซิงค์ฮาร์ดแวร์ HWC (หรือเคอร์เนลหรือไดรเวอร์)