[FFmpeg-user] Custom data in AVPacket or AVFrame
laddoe
xyfix at hotmail.com
Tue Feb 15 09:38:28 EET 2022
Hi,
I want to add a custom number to either an AVFame or an AVPacket before I encode it and I want to retrieve it back when I decode it. I have tried using the AVFrame/AVPacket metadata or side_data but I guess I don't understand how to get it to work. I have also looked into using AVDictionary/ AVDictionaryEntry but nothing so far. The data that I want to store per frame is only a uint32_t. The encoding/decoding of frames work correctly, I have been running it for weeks, here is my encoding piece that suppose to add the "custom number" in, but I'm stuck ....
void MovieEncoder::writeFrame( AVFrame* frame, int frameNumber )
{
int result;
if ( s_frameCount >= streamNumberOfFrames)
s_frameCount = streamNumberOfFrames;
frame->pts = s_frameCount;
if (m_formatCtx->oformat->flags & AVFMT_NOFILE )
{
AVPacket pkt;
av_init_packet(&pkt);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = m_stream->index;
pkt.data = frame->data[0];
pkt.size = sizeof(AVPicture);
result = av_write_frame( m_formatCtx, &pkt );
}
else
{
AVPacket pkt;
av_init_packet(&pkt);
AVFrameSideData* numberSideData = av_frame_new_side_data( frame, AV_FRAME_DATA_GOP_TIMECODE, sizeof( uint64_t ))
// Here the magic should happen, I think
if( !numberSideData)
return;
result = avcodec_send_frame(m_codecCtx, frame);
checkError( result, "Error encoding video frame: ");
while( result >= 0 )
{
result = avcodec_receive_packet(m_codecCtx, &pkt);
if (result == AVERROR(EAGAIN) /*|| ret == AVERROR_EOF*/)
{
Log::printLine("No more packet to write", Log::Debug );
return;
}
else if (result < 0)
{
Log::printLine("Codec context of the package is not correct", Log::Debug);
return;
}
pkt.stream_index = m_stream->index;
pkt.pts = av_rescale_q( pkt.pts, m_codecCtx->time_base, m_stream->time_base );
pkt.dts = av_rescale_q( pkt.dts, m_codecCtx->time_base, m_stream->time_base );
// AVDictionary* dictionary = nullptr;
// av_dict_set( &dictionary, metaKey.c_str(),std::to_string( frameNumber ).c_str(), 0 );
// int dictionarySize = 0;
// uint8_t* dictionaryData = av_packet_pack_dictionary( dictionary, &dictionarySize );
// av_dict_free( &dictionary );
// av_packet_add_side_data( &pkt, AV_PKT_DATA_STRINGS_METADATA, dictionaryData, dictionarySize );
pkt.duration = int64( 1 / streamFrameRate );
result = av_write_frame( m_formatCtx, &pkt );
s_frameCount++;
}
}
// av_dict_free( &dictionary );
}
More information about the ffmpeg-user
mailing list