我的代码运行之后好像没有获取到视频流的数据一直无法播放,我想知道是什么原因,我的流程有问题还是播放地址有问题,该如何解决?
package com.example.sditest;
import android.media.MediaCodec;
import android.media.MediaExtractor;
import android.media.MediaFormat;
import android.util.Log;
import android.util.Size;
import android.view.Surface;
import java.io.BufferedReader;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
public class MediaThread extends Thread {
private Surface surface;
private MediaCodec mediaCodec;
private MediaFormat mformat;
private String mime = null;
private int width = 0; // 视频宽度
private int height = 0; // 视频高度
private Size preSize;
private Process process = null;
private DataOutputStream os = null;
private long startMs = -1;
private ByteBuffer[] inputBuffers;
private boolean runing = false;
private String inout = null;
public MediaThread(Surface surface, Size size, Size preSize, String inout) {
this.surface = surface;
width = size.getWidth();
height = size.getHeight();
this.inout = inout;
this.preSize = preSize;
}
//初始化MediaCodec
public void extractor() {
try {
mediaCodec = MediaCodec.createDecoderByType("video/avc");
mformat = MediaFormat.createVideoFormat("video/avc", width, height);
mediaCodec.configure(mformat, surface, null, 0);
mediaCodec.start();
inputBuffers = mediaCodec.getInputBuffers();
runing =true;
} catch (IOException e) {
e.printStackTrace();
}
}
public void showSdi(byte[] data){
}
public void showHdmi(byte[] data){
Log.d("MediaThread", "开始解码 HDMI IN");
int inputBufferIndex = mediaCodec.dequeueInputBuffer(10000);
if (inputBufferIndex >= 0) {
ByteBuffer inputBuffer = inputBuffers[inputBufferIndex];
inputBuffer.clear();
inputBuffer.put(data);
mediaCodec.queueInputBuffer(inputBufferIndex, 0, data.length, 0, 0);
}
MediaCodec.BufferInfo bufferInfo = new MediaCodec.BufferInfo();
int outputBufferIndex = mediaCodec.dequeueOutputBuffer(bufferInfo, 10000);
if (outputBufferIndex >= 0) {
//保持播放的速度与实际帧率相同
while (bufferInfo.presentationTimeUs / 1000 > System.currentTimeMillis() - startMs) {
try {
Thread.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
mediaCodec.releaseOutputBuffer(outputBufferIndex, true);
}
}
public void execCommand(String cmd) {
try {
process = Runtime.getRuntime().exec("su");
os = new DataOutputStream(process.getOutputStream());
os.writeBytes(cmd + "\n");
os.writeBytes("exit\n");
os.flush();
extractor();
char[] buff = new char[1024];
int ch = 0;
BufferedReader bfsd = new BufferedReader(new InputStreamReader(process.getInputStream()));
StringBuffer sbs = new StringBuffer();
runing = true;
while ((ch = bfsd.read(buff)) != -1 && runing) {
Log.d("MediaThread", "获取视频帧数据");
sbs.append(buff, 0, ch);
Log.d("buffer", sbs.toString().getBytes().length + "\n");
byte[] data = sbs.toString().getBytes();
if (inout.equals("sdi")) {
showSdi(data);
}
if (inout.equals("hdmi")) {
showHdmi(data);
}
}
mediaCodec.stop();
mediaCodec.release();
surface.release();
bfsd.close();
os.close();
process.destroy();
} catch (IOException e) {
e.printStackTrace();
}
}
@Override
public void run() {
Log.d("MediaThread", "开始进入播放线程");
String sdi_cmd2 = "v4l2-ctl --verbose -d /dev/video0 --set-fmt-video=width=" + width + ",height=" + height + ",pixelformat='YUYV' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=" + preSize.getWidth() + ",height=" + preSize.getHeight();
String hdmi_cmd2 = "v4l2-ctl --verbose -d /dev/video11 --set-fmt-video=width=" + width + ",height=" + height + ",pixelformat='NV12' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=" + preSize.getWidth() + ",height=" + preSize.getHeight();
if (inout.equals("sdi")) {
execCommand(sdi_cmd2);
}
Log.d("MediaThread",hdmi_cmd2);
if (inout.equals("hdmi")) {
execCommand(hdmi_cmd2);
}
}
public void stopTheard(){
runing = false;
}
}
运行后的log:
D/MediaThread: 开始进入播放线程
v4l2-ctl --verbose -d /dev/video11 --set-fmt-video=width=1920,height=1080,pixelformat='NV12' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=1920,height=876
D/MediaCodecList: codecHandlesFormat: no format, so no extra checks
codecHandlesFormat: no format, so no extra checks
codecHandlesFormat: no format, so no extra checks
D/CCodec: allocate(c2.rk.avc.decoder)
I/Codec2Client: Available Codec2 services: "default" "software"
I/CCodec: setting up 'default' as default (vendor) store
I/CCodec: Created component [c2.rk.avc.decoder]
D/CCodecConfig: read media type: video/avc
D/ReflectedParamUpdater: extent() != 1 for single value type: output.subscribed-indices.values
extent() != 1 for single value type: input.buffers.allocator-ids.values
extent() != 1 for single value type: output.buffers.allocator-ids.values
extent() != 1 for single value type: output.buffers.pool-ids.values
D/ReflectedParamUpdater: ignored struct field coded.color-format.locations
D/CCodecConfig: ignoring local param raw.size (0xd2001800) as it is already supported
ignoring local param default.color (0x5200180b) as it is already supported
D/ReflectedParamUpdater: ignored struct field raw.hdr-static-info.mastering
I/CCodecConfig: query failed after returning 12 values (BAD_INDEX)
D/CCodecConfig: c2 config diff is Dict {
c2::u32 algo.low-latency.value = 0
c2::u32 coded.pl.level = 20495
c2::u32 coded.pl.profile = 20480
c2::u32 coded.vui.color.matrix = 0
c2::u32 coded.vui.color.primaries = 0
c2::u32 coded.vui.color.range = 2
c2::u32 coded.vui.color.transfer = 0
c2::u32 default.color.matrix = 0
c2::u32 default.color.primaries = 0
c2::u32 default.color.range = 0
c2::u32 default.color.transfer = 0
c2::u32 input.buffers.max-size.value = 2097152
string input.media-type.value = "video/avc"
c2::u32 output.delay.value = 16
string output.media-type.value = "video/raw"
c2::u32 raw.color.matrix = 0
c2::u32 raw.color.primaries = 0
c2::u32 raw.color.range = 2
c2::u32 raw.color.transfer = 0
c2::u32 raw.max-size.height = 240
c2::u32 raw.max-size.width = 320
c2::u32 raw.pixel-format.value = 35
c2::i32 raw.rotation.flip = 0
c2::i32 raw.rotation.value = 0
c2::u32 raw.sar.height = 1
c2::u32 raw.sar.width = 1
c2::u32 raw.size.height = 240
c2::u32 raw.size.width = 320
W/ColorUtils: expected specified color aspects (2:0:0:0)
D/SurfaceUtils: connecting to surface 0x771fd30110, reason connectToSurface
I/MediaCodec: [c2.rk.avc.decoder] setting surface generation to 10882049
D/SurfaceUtils: disconnecting from surface 0x771fd30110, reason connectToSurface(reconnect)
connecting to surface 0x771fd30110, reason connectToSurface(reconnect)
D/CCodec: [c2.rk.avc.decoder] buffers are bound to CCodec for this session
D/CCodecConfig: no c2 equivalents for native-window
no c2 equivalents for flags
config failed => CORRUPTED
D/CCodecConfig: c2 config diff is c2::u32 raw.size.height = 1080
c2::u32 raw.size.width = 1920
W/Codec2Client: query -- param skipped: index = 1107298332.
D/CCodec: setup formats input: AMessage(what = 0x00000000) = {
int32_t height = 1080
int32_t level = 32768
int32_t max-input-size = 2097152
string mime = "video/avc"
int32_t profile = 1
int32_t width = 1920
Rect crop(0, 0, 1919, 1079)
}
setup formats output: AMessage(what = 0x00000000) = {
int32_t android._color-format = 2135033992
int32_t android._video-scaling = 1
int32_t rotation-degrees = 0
int32_t color-standard = 1
int32_t color-range = 2
int32_t color-transfer = 3
int32_t sar-height = 1
int32_t sar-width = 1
Rect crop(0, 0, 1919, 1079)
int32_t width = 1920
int32_t height = 1080
int32_t max-height = 240
int32_t max-width = 320
string mime = "video/raw"
int32_t android._dataspace = 260
int32_t color-format = 2130708361
}
I/CCodecConfig: query failed after returning 12 values (BAD_INDEX)
D/CCodecConfig: c2 config diff is c2::u32 raw.max-size.height = 1080
c2::u32 raw.max-size.width = 1920
W/Codec2Client: query -- param skipped: index = 1342179345.
query -- param skipped: index = 2415921170.
query -- param skipped: index = 1073743886.
query -- param skipped: index = 1610614798.
query -- param skipped: index = 2684356609.
D/C2Store: Using DMABUF Heaps
D/CCodecBufferChannel: [c2.rk.avc.decoder#257] Created input block pool with allocatorID 16 => poolID 17 - OK (0)
D/CCodecBufferChannel: [c2.rk.avc.decoder#257] Configured output block pool ids 20 => OK
D/Codec2-OutputBufferQueue: remote graphic buffer migration 0/0
D/Codec2Client: setOutputSurface -- failed to set consumer usage (6/BAD_INDEX)
setOutputSurface -- generation=10882049 consumer usage=0x900
D/Codec2Client: Surface configure completed
I/DMABUFHEAPS: Using DMA-BUF heap named: system
推流命令从shell执行的结果:
rk3588s_s:/ # su
rk3588s_s:/ # v4l2-ctl --verbose -d /dev/video11 --set-fmt-video=width=1920,height=1080,pixelformat='NV12' --stream-mmap=4 --set-selection=target=crop,flags=0,top=0,left=0,width=1920,height=876
VIDIOC_QUERYCAP: ok
VIDIOC_G_FMT: ok
VIDIOC_S_FMT: ok
Format Video Capture Multiplanar:
Width/Height : 1920/1080
Pixel Format : 'NV12'
Field : None
Number of planes : 1
Flags :
Colorspace : Default
Transfer Function : Default
YCbCr Encoding : Default
Quantization : Default
Plane 0 :
Bytes per Line : 1920
Size Image : 3110400
VIDIOC_G_SELECTION: ok
VIDIOC_S_SELECTION: failed: Inappropriate ioctl for device
VIDIOC_REQBUFS: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_QUERYBUF: ok
VIDIOC_QBUF: ok
VIDIOC_STREAMON: ok
idx: 0 seq: 0 bytesused: 3110400 ts: 21003.165904
idx: 1 seq: 1 bytesused: 3110400 ts: 21003.182595 delta: 16.691 ms
idx: 2 seq: 2 bytesused: 3110400 ts: 21003.199244 delta: 16.649 ms
idx: 3 seq: 3 bytesused: 3110400 ts: 21003.215906 delta: 16.662 ms
idx: 0 seq: 4 bytesused: 3110400 ts: 21003.232608 delta: 16.702 ms fps: 59.97
idx: 1 seq: 5 bytesused: 3110400 ts: 21003.249229 delta: 16.621 ms fps: 60.01
idx: 2 seq: 6 bytesused: 3110400 ts: 21003.265918 delta: 16.689 ms fps: 59.99
idx: 3 seq: 7 bytesused: 3110400 ts: 21003.282575 delta: 16.657 ms fps: 60.00
idx: 0 seq: 8 bytesused: 3110400 ts: 21003.299255 delta: 16.680 ms fps: 59.99
idx: 1 seq: 9 bytesused: 3110400 ts: 21003.315906 delta: 16.651 ms fps: 60.00
idx: 2 seq: 10 bytesused: 3110400 ts: 21003.332585 delta: 16.679 ms fps: 59.99
idx: 3 seq: 11 bytesused: 3110400 ts: 21003.349231 delta: 16.646 ms fps: 60.00
idx: 0 seq: 12 bytesused: 3110400 ts: 21003.365890 delta: 16.659 ms fps: 60.00
idx: 1 seq: 13 bytesused: 3110400 ts: 21003.382563 delta: 16.673 ms fps: 60.00
idx: 2 seq: 14 bytesused: 3110400 ts: 21003.399239 delta: 16.676 ms fps: 60.00
idx: 3 seq: 15 bytesused: 3110400 ts: 21003.415894 delta: 16.655 ms fps: 60.00
idx: 0 seq: 16 bytesused: 3110400 ts: 21003.432586 delta: 16.692 ms fps: 60.00