Отправить AVPacket по сети - PullRequest
       10

Отправить AVPacket по сети

0 голосов
/ 26 сентября 2019

Я генерирую 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 есть несколько байтов, которые я получил от другоговидео, потому что без них оно тоже не работает.

1 Ответ

0 голосов
/ 27 сентября 2019

Вызов AVPacket.data() возвращает BytePointer, который является оберткой для собственного указателя C ++.Нет информации о емкости, связанной с указателем, что означает, что вам нужно установить емкость вручную.Вам, вероятно, нужно что-то вроде:

int packetSize = packet.size();
ByteBuffer dataBuffer = packet.data().capacity(packetSize).asByteBuffer();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...