【发布时间】:2018-07-14 07:44:54
【问题描述】:
我们正在开发一个视频流应用程序, 目前我们能够捕获视频并逐帧处理,然后在两个设备之间发送/接收数据。
问题出在接收端,因为我们正在发送固定大小的帧,所以接收端也应该以固定大小处理它们,否则他将无法获得帧。
希望这张图能说明问题。
代码:
public void process(@NonNull Frame frame) {
byte[] data = frame.getData();
frameWidth = frame.getSize().getWidth();
frameHieght = frame.getSize().getHeight();
YuvImage yuv = new YuvImage(data, frame.getFormat(), frameWidth, frameHieght, null);
ByteArrayOutputStream out = new ByteArrayOutputStream();
yuv.compressToJpeg(new Rect(0, 0, frameWidth, frameHieght), 25, out);
final byte[] bytes = out.toByteArray();
frameByteSize = bytes.length;
OutputStream outputStream = StreamHandler.getOutputStream();
if (out != null) {
try {
outputStream.write(bytes, 0, frameByteSize);
} catch (IOException e) {
e.printStackTrace();
}
}
代码:
public void run() {
int read = 0;
int hold = 0;
int frameSize = StreamHandler.getFrameByteSize();
try {
Thread.sleep(10000);
if (SrtreamHandler != null) {
InputStream inputStream = StreamHandler.getInputStream();
if (inputStream != null) {
BufferedInputStream bufferedInputStream = new BufferedInputStream(inputStream);
while (microPhoneActive) {
byte[] frame = new byte[frameSize];
read = bufferedInputStream.read(frame, 0, frame.length);
Bitmap bitmap = BitmapFactory.decodeByteArray(frame, 0, frame.length);
if (bitmap != null) {
final Bitmap rotatedBitmap = rotateBitmap(bitmap, -90);
frameEvent.onNewFrame(rotatedBitmap);
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
当前缓冲区读取器正在读取不同大小的数据块,因此构建的位图如下:
图像的黑色部分还没有被接收到,因为缓冲的阅读器没有阻塞并等待所有缓冲的都被填满。
【问题讨论】:
-
你应该收集块直到你有一个完整的框架。使用 tcp/ip 以大块形式输入的字节是很正常的。
-
您对
read整数无能为力。开始检查实际读取了多少字节。 -
@greenapps 当我继续阅读直到有完整的帧时,在大多数情况下,我最终会得到一个完整的帧,并且下一帧的某些字节会破坏下一帧和之后的所有帧,是否有处理框架的数据结构?至于读取值,我已经读取了数据,它小于我损坏流的帧
-
当然,您不应该已经读取下一帧的字节。您应该只先读取一帧的字节。收集块直到你有一个框架。使用 Oleg 提供的链接。
-
@greenapps 这正是我现在的问题,我知道使用 inputStream.available() 是没用的,并且 read 是阻塞的,但不是固定长度
标签: java android sockets bitmap inputstream