호환 가능한 미디어 트랜스코딩

Android 12에 도입된 호환 가능한 미디어 트랜스코딩은 기기에서 앱과의 호환성을 유지하면서 HEVC와 같은 비디오 캡처를 위해 보다 현대적이고 스토리지 효율적인 미디어 형식을 사용할 수 있도록 하는 기능입니다. 이 기능을 통해 장치 제조업체는 기본적으로 AVC 대신 HEVC를 사용하여 저장 및 대역폭 요구 사항을 줄이면서 비디오 품질을 개선할 수 있습니다. 호환 가능한 미디어 트랜스코딩이 활성화된 기기의 경우 Android는 HEVC 또는 HDR과 같은 형식으로 녹화된 비디오(최대 1분 길이)를 지원하지 않는 앱에서 비디오를 열 때 자동으로 변환할 수 있습니다. 이렇게 하면 비디오가 장치에서 최신 형식으로 캡처된 경우에도 앱이 작동할 수 있습니다.

호환 가능한 미디어 트랜스코딩 기능은 기본적으로 꺼져 있습니다. 미디어 트랜스코딩을 요청하려면 앱에서 미디어 기능을 선언해야 합니다. 미디어 기능 선언에 대한 자세한 내용은 Android 개발자 사이트에서 호환 가능한 미디어 트랜스코딩 을 참조하세요.

작동 원리

호환 가능한 미디어 트랜스코딩 기능은 두 가지 주요 부분으로 구성됩니다.

  • 미디어 프레임워크의 트랜스코딩 서비스: 이 서비스는 짧은 대기 시간과 고품질 변환을 위해 하드웨어를 사용하여 파일을 한 형식에서 다른 형식으로 변환합니다. 여기에는 트랜스코딩 API, 트랜스코딩 서비스, 사용자 지정 필터용 OEM 플러그인 및 하드웨어가 포함됩니다. 자세한 내용은 아키텍처 개요 를 참조하십시오.
  • 미디어 공급자의 호환 가능한 미디어 트랜스코딩 기능: 미디어 공급자 에 있는 이 구성 요소는 미디어 파일에 액세스하는 앱을 가로채고 앱의 선언된 기능을 기반으로 원본 파일 또는 트랜스코딩된 파일을 제공합니다. 앱이 미디어 파일 형식을 지원하는 경우 특별한 처리가 필요하지 않습니다. 앱이 형식을 지원하지 않는 경우 프레임워크는 앱이 파일에 액세스할 때 파일을 AVC와 같은 이전 형식으로 변환합니다.

그림 1은 미디어 트랜스코딩 프로세스의 개요를 보여줍니다.

호환 가능한 미디어 트랜스코딩 프로세스

그림 1. 호환 가능한 미디어 트랜스코딩 개요.

지원되는 형식

호환 가능한 미디어 트랜스코딩 기능은 다음 형식 변환을 지원합니다.

  • HEVC(8-bit) to AVC: 코덱 변환은 하나의 미디어 코덱 디코더와 하나의 미디어 코드 인코더를 연결하여 수행됩니다.
  • HDR10+(10비트)에서 AVC(SDR)로: HDR에서 SDR로의 변환은 미디어 코덱 인스턴스와 디코더 인스턴스에 대한 공급업체 플러그인 후크를 사용하여 수행됩니다. 자세한 내용은 HDR-SDR 인코딩을 참조하십시오.

지원되는 콘텐츠 소스

호환 가능한 미디어 트랜스코딩 기능은 기본 외부 볼륨의 DCIM/Camera/ 폴더에 저장된 기본 OEM 카메라 앱에서 생성된 온디바이스 미디어를 지원합니다. 이 기능은 보조 저장소의 미디어를 지원하지 않습니다. 이메일 또는 SD 카드를 통해 기기로 전달된 콘텐츠는 지원되지 않습니다.

