Я генерирую AVPackets с кодировщиком с ffmpeg, и теперь я хочу отправить их с UDP на другой компьютер и показать их там.Проблема в том, что я не знаю, как преобразовать пакет в байты и обратно.Я пытался это скопировать пакет:
AVPacket newPacket = avcodec.av_packet_alloc();
ByteBuffer byteBuffer = packet.buf().buffer().asByteBuffer();
int bufferSize = byteBuffer.capacity();
byte bytes[] = new byte[bufferSize];
byteBuffer.get(bytes);
AVBufferRef newBufferRef = avutil.av_buffer_alloc(bufferSize);
newBufferRef.data(new BytePointer(bytes));
newPacket.buf(newBufferRef);
ByteBuffer dataBuffer = packet.data().asByteBuffer();
int dataSize = dataBuffer.capacity();
byte dataBytes[] = new byte[dataSize];
dataBuffer.get(dataBytes);
BytePointer dataPointer = new BytePointer(dataBytes);
newPacket.data(dataPointer);
newPacket.dts(packet.dts());
newPacket.duration(packet.duration());
newPacket.flags(packet.flags());
newPacket.pos(packet.pos());
newPacket.pts(packet.pts());
newPacket.side_data_elems(0);
newPacket.size(packet.size());
newPacket.stream_index(packet.stream_index());
videoPlayer.sendPacket(newPacket);
Это дает мне эту ошибку:
[h264 @ 0000018951be8440] Invalid NAL unit size (3290676 > 77).
[h264 @ 0000018951be8440] Error splitting the input into NAL units.
[h264 @ 0000018951bf6480] Invalid NAL unit size (15305314 > 163).
[h264 @ 0000018951bf6480] Error splitting the input into NAL units.
Проблема newPacket.data()
.Когда я установил это непосредственно: newPacket.data(packet.data())
это работает.Также packet.data().asByteBuffer().capacity()
возвращает 1, а packet.data().capacity()
возвращает 0.
Это мой метод, который создает декодер:
private void startUnsafe() throws Exception
{
int result;
convertContext = null;
codec = null;
codecContext = null;
AVFrame = null;
RGBAVFrame = null;
frame = new Frame();
codec = avcodec_find_decoder(codecID);
if(codec == null)
{
throw new Exception("Unable to find decoder");
}
codecContext = avcodec_alloc_context3(codec);
if(codecContext == null)
{
releaseUnsafe();
throw new Exception("Unable to alloc codec context!");
}
AVCodecParameters para = avcodec_parameters_alloc();
para.bit_rate(streamBitrate);
para.width(streamWidth);
para.height(streamHeight);
para.codec_id(codecID);
para.codec_type(AVMEDIA_TYPE_VIDEO);
try
{
byte extradataByte[] = Files.readAllBytes(new File("extradata.byte").toPath());
para.extradata(new BytePointer(extradataByte));
para.extradata_size(extradataByte.length);
}
catch (IOException e1)
{
e1.printStackTrace();
throw new Exception("extradata file not available");
}
result = avcodec_parameters_to_context(codecContext, para);
if(result < 0)
{
throw new Exception("Unable to copy parameters to context! [" + result + "]");
}
codecContext.thread_count(0);
result = avcodec_open2(codecContext, codec, new AVDictionary());
if(result < 0)
{
releaseUnsafe();
throw new Exception("Unable to open codec context![" + result + "]");
}
AVFrame = av_frame_alloc();
if(AVFrame == null)
{
releaseUnsafe();
throw new Exception("Unable to alloc AVFrame!");
}
RGBAVFrame = av_frame_alloc();
if(RGBAVFrame == null)
{
releaseUnsafe();
throw new Exception("Unable to alloc AVFrame!");
}
initRGBAVFrame();
TimerTask task = new TimerTask() {
@Override
public void run()
{
timerTask();
}
};
timer = new Timer();
timer.scheduleAtFixedRate(task, 0, (long) (1000/streamFramerateDouble));
window.setVisible(true);
}
В файле extradata.byte есть несколько байтов, которые я получил от другоговидео, потому что без них оно тоже не работает.