Share via


MediaCodec 클래스

정의

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

[Android.Runtime.Register("android/media/MediaCodec", DoNotGenerateAcw=true)]
public sealed class MediaCodec : Java.Lang.Object
[<Android.Runtime.Register("android/media/MediaCodec", DoNotGenerateAcw=true)>]
type MediaCodec = class
    inherit Object
상속
MediaCodec
특성

설명

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱(예: 인코더/디코더 구성 요소)에 액세스할 수 있습니다. Android 하위 수준 멀티미디어 지원 인프라의 일부입니다(일반적으로 , , , MediaSyncMediaMuxer, ImageMediaCryptoMediaDrmSurface및 와 AudioTrack함께 MediaExtractor사용됨).

<center><img src=".. /.. /.. /images/media/mediacodec_buffers.svg" style="width: 540px; height: 205px" alt="MediaCodec 버퍼 흐름 다이어그램"></center>

일반적으로 코덱은 입력 데이터를 처리하여 출력 데이터를 생성합니다. 데이터를 비동기적으로 처리하고 입력 및 출력 버퍼 집합을 사용합니다. 간단한 수준에서 빈 입력 버퍼를 요청(또는 수신)하고, 데이터로 채우고, 처리를 위해 코덱으로 보냅니다. 코덱은 데이터를 사용하고 빈 출력 버퍼 중 하나로 변환합니다. 마지막으로 채워진 출력 버퍼를 요청(또는 수신)하고, 해당 콘텐츠를 사용하고, 코덱으로 다시 해제합니다.

<h3 id=qualityFloor>"qualityFloor">비디오 인코딩</h3에 대한 최소 품질 바닥>

android.os.Build.VERSION_CODES#S부터 Android의 Video MediaCodecs는 최소 품질 층을 적용합니다. 품질이 낮은 비디오 인코딩을 제거하려는 의도입니다. 이 품질 바닥은 코덱이 VBR(가변 비트 전송률) 모드에 있을 때 적용됩니다. 코덱이 CBR(상수 비트 전송률) 모드에 있을 때 적용되지 않습니다. 품질 바닥 적용은 특정 크기 범위로 제한됩니다. 이 크기 범위는 현재 1920x1080까지 320x240보다 큰 비디오 해상도에 적합합니다.

이 품질 바닥이 적용되면 코덱 및 지원 프레임워크 코드는 생성된 비디오가 적어도 "공정" 또는 "양호한" 품질인지 확인하기 위해 작동합니다. 이러한 대상을 선택하는 데 사용되는 메트릭은 선택한 테스트 시퀀스에 대해 대상 점수가 70인 VMAF(비디오 다중 메서드 평가 함수)입니다.

일반적인 효과는 일부 동영상이 원래 구성된 것보다 더 높은 비트 전송률을 생성한다는 것입니다. 이것은 매우 낮은 비트 전송률로 구성된 비디오에 가장 주목할 만합니다. 코덱은 "공정" 또는 "양호한" 품질의 비디오를 생성할 가능성이 더 높은 비트 전송률을 사용합니다. 또 다른 상황은 비디오에 매우 복잡한 콘텐츠(많은 동작 및 세부 정보)가 포함된 경우입니다. 이러한 구성에서 코덱은 필요에 따라 추가 비트 전송률을 사용하여 콘텐츠의 세부 정보를 모두 잃지 않도록 합니다.

이 품질 바닥은 높은 비트 전송률로 캡처된 콘텐츠에 영향을 주지 않습니다(높은 비트 전송률은 이미 모든 세부 정보를 인코딩할 수 있는 충분한 용량을 코덱에 제공해야 합니다). 품질 바닥은 CBR 인코딩에서 작동하지 않습니다. 품질 바닥은 현재 320x240 이하의 해상도나 해상도가 1920x1080보다 높은 동영상에서는 작동하지 않습니다.

<h3>데이터 형식</h3>

코덱은 압축된 데이터, 원시 오디오 데이터 및 원시 비디오 데이터의 세 가지 종류의 데이터에서 작동합니다. 세 종류의 데이터는 모두 를 사용하여 ByteBuffer ByteBuffers처리할 수 있지만 원시 비디오 데이터에 를 사용하여 Surface 코덱 성능을 향상시켜야 합니다. Surface는 네이티브 비디오 버퍼를 ByteBuffers에 매핑하거나 복사하지 않고 사용합니다. 따라서 훨씬 더 효율적입니다. 일반적으로 Surface를 사용할 때는 원시 비디오 데이터에 액세스할 수 없지만 클래스를 ImageReader 사용하여 보안되지 않은 디코딩(원시) 비디오 프레임에 액세스할 수 있습니다. 일부 네이티브 버퍼가 ByteBuffer#isDirect 직접 ByteBuffers에 매핑될 수 있으므로 ByteBuffers를 사용하는 것보다 더 효율적일 수 있습니다. ByteBuffer 모드를 사용하는 경우 클래스 및 #getInputImage getInput/#getOutputImage OutputImage(int)를 사용하여 원시 비디오 프레임에 Image 액세스할 수 있습니다.

<h4>압축 버퍼</h4>

입력 버퍼(디코더의 경우) 및 출력 버퍼(인코더용)에는 MediaFormat#KEY_MIME 형식의 형식에 따라 압축된 데이터가 포함됩니다. 비디오 형식의 경우 일반적으로 단일 압축 비디오 프레임입니다. 오디오 데이터의 경우 일반적으로 단일 액세스 단위(일반적으로 형식 유형에 따라 몇 밀리초의 오디오를 포함하는 인코딩된 오디오 세그먼트)이지만 버퍼에 여러 인코딩된 오디오 액세스 단위가 포함될 수 있으므로 이 요구 사항이 약간 완화됩니다. 두 경우 모두 버퍼는 임의의 바이트 경계에서 시작되거나 끝나는 것이 아니라 로 플래그가 지정 #BUFFER_FLAG_PARTIAL_FRAME되지 않는 한 프레임/액세스 단위 경계에서 끝납니다.

<h4>원시 오디오 버퍼</h4>

원시 오디오 버퍼에는 각 채널에 대한 하나의 샘플인 PCM 오디오 데이터의 전체 프레임이 채널 순서로 포함됩니다. 각 PCM 오디오 샘플은 16비트 부속 정수 또는 부동 소수점(네이티브 바이트 순서)입니다. 부동 PCM 인코딩의 원시 오디오 버퍼는 MediaFormat의 MediaFormat#KEY_PCM_ENCODING MediaCodec #configure configure(&hellip;) 중에 AudioFormat#ENCODING_PCM_FLOAT 설정되고 디코더 또는 #getInputFormat 인코더에 대해 에서 #getOutputFormat 확인되는 경우에만 가능합니다. MediaFormat에서 float PCM에 대해 검사 샘플 방법은 다음과 같습니다.

static boolean isPcmFloat(MediaFormat format) {
               return format.getInteger(MediaFormat.KEY_PCM_ENCODING, AudioFormat.ENCODING_PCM_16BIT)
                   == AudioFormat.ENCODING_PCM_FLOAT;
             }

짧은 배열에서 16비트 부호 있는 정수 오디오 데이터를 포함하는 버퍼의 한 채널을 추출하기 위해 다음 코드를 사용할 수 있습니다.

// Assumes the buffer PCM encoding is 16 bit.
             short[] getSamplesForChannel(MediaCodec codec, int bufferId, int channelIx) {
               ByteBuffer outputBuffer = codec.getOutputBuffer(bufferId);
               MediaFormat format = codec.getOutputFormat(bufferId);
               ShortBuffer samples = outputBuffer.order(ByteOrder.nativeOrder()).asShortBuffer();
               int numChannels = format.getInteger(MediaFormat.KEY_CHANNEL_COUNT);
               if (channelIx &lt; 0 || channelIx &gt;= numChannels) {
                 return null;
               }
               short[] res = new short[samples.remaining() / numChannels];
               for (int i = 0; i &lt; res.length; ++i) {
                 res[i] = samples.get(i * numChannels + channelIx);
               }
               return res;
             }

<h4>원시 비디오 버퍼</h4>

ByteBuffer 모드에서 비디오 버퍼는 MediaFormat#KEY_COLOR_FORMAT 색 형식에 따라 배치됩니다. 에서 지원되는 색 형식을 배열#getCodecInfo..MediaCodecInfo#getCapabilitiesForType getCapabilitiesForType(&hellip;)CodecCapabilities#colorFormats colorFormats로 가져올 수 있습니다. 비디오 코덱은 세 가지 종류의 색 형식<을 지원할 수 있습니다. ul><li><strong>네이티브 원시 비디오 형식:</strong> 이 로 표시 CodecCapabilities#COLOR_FormatSurface 되며 입력 또는 출력 Surface와 함께 사용할 수 있습니다.</li li><><strong>유연한 YUV 버퍼</strong>(예: CodecCapabilities#COLOR_FormatYUV420Flexible): 를 사용하여/#getInputImage getInput#getOutputImage OutputImage(int) 입력/출력 Surface뿐만 아니라 ByteBuffer 모드에서도 사용할 수 있습니다.</li li>><<strong>other, specific formats:</strong> 이러한 형식은 일반적으로 ByteBuffer 모드에서만 지원됩니다. 일부 색 형식은 공급업체별로 다릅니다. 다른 항목은 에 정의되어 있습니다 CodecCapabilities. 유연한 형식과 동일한 색 형식의 경우 를 계속 사용할 #getInputImage getInput/#getOutputImage OutputImage(int)수 있습니다.</li></ul>

모든 비디오 코덱은 이후 android.os.Build.VERSION_CODES#LOLLIPOP_MR1유연한 YUV 4:2:0 버퍼를 지원합니다.