앱은 다양한 파일 경로를 기반으로 파일에 액세스합니다. 다음은 트랜스코딩이 활성화되거나 우회되는 파일 경로에 대한 설명입니다.

  • 트랜스코딩 활성화됨:

    • MediaStore API를 통한 앱 액세스
    • Java 및 기본 코드를 포함한 직접 파일 경로 API를 통한 앱 액세스
    • SAF(Storage Access Framework)를 통한 앱 액세스
    • OS 공유 시트 Intents를 통한 앱 액세스. (MediaStore URI만 해당)
    • 전화에서 PC로 MTP/PTP 파일 전송
  • 트랜스코딩 우회:

    • SD 카드를 꺼내 장치에서 파일 전송
    • Nearby Share 또는 Bluetooth 전송과 같은 옵션을 사용하여 장치에서 장치로 파일을 전송합니다.

트랜스코딩을 위한 사용자 지정 파일 경로 추가

장치 제조업체는 선택적으로 DCIM/ 디렉토리 아래에 미디어 트랜스코딩을 위한 파일 경로를 추가할 수 있습니다. DCIM/ 디렉토리 외부의 모든 경로는 거부됩니다. 이러한 파일 경로를 추가하는 것은 이동통신사 요구 사항이나 현지 규정을 충족하는 데 필요할 수 있습니다.

파일 경로를 추가하려면 코드 변환 경로 RRO(런타임 리소스 오버레이) , config_supported_transcoding_relative_paths 를 사용하세요. 다음은 파일 경로를 추가하는 방법의 예입니다.

<string-array name="config_supported_transcoding_relative_paths" translatable="false">
    <item>DCIM/JCF/</item>
</string-array>

구성된 파일 경로를 확인하려면 다음을 사용하십시오.

adb shell dumpsys activity provider com.google.android.providers.media.module/com.android.providers.media.MediaProvider | head -n 20

아키텍처 개요

이 섹션에서는 미디어 트랜스코딩 기능의 아키텍처에 대해 설명합니다.

미디어 트랜스코딩 아키텍처

그림 2. 미디어 트랜스코딩 아키텍처.

미디어 트랜스코딩 아키텍처는 다음 구성 요소로 구성됩니다.

  • MediaTranscodingManager 시스템 API: 클라이언트가 MediaTranscoding 서비스와 통신할 수 있도록 하는 인터페이스입니다. MediaProvider 모듈은 이 API를 사용합니다.
  • MediaTranscodingService: 클라이언트 연결을 관리하고, 트랜스코딩 요청을 예약하고, TranscodingSessions 에 대한 부기를 관리하는 기본 서비스입니다.
  • MediaTranscoder: 트랜스코딩을 수행하는 기본 라이브러리입니다. 이 라이브러리는 모듈 과 호환되도록 미디어 프레임워크 NDK 위에 구축되었습니다.

호환 가능한 미디어 트랜스코딩 기능은 서비스와 미디어 트랜스코더 모두에서 트랜스코딩 메트릭을 기록합니다. 클라이언트 측 및 서비스 측 코드는 적시에 버그 수정 및 업데이트를 허용하기 위해 MediaProvider 모듈에 있습니다.

파일 액세스

호환 가능한 미디어 트랜스코딩은 범위 지정 저장소에 사용되는 FUSE(Filesystem in Userspace) 파일 시스템 위에 구축됩니다. FUSE를 사용하면 MediaProvider 모듈이 사용자 공간에서 파일 작업을 검사하고 액세스를 허용, 거부 또는 수정하는 정책에 따라 파일에 대한 액세스를 차단할 수 있습니다.

앱이 파일에 액세스하려고 하면 FUSE 데몬이 앱에서 파일 읽기 액세스를 가로챕니다. 앱이 최신 형식(예: HEVC)을 지원하는 경우 원본 파일이 반환됩니다. 앱이 형식을 지원하지 않는 경우 파일은 이전 형식(예: AVC)으로 트랜스코딩되거나 트랜스코딩된 버전을 사용할 수 있는 경우 캐시에서 반환됩니다.

트랜스코딩된 파일 요청

