-
Notifications
You must be signed in to change notification settings - Fork 24
Expand file tree
/
Copy pathAvcDecoder.java
More file actions
113 lines (96 loc) · 3.83 KB
/
Copy pathAvcDecoder.java
File metadata and controls
113 lines (96 loc) · 3.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package com.avc.demo;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.Vector;
import android.annotation.SuppressLint;
import android.media.MediaCodec;
import android.media.MediaCodecInfo;
import android.media.MediaFormat;
import android.util.Log;
import android.view.SurfaceHolder;
@SuppressLint("NewApi")
public class AvcDecoder {
private MediaCodec mediaCodec;
int mCount = 0;
Vector mVector;
byte[] nv12;
public AvcDecoder(int width, int height, SurfaceHolder surfaceHolder) {
Log.d("Codec", "AvcDecoder IN");
try {
mediaCodec = MediaCodec.createDecoderByType("video/avc");
MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height);
nv12 = new byte[width * height * 3 / 2];
mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar);
//mediaCodec.configure(mediaFormat, surfaceHolder.getSurface(), null, 0);
mediaCodec.configure(mediaFormat, null, null, 0);
mediaCodec.start();
MyThread mThread = new MyThread();
mVector = new Vector(50);
mThread.start();
Log.d("Codec", "AvcDecoder OUT");
} catch (IOException e) {
e.printStackTrace();
}
}
public void pushData(byte[] buf, int length) {
if (length > 0) {
MyStruct mMyStruct = new MyStruct();
mMyStruct.h264data = new byte[length];
System.arraycopy(buf, 0, mMyStruct.h264data, 0, length);
mMyStruct.size = length;
mVector.add(mMyStruct);
byte[] str = new byte[100];
System.arraycopy(mMyStruct.h264data, 0, str, 0, 100);
Log.d("Decoder", "pos: " + mMyStruct.size + "m_info: " + Arrays.toString(str));
}
}
public void onFrame(byte[] buf, int length) {
ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers();
ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers();
int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1);
Log.d("Decoder", "inputBufferIndex: " + inputBufferIndex);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(buf, 0, length);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, length, mCount * 1000000, 0);
mCount++;
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
while (outputBufferIndex >= 0) {
outputBuffers[outputBufferIndex].get(nv12 , 0 , nv12.length);
CallbackAdapt.UpdateH264Decode(nv12, outputBufferIndex);
mediaCodec.releaseOutputBuffer(outputBufferIndex, false);
outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0);
}
}
public void close() {
try {
mediaCodec.stop();
mediaCodec.release();
} catch (Exception e) {
e.printStackTrace();
}
}
class MyThread extends Thread {
public void run() {
while (true) {
//Log.d("Codec", "Codec thread start!");
if (mVector.size() >= 1) {
MyStruct mMyStruct = (MyStruct) mVector.get(0);
onFrame(mMyStruct.h264data, mMyStruct.size);
mVector.remove(0);
} else {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
}
}