<h4>이전 디바이스<에서 원시 비디오 바이트 버퍼에 액세스/h4>

Image 지원 전에 android.os.Build.VERSION_CODES#LOLLIPOPMediaFormat#KEY_SLICE_HEIGHT 출력 형식 값을 사용하여 MediaFormat#KEY_STRIDE 원시 출력 버퍼의 레이아웃을 이해해야 합니다. <p class=note> 일부 디바이스에서는 조각 높이가 0으로 보급됩니다. 이는 조각 높이가 프레임 높이와 동일하거나 조각 높이가 일부 값(일반적으로 2의 힘)에 맞춰진 프레임 높이임을 의미할 수 있습니다. 아쉽게도 이 경우 실제 조각 높이를 알려주는 표준적이고 간단한 방법은 없습니다. 또한 평면 형식의 U 세로 보폭도 지정되거나 정의되지 않지만 일반적으로 조각 높이의 절반입니다.

MediaFormat#KEY_HEIGHT 키는 MediaFormat#KEY_WIDTH 비디오 프레임의 크기를 지정합니다. 그러나 대부분의 경우 비디오(사진)는 비디오 프레임의 일부만 차지합니다. 이는 '자르기 사각형'으로 표시됩니다.

다음 키를 사용하여 #getOutputFormat 출력 형식에서 원시 출력 이미지의 자르기 사각형을 가져와야 합니다. 이러한 키가 없는 경우 비디오는 전체 비디오 프레임을 차지합니다. 자르기 사각형은 MediaFormat#KEY_ROTATION 회전을 적용하기 전에<> 출력 프레임 <em>의 컨텍스트에서 이해됩니다. <table style="width: 0%">thead><tr<>th>Format Key</th><th>Type</th th><>Description</th></tr></thead<>tbody><tr><tdMediaFormat#KEY_CROP_LEFT></td td<>>Integer</td td td td<>>자르기 사각형</td></tr tr><tr td><<MediaFormat#KEY_CROP_TOP> td><>정<수/< td td>><자르기 사각형</td<>/tr tr><tr><td<>MediaFormat#KEY_CROP_RIGHT/td td<>>정<수/td td td<>>의 위쪽 좌표(y) 자르기 사각형</td/tr tr><td><td><<MediaFormat#KEY_CROP_BOTTOM> 정수/<<>>td><td>아래쪽 좌표(y) strong>MINUS 1/strong의 오른쪽 좌표(x) <<strong>MINUS<> 1</strong> 자르기 사각형</td></tr tr<><>td colspan=3> 오른쪽 및 아래쪽 좌표는 잘린 출력 이미지의 오른쪽에서 가장 유효한 열/맨 아래 가장 유효한 행의 좌표로 인식될 수 있습니다. </td></tr></tbody></table>

비디오 프레임의 크기(회전 전)는 다음과 같이 계산할 수 있습니다.

MediaFormat format = decoder.getOutputFormat(&hellip;);
             int width = format.getInteger(MediaFormat.KEY_WIDTH);
             if (format.containsKey(MediaFormat.KEY_CROP_LEFT)
                     && format.containsKey(MediaFormat.KEY_CROP_RIGHT)) {
                 width = format.getInteger(MediaFormat.KEY_CROP_RIGHT) + 1
                             - format.getInteger(MediaFormat.KEY_CROP_LEFT);
             }
             int height = format.getInteger(MediaFormat.KEY_HEIGHT);
             if (format.containsKey(MediaFormat.KEY_CROP_TOP)
                     && format.containsKey(MediaFormat.KEY_CROP_BOTTOM)) {
                 height = format.getInteger(MediaFormat.KEY_CROP_BOTTOM) + 1
                              - format.getInteger(MediaFormat.KEY_CROP_TOP);
             }

<p class=note> 또한 의 BufferInfo#offset BufferInfo.offset 의미가 디바이스 간에 일관되지 않았습니다. 일부 디바이스에서는 오프셋이 자르기 사각형의 왼쪽 위 픽셀을 가리키는 반면, 대부분의 디바이스에서는 전체 프레임의 왼쪽 위 픽셀을 가리켰습니다.

<h3>States</h3>

코덱은 수명 동안 개념적으로 중지됨, 실행 중 또는 해제됨의 세 가지 상태 중 하나에 존재합니다. 중지된 집합 상태는 실제로 초기화되지 않음, 구성됨 및 오류의 세 가지 상태의 결합인 반면 실행 상태는 개념적으로 플러시됨, 실행 중 및 스트림 끝의 세 가지 하위 상태를 통해 진행됩니다.

<center><img src=".. /.. /.. /images/media/mediacodec_states.svg" style="width: 519px; height: 356px" alt="MediaCodec 상태 다이어그램"></center>

팩터리 메서드 중 하나를 사용하여 코덱을 만들 때 코덱은 초기화되지 않은 상태입니다. 먼저 를 통해 #configure configure(&hellip;)구성해야 합니다. 이 경우 구성됨 상태로 전환한 다음 를 호출 #start 하여 실행 상태로 이동해야 합니다. 이 상태에서는 위에서 설명한 버퍼 큐 조작을 통해 데이터를 처리할 수 있습니다.

실행 상태에는 플러시됨, 실행 중 및 스트림 끝의 세 가지 하위 상태가 있습니다. #start 코덱이 플러시된 하위 상태에 있는 즉시 모든 버퍼를 보유합니다. 첫 번째 입력 버퍼가 큐에서 해제되는 즉시 코덱은 실행 중인 하위 상태로 이동하여 대부분의 수명을 소비합니다. #BUFFER_FLAG_END_OF_STREAM 스트림 끝 마커를 사용하여 입력 버퍼를 큐에 대기하면 코덱이 스트림 끝 하위 상태로 전환됩니다. 이 상태에서 코덱은 더 이상 추가 입력 버퍼를 허용하지 않지만 출력에서 스트림의 끝에 도달할 때까지 출력 버퍼를 생성합니다. 디코더의 경우 를 사용하여 #flush실행 중 상태일 때 언제든지 Flushed 하위 상태로 다시 이동할 수 있습니다. <p class=note><strong>Note:</strong> 플러시 상태로 돌아가기는 디코더에 대해서만 지원되며 인코더에 대해 작동하지 않을 수 있습니다(동작이 정의되지 않음).

를 호출 #stop 하여 코덱을 초기화되지 않은 상태로 반환하고, 그 후에 다시 구성할 수 있습니다. 코덱 사용을 마쳤으면 를 호출 #release하여 해제해야 합니다.

드문 경우지만 코덱에 오류가 발생하여 오류 상태로 이동할 수 있습니다. 큐 작업에서 잘못된 반환 값을 사용하거나 경우에 따라 예외를 통해 전달됩니다. 를 호출 #reset 하여 코덱을 다시 사용할 수 있도록 합니다. 모든 상태에서 호출하여 코덱을 초기화되지 않은 상태로 다시 이동할 수 있습니다. 그렇지 않으면 를 호출 #release 하여 터미널 해제 상태로 이동합니다.

<h3>만들기</h3>

를 사용하여 MediaCodecList 특정 MediaFormat에 대한 MediaCodec를 만듭니다. 파일 또는 스트림을 디코딩할 때 에서 MediaExtractor#getTrackFormat MediaExtractor.getTrackFormat원하는 형식을 가져올 수 있습니다. 를 사용하여 MediaFormat#setFeatureEnabled MediaFormat.setFeatureEnabled추가하려는 특정 기능을 삽입한 다음 를 호출 MediaCodecList#findDecoderForFormat MediaCodecList.findDecoderForFormat 하여 해당 특정 미디어 형식을 처리할 수 있는 코덱의 이름을 가져옵니다. 마지막으로 를 사용하여 #createByCodecName코덱을 만듭니다. <p class=note><strong>Note:</strong> On android.os.Build.VERSION_CODES#LOLLIPOP, 형식에 MediaCodecList.findDecoder/EncoderForFormat MediaFormat#KEY_FRAME_RATE 프레임 속도가 포함되어서는 안됩니다. 기존 프레임 속도 설정을 형식으로 지우려면 를 사용합니다 format.setString(MediaFormat.KEY_FRAME_RATE, null) .

를 사용하여 #createDecoderByType createDecoder/#createEncoderByType EncoderByType(String)특정 MIME 형식에 대한 기본 코덱을 만들 수도 있습니다. 그러나 기능을 삽입하는 데 사용할 수 없으며 원하는 특정 미디어 형식을 처리할 수 없는 코덱을 만들 수 있습니다.

<h4>보안 디코더< 만들기/h4>

버전 및 이전 버전 android.os.Build.VERSION_CODES#KITKAT_WATCH 에서는 보안 코덱이 에 MediaCodecList나열되지 않을 수 있지만 시스템에서 계속 사용할 수 있습니다. 존재하는 보안 코덱은 일반 코덱의 이름(모든 보안 코덱의 이름은 로 끝나".secure"야 함) #createByCodecName 에 추가하여 ".secure" 이름으로만 인스턴스화할 수 있습니다. 코덱이 시스템에 없는 경우 을 throw IOException 합니다.

이후 android.os.Build.VERSION_CODES#LOLLIPOP 부터 미디어 형식의 CodecCapabilities#FEATURE_SecurePlayback 기능을 사용하여 보안 디코더를 만들어야 합니다.

<h3>초기화</h3>

