Check for correct frame ordering
Check that B frames come out of the decoder in the correct order,
for both fragmented and non-fragmented h264 mp4 files.
The new test files were created with:
ffmpeg -i video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz.mp4\
-f mp4 -vcodec h264 -profile:main -acodec copy video_h264_main_b_frames.mp4
and
ffmpeg -i video_h264_main_b_frames.mp4 -f mp4\
-movflags frag_keyframe+empty_moov -codec copy\
video_h264_main_b_frames_frag.mp4
Change-Id: I33b4ced8688ab606689d7e8390caf1082c9df0c1
diff --git a/tests/tests/media/res/raw/video_h264_main_b_frames.mp4 b/tests/tests/media/res/raw/video_h264_main_b_frames.mp4
new file mode 100644
index 0000000..448ad3c
--- /dev/null
+++ b/tests/tests/media/res/raw/video_h264_main_b_frames.mp4
Binary files differ
diff --git a/tests/tests/media/res/raw/video_h264_main_b_frames_frag.mp4 b/tests/tests/media/res/raw/video_h264_main_b_frames_frag.mp4
new file mode 100644
index 0000000..b54a4d6c
--- /dev/null
+++ b/tests/tests/media/res/raw/video_h264_main_b_frames_frag.mp4
Binary files differ
diff --git a/tests/tests/media/src/android/media/cts/DecoderTest.java b/tests/tests/media/src/android/media/cts/DecoderTest.java
index 0b6e0d7..c870a53 100644
--- a/tests/tests/media/src/android/media/cts/DecoderTest.java
+++ b/tests/tests/media/src/android/media/cts/DecoderTest.java
@@ -133,6 +133,62 @@
R.raw.video_480x360_mp4_h264_1350kbps_30fps_aac_stereo_128kbps_44100hz_dash);
}
+ public void testBFrames() throws Exception {
+ testBFrames(R.raw.video_h264_main_b_frames);
+ testBFrames(R.raw.video_h264_main_b_frames_frag);
+ }
+
+ public void testBFrames(int res) throws Exception {
+ AssetFileDescriptor fd = mResources.openRawResourceFd(res);
+ MediaExtractor ex = new MediaExtractor();
+ ex.setDataSource(fd.getFileDescriptor(), fd.getStartOffset(), fd.getLength());
+ MediaFormat format = ex.getTrackFormat(0);
+ String mime = format.getString(MediaFormat.KEY_MIME);
+ assertTrue("not a video track. Wrong test file?", mime.startsWith("video/"));
+ MediaCodec dec = MediaCodec.createDecoderByType(mime);
+ Surface s = getActivity().getSurfaceHolder().getSurface();
+ dec.configure(format, s, null, 0);
+ dec.start();
+ ByteBuffer[] buf = dec.getInputBuffers();
+ ex.selectTrack(0);
+ MediaCodec.BufferInfo info = new MediaCodec.BufferInfo();
+ long lastPresentationTimeUsFromExtractor = -1;
+ long lastPresentationTimeUsFromDecoder = -1;
+ boolean inputoutoforder = false;
+ while(true) {
+ int flags = ex.getSampleFlags();
+ long time = ex.getSampleTime();
+ if (time >= 0 && time < lastPresentationTimeUsFromExtractor) {
+ inputoutoforder = true;
+ }
+ lastPresentationTimeUsFromExtractor = time;
+ int bufidx = dec.dequeueInputBuffer(5000);
+ if (bufidx >= 0) {
+ int n = ex.readSampleData(buf[bufidx], 0);
+ if (n < 0) {
+ flags = MediaCodec.BUFFER_FLAG_END_OF_STREAM;
+ time = 0;
+ n = 0;
+ }
+ dec.queueInputBuffer(bufidx, 0, n, time, flags);
+ ex.advance();
+ }
+ int status = dec.dequeueOutputBuffer(info, 5000);
+ if (status >= 0) {
+ if ((info.flags & MediaCodec.BUFFER_FLAG_END_OF_STREAM) != 0) {
+ break;
+ }
+ assertTrue("out of order timestamp from decoder",
+ info.presentationTimeUs > lastPresentationTimeUsFromDecoder);
+ dec.releaseOutputBuffer(status, true);
+ lastPresentationTimeUsFromDecoder = info.presentationTimeUs;
+ }
+ }
+ assertTrue("extractor timestamps were ordered, wrong test file?", inputoutoforder);
+ dec.release();
+ ex.release();
+ }
+
private void testTrackSelection(int resid) throws Exception {
AssetFileDescriptor fd1 = null;
try {