How to decode the H.264 video stream received from parcelfiledescriptor

↘锁芯ラ 提交于 2019-12-12 02:48:51

问题


I'm creating an Android application of live video streaming between two android phone. I've already established a socket connection between these devices. I'm capturing video in one device and send the stream to other device but currently I just want to save in the receiver side mobile device and save it. I'm recording using MediaRecorder in one device , so to stream to the receiver I,m using parcelfiledescriptor object by setting the data

Client side code

    mediaRecorder.setAudioSource(MediaRecorder.AudioSource.CAMCORDER);
    mediaRecorder.setVideoSource(MediaRecorder.VideoSource.CAMERA);
    mediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
    mediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AMR_NB);
    mediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H263);
    mediaRecorder.setOutputFile(pfd.getFileDescriptor());

Receiver side code

  pfd= ParcelFileDescriptor.fromSocket(s);
  InputStream in = new FileInputStream(pfd.getFileDescriptor()); 
  DataInputStream clientData = new DataInputStream(in);  
  OutputStream newDatabase = new FileOutputStream(file);
  int available=in.available();
  byte[] buffer = new byte[available];
  int length;


                while((length = in.read(buffer)) > 0)
                {
                    newDatabase.write(buffer, 0, length);

                }
                newDatabase.close();

The video file is being created on the receiver side mobile, but it's not able to receive any bytes. So Do I've to decode the coming stream on the receiver side since the video stream sent is encoded while recording. So how can I decode the stream that is received ? I found some solution like MediaExtractor and MediaCodec...but will this work with live video capturing and moreover I'm testing on android version 2.3.6 GingerBread Is it possible to decode the video stream from MediaCodec for version 2.3.6 or some other method is available ?


回答1:


The video file is being created on the receiver side mobile, but it's not able to receive any bytes.

If I understand you right, you are getting no data from the socket. That is a separate problem, which has nothing to do with the video format, decoding or encoding.

To debug your sockets, it may be helpful to use a separate application which just dumps the recieved data. Once the data looks fine, you can go to the next step - decoding the video.


Second part of the problem is the video format. You are using mp4, which is not usable for streaming. Here is more info about the format structure. You can use mp4 to record a video into a local file and then transfer the whole file over socket somewhere, but true realtime streaming cannot be done because of the non-seekable nature of the socket (as described in the linked article). There is a block of metadata at the beginning of the file, which acts as a "table of contents" and without it, the previous data are just junk. The problem is, you can assemble a "table of contents" only after you got all the contents. But at that moment, the data was already sent through the socket and you cannot insert anything at its beginning.

There are few walkarounds, but that's just for your future research and I haven't used them yet.

The most intuitive way would be to switch from mp4 to mpeg-ts, a container designed for streaming. Take a look at a hidden constant in MediaRecorder.OutputFormat with value 8.

Another option is to pack the raw H.264 data into RTP/RTCP packets, which is again a protocol designed for streaming. Also your application would be able to stream to any device that support this protocol (for example a PC running VLC). To further reasearch, take a look at Spydroid IP camera, which does exactly the thing.



来源:https://stackoverflow.com/questions/18886981/how-to-decode-the-h-264-video-stream-received-from-parcelfiledescriptor

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!