├── bin ├── classes.dex ├── resources.ap_ ├── MediaEncodeAndDecodeDemo.apk ├── jarlist.cache ├── res │ └── crunch │ │ ├── drawable-hdpi │ │ └── ic_launcher.png │ │ ├── drawable-mdpi │ │ └── ic_launcher.png │ │ ├── drawable-xhdpi │ │ └── ic_launcher.png │ │ └── drawable-xxhdpi │ │ └── ic_launcher.png ├── dexedLibs │ └── android-support-v4-09d91030209f51de15a0c3efa0f6dac2.jar └── AndroidManifest.xml ├── ic_launcher-web.png ├── libs └── android-support-v4.jar ├── res ├── drawable-hdpi │ └── ic_launcher.png ├── drawable-mdpi │ └── ic_launcher.png ├── drawable-xhdpi │ └── ic_launcher.png ├── drawable-xxhdpi │ └── ic_launcher.png ├── values │ ├── dimens.xml │ ├── strings.xml │ └── styles.xml ├── values-v11 │ └── styles.xml ├── menu │ └── main.xml ├── values-w820dp │ └── dimens.xml ├── values-v14 │ └── styles.xml └── layout │ ├── activity_encode.xml │ ├── activity_decode.xml │ └── activity_main.xml ├── .settings └── org.eclipse.core.resources.prefs ├── .classpath ├── project.properties ├── proguard-project.txt ├── .project ├── src └── com │ └── example │ └── mediaencodeanddecodedemo │ ├── MainActivity.java │ ├── AvcEncoder.java │ ├── EncodeActivity.java │ └── DecodeActivity.java └── AndroidManifest.xml /bin/classes.dex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/classes.dex -------------------------------------------------------------------------------- /bin/resources.ap_: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/resources.ap_ -------------------------------------------------------------------------------- /ic_launcher-web.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/ic_launcher-web.png -------------------------------------------------------------------------------- /libs/android-support-v4.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/libs/android-support-v4.jar -------------------------------------------------------------------------------- /bin/MediaEncodeAndDecodeDemo.apk: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/MediaEncodeAndDecodeDemo.apk -------------------------------------------------------------------------------- /res/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/res/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/res/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/res/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /res/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/res/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/jarlist.cache: -------------------------------------------------------------------------------- 1 | # cache for current jar dependency. DO NOT EDIT. 2 | # format is 3 | # Encoding is UTF-8 4 | -------------------------------------------------------------------------------- /bin/res/crunch/drawable-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/res/crunch/drawable-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/res/crunch/drawable-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/res/crunch/drawable-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /bin/res/crunch/drawable-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/res/crunch/drawable-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /.settings/org.eclipse.core.resources.prefs: -------------------------------------------------------------------------------- 1 | eclipse.preferences.version=1 2 | encoding//src/com/example/mediaencodeanddecodedemo/EncodeActivity.java=UTF-8 3 | encoding/=UTF-8 4 | -------------------------------------------------------------------------------- /bin/dexedLibs/android-support-v4-09d91030209f51de15a0c3efa0f6dac2.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/love-xunmeng/MediaCodecDemo/HEAD/bin/dexedLibs/android-support-v4-09d91030209f51de15a0c3efa0f6dac2.jar -------------------------------------------------------------------------------- /res/values/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 16dp 5 | 16dp 6 | 7 | 8 | -------------------------------------------------------------------------------- /res/values/strings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | MediaEncodeAndDecodeDemo 5 | Hello world! 6 | Settings 7 | 8 | 9 | -------------------------------------------------------------------------------- /res/values-v11/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/menu/main.xml: -------------------------------------------------------------------------------- 1 | 4 | 5 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /res/values-w820dp/dimens.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 64dp 9 | 10 | 11 | -------------------------------------------------------------------------------- /res/values-v14/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 8 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /res/layout/activity_encode.xml: -------------------------------------------------------------------------------- 1 | 7 | 8 | 12 | 13 | -------------------------------------------------------------------------------- /res/layout/activity_decode.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 8 | 9 | 13 | 14 | 18 | 19 | -------------------------------------------------------------------------------- /project.properties: -------------------------------------------------------------------------------- 1 | # This file is automatically generated by Android Tools. 2 | # Do not modify this file -- YOUR CHANGES WILL BE ERASED! 3 | # 4 | # This file must be checked in Version Control Systems. 5 | # 6 | # To customize properties used by the Ant build system edit 7 | # "ant.properties", and override values to adapt the script to your 8 | # project structure. 9 | # 10 | # To enable ProGuard to shrink and obfuscate your code, uncomment this (available properties: sdk.dir, user.home): 11 | #proguard.config=${sdk.dir}/tools/proguard/proguard-android.txt:proguard-project.txt 12 | 13 | # Project target. 14 | target=android-22 15 | -------------------------------------------------------------------------------- /res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 7 | 14 | 15 | 16 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /proguard-project.txt: -------------------------------------------------------------------------------- 1 | # To enable ProGuard in your project, edit project.properties 2 | # to define the proguard.config property as described in that file. 3 | # 4 | # Add project specific ProGuard rules here. 5 | # By default, the flags in this file are appended to flags specified 6 | # in ${sdk.dir}/tools/proguard/proguard-android.txt 7 | # You can edit the include path and order by changing the ProGuard 8 | # include property in project.properties. 9 | # 10 | # For more details, see 11 | # http://developer.android.com/guide/developing/tools/proguard.html 12 | 13 | # Add any project specific keep options here: 14 | 15 | # If your project uses WebView with JS, uncomment the following 16 | # and specify the fully qualified class name to the JavaScript interface 17 | # class: 18 | #-keepclassmembers class fqcn.of.javascript.interface.for.webview { 19 | # public *; 20 | #} 21 | -------------------------------------------------------------------------------- /.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | MediaCodecDemo 4 | 5 | 6 | 7 | 8 | 9 | com.android.ide.eclipse.adt.ResourceManagerBuilder 10 | 11 | 12 | 13 | 14 | com.android.ide.eclipse.adt.PreCompilerBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.jdt.core.javabuilder 20 | 21 | 22 | 23 | 24 | com.android.ide.eclipse.adt.ApkBuilder 25 | 26 | 27 | 28 | 29 | 30 | com.android.ide.eclipse.adt.AndroidNature 31 | org.eclipse.jdt.core.javanature 32 | 33 | 34 | -------------------------------------------------------------------------------- /res/layout/activity_main.xml: -------------------------------------------------------------------------------- 1 | 10 | 11 | 17 | 18 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /src/com/example/mediaencodeanddecodedemo/MainActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.mediaencodeanddecodedemo; 2 | 3 | import android.app.Activity; 4 | import android.content.Intent; 5 | import android.os.Bundle; 6 | import android.view.Menu; 7 | import android.view.MenuItem; 8 | import android.view.View; 9 | import android.widget.Button; 10 | 11 | public class MainActivity extends Activity { 12 | 13 | private Button btnEncode = null; 14 | private Button btnDecode = null; 15 | 16 | @Override 17 | protected void onCreate(Bundle savedInstanceState) { 18 | super.onCreate(savedInstanceState); 19 | setContentView(R.layout.activity_main); 20 | 21 | initWidgets(); 22 | } 23 | 24 | private void initWidgets(){ 25 | btnEncode = (Button)findViewById(R.id.btnEncode); 26 | btnEncode.setOnClickListener(new View.OnClickListener() { 27 | 28 | @Override 29 | public void onClick(View v) { 30 | Intent intent = new Intent(); 31 | intent.setClass(MainActivity.this, EncodeActivity.class); 32 | startActivity(intent); 33 | } 34 | }); 35 | 36 | btnDecode = (Button)findViewById(R.id.btnDecode); 37 | btnDecode.setOnClickListener(new View.OnClickListener() { 38 | @Override 39 | public void onClick(View v) { 40 | Intent intent = new Intent(); 41 | intent.setClass(MainActivity.this, DecodeActivity.class); 42 | startActivity(intent); 43 | } 44 | }); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /bin/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 26 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /src/com/example/mediaencodeanddecodedemo/AvcEncoder.java: -------------------------------------------------------------------------------- 1 | package com.example.mediaencodeanddecodedemo; 2 | 3 | import java.io.IOException; 4 | import java.nio.ByteBuffer; 5 | 6 | import android.annotation.SuppressLint; 7 | import android.media.MediaCodec; 8 | import android.media.MediaCodecInfo; 9 | import android.media.MediaFormat; 10 | import android.util.Log; 11 | 12 | public class AvcEncoder 13 | { 14 | 15 | private MediaCodec mediaCodec; 16 | int m_width; 17 | int m_height; 18 | byte[] m_info = null; 19 | 20 | 21 | private byte[] yuv420 = null; 22 | @SuppressLint("NewApi") 23 | public AvcEncoder(int width, int height, int framerate, int bitrate) throws IOException { 24 | 25 | m_width = width; 26 | m_height = height; 27 | yuv420 = new byte[width*height*3/2]; 28 | 29 | mediaCodec = MediaCodec.createEncoderByType("video/avc"); 30 | MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, height); 31 | mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, bitrate); 32 | mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, framerate); 33 | mediaFormat.setInteger(MediaFormat.KEY_COLOR_FORMAT, MediaCodecInfo.CodecCapabilities.COLOR_FormatYUV420SemiPlanar); 34 | mediaFormat.setInteger(MediaFormat.KEY_I_FRAME_INTERVAL, 1); 35 | 36 | mediaCodec.configure(mediaFormat, null, null, MediaCodec.CONFIGURE_FLAG_ENCODE); 37 | mediaCodec.start(); 38 | } 39 | 40 | @SuppressLint("NewApi") 41 | public void close() { 42 | try { 43 | mediaCodec.stop(); 44 | mediaCodec.release(); 45 | } catch (Exception e){ 46 | e.printStackTrace(); 47 | } 48 | } 49 | 50 | @SuppressLint("NewApi") 51 | public int offerEncoder(byte[] input, byte[] output) 52 | { 53 | //Log.d("Fuck", "input lenght: " + input.length); 54 | int pos = 0; 55 | //swapYV12toI420(input, yuv420, m_width, m_height); 56 | swapYV12toYUV420SemiPlanar(input, yuv420, m_width, m_height); 57 | try { 58 | ByteBuffer[] inputBuffers = mediaCodec.getInputBuffers(); 59 | ByteBuffer[] outputBuffers = mediaCodec.getOutputBuffers(); 60 | int inputBufferIndex = mediaCodec.dequeueInputBuffer(-1); 61 | if (inputBufferIndex >= 0) 62 | { 63 | ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; 64 | inputBuffer.clear(); 65 | inputBuffer.put(yuv420); 66 | mediaCodec.queueInputBuffer(inputBufferIndex, 0, yuv420.length, 0, 0); 67 | } 68 | 69 | MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); 70 | int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo,0); 71 | while (outputBufferIndex >= 0) 72 | { 73 | ByteBuffer outputBuffer = outputBuffers[outputBufferIndex]; 74 | byte[] outData = new byte[bufferInfo.size]; 75 | outputBuffer.get(outData); 76 | 77 | if(m_info != null) 78 | { 79 | System.arraycopy(outData, 0, output, pos, outData.length); 80 | pos += outData.length; 81 | } 82 | else 83 | { 84 | ByteBuffer spsPpsBuffer = ByteBuffer.wrap(outData); 85 | if (spsPpsBuffer.getInt() == 0x00000001) 86 | { 87 | m_info = new byte[outData.length]; 88 | System.arraycopy(outData, 0, m_info, 0, outData.length); 89 | } 90 | else 91 | { 92 | return -1; 93 | } 94 | } 95 | 96 | mediaCodec.releaseOutputBuffer(outputBufferIndex, false); 97 | outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 0); 98 | } 99 | 100 | if(output[4] == 0x65) //key frame 101 | { 102 | Log.d("Fuck", "key frame"); 103 | System.arraycopy(output, 0, yuv420, 0, pos); 104 | System.arraycopy(m_info, 0, output, 0, m_info.length); 105 | Log.d("Fuck", "m_info.length: " + m_info.length); 106 | System.arraycopy(yuv420, 0, output, m_info.length, pos); 107 | pos += m_info.length; 108 | }else{ 109 | //Log.d("Fuck", "NOT key frame"); 110 | } 111 | 112 | } catch (Throwable t) { 113 | t.printStackTrace(); 114 | } 115 | 116 | return pos; 117 | } 118 | 119 | private void swapYV12toI420(byte[] yv12bytes, byte[] i420bytes, int width, int height) 120 | { 121 | System.arraycopy(yv12bytes, 0, i420bytes, 0,width*height); 122 | System.arraycopy(yv12bytes, width*height+width*height/4, i420bytes, width*height,width*height/4); 123 | System.arraycopy(yv12bytes, width*height, i420bytes, width*height+width*height/4,width*height/4); 124 | } 125 | 126 | private void swapYV12toYUV420SemiPlanar(byte[] yv12bytes, byte[] i420bytes, int width, int height){ 127 | System.arraycopy(yv12bytes, 0, i420bytes, 0,width*height); 128 | int startPos = width*height; 129 | int yv_start_pos_v = width*height+width; 130 | int yv_start_pos_u = width*height+width*height/4; 131 | for(int i = 0; i < width*height/4; i++){ 132 | i420bytes[startPos + 2 * i + 0] = yv12bytes[yv_start_pos_u + i]; 133 | i420bytes[startPos + 2 * i + 1] = yv12bytes[yv_start_pos_v + i]; 134 | } 135 | } 136 | } -------------------------------------------------------------------------------- /src/com/example/mediaencodeanddecodedemo/EncodeActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.mediaencodeanddecodedemo; 2 | 3 | import java.io.FileNotFoundException; 4 | import java.io.FileOutputStream; 5 | import java.io.IOException; 6 | import java.net.DatagramPacket; 7 | import java.net.DatagramSocket; 8 | import java.net.InetAddress; 9 | import java.net.SocketException; 10 | import java.net.UnknownHostException; 11 | 12 | import android.annotation.SuppressLint; 13 | import android.app.Activity; 14 | import android.graphics.ImageFormat; 15 | import android.hardware.Camera; 16 | import android.hardware.Camera.PreviewCallback; 17 | import android.os.Bundle; 18 | import android.os.StrictMode; 19 | import android.util.Log; 20 | import android.view.Menu; 21 | import android.view.SurfaceHolder; 22 | import android.view.SurfaceView; 23 | import android.view.SurfaceHolder.Callback; 24 | 25 | 26 | @SuppressWarnings("deprecation") 27 | public class EncodeActivity extends Activity implements SurfaceHolder.Callback, PreviewCallback 28 | { 29 | DatagramSocket socket; 30 | InetAddress address; 31 | 32 | AvcEncoder avcCodec; 33 | public Camera m_camera; 34 | SurfaceView m_prevewview; 35 | SurfaceHolder m_surfaceHolder; 36 | int width = 1280; 37 | int height = 720; 38 | int framerate = 5; 39 | int bitrate = 2500000; 40 | //int bitRate = camera.getFpsRange()[1] * currentSize.width * currentSize.height / 15; 41 | 42 | byte[] h264 = new byte[width*height*3/2]; 43 | 44 | private FileOutputStream file = null; 45 | private String filename = "/sdcard/camera.h264"; 46 | private int byteOffset = 0; 47 | private long lastTime = 0; 48 | 49 | @SuppressLint("NewApi") 50 | @Override 51 | protected void onCreate(Bundle savedInstanceState) { 52 | 53 | StrictMode.setThreadPolicy(new StrictMode.ThreadPolicy.Builder() 54 | .detectDiskReads() 55 | .detectDiskWrites() 56 | .detectAll() // or .detectAll() for all detectable problems 57 | .penaltyLog() 58 | .build()); 59 | StrictMode.setVmPolicy(new StrictMode.VmPolicy.Builder() 60 | .detectLeakedSqlLiteObjects() 61 | .detectLeakedClosableObjects() 62 | .penaltyLog() 63 | .penaltyDeath() 64 | .build()); 65 | 66 | super.onCreate(savedInstanceState); 67 | setContentView(R.layout.activity_encode); 68 | 69 | Log.d("Fuck", "width=" + width+ ", height=" + height + ", framerate=" + framerate + ", bitrate=" + bitrate); 70 | try { 71 | avcCodec = new AvcEncoder(width,height,framerate,bitrate); 72 | } catch (IOException e1) { 73 | Log.d("Fuck", "Fail to AvcEncoder"); 74 | } 75 | m_prevewview = (SurfaceView) findViewById(R.id.surfaceViewPlay); 76 | m_surfaceHolder = m_prevewview.getHolder(); 77 | m_surfaceHolder.setFixedSize(width, height); 78 | m_surfaceHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS); 79 | m_surfaceHolder.addCallback((Callback) this); 80 | 81 | try { 82 | socket = new DatagramSocket(); 83 | address = InetAddress.getByName("192.169.1.222"); 84 | } catch (SocketException e) { 85 | // TODO Auto-generated catch block 86 | e.printStackTrace(); 87 | } catch (UnknownHostException e) { 88 | // TODO Auto-generated catch block 89 | e.printStackTrace(); 90 | } 91 | } 92 | 93 | @Override 94 | public boolean onCreateOptionsMenu(Menu menu) { 95 | // Inflate the menu; this adds items to the action bar if it is present. 96 | getMenuInflater().inflate(R.menu.main, menu); 97 | return true; 98 | } 99 | @Override 100 | public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) 101 | { 102 | 103 | } 104 | 105 | @SuppressLint("NewApi") 106 | @Override 107 | public void surfaceCreated(SurfaceHolder arg0) 108 | { 109 | try 110 | { 111 | m_camera = Camera.open(); 112 | m_camera.setPreviewDisplay(m_surfaceHolder); 113 | Camera.Parameters parameters = m_camera.getParameters(); 114 | parameters.setPreviewSize(width, height); 115 | parameters.setPictureSize(width, height); 116 | parameters.setPreviewFormat(ImageFormat.YV12); 117 | parameters.set("rotation", 90); 118 | //parameters.set("orientation", "portrait"); 119 | m_camera.setParameters(parameters); 120 | m_camera.setDisplayOrientation(90); 121 | m_camera.setPreviewCallback((PreviewCallback) this); 122 | m_camera.startPreview(); 123 | 124 | } catch (IOException e) 125 | { 126 | e.printStackTrace(); 127 | } 128 | 129 | // 130 | try { 131 | file = new FileOutputStream(filename); 132 | } catch (FileNotFoundException e) { 133 | Log.d("Fuck", "File open error"); 134 | e.printStackTrace(); 135 | } 136 | } 137 | 138 | @Override 139 | public void surfaceDestroyed(SurfaceHolder arg0) 140 | { 141 | m_camera.setPreviewCallback(null); //m_camera.stopPreview(); 142 | m_camera.release(); 143 | m_camera = null; 144 | avcCodec.close(); 145 | try { 146 | file.flush(); 147 | file.close(); 148 | } catch (IOException e) { 149 | Log.d("Fuck", "File close error"); 150 | e.printStackTrace(); 151 | } 152 | } 153 | 154 | 155 | @Override 156 | public void onPreviewFrame(byte[] data, Camera camera) 157 | { 158 | //Log.v("h264", "h264 start"); 159 | long newTime = System.currentTimeMillis(); 160 | long diff = newTime - lastTime; 161 | lastTime = newTime; 162 | //Log.d("Fuck", " "); 163 | //Log.d("Fuck", "Time Past: " + diff); 164 | 165 | int ret = avcCodec.offerEncoder(data,h264); 166 | //Log.d("Fuck", "ret length: " + ret); 167 | //Log.d("Fuck", "h264.length: " + h264.length); 168 | 169 | /*try { 170 | Thread.sleep(1000); 171 | } catch (InterruptedException e) { 172 | // TODO Auto-generated catch block 173 | e.printStackTrace(); 174 | }*/ 175 | 176 | if(ret > 0) 177 | { 178 | try { 179 | byte[] length_bytes = intToBytes(ret); 180 | file.write(length_bytes); 181 | file.write(h264, 0, ret); 182 | //file.flush(); 183 | //byteOffset += h264.length; 184 | //DatagramPacket packet=new DatagramPacket(h264,ret, address,5000); 185 | //socket.send(packet); 186 | } catch (IOException e) 187 | { 188 | Log.d("Fuck", "@@@@@@@@ exception: " + e.toString()); 189 | } 190 | } 191 | //Log.v("h264", "h264 end"); 192 | } 193 | 194 | public static byte[] intToBytes( int value ) 195 | { 196 | byte[] src = new byte[4]; 197 | src[3] = (byte) ((value>>24) & 0xFF); 198 | src[2] = (byte) ((value>>16) & 0xFF); 199 | src[1] = (byte) ((value>>8) & 0xFF); 200 | src[0] = (byte) (value & 0xFF); 201 | return src; 202 | } 203 | } -------------------------------------------------------------------------------- /src/com/example/mediaencodeanddecodedemo/DecodeActivity.java: -------------------------------------------------------------------------------- 1 | package com.example.mediaencodeanddecodedemo; 2 | 3 | import java.io.ByteArrayOutputStream; 4 | import java.io.FileInputStream; 5 | import java.io.FileNotFoundException; 6 | import java.io.IOException; 7 | import java.nio.ByteBuffer; 8 | 9 | import android.annotation.SuppressLint; 10 | import android.app.Activity; 11 | import android.content.Context; 12 | import android.graphics.Bitmap; 13 | import android.graphics.BitmapFactory; 14 | import android.graphics.Canvas; 15 | import android.graphics.Color; 16 | import android.graphics.ImageFormat; 17 | import android.graphics.Paint; 18 | import android.graphics.Rect; 19 | import android.graphics.YuvImage; 20 | import android.hardware.Camera.Size; 21 | import android.media.MediaCodec; 22 | import android.media.MediaFormat; 23 | import android.media.MediaCodec.BufferInfo; 24 | import android.os.Bundle; 25 | import android.util.Log; 26 | import android.view.Surface; 27 | import android.view.SurfaceHolder; 28 | import android.view.SurfaceView; 29 | import android.view.View; 30 | import android.view.WindowManager; 31 | import android.widget.ImageView; 32 | 33 | public class DecodeActivity extends Activity implements SurfaceHolder.Callback { 34 | private final int width = 1280; 35 | private final int height = 720; 36 | 37 | // private static String fileString = Environment 38 | // .getExternalStorageDirectory() + "/h264/test.h264"; 39 | // private static String fileString = "/sdcard/test.h264"; 40 | // private static String fileString = 41 | // "/sdcard/yangjin_and_xieaini_h264.mp4"; 42 | private static String fileString = "/sdcard/camera.h264"; 43 | private PlayerThread mPlayer = null; 44 | private SurfaceHolder holder = null; 45 | private ImageView imageView = null; 46 | 47 | @Override 48 | protected void onCreate(Bundle savedInstanceState) { 49 | super.onCreate(savedInstanceState); 50 | // SurfaceView sv = new SurfaceView(this); 51 | // sv.getHolder().addCallback(this); 52 | // Set keep screen on 53 | getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON); 54 | setContentView(R.layout.activity_decode); 55 | SurfaceView sfv_video = (SurfaceView) findViewById(R.id.sfv_video); 56 | imageView = (ImageView)findViewById(R.id.image_view); 57 | if(null == imageView){ 58 | Log.d("Fuck002", "can not find imageView"); 59 | } 60 | holder = sfv_video.getHolder(); 61 | holder.addCallback(this); 62 | 63 | // 64 | // setContentView(new CustomView(this)); 65 | } 66 | 67 | protected void onDestroy() { 68 | super.onDestroy(); 69 | } 70 | 71 | @Override 72 | public void surfaceCreated(SurfaceHolder holder) { 73 | if (mPlayer == null) { 74 | mPlayer = new PlayerThread(imageView, holder.getSurface(), holder); 75 | mPlayer.start(); 76 | } 77 | } 78 | 79 | @Override 80 | public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { 81 | 82 | } 83 | 84 | @Override 85 | public void surfaceDestroyed(SurfaceHolder holder) { 86 | if (mPlayer != null) { 87 | mPlayer.interrupt(); 88 | } 89 | } 90 | 91 | private class PlayerThread extends Thread { 92 | private MediaCodec decoder = null; 93 | private ImageView imageView = null; 94 | private Surface surface = null; 95 | private SurfaceHolder surfaceHolder = null; 96 | 97 | public PlayerThread(ImageView imageView2, Surface surface, SurfaceHolder surfaceHolder) { 98 | this.imageView = imageView2; 99 | this.surface = surface; 100 | this.surfaceHolder = surfaceHolder; 101 | } 102 | 103 | @SuppressLint("NewApi") 104 | @Override 105 | public void run() { 106 | MediaFormat mediaFormat = MediaFormat.createVideoFormat("video/avc", width, width); 107 | mediaFormat.setInteger(MediaFormat.KEY_BIT_RATE, 2500000); 108 | mediaFormat.setInteger(MediaFormat.KEY_FRAME_RATE, 20); 109 | try { 110 | decoder = MediaCodec.createDecoderByType("video/avc"); 111 | } catch (IOException e) { 112 | Log.d("Fuck", "Fail to create MediaCodec: " + e.toString()); 113 | } 114 | decoder.configure(mediaFormat, surface, null, 0); 115 | //decoder.configure(mediaFormat, null, null, 0); 116 | decoder.start(); 117 | 118 | // new BufferInfo(); 119 | 120 | ByteBuffer[] inputBuffers = decoder.getInputBuffers(); 121 | ByteBuffer[] outputBuffers = decoder.getOutputBuffers(); 122 | if (null == inputBuffers) { 123 | Log.d("Fuck", "null == inputBuffers"); 124 | } 125 | if (null == outputBuffers) { 126 | Log.d("Fuck", "null == outbputBuffers 111"); 127 | } 128 | 129 | FileInputStream file = null; 130 | try { 131 | file = new FileInputStream(fileString); 132 | } catch (FileNotFoundException e) { 133 | Log.d("Fuck", "open file error: " + e.toString()); 134 | return; 135 | } 136 | int read_size = -1; 137 | int mCount = 0; 138 | 139 | for (;;) { 140 | byte[] h264 = null; 141 | try { 142 | byte[] length_bytes = new byte[4]; 143 | read_size = file.read(length_bytes); 144 | if (read_size < 0) { 145 | Log.d("Fuck", "read_size<0 pos1"); 146 | break; 147 | } 148 | int byteCount = bytesToInt(length_bytes, 0); 149 | Log.d("Fuck", "byteCount: " + byteCount); 150 | 151 | h264 = new byte[byteCount]; 152 | read_size = file.read(h264, 0, byteCount); 153 | // Log.d("Fuck", "read_size: " + read_size); 154 | if (read_size < 0) { 155 | Log.d("Fuck", "read_size<0 pos2"); 156 | break; 157 | } 158 | // Log.d("Fuck", "pos: " + file.) 159 | } catch (IOException e) { 160 | Log.d("Fuck", "read_size 2: " + read_size); 161 | Log.d("Fuck", "e.toStrinig(): " + e.toString()); 162 | break; 163 | } 164 | 165 | int inputBufferIndex = decoder.dequeueInputBuffer(-1); 166 | if (inputBufferIndex >= 0) { 167 | ByteBuffer inputBuffer = inputBuffers[inputBufferIndex]; 168 | inputBuffer.clear(); 169 | inputBuffer.put(h264); 170 | // long sample_time = ; 171 | decoder.queueInputBuffer(inputBufferIndex, 0, h264.length, mCount * 1000000 / 20, 0); 172 | ++mCount; 173 | } else { 174 | Log.d("Fuck", "dequeueInputBuffer error"); 175 | } 176 | 177 | ByteBuffer outputBuffer = null; 178 | MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo(); 179 | int outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0); 180 | while (outputBufferIndex >= 0) { 181 | outputBuffer = outputBuffers[outputBufferIndex]; 182 | decoder.releaseOutputBuffer(outputBufferIndex, true); 183 | outputBufferIndex = decoder.dequeueOutputBuffer(bufferInfo, 0); 184 | } 185 | 186 | // 187 | /*Canvas canvas = null; 188 | synchronized (surfaceHolder) { 189 | try { 190 | // Log.d("Fuck", "Drawing-------------"); 191 | canvas = surfaceHolder.lockCanvas(); 192 | //canvas.drawColor(Color.WHITE); 193 | //Paint p = new Paint(); 194 | //p.setColor(Color.BLACK); 195 | 196 | 197 | //canvas.drawRect(r, p); 198 | byte[] outData = new byte[width*width*3/2]; 199 | if(null != outputBuffer){ 200 | outputBuffer.get(outData, 0, outData.length); 201 | outputBuffer.clear(); 202 | 203 | //Bitmap bitmap = Bytes2Bimap(outData); 204 | //if(null == bitmap) Log.d("Fuck", "null == bitmap"); 205 | //canvas.drawBitmap(bitmap, null, r, null); 206 | //canvas.drawText("���ǵ�" + (mCount++) + "��", 100, 310, p); 207 | 208 | // 209 | //Bitmap bmp = decodeToBitMap(outData); 210 | if(null == imageView) Log.d("Fuck", "null == imageView"); 211 | //if(null == bmp) Log.d("Fuck", "null == bmp"); 212 | //Log.d("Fuck", "count=" + mCount + ", bmp.width=" + bmp.getWidth() + ", bmp.height="+bmp.getHeight()); 213 | //imageView.setImageBitmap(bmp); 214 | Rect r = new Rect(0, 0, width, width); 215 | //canvas.drawBitmap(bmp, 0, 0, null); 216 | int[] rgb = new int[width * width]; 217 | decodeYUV420SP(rgb, outData, width, width); 218 | canvas.drawBitmap(rgb, 0, width, 0, 0, width, width, false, null); 219 | 220 | Thread.sleep(1000/20);// 221 | } 222 | } catch (Exception e) { 223 | Log.d("Fuck", "throw Exception in run"); 224 | e.printStackTrace(); 225 | break; 226 | } finally { 227 | if (null != canvas) { 228 | surfaceHolder.unlockCanvasAndPost(canvas); 229 | } 230 | } 231 | 232 | }// end of synchronized 233 | */ 234 | 235 | if (outputBufferIndex >= 0) { 236 | decoder.releaseOutputBuffer(outputBufferIndex, false); 237 | } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED) { 238 | outputBuffers = decoder.getOutputBuffers(); 239 | Log.d("Fuck", "outputBufferIndex == MediaCodec.INFO_OUTPUT_BUFFERS_CHANGED"); 240 | } else if (outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED) { 241 | // Subsequent data will conform to new format. 242 | Log.d("Fuck", "outputBufferIndex == MediaCodec.INFO_OUTPUT_FORMAT_CHANGED"); 243 | } 244 | 245 | try { 246 | Thread.sleep(1000/20); 247 | } catch (InterruptedException e) { 248 | // TODO Auto-generated catch block 249 | e.printStackTrace(); 250 | } 251 | }// end of for 252 | 253 | if (null != file) { 254 | try { 255 | file.close(); 256 | } catch (IOException e) { 257 | // TODO Auto-generated catch block 258 | e.printStackTrace(); 259 | } 260 | } 261 | 262 | Log.d("Fuck", "Finish"); 263 | }// end of run 264 | 265 | public Bitmap Bytes2Bimap(byte[] b) { 266 | if (b.length != 0) { 267 | return BitmapFactory.decodeByteArray(b, 0, b.length); 268 | } else { 269 | return null; 270 | } 271 | } 272 | 273 | public Bitmap decodeToBitMap(byte[] data) { 274 | Bitmap bmp = null; 275 | try { 276 | YuvImage image = new YuvImage(data, ImageFormat.NV21, width, width, null); 277 | if (image != null) { 278 | Log.d("Fuck", "image != null"); 279 | ByteArrayOutputStream stream = new ByteArrayOutputStream(); 280 | image.compressToJpeg(new Rect(0, 0, width, width), 80, stream); 281 | bmp = BitmapFactory.decodeByteArray(stream.toByteArray(), 0, stream.size()); 282 | stream.close(); 283 | } 284 | } catch (Exception ex) { 285 | Log.e("Fuck", "Error:" + ex.getMessage()); 286 | } 287 | return bmp; 288 | } 289 | 290 | public void decodeYUV420SP(int[] rgb, byte[] yuv420sp, int width, int height) { 291 | final int frameSize = width * height; 292 | 293 | for (int j = 0, yp = 0; j < height; j++) { 294 | int uvp = frameSize + (j >> 1) * width, u = 0, v = 0; 295 | for (int i = 0; i < width; i++, yp++) { 296 | int y = (0xff & ((int) yuv420sp[yp])) - 16; 297 | if (y < 0) 298 | y = 0; 299 | if ((i & 1) == 0) { 300 | v = (0xff & yuv420sp[uvp++]) - 128; 301 | u = (0xff & yuv420sp[uvp++]) - 128; 302 | } 303 | 304 | int y1192 = 1192 * y; 305 | int r = (y1192 + 1634 * v); 306 | int g = (y1192 - 833 * v - 400 * u); 307 | int b = (y1192 + 2066 * u); 308 | 309 | if (r < 0) 310 | r = 0; 311 | else if (r > 262143) 312 | r = 262143; 313 | if (g < 0) 314 | g = 0; 315 | else if (g > 262143) 316 | g = 262143; 317 | if (b < 0) 318 | b = 0; 319 | else if (b > 262143) 320 | b = 262143; 321 | 322 | rgb[yp] = 0xff000000 | ((r << 6) & 0xff0000) 323 | | ((g >> 2) & 0xff00) | ((b >> 10) & 0xff); 324 | } 325 | } 326 | } 327 | 328 | public int bytesToInt(byte[] src, int offset) { 329 | int value; 330 | value = (int) ((src[offset] & 0xFF) 331 | | ((src[offset+1] & 0xFF)<<8) 332 | | ((src[offset+2] & 0xFF)<<16) 333 | | ((src[offset+3] & 0xFF)<<24)); 334 | return value; 335 | } 336 | 337 | }// end of class 338 | 339 | private class CustomView extends View { 340 | private Paint paint = null; 341 | 342 | public CustomView(Context context) { 343 | super(context); 344 | paint = new Paint(); 345 | paint.setColor(Color.YELLOW); 346 | paint.setStrokeJoin(Paint.Join.ROUND); 347 | paint.setStrokeCap(Paint.Cap.ROUND); 348 | paint.setStrokeWidth(3); 349 | } 350 | 351 | @Override 352 | protected void onDraw(Canvas canvas) { 353 | canvas.drawCircle(100, 100, 90, paint); 354 | } 355 | } 356 | } 357 | --------------------------------------------------------------------------------