Multiple codec contexts mixing frames between each other #322
Replies: 1 comment
-
It turns out I wasn't unreferencing packets and frames: private unsafe void HandleEncodedpacket(ArraySegment<byte> encodedData)
{
Debug.Assert(_ffmpegContext is not null);
var codecContext = _ffmpegContext.codecContext;
var swsContext = _ffmpegContext.swsContext;
var packet = _ffmpegContext.packet;
var sourceFrame = _ffmpegContext.sourceFrame;
var bgraFrame = _ffmpegContext.bgraFrame;
Debug.Assert(codecContext != null);
Debug.Assert(packet != null);
Debug.Assert(sourceFrame != null);
Debug.Assert(bgraFrame != null);
int result;
fixed (byte* encodedDataBytes = encodedData.Array)
{
packet->data = encodedDataBytes;
packet->size = encodedData.Count;
result =
ffmpeg.avcodec_send_packet(codecContext, packet)
//.ThrowIfError()
;
ffmpeg.av_packet_unref(packet); // <---
if (result != 0)
{
return;
}
}
while ((result = ffmpeg.avcodec_receive_frame(codecContext, sourceFrame)) >= 0)
{
var sourceWidth = sourceFrame->width;
var sourceHeight = sourceFrame->height;
var destinationWidth = sourceFrame->width;
var destinationHeight = sourceFrame->height;
// Convert the frame to BGRA
var pixelFormat = (AVPixelFormat)sourceFrame->format switch
{
AVPixelFormat.AV_PIX_FMT_YUVJ420P => AVPixelFormat.AV_PIX_FMT_YUV420P,
AVPixelFormat.AV_PIX_FMT_YUVJ422P => AVPixelFormat.AV_PIX_FMT_YUV422P,
AVPixelFormat.AV_PIX_FMT_YUVJ444P => AVPixelFormat.AV_PIX_FMT_YUV444P,
_ => (AVPixelFormat)sourceFrame->format,
};
if (swsContext == null)
{
_ffmpegContext.swsContext = swsContext = ffmpeg.sws_getContext(
sourceWidth, sourceHeight, pixelFormat,
destinationWidth, destinationHeight, AVPixelFormat.AV_PIX_FMT_BGRA,
ffmpeg.SWS_BILINEAR, null, null, null);
}
bgraFrame->format = (int)AVPixelFormat.AV_PIX_FMT_BGRA;
bgraFrame->width = destinationWidth;
bgraFrame->height = destinationHeight;
ffmpeg.av_frame_get_buffer(bgraFrame, 32).ThrowIfError();
ffmpeg.sws_scale(
swsContext,
sourceFrame->data, sourceFrame->linesize, 0, sourceFrame->height,
bgraFrame->data, bgraFrame->linesize);
ffmpeg.av_frame_unref(sourceFrame); // <---
var bgraSize = ffmpeg.av_image_get_buffer_size(AVPixelFormat.AV_PIX_FMT_BGRA, destinationWidth, destinationHeight, 1);
var bgraArray = ArrayPool<byte>.Shared.Rent(bgraSize);
var bgraSegment = new ArraySegment<byte>(bgraArray, 0, bgraSize);
fixed (byte* pBgraData = bgraArray)
{
var data4 = new byte_ptrArray4();
data4.UpdateFrom(bgraFrame->data.ToArray());
var linesize4 = new int_array4();
linesize4.UpdateFrom(bgraFrame->linesize.ToArray());
ffmpeg.av_image_copy_to_buffer(
pBgraData, bgraSize,
data4, linesize4,
(AVPixelFormat)bgraFrame->format, destinationWidth, destinationHeight, 1);
}
ffmpeg.av_frame_unref(bgraFrame); // <---
_decodedWriter.TryWrite((bgraSegment, destinationWidth, destinationHeight));
}
switch (result)
{
case 0:
case var eagain when (eagain == FfmpegContext.eagain):
case var eof when (eof == ffmpeg.AVERROR_EOF):
break;
default:
result.ThrowIfError();
break;
}
} |
Beta Was this translation helpful? Give feedback.
0 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
-
I have these decoders that are guaranteed to not share any data between them and there is no concurrency within each one.
However, I get, frequent mixed frames where one decoder gets a frame from packets fed to another.
This is the code I'm using:
Old code using
avcodec_decode_video2
works fine.What am I doing wrong here?
Beta Was this translation helpful? Give feedback.
All reactions