코덱을 만든 후 데이터를 비동기적으로 처리하려는 경우 를 사용하여 #setCallback setCallback 콜백을 설정할 수 있습니다. 그런 다음 #configure 특정 미디어 형식을 사용하여 코덱을 구성합니다. 이 경우 ndash를 &비디오 생산자, 원시 비디오 데이터를 생성하는 코덱(예: 비디오 디코더)에 대한 출력 Surface 을 지정할 수 있습니다. 보안 코덱에 대한 암호 해독 매개 변수를 설정할 수도 있습니다(참조 MediaCrypto). 마지막으로, 일부 코덱은 여러 모드에서 작동할 수 있으므로 디코더 또는 인코더로 작동할지 여부를 지정해야 합니다.

이후 android.os.Build.VERSION_CODES#LOLLIPOP에서는 구성된 상태에서 결과 입력 및 출력 형식을 쿼리할 수 있습니다. 코덱을 시작하기 전에 이를 사용하여 결과 구성(예: 색 형식)을 확인할 수 있습니다.

비디오 소비자 &ndash를 사용하여 원시 입력 비디오 버퍼를 기본적으로 처리하려는 경우 비디오 인코더 &ndash와 같은 원시 비디오 입력을 처리하는 코덱입니다. 구성 후를 사용하여 입력 데이터에 대한 대상 Surface를 #createInputSurface 만듭니다. 또는 를 호출 #setInputSurface하여 이전에 만든 #createPersistentInputSurface 영구 입력 화면을 사용하도록 코덱을 설정합니다.

<h4 id=CSD>"CSD">코덱 관련 데이터</h4>

일부 형식( 특히 AAC 오디오 및 MPEG4, H.264 및 H.265 비디오 형식)에는 설치 데이터 또는 코덱 특정 데이터가 포함된 여러 버퍼의 접두사로 실제 데이터를 접두사로 지정해야 합니다. 이러한 압축된 형식을 처리할 때 이 데이터는 프레임 데이터 전후 #start 의 코덱에 제출되어야 합니다. 이러한 데이터는 에 대한 호출#queueInputBuffer queueInputBuffer에서 플래그 #BUFFER_FLAG_CODEC_CONFIG 를 사용하여 표시해야 합니다.

코덱 관련 데이터는 "csd-0", "csd-1" 등의 키가 있는 ByteBuffer 항목에 전달 #configure configure 되는 형식으로 포함할 수도 있습니다. 이러한 키는 항상 에서 가져온 트랙 MediaFormatMediaExtractor#getTrackFormat MediaExtractor포함됩니다. 형식의 코덱 관련 데이터는 에 따라 코덱에 #start<자동으로 제출됩니다. 강력한>경우 이 데이터를 명시적으로 제출하지 않아야<> 합니다. 형식에 코덱 특정 데이터가 포함되지 않은 경우 형식 요구 사항에 따라 지정된 수의 버퍼를 올바른 순서로 사용하여 제출할 수 있습니다. H.264 AVC의 경우 모든 코덱 관련 데이터를 연결하고 단일 코덱 구성 버퍼로 제출할 수도 있습니다.

Android는 다음 코덱 관련 데이터 버퍼를 사용합니다. 또한 적절한 MediaMuxer 트랙 구성을 위해 트랙 형식으로 설정해야 합니다. 각 매개 변수 집합 및 (<sup>*</sup>)로 표시된 코덱별 데이터 섹션은 의 "\x00\x00\x00\x01"시작 코드로 시작해야 합니다.

