2016-06-15 4 views
0

삼성 S6에서 h264 스트림 디코 딕에 mediacodec을 사용하고 있습니다. 안드로이드 5.1.1에서 mediacodec의 입력 버퍼가 "0001"으로 시작해야합니다 (pps, sps를 설정할 필요가 없습니다) , 또는 ACodec에서 오류를보고합니다.mediacodec 디코딩 h264 스트림 제한

또한 mediaextractor를 사용하여 mp4 파일을 재생하려고했으나 정상적으로 작동하지만 mediacodec의 버퍼가 "0001"로 시작하지 않습니다.

왜 decodec h264 스트림에는 이러한 제한이 있는지 알지 못합니다. 현재 소켓에서 스트림을 분석하고 데이터를 작은 패키지 (각 패키지가 0001로 시작)로 잘라서 mediacodec에 제공해야하지만 비효율적이다.

MediaFormat format = MediaFormat.createVideoFormat(MediaFormat.MIMETYPE_VIDEO_AVC, 1024, 1024); 
+0

MediaCodec은 NAL 단위로 작동합니다. 시작 접두사가 필요합니다. 참조 http://stackoverflow.com/questions/1685494/what-does-this-h264-nal-header-mean – fadden

답변

0

일부 특정 디코더는 (시작 코드의 다른 종류의)은 "MP4"포맷 H264 NAL 단위를 디코딩 할 수도 있지만, 모든 장치에 걸쳐 보장 아니에요.

Samsung의 MediaExtractor 버전은 자신의 디코더에서 처리 할 수있는 경우이 형식으로 반환 할 수 있습니다. 적어도 삼성이 MediaExtractor 버전으로 타임 스탬프가있는 비표준 방식을 사용한 예가 있습니다. https://code.google.com/p/android/issues/detail?id=74356.

(MediaExtractor가 현재 장치의 디코더 만 처리 할 수있는 데이터를 반환하는 것은 MediaExtractor를 사용하여 파일을 읽지 만 네트워크를 통해 압축 된 데이터를 다른 장치로 보내 디코딩 할 수 있기 때문에 잘못된 IMO입니다. 이 경우, 비표준 형식의 데이터를 반환하는 것은 잘못된 것입니다.)

fadden이 쓴 것처럼 MediaCodec은 전체 NAL 단위로 작동하므로 비효율적이라고 생각하는 경우에도이 형식으로 데이터를 제공해야합니다. 이 정보 (프레임 경계에 관한)를 쉽게 사용할 수없는 형식으로 소켓을 통해 데이터를 수신하는 경우 MediaCodec 자체가 아니라 프로토콜 형식 (예 : RTP 수신 구현이 쉽지 않음)에 문제가있는 형식으로 데이터를 수신하면 - 전체 프레임을 가질 때까지 임의의 청크를 공급할 수있는 대신 전체 프레임을 디코딩하기 전에 필요로하는 상당히 일반적인 제한 사항입니다. 이것은 자신의 구현이 비효율적 인 경우가 아니면 비효율적이어서는 안됩니다.

0

일반적으로 안드로이드는 각 입력에 대해 nal 단위를 기대합니다. 일부 장치의 경우 h264의 미디어 형식에 csd-0/1을 설정하면 일관되게 작동하지 않습니다. 그러나 각 매개 변수 세트를 입력 버퍼로 공급하는 경우 미디어 코덱은 형식 변경으로이를 선택합니다.

int outputBufferIndex = NativeDecoder.DequeueOutputBuffer (info, 1000); 
if (outputBufferIndex == (int)MediaCodec.InfoOutputFormatChanged) { 
    Console.WriteLine ("Format changed: {0}", NativeDecoder.OutputFormat); 
} else if (outputBufferIndex >= 0) { 
    CodecOutputBufferAvailable (NativeDecoder, outputBufferIndex, info); 
} 

또한이 설정 넥서스와 다른 삼성 기기에 대한 필수입니다주의 :

formatDescription.SetInteger(MediaFormat.KeyWidth, SelectedPalette.Value.Width); 
formatDescription.SetInteger(MediaFormat.KeyHeight, SelectedPalette.Value.Height); 
formatDescription.SetInteger(MediaFormat.KeyMaxInputSize, SelectedPalette.Value.Width * SelectedPalette.Value.Height); 

나는 이러한 해상도를 조회 할 수 있습니다 내 상황에서 운입니다. 그러나 SPS 및 PPS nal 단위에서 수동으로 해상도를 파싱 할 수 있습니다.

// 참고 여기서 Xamarin을 사용하고 있습니다. 그러나 전화와 사물은 거의 같습니다. 나는 iOS VideoToolbox Xamarin Wrapper에 버그가 있음을 확신합니다. 그렇습니다. 비디오 디코딩을 위해 Xamarin을 고려해 본 점을 명심하십시오. 모든 것을위한 그 위대한하지만 아무것도 조금 더 정의 또는 낮은 수준 thats.