Reputation: 803
I want to be able to open a stream with a video file and send in the decoder my own packets with data that I previously stored from a different stream with the same codec. So like forging my own packets in the decoder.
My approach is that I encode frames into packets using H.265 and store the data in a file like this:
AVPacket *packet;
std::vector<uint8_t> data;
...encoding...
data->insert(data->end(), &packet->data[0], &packet->data[packet->size]);
...storing the buffer in a file...
I also have one mkv video with H.265 stream of the same parameters. Now I want to get the stored packet data in the file, create a new packet, and send it into the decoding process of the mkv file. To make it easier I just copy the parameters of the first packet in the mkv stream into a new packet where I insert my data and send it to the decoder. Is this a right approach?
...open decoder with mkv file...
auto packet = av_packet_alloc();
av_read_frame(formatContext, packet);
//here is the packet I will use later with my data
av_packet_copy_props(decodingPacket, packet);
decodingPacket->flags = 0;
//sending the packet from the mkv
avcodec_send_packet(codecContext, packet);
//the data contains the previously stored data
av_packet_from_data(decodingPacket, data.data(), data.size());
avcodec_send_packet(codecContext, decodingPacket);
...retrieving the frame...
However, I am getting this error when I try to send the forget packet:
Assertion buf_size >= 0 failed at libavcodec/bytestream.h:141
I have tried to manually change the decodingPacket->buf->size
but that is probably not the problem. I believe that I need to set up some other parameters in the forged packet but what exactly? Maybe I can also somehow store not only the packet data but the whole structure? Please let me know, if there is a better way to store and reload a packet and force it into an unrelated decoder with the same parameters.
Thanks!
EDIT: Seems like the buf_size problem was related to my data which were wrongly retrieved. I can confirm that this works now but I am getting a new error:
[hevc @ 0x559b931606c0] Invalid NAL unit size (0 > 414).
[hevc @ 0x559b931606c0] Error splitting the input into NAL units.
Upvotes: 0
Views: 1315
Reputation: 803
So the process I've described above seems to be correct and possible! My problem was with the inconsistency of the packets. The encoder and decoder need to be exactly the same (certain codec parameters can apparently produce different kind of packets). The easiest way to achieve that is to create a minimal reference file that would be used to initialize the decoder. The problem with NAL can be caused by different stream formats of h.265. This great answer helped me with identifying that! The output format affects the packet data so, for example, when having the raw data and using Annex B, it's necessary to insert the start code like:
data.insert(data.begin(), {0,0,0,1});
Upvotes: 0