<style>td. NA { background: #ccc; } .mid > tr > td { vertical-align: middle; }</style><table><thead><th>Format</th>><CSD buffer #0</th th>><CSD buffer #1</th>><CSD buffer #2</th></thead<>tbody class=mid<>tr<>td>AAC</td td<>>Decoder-specific information from ESDS<sup>*</sup></td td td<>class=NA Not Used</td td><class=NA>>Not Used</Td></tr tr td>><VORBIS</td td><>Identification header</td td>><Setup header</td td<>class=NA>Not Used</td></tr tr><td<>>OPUS</td td><>Identification header</td td td>><pre-skip in nanosecs br> (unsigned<64비트 ByteOrder#nativeOrder native-order integer.)<><br> 식별 헤더의 미리 건너뛰기 값을 재정의합니다.</td td>><Seek Pre-roll in nanosecs<br> (unsigned 64비트 ByteOrder#nativeOrder native-order integer.)</td></tr tr><<>td>FLAC</td td><>"fLaC", ASCII의 FLAC 스트림 마커,<br> 뒤에 STREAMINFO 블록(필수 메타데이터 블록),<br> 선택적으로 뒤에 다른 메타데이터 블록</td td><클래스=NA>Not Used</td td><class=NA>Not Used</td<>/tr tr tr<<>>>MPEG-4</td><Td>ESDS sup*/sup></td td><class=NA>Not Used</td td<>class=NA>Not Used</td<>/tr tr tr><<>td>H.264 AVC</td td>><SPS(Sequence Parameter Sets<sup>*</sup>)/td td>><PPS(Picture Parameter Sets<sup>*</sup>)<</td<>td의 디코더 관련 정보<>< class=NA>Not Used</td></tr tr>><<td>H.265 HEVC</td td><>VPS (Video Parameter Sets<sup>*</sup>) +<br> SPS (Sequence Parameter Sets<sup>*</sup>) +<br> PPS (Picture Parameter Sets<sup>*</sup>)</td td<>class=NA Not Used</td td><class=NA>>Not Used/< td></tr tr>><<td>VP9</td td>><VP9 CodecPrivate Data (선택 사항)</td td><class=NA>Not Used</td td<>class=NA>Not Used</td></tr tr><tr><td>AV1</td td ><>AV1 AV1CodecConfigurationRecord Data (optional) </td td<>class=NA>Not Used</td><td class=NA>Not Used</td></tr></tbody></table>

<p class=note><strong>Note:</strong> care는 코덱이 플러시 중에 코덱 특정 데이터가 손실될 수 있으므로 출력 버퍼 또는 출력 형식 변경이 반환되기 직전에 즉시 또는 시작 직후에 플러시되는 경우 주의해야 합니다. 적절한 코덱 작업을 보장하려면 이러한 플러시 후에 로 #BUFFER_FLAG_CODEC_CONFIG 표시된 버퍼를 사용하여 데이터를 다시 제출해야 합니다.

인코더(또는 압축된 데이터를 생성하는 코덱)는 #BUFFER_FLAG_CODEC_CONFIG 코덱 구성 플래그로 표시된 출력 버퍼의 유효한 출력 버퍼 앞에 코덱 특정 데이터를 만들고 반환합니다. 코덱별 데이터를 포함하는 버퍼에는 의미 있는 타임스탬프가 없습니다.

<h3>데이터 처리</h3>

각 코덱은 API 호출에서 buffer-ID로 참조되는 입력 및 출력 버퍼 집합을 유지 관리합니다. 클라이언트를 #start 성공적으로 호출한 후에는 입력 버퍼나 출력 버퍼를 모두 "소유"하지 않습니다. 동기 모드에서 를 호출 #dequeueInputBuffer dequeueInput/#dequeueOutputBuffer OutputBuffer(&hellip;) 하여 코덱에서 입력 또는 출력 버퍼를 얻습니다(소유권 가져오기). 비동기 모드에서는 콜백을 통해 사용 가능한 버퍼를 Callback#onInputBufferAvailable MediaCodec.Callback.onInput/Callback#onOutputBufferAvailable OutputBufferAvailable(&hellip;) 자동으로 받습니다.

입력 버퍼를 가져오면 데이터로 채우고 &ndash를 사용 #queueInputBuffer queueInputBuffer 하거나 #queueSecureInputBuffer queueSecureInputBuffer 암호 해독을 사용하는 경우 코덱에 제출합니다. 동일한 타임스탬프를 사용하여 여러 입력 버퍼를 제출하지 마세요(로 표시된 코덱별 데이터가 아닌 경우).

코덱은 차례로 비동기 모드에서 콜백을 Callback#onOutputBufferAvailable onOutputBufferAvailable 통해 또는 동기 모드의 호출에 대한 응답으로 읽기 전용 출력 버퍼를 #dequeueOutputBuffer dequeueOutputBuffer 반환합니다. 출력 버퍼가 처리된 후 메서드 중 #releaseOutputBuffer releaseOutputBuffer 하나를 호출하여 버퍼를 코덱으로 반환합니다.

코덱에 버퍼를 즉시 다시 제출/해제할 필요는 없지만 입력 및/또는 출력 버퍼를 유지하면 코덱이 중단될 수 있으며 이 동작은 디바이스에 따라 달라집니다. <강력한>특히, em all</em> 미해결 버퍼가 해제/다시 제출될 때까지 <>코덱이 출력 버퍼 생성을 보류할 수 있습니다.</strong> 따라서 사용 가능한 버퍼를 최대한 적게 유지합니다.

API 버전에 따라 세 가지 방법으로 <데이터를 처리할 수 있습니다. table><thead<>trth><>Processing Mode</th th><>API version <= 20<br>Jelly Bean/KitKat</th<>>API version >= 21<br>Lollipop and later</th></tr></thead<>tbody<>tr td><>Synchronous API using buffer arrays</td td<>>supported</tdtd>Deprecated</td></tr tr<>tr<>td>buffers</td td><class=NA>Not Available</td td>><Supported</td<>/tr tr tr>>><<td asynchronous API using buffers</td td<>class=NA>Not Available</td td<>>supported</td></tr></tbody></table ><>

<버퍼</h4>를 사용한 h4 비동기 처리>

부터 android.os.Build.VERSION_CODES#LOLLIPOP는 를 호출 #configure configure하기 전에 콜백을 설정하여 데이터를 비동기적으로 처리하는 것이 좋습니다. 비동기 모드는 코덱을 실행 중인 하위 상태로 전환하고 입력 버퍼 수신을 시작하려면 를 호출 #start#flush 해야 하기 때문에 상태가 약간 변경됩니다. 마찬가지로 코덱에 대한 초기 호출 start 시 실행 중인 하위 상태로 직접 이동하고 콜백을 통해 사용 가능한 입력 버퍼 전달을 시작합니다.

<center><img src=".. /.. /.. /images/media/mediacodec_async_states.svg" style="width: 516px; height: 353px" alt="비동기 작업에 대한 MediaCodec 상태 다이어그램"></center>

MediaCodec는 일반적으로 비동기 모드에서 다음과 같이 사용됩니다.

MediaCodec codec = MediaCodec.createByCodecName(name);
             MediaFormat mOutputFormat; // member variable
             codec.setCallback(new MediaCodec.Callback() {
               {@literal @Override}
               void onInputBufferAvailable(MediaCodec mc, int inputBufferId) {
                 ByteBuffer inputBuffer = codec.getInputBuffer(inputBufferId);
                 // fill inputBuffer with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }

               {@literal @Override}
               void onOutputBufferAvailable(MediaCodec mc, int outputBufferId, &hellip;) {
                 ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
                 MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
                 // bufferFormat is equivalent to mOutputFormat
                 // outputBuffer is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               }

               {@literal @Override}
               void onOutputFormatChanged(MediaCodec mc, MediaFormat format) {
                 // Subsequent data will conform to new format.
                 // Can ignore if using getOutputFormat(outputBufferId)
                 mOutputFormat = format; // option B
               }

               {@literal @Override}
               void onError(&hellip;) {
                 &hellip;
               }
               {@literal @Override}
               void onCryptoError(&hellip;) {
                 &hellip;
               }
             });
             codec.configure(format, &hellip;);
             mOutputFormat = codec.getOutputFormat(); // option B
             codec.start();
             // wait for processing to complete
             codec.stop();
             codec.release();

<버퍼</h4>를 사용한 h4 동기 처리>

이후android.os.Build.VERSION_CODES#LOLLIPOP, 동기 모드에서 코덱을 사용하는/#getOutputBuffer OutputBuffer(int)#getInputBuffer getInput경우에도 및/또는 #getInputImage getInput/#getOutputImage OutputImage(int) 를 사용하여 입력 및 출력 버퍼를 검색해야 합니다. 이렇게 하면 동적 콘텐츠를 처리할 때와 같이 프레임워크에서 특정 최적화를 수행할 수 있습니다. 를 호출하면 이 최적화를 사용할 #getInputBuffers getInput/#getOutputBuffers OutputBuffers()수 없습니다.

<p class=note><strong>Note:</strong> 은 버퍼와 버퍼 배열을 동시에 사용하는 방법을 혼합하지 않습니다. 특히 값#INFO_OUTPUT_FORMAT_CHANGED이 인 출력 버퍼 ID를 큐에서 해제한 직후 또는 그 후에 #start 만 를 호출 getInput/OutputBuffers 합니다.

MediaCodec는 일반적으로 동기 모드에서 다음과 같이 사용됩니다.

MediaCodec codec = MediaCodec.createByCodecName(name);
             codec.configure(format, &hellip;);
             MediaFormat outputFormat = codec.getOutputFormat(); // option B
             codec.start();
             for (;;) {
               int inputBufferId = codec.dequeueInputBuffer(timeoutUs);
               if (inputBufferId &gt;= 0) {
                 ByteBuffer inputBuffer = codec.getInputBuffer(&hellip;);
                 // fill inputBuffer with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }
               int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
               if (outputBufferId &gt;= 0) {
                 ByteBuffer outputBuffer = codec.getOutputBuffer(outputBufferId);
                 MediaFormat bufferFormat = codec.getOutputFormat(outputBufferId); // option A
                 // bufferFormat is identical to outputFormat
                 // outputBuffer is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 // Subsequent data will conform to new format.
                 // Can ignore if using getOutputFormat(outputBufferId)
                 outputFormat = codec.getOutputFormat(); // option B
               }
             }
             codec.stop();
             codec.release();

<h4>버퍼 배열을 사용한 동기 처리(사용되지 않음)</h4>

버전 android.os.Build.VERSION_CODES#KITKAT_WATCH 및 이전 버전에서는 입력 및 출력 버퍼 집합이 배열로 ByteBuffer[] 표시됩니다. 를 성공적으로 호출한 #start후 를 사용하여 #getInputBuffers getInput/#getOutputBuffers OutputBuffers()버퍼 배열을 검색합니다. 아래 샘플에 설명된 대로 버퍼 ID를 이러한 배열에 인덱스로 사용합니다(음수가 아닌 경우). 배열 크기는 상한을 제공하지만 배열 크기와 시스템에서 사용하는 입력 및 출력 버퍼 수 사이에는 내재된 상관 관계가 없습니다.

MediaCodec codec = MediaCodec.createByCodecName(name);
             codec.configure(format, &hellip;);
             codec.start();
             ByteBuffer[] inputBuffers = codec.getInputBuffers();
             ByteBuffer[] outputBuffers = codec.getOutputBuffers();
             for (;;) {
               int inputBufferId = codec.dequeueInputBuffer(&hellip;);
               if (inputBufferId &gt;= 0) {
                 // fill inputBuffers[inputBufferId] with valid data
                 &hellip;
                 codec.queueInputBuffer(inputBufferId, &hellip;);
               }
               int outputBufferId = codec.dequeueOutputBuffer(&hellip;);
               if (outputBufferId &gt;= 0) {
                 // outputBuffers[outputBufferId] is ready to be processed or rendered.
                 &hellip;
                 codec.releaseOutputBuffer(outputBufferId, &hellip;);
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) {
                 outputBuffers = codec.getOutputBuffers();
               } else if (outputBufferId == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) {
                 // Subsequent data will conform to new format.
                 MediaFormat format = codec.getOutputFormat();
               }
             }
             codec.stop();
             codec.release();

<h4>스트림의 끝 처리</h4>

입력 데이터의 끝에 도달하면 에 대한 호출#queueInputBuffer queueInputBuffer에서 플래그를 지정하여 #BUFFER_FLAG_END_OF_STREAM 코덱에 신호를 전송해야 합니다. 마지막 유효한 입력 버퍼에서 또는 스트림 종료 플래그가 설정된 빈 입력 버퍼를 추가로 제출하여 이 작업을 수행할 수 있습니다. 빈 버퍼를 사용하는 경우 타임스탬프는 무시됩니다.

코덱은 에서 또는 을 통해 Callback#onOutputBufferAvailable onOutputBufferAvailable반환된 집합에서 동일한 스트림 끝 플래그 BufferInfo 를 지정하여 출력 스트림의 끝을 알릴 때까지 출력 버퍼를 #dequeueOutputBuffer dequeueOutputBuffer 계속 반환합니다. 마지막 유효한 출력 버퍼 또는 마지막 유효한 출력 버퍼 이후의 빈 버퍼에서 설정할 수 있습니다. 이러한 빈 버퍼의 타임스탬프는 무시해야 합니다.

코덱이 플러시되거나 중지되고 다시 시작되지 않는 한 입력 스트림의 끝을 신호로 표시한 후 추가 입력 버퍼를 제출하지 마세요.

<h4>출력 Surface< 사용/h4>

데이터 처리는 출력을 사용할 때 ByteBuffer 모드와 거의 동일합니다. 그러나 출력 Surface버퍼는 액세스할 수 없으며 값으로 null 표시됩니다. 예를 들어 #getOutputBuffer getOutputBuffer/#getOutputImage Image(int) 는 를 반환 null 하고 #getOutputBuffers -s만 null포함하는 배열을 반환합니다.

출력 Surface를 사용하는 경우 표면에서 각 출력 버퍼를 렌더링할지 여부를 선택할 수 있습니다. 세 가지 선택 항목이 <있습니다. ul><li><strong>버퍼를 렌더링하지 마세요.</strong> Call #releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, false).</li li><><strong>기본 타임스탬프:</strong> 호출#releaseOutputBuffer(int, boolean) releaseOutputBuffer(bufferId, true)을 사용하여 버퍼를 렌더링합니다.</li li><><strong>특정 타임스탬프:</strong> 호출#releaseOutputBuffer(int, long) releaseOutputBuffer(bufferId, timestamp)을 사용하여 버퍼를 렌더링합니다.</li></ul>

부터 android.os.Build.VERSION_CODES#M기본 타임스탬프는 버퍼의 BufferInfo#presentationTimeUs 프레젠테이션 타임스탬프입니다(나노초로 변환됨). 그 전에는 정의되지 않았습니다.

또한 이후 android.os.Build.VERSION_CODES#M을 사용하여 #setOutputSurface setOutputSurface출력 Surface를 동적으로 변경할 수 있습니다.

Surface로 출력을 렌더링할 때 Surface가 과도한 프레임(Surface에서 적시에 사용하지 않음)을 삭제하도록 구성할 수 있습니다. 또는 과도한 프레임을 삭제하지 않도록 구성할 수 있습니다. 후자 모드에서 Surface가 출력 프레임을 충분히 빠르게 사용하지 않으면 결국 디코더가 차단됩니다. android.os.Build.VERSION_CODES#Q 보기 표면(SurfaceView 또는 TextureView)은 항상 과도한 프레임을 삭제한다는 점을 제외하고 정확한 동작이 정의되지 않았습니다. android.os.Build.VERSION_CODES#Q 기본 동작은 과도한 프레임을 삭제하는 것입니다. 애플리케이션은 SDK android.os.Build.VERSION_CODES#Q 를 대상으로 하고 키를 MediaFormat#KEY_ALLOW_FRAME_DROP 구성 형식으로 설정하여 보기가 아닌 표면(예: ImageReader 또는 SurfaceTexture)에 대해 이 동작을 옵트아웃할 0 수 있습니다.

<Surface</h4>로 렌더링할 때의 h4 변환>

코덱이 Surface 모드로 구성된 경우 자르기 사각형, MediaFormat#KEY_ROTATION 회전 및 #setVideoScalingMode 비디오 크기 조정 모드가 한 가지 예외 <로 자동으로 적용됩니다. p class=note> 릴리스 전에 android.os.Build.VERSION_CODES#M 소프트웨어 디코더는 Surface에 렌더링될 때 회전을 적용하지 않았을 수 있습니다. 아쉽게도 소프트웨어 디코더를 식별하는 표준적이고 간단한 방법이 없거나, 소프트웨어 디코더를 사용해보는 것 외에 다른 회전을 적용하는 경우는 없습니다.

몇 가지 주의 사항도 있습니다. <p class=note> 출력을 Surface에 표시할 때 픽셀 가로 세로 비율이 고려되지 않습니다. 즉, 모드를 사용하는 #VIDEO_SCALING_MODE_SCALE_TO_FIT 경우 최종 디스플레이 가로 세로 비율이 적절하게 표시되도록 출력 Surface의 위치를 지정해야 합니다. 반대로 정사각형 픽셀(픽셀 가로 세로 비율 또는 1:1)이 있는 콘텐츠에만 모드를 사용할 #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING 수 있습니다. <p class=note> 릴리스 #VIDEO_SCALING_MODE_SCALE_TO_FIT_WITH_CROPPING 기준으로 android.os.Build.VERSION_CODES#N 90도 또는 270도 회전된 비디오의 경우 모드가 제대로 작동하지 않을 수 있습니다. <p class=note> 비디오 크기 조정 모드를 설정할 때 출력 버퍼가 변경될 때마다 다시 설정해야 합니다. #INFO_OUTPUT_BUFFERS_CHANGED 이벤트는 더 이상 사용되지 않으므로 출력 형식이 변경될 때마다 이 작업을 수행할 수 있습니다.

<h4>입력 Surface< 사용/h4>

입력 Surface를 사용하는 경우 버퍼가 입력 화면에서 코덱으로 자동으로 전달되기 때문에 액세스할 수 있는 입력 버퍼가 없습니다. 를 호출 #dequeueInputBuffer dequeueInputBuffer 하면 가 IllegalStateExceptionthrow되고 #getInputBuffers 강력한>NOT</strong>이 기록되어야 하는 <가짜 ByteBuffer[] 배열이 반환됩니다.

를 호출 #signalEndOfInputStream 하여 스트림 끝 신호를 보냅니다. 입력 화면은 이 호출 직후 코덱에 데이터 전송을 중지합니다.

<h3>&를 찾고 있습니다. 적응 재생 지원</h3>

비디오 디코더(및 압축된 비디오 데이터를 사용하는 일반 코덱)는 적응 재생을 지원하고 구성했는지 여부에 관계없이 검색 및 형식 변경에 대해 다르게 동작합니다. 디코더가 를 통해 CodecCapabilities#isFeatureSupported CodecCapabilities.isFeatureSupported(String)CodecCapabilities#FEATURE_AdaptivePlayback 적응 재생을 지원하는지 검사 수 있습니다. 비디오 디코더에 대한 적응 재생 지원은 로 디코딩 Surface하도록 코덱을 구성하는 경우에만 활성화됩니다.

<h4 id=KeyFrames>"KeyFrames">스트림 경계 및 키 프레임</h4>

적절한 스트림 경계에서 시작하거나 #flush 나면 #start 입력 데이터가 중요합니다. 첫 번째 프레임은 키 프레임이어야 합니다. <em>키 프레임</em>은 자체적으로 완전히 디코딩할 수 있으며(대부분의 코덱은 I 프레임을 의미함), 키 프레임 이후에 표시할 프레임이 키 프레임 앞의 프레임을 참조하지 않습니다.

다음 표에서는 다양한 비디오 형식에 적합한 키 프레임을 요약합니다. <table>thead><tr><th>Format</th<>th>Suitable key frame</th<>/tr<>/thead<>tbody class=mid<>tr td>><VP9/VP8</td td td><>는 이 프레임 이전의 프레임을 참조하는 후속 프레임이 없는 적합한 인트라프레임입니다.<<br>(이러한 키 프레임에 대한 특정 이름은 없습니다.)</td></tr tr><<>td>H.265 HEVC</td td><>IDR 또는 CRA</td></tr tr tr>><<td>H.264 AVC</td td><>IDR</td/tr tr>><<td<>> MPEG-4<br>H.263<br>MPEG-2</td td<>>는 이 프레임 이전의 프레임을 참조하지 않는 적합한 I-프레임입니다.<br>(이러한 키 프레임에 대한 특정 이름은 없습니다.)</td></tr></tbody></table>

<h4>적응 재생을 지원하지 않는 디코더의 경우(Surface로 디코딩하지 않는 경우 포함)</h4>

이전에 제출된 데이터(예: 검색 후)<에 인접하지 않은 데이터 디코딩을 시작하려면 디>코더를 플러시해야 합니다<>. 모든 출력 버퍼는 플러시 지점에서 즉시 해지되므로 먼저 신호를 받은 다음, 를 호출 flush하기 전에 스트림의 끝을 기다리는 것이 좋습니다. 플러시 후의 입력 데이터는 적절한 스트림 경계/키 프레임에서 시작하는 것이 중요합니다. <p class=note>strong Note:</strong> 플러시 후에 제출된 데이터의 형식은 변경되지 #flush 않아야 하며 형식 불연속성을 지원하지 않습니다. 이를 위해 전체#start - - #stop#configure configure(&hellip;) 주기가 필요합니다.><

<p class=note><strong>또한 참고:</strong> &ndash 후에 #start 코덱을 너무 빨리 플러시하면 이고, 일반적으로 ndash에 &첫 번째 출력 버퍼 또는 출력 형식 변경이 수신되기 전에 코덱 관련 데이터를 코덱에 다시 제출해야 합니다. 자세한 내용은 codec-specific-data 섹션을 참조하세요.

<h4>적응 재생</h4를 지원하고 구성된 디코더의 경우>

이전에 제출된 데이터(즉, 검색 후)<>에 인접하지 않은 데이터 디코딩을 시작하려면 디코더를 플러시할 필요가<> 없습니다. 그러나 불연속성 이후의 입력 데이터는 적절한 스트림 경계/키 프레임에서 시작해야 합니다.

일부 비디오 형식(예: H.264, H.265, VP8 및 VP9)의 경우 사진 크기 또는 구성 중간 스트림을 변경할 수도 있습니다. 이렇게 하려면 키 프레임과 함께 전체 새 코덱 관련 구성 데이터를 단일 버퍼(시작 코드 포함)로 패키지하고 강력한>일반</강력한> 입력 버퍼로 <제출해야 합니다.

그림 크기 변경이 발생하고 새 크기의 프레임이 반환되기 직전에 또는 Callback#onOutputBufferAvailable onOutputFormatChanged 콜백에서 #dequeueOutputBuffer dequeueOutputBuffer 반환 값을 받게 #INFO_OUTPUT_FORMAT_CHANGED 됩니다. <p class=note><strong>Note:</strong> 코덱별 데이터의 경우처럼 그림 크기를 변경한 직후 호출 #flush 할 때는 주의해야 합니다. 사진 크기 변경에 대한 확인을 받지 못한 경우 새 사진 크기에 대한 요청을 반복해야 합니다.

<h3>오류 처리</h3>

팩터리 메서드 #createByCodecName createByCodecName#createEncoderByType EncoderByType#createDecoderByType createDecoder/throw IOException 실패 시 전달을 catch하거나 선언해야 합니다. MediaCodec 메서드는 메서드를 허용하지 않는 코덱 상태에서 호출할 때 throw IllegalStateException 됩니다. 이는 일반적으로 잘못된 애플리케이션 API 사용으로 인한 것입니다. 보안 버퍼와 관련된 메서드는 에서 CryptoException#getErrorCode얻을 수 있는 추가 오류 정보가 있는 를 throwCryptoException할 수 있습니다.

내부 코덱 오류는 애플리케이션이 API를 CodecException올바르게 사용하는 경우에도 미디어 콘텐츠 손상, 하드웨어 오류, 리소스 소모 등으로 인해 발생할 수 있는 을 발생합니다. 를 받을 CodecException 때 권장되는 작업은 및 를 <호출 CodecException#isRecoverable 하여 확인할 수 있습니다. CodecException#isTransientul<>li><strong>recoverable errors:</strong> If가 true를 반환하면 isRecoverable() , 및 를 #configure configure(&hellip;)호출#stop하여 #start 복구할 수 있습니다.</li li><><strong>일시적인 오류:</strong> true를 반환하면 isTransient() 리소스를 일시적으로 사용할 수 없으며 메서드가 나중에 다시 시도될 수 있습니다.</li li><><strong>fatal errors:</strong> 둘 다 isRecoverable()isTransient() 가 false를 반환하면 가 CodecException 치명적이며 코덱이 다시 설정되거나 해제되지 #release #reset 합니다.</li></ul>

및 는 isTransient() 모두 isRecoverable() true를 동시에 반환하지 않습니다.

<h2 id=History>"History">유효한 API 호출 및 API 기록</h2>

이 섹션에서는 각 상태의 유효한 API 호출과 MediaCodec 클래스의 API 기록을 요약합니다. API 버전 번호는 를 참조하세요 android.os.Build.VERSION_CODES.

<style> .api > tr > th, .api > tr > td { text-align: center; padding: 4px 4px; } .api > tr > th { vertical-align: bottom; } .api > tr > td { vertical-align: middle; } .sml tr > th, .sml >> tr > td { text-align: center; padding: 2px 4px; } .fn { text-align: left; } .fn > code > a { font: 14px/19px Roboto Condensed, sans-serif; } .deg45 { 공백: nowrap; background: none; border: none; vertical-align: bottom; width: 30px; height: 83px; } .deg45 > div { transform: skew(-45deg, 0deg) translate(1px, -67px); transform-origin: bottom left 0; width: 30px; height: 20px; } .deg45 > div > div { border: 1px solid #ddd; background: #999; height: 90px; width: 42px; } .deg45 > div > div div > { transform: skew(45deg, 0deg) translate(-55px, 55px) rotate(-45deg); }</스타일>

<table align="right" style="width: 0%">thead><tr><th>Symbol</th th>><Meaning</th></tr></thead<>tbody class=sml<>tr><td>●</td td><>Supported</td></tr tr><><td>⁕</td td><>Semantics changed</td></tr tr<>td><>○</td td>><Experimental support</td></tr tr tr>><<td<>[ ]</td td>><Deprecated</td></tr tr tr>><<td>⎋</td td>><Restricted to surface input mode</td></tr tr<>><td>⎆</td td><>Restricted to surface output mode</td></tr tr><<>td>▧</td td><>Restricted to ByteBuffer input mode</td></tr tr><><td>↩</td td><>Restricted to 동기 모드/< td></tr tr><<>td>⇄</td td>><비동기 모드</td></tr tr<>><td>( )</td td><>를 호출할 수 있지만 t</td></tr<>/tbody></table로 제한됩니다.>

<table style="width: 100%;"><thead class=api><tr><th class=deg45><div><div style="background:#4285f4"><div>Uninitialized</div></div></div></th<>class=deg45><div><style="background::#f4b400"><div>Configured</div></div></div></th th<>class=deg45><div><style="background:#e67c73"><div>Flushed</div/div><></div></th th><class=deg45><div div><style="background:#0f9d58"><div>Running</div></div></div></th><class=deg45><div><div style="background:#f7cb4d"><div>End of Stream</div></div></div></th th><class=deg45><div><div style="background:#db4437"><div>Error</div></div></div></th<>class=deg45><div><style="background:#666"><div>Released</div></div></div></th><th></th<>colspan="8">SDK Version</th<>/tr tr><<>th colspan="7">State</th th><>Method</th><>th 16</><>th 17</th>><18</th<>>th 19</th<>>th 20/th 21</thth><>th 21</thth><>22</th>><th 23</th<>/tr<>/thead<>tbody class=api><tr<>td></td td>><</td<>td></td<>td><></><td td/><td><td<><>>< td class=fn/td td class=fn>#createByCodecName createByCodecName</td td><>●</td td<>>●</td><td>●</td td>><●</td td>><●</td<>td>●</td td><>●</td td>><●</td></tr tr<>><td></td<>td></><><td td/<>td td></><><>><><<<>td td td/td><td class=fnn>#createDecoderByType createDecoderByType</td td><>●</td td<>>●</td td>><●</td<>td>●</td td>><●</td<>td>●</td<>td>●/td td><>●<</td<>/tr tr>><<td></<><>td><>< td/td><><><></Td><td></td><td></td td><class=fn>#createEncoderByType createEncoderByType</td td><>●</td td><>●</td td><>●</td<>td>●</td<>td>●</td<>td>●</td><td>●/td td><>●<</td></tr tr tr>><<td></td><td></td><td></td><td></td><td></td><td></td><td>< class=fn#createPersistentInputSurface createPersistentInputSurface<>/td><td<>/td><td><></td td/><td td></td><td></<>td td></><td td></<>>td><td>< td●</td<>/tr tr tr><><td>16+</td><td>-</td<>td>-</td><td>-</td><td>-</td><td> td-<</td<>td> td class=fn>#configure configure</td><td><>●</td td<>>●</td td>●/td><td>><●<</td><td>●</td td<>>⁕</td td<>>●</td td><>●</td<>/tr tr tr<<>>td>-</td td><>18+</td<>td>-</td><td>-</td<>td>-</td<>td>-</td<><>td<> td 클래스=fn>#createInputSurface createInputSurface</Td><td></td><td></td><td>⎋</td td><>⎋</td td>><⎋</td td<>>⎋</td<>td>⎋</td td><>⎋</td></tr tr<>td<>>-<</td><td><> td>16+/td<>td>16+<</td td><td>(16+)</td<>td>-</td><td td<>>< class=fn<>#dequeueInputBuffer dequeueInputBuffer/td td<>>●/td td>●<</td><><td>▧</td<>td▧/td><td>>▧<</td><td>⁕▧↩/td<>td>▧↩</td td>▧↩<</td/><>< tr tr><><td>-</td><td>-</td><td>16+</td td><>16+/td td>><16+<</td><td> td-<</><td td td<>> td class=fn<>#dequeueOutputBuffer dequeueOutputBuffer/td td>><●/td td>●</td><td>><●</td td●<><></Td><td>●</td td>><⁕↩</td td>><↩</td td<>>↩</td></tr tr><td><>-</td td>><< td td><>16+/td td>><16+<</td td<>>16+</td><td>-</td><td>-</td td<>class=fnn>#flush flush</Td><td>●</td td>><●</td td>><●</td td<>>●</td td><>●</td td><>●</td td td><>●</td td>><●</td></tr tr tr>><<td>18+</td td<>>18+</td td>><18+</td td><>18+</Td><td>18+/td td<>>18+<</td<>td>-</td td><class=fn#getCodecInfo getCodecInfo<>/td<>td></>><td<><>●</td<>td>●</td><td>●</td><td>●</td td>●/td<>td>●<</td><<>/tr tr tr><><td>-</td td>><-</td><td>(21+)</td td><>21+</td td>><(21+)</td td<>>-</td><td>-</td><td td class=fn<#getInputBuffer getInputBuffer>/td td><<>/td><td></td<>td></td>><< td/><td<>>< td td><●/td td>><●</td td>><●</td<>/tr tr><td><>-</td td<>td><><> 16+/td<>td>(16+<)</td<>td>(16+)</td><td>-<</td><td> class=fn><#getInputBuffers getInputBuffers/td<>td●><></Td><td>●</td td>><●</td td><>●</td td>><●</td<>td>[⁕↩]</td td>><[↩]</td><td>[↩]</td<>/tr tr><tr<>td>-</td td><>21+</td td><>(21+)</td td>><(21+)</td td td><>(21+)</td<>td>-</td><td>-</td td<>class=fn>#getInputFormat getInputFormat</td td>><</td><td></td<>td></td<>td></<><><>>td●</td><td>●</td td>><●</td></tr tr tr>><<td>-</tdtd>-</td td>><(21+)</td td><>21+</td td><>(21+)</td td>><-</td td><>-</td td td><class=fn#getInputImage getInputImage></td td><<>/td<>td></td><td></td<><>><>< td/td><td td>><<○/td td<>>●</td td<>>●</td></tr tr><td><>18+</td td<>td>18+</td<>td>18+</td<>td><>>18+</td td 18+</td><td>td 18+</td><td>-</td td><class=fn>#getName getName</td td><></td><td><<>> td●</td td><>●</td td<>>●</td td>><●</td td>><●</td td><>●</td<>/tr tr tr><><td>-</td<>>-</td/td><td>(21+)</td td>><21+</td td><>21+</td td><>-</td td><>-</td td><class=fn>#getOutputBuffer getOutputBuffer</td><td></td<>td/><td td></<>td td><></td><td><>>< td●</td td><td><●/td td<>>●</td></tr tr<>tr><td>-</td td><<> td><>16+</td td<>>16+/td td<>>16+<</td td<>>-</td<>td> td< class=fn><#getOutputBuffers getOutputBuffers/td<>td><><●/td td<>>●</td td<>>●</td td>><●</td td<>>●</td<>td>[⁕↩]</td<>td>[↩]/td td<>>[↩]<</td<>/tr tr><tr><td>-</td><td>21+</td><td>16+</td td<>>16+</td td><>16+</td td><-</td>>< td td>><< class=fn#getOutputFormat()<>/td td><> td●</td td<>>●</td<>td>●/td td>●</td><td>><●/<< td td>><●</td td>><●</td td><>●</td></tr tr><><td>-</td td><>-</td td><td>(21+)</td td<>>21+</td td><>21+</td td>><-</td-/td<>>-</td><td class=fn>#getOutputFormat(int)</td td><></td><td></td><td></td><td></><><>td td><●/td td●</td<>td><>>●<</td<>/tr tr<<>>td>-</td<>td>><< td>(21+)</td td><>21+</td td<>>21+</td td>><-</td<>td>-</td td><class=fn><#getOutputImage getOutputImage/td td>><</td<>td></td><td></td><td td></td><td><<>> td○/td td>><●<</td td td><><●/td<>/tr tr<>><td>-</td<>td>-<</td<>td td> 16+/td><td><>>(16+<)</td td><>-/td td<>>-<</td td<>td class=fn<>#queueInputBuffer queueInputBuffer/td td><>●</td td><><●/td td<>>●</td td><>●</td<>td>●</td td><>⁕</td<>td>●</td td<>>●</td<>/tr tr>><<td>-</td<>td>-<</td>>><<td> td 16 이상</Td><td>(16+)</td<>td>-</td<>td>-</td td><class=fn>#queueSecureInputBuffer queueSecureInputBuffer</td td>><●</td td<>>●</td td><>●</td<>td>●</td><td>●/td td><>⁕</td td>><●<</tdtd>●</td></tr tr td><><>16+</td td td><>16+</td td>><16+</td<>td>td<>>16+</td td>><16+</td td><>16+<</td td<>class=fn#release release></td td><td●>><</Td><td>●</td td<>>●</td td>><●</td td<>>●</td td<>>●</td td<>>●</td td><>●</td<>/tr tr<<>>td>-</td><td>-</td><> td-</td td td><>16+</td td<>>16+</td td><>-<</><td><td td> class=fn#releaseOutputBuffer(int, boolean)<>/td td●</td><td>><>●</td><td>●</td td<>>●</td td>><●/td td>><⁕<</td><td>●</td td<>>⁕</td></tr tr><td><>-</td><td>-<</td<>td td>>>< 21+/td td td><>21+<</td td><>-</td td><>-</td td class=fn<>#releaseOutputBuffer(int, long)/td><><td></td><td></td><td></td><td><></<<>>>td⎆</td td>><⎆</td td>><⎆</td<>/tr tr td>>><<21+</td td<>>21+/td td>21+<</td<>td td><>21+</td td<>>21+</td td><>21+</td td>><-</td td<>class=fn#reset reset<>/td td<><>/td><td></td td></><td<>td><><<>>></td●/td td>●<</td<>td td><><●/td></tr tr>><<td>21+</td<>td>-</td<>td>-</td<>td>-</td<>td>-</td td<>>-</td<>td>-</td td><class=fn<#setCallback(Callback) setCallback>/td td><></td/td>><< td td><></Td><td></td><td></td td>><●</td td><>●</td><td#setCallback(Callback, Handler) &#8277;></td></tr tr<<>>td<> td><>23+</td td>><-</td td><>-/td<>td-</td td>>-</td-/td<>/td-</td><td>-</td td<>class=fn><#setInputSurface setInputSurface/td><td></td><td></td><td></td><td></td><td></td><td></td><td td>><>< td⎋</td></tr tr<>td>><23+</td td>23+</td><><td>23+</td td>><23+</td td>><23+</td td>><(23+)</td td><>(23+)</td td><class=fn#setOnFrameRenderedListener setOnFrameRenderedListener<>/td td<>/td td><<>></td><td></td><td></td><td></td<><><> td td></Td><td○ ⎆/td></tr tr<>td>><-</td td<>>23+</td td>><23+</td td><>23+</td td>><23+</td><td>-</td<>td>-</td td<>class=fn><#setOutputSurface setOutputSurface/td td>><</td/td><></td <>td></td><td></td><td></td><td></td><td></td td><>⎆</td<>/tr tr tr td<>>><19+</td td><>19+</td td>><19+</td td>><19+/td td><>19+<</td td td>><><(19 이상)</td td><>-</td td><class=fn>#setParameters setParameters</td td><<>/td><>< td/>><td>><<●</td td><>●</td td<>●</td td>>><●</td td>●</td><></tr tr><><td>-</td td><>(16+)</td td>><(16+)</td td>><16+</td td<>>(16+)</td><td>(16+)</td<>td>< td class=fn#setVideoScalingMode setVideoScalingMode></td><td<>>⎆/td td><>⎆</td td>⎆<</td><><td>⎆</td td><>⎆</td td>><⎆</td<>td>⎆</td td>><⎆</td<>/tr tr<>tr><td>(29+)</td td><>29+</td td<>>29+</td td 29+</td<>><td>>(29+)/< td td>><(29+)</td td><>-</td td<>class=fn><#setAudioPresentation setAudioPresentation/td td>><</td><td></td<>td></td<>td></td><td></td><td></td td<>></td<>td></td/tr tr<>tr<>td<>>-/td/<td><td>-</td td><>18+</td td><>18+</td td><>-/td<>td>-<</td<>td>-</td td><td class=fn>#signalEndOfInputStream signalEndOfInputStream</td><td></td><td></><td td>⎋</td td>><⎋/td td⎋<><></Td><td>⎋</td td>><⎋</td td<>>⎋</td<>/tr tr><><td>-</td td td>><16+</td td>><21+(⇄)</td<>td>-</td<>td>-</td><td>-</td><<>td>< td class=fn>#start start</td td><>●</td td>><●</td td><>●</td td><>●</td td><>●</td<>td>⁕</td td>><●</td td>><●</td<>/tr tr td<>>><-/<><>< td td><>16+</td td>><16+</td td>><16+</td td<>>-</td td<>td>><< class=fn#stop stop<>/td td<>>●</td td>●/td<>><td>●</td td●</td><td●<>><></Td><td●/td td>><●</td td<>>●</td></tr></tbody></table <>>

에 대한 Java 설명서입니다 android.media.MediaCodec.

이 페이지의 일부는 만들고 공유하며 에 설명된 조건에 따라 사용되는 작업을 기반으로 수정됩니다.

필드

BufferFlagCodecConfig
사용되지 않음.

이렇게 표시된 버퍼에 미디어 데이터 대신 코덱 초기화/코덱 특정 데이터가 포함됨을 나타냅니다.

BufferFlagDecodeOnly
사용되지 않음.

이는 버퍼가 디코딩되고 디코더의 내부 상태를 업데이트하지만 출력 버퍼를 생성하지 않음을 나타냅니다.

BufferFlagEndOfStream
사용되지 않음.

스트림의 끝을 신호로 표시합니다. i.

BufferFlagKeyFrame
사용되지 않음.

이는 로 표시된 (인코딩된) 버퍼에 키 프레임에 대한 데이터가 포함되어 있음을 나타냅니다.

BufferFlagPartialFrame
사용되지 않음.

이는 버퍼에 프레임의 일부만 포함되어 있음을 나타내며 디코더는 프레임을 디코딩하기 전에 이 플래그가 없는 버퍼가 나타날 때까지 데이터를 일괄 처리해야 합니다.

BufferFlagSyncFrame
사용되지 않음.

이는 로 표시된 (인코딩된) 버퍼에 키 프레임에 대한 데이터가 포함되어 있음을 나타냅니다.

ConfigureFlagEncode
사용되지 않음.

이 코덱을 인코더로 사용하는 경우 이 플래그를 전달합니다.

ConfigureFlagUseBlockModel
사용되지 않음.

이 코덱을 및/또는 HardwareBuffer와 함께 LinearBlock 사용하는 경우 이 플래그를 전달합니다.

ConfigureFlagUseCryptoAsync
사용되지 않음.

이 플래그는 보안 디코더에서만 사용해야 합니다.

CryptoModeAesCbc
사용되지 않음.

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

CryptoModeAesCtr
CryptoModeUnencrypted
InfoOutputBuffersChanged
사용되지 않음.

출력 버퍼가 변경되었습니다. 클라이언트는 이 시점부터 에서 반환된 #getOutputBuffers 새 출력 버퍼 집합을 참조해야 합니다.

InfoOutputFormatChanged
사용되지 않음.

출력 형식이 변경되었습니다. 후속 데이터는 새 형식을 따릅니다.

InfoTryAgainLater
사용되지 않음.

에 대한 호출에서 음수가 아닌 시간 제한이 지정된 경우 호출 #dequeueOutputBuffer시간이 초과되었음을 나타냅니다.

ParameterKeyHdr10PlusInfo

대기 중인 다음 입력 프레임에서 HDR10+ 메타데이터를 설정합니다.

ParameterKeyLowLatency

짧은 대기 시간 디코딩 모드를 사용하거나 사용하지 않도록 설정합니다.

ParameterKeyOffsetTime

타임스탬프 위에 추가할 오프셋(마이크로초)을 지정합니다.

ParameterKeyRequestSyncFrame

인코더가 동기화 프레임 "soon"을 생성할 것을 요청합니다.

ParameterKeySuspend

입력 데이터의 인코딩을 일시적으로 일시 중단/다시 시작합니다.

ParameterKeySuspendTime

이 있는 경우 #PARAMETER_KEY_SUSPEND 클라이언트는 필요에 따라 이 키를 사용하여 일시 중단/다시 시작 작업이 적용되는 타임스탬프(마이크로초)를 지정할 수도 있습니다.

ParameterKeyTunnelPeek

가 일시 중지되는 동안 로 터널 모드 MediaFormat#KEY_AUDIO_SESSION_ID 에 대해 코덱이 구성된 경우 첫 번째 프레임의 비디오 피킹을 AudioTrack 제어합니다.

ParameterKeyVideoBitrate

비디오 인코더의 대상 비트 전송률을 즉시 변경합니다.

VideoScalingModeScaleToFit
사용되지 않음.

콘텐츠가 표면 크기로 조정됩니다.

VideoScalingModeScaleToFitWithCropping
사용되지 않음.

콘텐츠의 크기를 조정하고 가로 세로 비율을 유지하며, 전체 노출 영역이 사용되고, 콘텐츠가 잘려질 수 있습니다.

속성

CanonicalName

기본 코덱 이름을 검색합니다.

Class

Object의 런타임 클래스를 반환합니다.

(다음에서 상속됨 Object)
CodecInfo

코덱 정보를 가져옵니다.

Handle

기본 Android instance 대한 핸들입니다.

(다음에서 상속됨 Object)
InputFormat

를 반환한 후 #configure 를 호출하여 코덱에서 허용하는 입력 형식을 가져옵니다.

JniIdentityHashCode

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
JniPeerMembers

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

Metrics

현재 코덱 instance 대한 메트릭 데이터를 반환합니다.

Name

코덱 이름을 검색합니다.

OutputFormat

dequeueOutputBuffer가 을 반환하여 형식 변경 신호를 보낸 후 이를 호출합니다 #INFO_OUTPUT_FORMAT_CHANGED.

PeerReference

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
SupportedVendorParameters

공급업체 매개 변수 이름 목록을 반환합니다.

ThresholdClass

이 API는 Android용 Mono 인프라를 지원하며 코드에서 직접 사용할 수 없습니다.

(다음에서 상속됨 Object)
ThresholdType

이 API는 Android용 Mono 인프라를 지원하며 코드에서 직접 사용할 수 없습니다.

(다음에서 상속됨 Object)

메서드

Clone()

이 개체의 복사본을 만들고 반환합니다.

(다음에서 상속됨 Object)
Configure(MediaFormat, Surface, MediaCodecConfigFlags, MediaDescrambler)

descrambler와 함께 사용할 구성 요소를 구성합니다.

Configure(MediaFormat, Surface, MediaCrypto, MediaCodecConfigFlags)

구성 요소를 구성합니다.

CreateByCodecName(String)

인스턴스화하려는 구성 요소의 정확한 이름을 알고 있는 경우 이 메서드를 사용하여 인스턴스화합니다.

CreateDecoderByType(String)

지정된 mime 형식의 입력 데이터를 지원하는 기본 디코더를 인스턴스화합니다.

CreateEncoderByType(String)

지정된 mime 형식의 출력 데이터를 지원하는 기본 인코더를 인스턴스화합니다.

CreateInputSurface()

입력 버퍼 대신 인코더에 대한 입력으로 사용할 Surface를 요청합니다.

CreatePersistentInputSurface()

일반적으로 비디오 인코더와 같은 입력 표면이 있는 코덱과 함께 사용할 수 있는 영구 입력 표면을 만듭니다.

DequeueInputBuffer(Int64)

유효한 데이터로 채울 입력 버퍼의 인덱스 또는 현재 사용할 수 있는 버퍼가 없는 경우 -1을 반환합니다.

DequeueOutputBuffer(MediaCodec+BufferInfo, Int64)

출력 버퍼를 큐에서 제거하여 최대 "timeoutUs" 마이크로초를 차단합니다.

Dispose()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
Dispose(Boolean)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
Equals(Object)

다른 개체가 이 개체와 "같음"인지 여부를 나타냅니다.

(다음에서 상속됨 Object)
Flush()

구성 요소의 입력 및 출력 포트를 모두 플러시합니다.

GetHashCode()

개체의 해시 코드 값을 반환합니다.

(다음에서 상속됨 Object)
GetInputBuffer(Int32)

큐에서 java.nio.Buffer#clear cleared제거된 입력 버퍼 인덱스에 대한 쓰기 가능한 ByteBuffer 개체를 반환하여 입력 데이터를 포함합니다.

GetInputBuffers()
사용되지 않음.

입력 버퍼 집합을 검색합니다.

GetInputImage(Int32)

원시 입력 비디오 프레임을 포함하도록 큐에서 벗긴 입력 버퍼 인덱스용 쓰기 가능한 Image 개체를 반환합니다.

GetOutputBuffer(Int32)

큐에서 해제된 출력 버퍼 인덱스에 대한 읽기 전용 ByteBuffer를 반환합니다.

GetOutputBuffers()
사용되지 않음.

출력 버퍼 집합을 검색합니다.

GetOutputFormat(Int32)

특정 출력 버퍼의 출력 형식을 반환합니다.

GetOutputFrame(Int32)

OutputFrame 개체를 반환합니다.

GetOutputImage(Int32)

원시 비디오 프레임을 포함하는 큐에서 해제된 출력 버퍼 인덱스에 대한 읽기 전용 Image 개체를 반환합니다.

GetParameterDescriptor(String)

이름이 인 매개 변수를 설명합니다.

GetQueueRequest(Int32)

QueueRequest 입력 슬롯 인덱스 개체를 반환합니다.

JavaFinalize()

가비지 수집에서 개체에 대한 참조가 더 이상 없다고 판단할 때 개체의 가비지 수집기에서 호출됩니다.

(다음에서 상속됨 Object)
MapHardwareBuffer(HardwareBuffer)

버퍼의 콘텐츠에 HardwareBufferImage액세스할 수 있도록 개체를 에 매핑합니다.

Notify()

이 개체의 모니터에서 대기 중인 단일 스레드를 해제합니다.

(다음에서 상속됨 Object)
NotifyAll()

이 개체의 모니터에서 대기 중인 모든 스레드를 해제합니다.

(다음에서 상속됨 Object)
QueueInputBuffer(Int32, Int32, Int32, Int64, MediaCodecBufferFlags)

지정된 인덱스에서 입력 버퍼의 범위를 채운 후 구성 요소에 제출합니다.

QueueSecureInputBuffer(Int32, Int32, MediaCodec+CryptoInfo, Int64, MediaCodecBufferFlags)

#queueInputBuffer queueInputBuffer 유사하지만 잠재적으로 암호화된 버퍼를 제출합니다.

Release()

코덱 instance 사용하는 리소스를 확보합니다.

ReleaseOutputBuffer(Int32, Boolean)

버퍼를 완료한 경우 이 호출을 사용하여 버퍼를 코덱으로 반환하거나 출력 화면에서 렌더링합니다.

ReleaseOutputBuffer(Int32, Int64)

버퍼를 완료한 경우 이 호출을 사용하여 표면 타임스탬프를 업데이트하고 코덱으로 반환하여 출력 화면에 렌더링합니다.

Reset()

코덱을 초기(초기화되지 않음) 상태로 반환합니다.

SetAudioPresentation(AudioPresentation)

오디오 프레젠테이션을 설정합니다.

SetCallback(MediaCodec+Callback)

기본 루퍼에서 실행 가능한 MediaCodec 이벤트에 대한 비동기 콜백을 설정합니다.

SetCallback(MediaCodec+Callback, Handler)

기본 루퍼에서 실행 가능한 MediaCodec 이벤트에 대한 비동기 콜백을 설정합니다.

SetHandle(IntPtr, JniHandleOwnership)

Handle 속성을 설정합니다.

(다음에서 상속됨 Object)
SetInputSurface(Surface)

코덱을 구성합니다(예:

SetOnFirstTunnelFrameReadyListener(Handler, MediaCodec+IOnFirstTunnelFrameReadyListener)

첫 번째 출력 프레임이 디코딩되고 를 사용하여 터널 모드 KEY_AUDIO_SESSION_ID로 구성된 코덱에서 렌더링할 준비가 되었을 때 호출할 콜백을 등록합니다.

SetOnFrameRenderedListener(MediaCodec+IOnFrameRenderedListener, Handler)

출력 프레임이 출력 화면에 렌더링될 때 호출할 콜백을 등록합니다.

SetOutputSurface(Surface)

코덱의 출력 표면을 동적으로 설정합니다.

SetParameters(Bundle)

구성 요소 instance 추가 매개 변수 변경 내용을 전달합니다.

SetVideoScalingMode(VideoScalingMode)

이전 호출에서 surface를 지정한 경우 를 사용하여 #configure 사용할 크기 조정 모드를 지정합니다.

SignalEndOfInputStream()

입력 시 스트림 끝 신호를 보냅니다.

Start()

구성 요소를 성공적으로 구성한 후 를 호출합니다 start.

Stop()

디코딩/인코딩 세션을 완료합니다. 코덱 instance 활성 상태로 유지되고 다시 ed를 사용할 준비가 된 상태로 유지됩니다#start.

SubscribeToVendorParameters(IList<String>)

공급업체 매개 변수를 구독하여 이러한 매개 변수가 에 표시 #getOutputFormat 되고 이러한 매개 변수를 변경하면 출력 형식 변경 이벤트가 생성됩니다.

ToArray<T>()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
ToString()

개체의 문자열 표현을 반환합니다.

(다음에서 상속됨 Object)
UnregisterFromRuntime()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
UnsubscribeFromVendorParameters(IList<String>)

공급업체 매개 변수에서 구독을 취소하여 이러한 매개 변수가 존재하지 #getOutputFormat 않고 이러한 매개 변수를 변경하면 더 이상 출력 형식 변경 이벤트가 생성되지 않습니다.

Wait()

현재 스레드가 각성될 때까지 대기하도록 합니다. 일반적으로 <알림을<> 받>거나<<> 중단/em>합니다.

(다음에서 상속됨 Object)
Wait(Int64)

현재 스레드가 깨어날 때까지 대기하게 하며, 일반적으로 <알림을 받<>거나 중단</>em>>을 받거나 <일정량의 실시간이 경과할 때까지 대기합니다.

(다음에서 상속됨 Object)
Wait(Int64, Int32)

현재 스레드가 깨어날 때까지 대기하게 하며, 일반적으로 <알림을 받<>거나 중단</>em>>을 받거나 <일정량의 실시간이 경과할 때까지 대기합니다.

(다음에서 상속됨 Object)

명시적 인터페이스 구현

IJavaPeerable.Disposed()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.DisposeUnlessReferenced()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.Finalized()

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.JniManagedPeerState

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.SetJniIdentityHashCode(Int32)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.SetJniManagedPeerState(JniManagedPeerStates)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)
IJavaPeerable.SetPeerReference(JniObjectReference)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

(다음에서 상속됨 Object)

확장 메서드

JavaCast<TResult>(IJavaObject)

Android 런타임 확인 형식 변환을 수행합니다.

JavaCast<TResult>(IJavaObject)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

GetJniTypeName(IJavaPeerable)

MediaCodec 클래스를 사용하여 하위 수준 미디어 코덱에 액세스할 수 있습니다. i.

적용 대상