호환 가능한 미디어 트랜스코딩 기능은 기본적으로 비활성화되어 있습니다. 즉, 기기가 HEVC를 지원하는 경우 앱에서 매니페스트 파일이나 강제 트랜스코딩 목록 에 지정하지 않는 한 Android는 파일을 트랜스코딩하지 않습니다.

앱은 다음 옵션을 사용하여 트랜스코딩된 자산을 요청할 수 있습니다.

  • 매니페스트 파일에서 지원되지 않는 형식을 선언합니다. 자세한 내용 은 리소스의 기능 선언 및 코드의 기능 선언을 참조하세요.
  • MediaProvider 모듈에 포함된 강제 코드 변환 목록 에 앱을 추가합니다. 이렇게 하면 매니페스트 파일을 업데이트하지 않은 앱에 대한 트랜스코딩이 활성화됩니다. 앱이 지원되지 않는 형식으로 매니페스트 파일을 업데이트하면 강제 코드 변환 목록에서 제거해야 합니다. 장치 제조업체는 패치를 제출 하거나 버그를 보고 하여 강제 코드 변환 목록에서 추가하거나 제거할 앱을 지정할 수 있습니다. Android 팀은 주기적으로 목록을 검토하고 목록에서 앱을 제거할 수 있습니다.
  • 런타임 시 앱 호환성 프레임워크로 지원되는 형식을 비활성화합니다(사용자는 설정에서 각 앱에 대해 이 기능을 비활성화할 수도 있습니다).
  • openTypedAssetFileDescriptor API로 지원되지 않는 형식을 명시적으로 지정하면서 MediaStore 로 파일을 엽니다.

USB 전송(장치에서 PC로)의 경우 트랜스코딩은 기본적으로 비활성화되어 있지만 사용자는 그림 3과 같이 USB 기본 설정 화면에서 비디오를 AVC로 변환 토글을 사용하여 트랜스코딩을 활성화하도록 선택할 수 있습니다.

미디어 트랜스코딩을 활성화하도록 전환

그림 3. USB 기본 설정 화면에서 미디어 트랜스코딩을 활성화하도록 토글합니다.

트랜스코딩된 파일 요청에 대한 제한 사항

트랜스코딩 요청이 장기간 시스템 리소스를 잠그는 것을 방지하기 위해 트랜스코딩 세션을 요청하는 앱은 다음으로 제한됩니다.

  • 10연속 세션
  • 총 러닝타임 3분

앱이 이러한 제한 사항을 모두 초과하면 프레임워크는 원본 파일 설명자를 반환합니다.

장치 요구 사항

호환 가능한 미디어 트랜스코딩 기능을 지원하려면 장치가 다음 요구 사항을 충족해야 합니다.

  • 장치에는 기본 카메라 앱에서 기본적으로 활성화된 HEVC 인코딩이 있습니다.
  • (HDR-SDR 트랜스코딩을 지원하는 장치) HDR 비디오 캡처를 지원하는 장치

미디어 트랜스코딩을 위한 장치 성능을 보장하려면 비디오 하드웨어 및 스토리지 읽기/쓰기 액세스 성능을 최적화해야 합니다. 미디어 코덱이 1 과 같은 우선 순위로 구성된 경우 코덱은 가능한 가장 높은 처리량으로 작동해야 합니다. 트랜스코딩 성능은 최소 200fps를 달성하는 것이 좋습니다. 하드웨어 성능을 테스트하려면 frameworks/av/media/libmediatranscoding/transcoder/benchmark benchmark 에서 미디어 트랜스코더 벤치마크를 실행하세요.

확인

호환되는 미디어 트랜스코딩 기능을 확인하려면 다음 CTS 테스트를 실행하세요.

  • android.media.mediatranscoding.cts
  • android.mediaprovidertranscode.cts

전 세계적으로 미디어 트랜스코딩 활성화

트랜스코딩을 사용하여 미디어 트랜스코딩 프레임워크 또는 앱 동작을 테스트하려면 호환되는 미디어 트랜스코딩 기능을 전역적으로 활성화하거나 비활성화할 수 있습니다. 설정 > 시스템 > 개발자 > 미디어 트랜스코딩 개발자 옵션 페이지에서 트랜스코딩 기본값 무시 토글을 켜기 로 설정한 다음 트랜스코딩 활성화 토글을 켜기 또는 끄기 로 설정합니다. 이 설정을 사용하면 개발 중인 앱이 아닌 다른 앱에 대해 백그라운드에서 미디어 트랜스코딩이 발생할 수 있습니다.

트랜스코딩 상태 확인

테스트하는 동안 다음 ADB 셸 명령을 사용하여 현재 및 과거 트랜스코딩 세션을 포함하여 트랜스코딩 상태를 확인할 수 있습니다.

adb shell dumpsys media.transcoding

비디오 길이 제한 확장

테스트 목적으로 다음 명령을 사용하여 트랜스코딩에 대한 1분 비디오 길이 제한을 확장할 수 있습니다. 이 명령을 실행한 후 재부팅이 필요할 수 있습니다.

adb shell device_config put storage_native_boot transcode_max_duration_ms <LARGE_NUMBER_IN_MS>

AOSP 소스 및 참조

다음은 호환 가능한 미디어 트랜스코딩과 관련된 AOSP 소스 코드입니다.

HDR-SDR 인코딩

HDR-SDR 인코딩을 지원하기 위해 기기 제조업체는 /platform/frameworks/av/media/codec2/hidl/plugin/ 에 있는 AOSP 샘플 코덱 2.0 필터 플러그인을 사용할 수 있습니다. 이 섹션에서는 필터 플러그인의 작동 방식, 플러그인 구현 방법 및 플러그인 테스트 방법에 대해 설명합니다.

장치에 HDR-SDR 인코딩을 지원하는 플러그인이 포함되어 있지 않은 경우 HDR 비디오에 액세스하는 앱은 매니페스트에 선언된 앱의 미디어 기능에 관계없이 원본 파일 설명자를 가져옵니다.

작동 원리

이 섹션에서는 코덱 2.0 필터 플러그인의 일반적인 동작에 대해 설명합니다.

배경

Android는 android::hardware::media::c2 에서 Codec 2.0 인터페이스와 android.hardware.media.c2 HAL 인터페이스 사이에 적응 계층 구현을 제공합니다. 필터 플러그인의 경우 AOSP에는 필터 플러그인과 함께 디코더를 래핑하는 래퍼 메커니즘이 포함되어 있습니다. MediaCodec 은 이러한 래핑된 구성 요소를 필터링 기능이 있는 디코더로 인식합니다.

개요

FilterWrapper 클래스는 공급업체 코덱을 가져오고 래핑된 코덱을 media.c2 적응 계층으로 다시 반환합니다. FilterWrapper 클래스는 FilterWrapper::Plugin API를 통해 libc2filterplugin.so 를 로드하고 플러그인에서 사용 가능한 필터를 기록합니다. 생성 시 FilterWrapper 는 사용 가능한 모든 필터를 인스턴스화합니다. 버퍼를 변경하는 필터만 시작할 때 시작됩니다.

필터 플러그인 아키텍처

그림 1. 필터 플러그인 아키텍처.

필터 플러그인 인터페이스

FilterPlugin.h 인터페이스는 필터를 노출하기 위해 다음 API를 정의합니다.

  • std::shared_ptr<C2ComponentStore>getComponentStore()

    필터를 포함하는 C2ComponentStore 개체를 반환합니다. 이것은 공급업체의 코덱 2.0 구현이 노출하는 것과 별개입니다. 일반적으로 이 저장소에는 FilterWrapper 클래스에서 사용하는 필터만 포함됩니다.

  • bool describe(C2String name, Descriptor *desc)

    C2ComponentStore 에서 사용할 수 있는 것 외에 필터를 설명합니다. 다음 설명이 정의됩니다.

    • controlParam : 필터의 동작을 제어하는 ​​매개변수. 예를 들어 HDR to SDR 톤 매퍼의 경우 제어 매개변수는 대상 전달 함수입니다.
    • affectedParams : 필터링 작업의 영향을 받는 매개변수입니다. 예를 들어 HDR to SDR 톤 매퍼의 경우 영향을 받는 매개변수는 색상 측면입니다.
  • bool isFilteringEnabled(const std::shared_ptr<C2ComponentInterface> &intf)

    필터 구성 요소가 버퍼를 변경하면 true 를 반환합니다. 예를 들어 톤 매핑 필터는 대상 전달 함수가 SDR이고 입력 전달 함수가 HDR(HLG 또는 PQ)인 경우 true 를 반환합니다.

FilterWrapper 세부 정보

이 섹션에서는 FilterWrapper 클래스에 대한 세부 정보를 설명합니다.

창조

래핑된 구성 요소는 생성 시 기본 디코더와 정의된 모든 필터를 인스턴스화합니다.

쿼리 및 구성

래핑된 구성 요소는 필터 설명에 따라 들어오는 매개변수를 쿼리 또는 구성 요청에서 분리합니다. 예를 들어 필터 제어 매개변수의 구성은 해당 필터로 라우팅되고 필터의 영향을 받는 매개변수가 쿼리에 표시됩니다(영향을 받지 않은 매개변수가 있는 디코더에서 읽는 대신).

쿼리 및 구성

그림 2. 쿼리 및 구성.

시작

시작 시 래핑된 구성 요소는 디코더와 버퍼를 변경하는 모든 필터를 시작합니다. 필터가 활성화되어 있지 않으면 래핑된 구성 요소가 디코더를 시작하고 버퍼를 통과하고 디코더 자체에 명령을 보냅니다.

버퍼 처리

버퍼 처리

그림 3. 버퍼 처리.

래핑된 디코더에 대기 중인 버퍼는 기본 디코더로 이동합니다. 래핑된 구성 요소는 onWorkDone_nb() 콜백을 통해 디코더에서 출력 버퍼를 가져온 다음 필터에 대기시킵니다. 마지막 필터의 최종 출력 버퍼가 클라이언트에 보고됩니다.

이 버퍼 처리가 작동하려면 래핑된 구성 요소가 C2PortBlockPoolsTuning 을 마지막 필터로 구성하여 프레임워크가 예상 블록 풀에서 버퍼를 출력하도록 해야 합니다.

중지, 재설정 및 해제

중지 시 래핑된 구성 요소는 디코더와 시작되었던 활성화된 모든 필터를 중지합니다. 재설정 및 해제 시 모든 구성 요소는 활성화 여부에 관계없이 재설정되거나 해제됩니다.

샘플 필터 플러그인 구현

플러그인을 활성화하려면 다음을 수행하십시오.

  1. 라이브러리에서 FilterPlugin 인터페이스를 구현하고 /vendor/lib[64]/libc2filterplugin.so에 /vendor/lib[64]/libc2filterplugin.so.
  2. 필요한 경우 mediacodec.te 에 추가 권한을 추가하십시오.
  3. 적응 계층을 Android 12로 업데이트하고 media.c2 서비스를 다시 빌드합니다.

플러그인 테스트

샘플 플러그인을 테스트하려면 다음을 수행하십시오.

  1. 장치를 다시 빌드하고 플래시합니다.
  2. 다음 명령을 사용하여 샘플 플러그인을 빌드합니다.

    m sample-codec2-filter-plugin
    
  3. 코덱 서비스에서 인식할 수 있도록 장치를 다시 마운트하고 공급업체 플러그인의 이름을 바꿉니다.

    adb root
    adb remount
    adb reboot
    adb wait-for-device
    adb root
    adb remount
    adb
    push /out/target/<...>/lib64/sample-codec2-filter-plugin.so \
    
    /vendor/lib64/libc2filterplugin.so
    adb push
    /out/target/<...>/lib/sample-codec2-filter-plugin.so \
    
    /vendor/lib/libc2filterplugin.so
    adb reboot