Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch to new FFmpeg AVPacket API #938

Merged
merged 4 commits into from
Jan 18, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/lib/ffmpeg-4.0/avcodec.pas
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ TAVPicture = record
do_not_instantiate_this_record: incomplete_record;
end;
PAVPacket = ^TAVPacket;
PPAVPacket = ^PAVPacket;
TAVPacket = record
we_do_not_use_buf: pointer;
pts: cint64;
Expand Down Expand Up @@ -306,7 +307,6 @@ TAVCodecContext = record
do_not_instantiate_this_record: incomplete_record;
end;
function av_dup_packet(pkt: PAVPacket): cint; cdecl; external av__codec; deprecated;
procedure av_init_packet(var pkt: TAVPacket); cdecl; external av__codec; deprecated;
procedure av_free_packet(pkt: PAVPacket); cdecl; external av__codec; deprecated;
function avcodec_version(): cuint; cdecl; external av__codec;
function av_codec_is_decoder(codec: PAVCodec): cint; cdecl; external av__codec;
Expand All @@ -325,5 +325,8 @@ function avcodec_send_packet(avctx: PAVCodecContext; avpkt: PAVPacket): cint; cd
function avcodec_alloc_context3(codec: PAVCodec): PAVCodecContext; cdecl; external av__codec;
procedure avcodec_free_context(avctx: PPAVCodecContext); cdecl; external av__codec;
function avcodec_parameters_to_context(codec: PAVCodecContext; par: PAVCodecParameters): cint; cdecl; external av__codec;
function av_packet_alloc(): PAVPacket; cdecl; external av__codec;
procedure av_packet_free(pkt: PPAVPacket); cdecl; external av__codec;
procedure av_packet_unref(pkt: PAVPacket); cdecl; external av__codec;
implementation
end.
7 changes: 1 addition & 6 deletions src/lib/ffmpeg-4.0/avformat.pas
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ interface
AVSEEK_FLAG_ANY = 4;
AVSEEK_FLAG_BACKWARD = 1;
type
PAVPacketList = ^TAVPacketList;
TAVPacketList = record
pkt: TAVPacket;
next: ^TAVPacketList;
end;
PAVInputFormat = ^TAVInputFormat;
PAVStream = ^TAVStream;
PPAVStream = ^PAVStream;
Expand Down Expand Up @@ -117,7 +112,7 @@ function avformat_version(): cuint; cdecl; external av__format;
procedure av_register_all(); cdecl; external av__format; deprecated;
function avformat_find_stream_info(ic: PAVFormatContext; options: PPAVDictionary): cint; cdecl; external av__format;
function av_stream_get_r_frame_rate(s: PAVStream): TAVRational; cdecl; external av__format; deprecated;
function av_read_frame(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; pkt: PAVPacket): cint; cdecl; external av__format;
function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint64; flags: cint): cint; cdecl; external av__format;
implementation
end.
4 changes: 3 additions & 1 deletion src/lib/ffmpeg-5.0/avcodec.pas
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface
AV_CODEC_ID_NONE
);
PAVPacket = ^TAVPacket;
PPAVPacket = ^PAVPacket;
TAVPacket = record
we_do_not_use_buf: pointer;
pts: cint64;
Expand Down Expand Up @@ -271,7 +272,6 @@ TAVCodecContext = record
end;
function av_packet_ref(dst: PAVPacket; src: PAVPacket): cint; cdecl; external av__codec;
procedure av_packet_unref(pkt: PAVPacket); cdecl; external av__codec;
procedure av_init_packet(var pkt: TAVPacket); cdecl; external av__codec; deprecated;
function avcodec_version(): cuint; cdecl; external av__codec;
function av_codec_is_decoder(codec: PAVCodec): cint; cdecl; external av__codec;
function av_codec_iterate(opaque: ppointer): PAVCodec; cdecl; external av__codec;
Expand All @@ -286,5 +286,7 @@ function avcodec_send_packet(avctx: PAVCodecContext; avpkt: PAVPacket): cint; cd
function avcodec_alloc_context3(codec: PAVCodec): PAVCodecContext; cdecl; external av__codec;
procedure avcodec_free_context(avctx: PPAVCodecContext); cdecl; external av__codec;
function avcodec_parameters_to_context(codec: PAVCodecContext; par: PAVCodecParameters): cint; cdecl; external av__codec;
function av_packet_alloc(): PAVPacket; cdecl; external av__codec;
procedure av_packet_free(pkt: PPAVPacket); cdecl; external av__codec;
implementation
end.
7 changes: 1 addition & 6 deletions src/lib/ffmpeg-5.0/avformat.pas
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ interface
AVSEEK_FLAG_ANY = 4;
AVSEEK_FLAG_BACKWARD = 1;
type
PAVPacketList = ^TAVPacketList;
TAVPacketList = record
pkt: TAVPacket;
next: ^TAVPacketList;
end;
PAVInputFormat = ^TAVInputFormat;
PAVStream = ^TAVStream;
PPAVStream = ^PAVStream;
Expand Down Expand Up @@ -112,7 +107,7 @@ function avformat_open_input(ps: PPAVFormatContext; url: PAnsiChar; fmt: PAVInpu
procedure avformat_close_input(s: PPAVFormatContext); cdecl; external av__format;
function avformat_version(): cuint; cdecl; external av__format;
function avformat_find_stream_info(ic: PAVFormatContext; options: PPAVDictionary): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; pkt: PAVPacket): cint; cdecl; external av__format;
function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint64; flags: cint): cint; cdecl; external av__format;
implementation
end.
9 changes: 3 additions & 6 deletions src/lib/ffmpeg-6.0/avcodec.pas
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface
AV_CODEC_ID_NONE
);
PAVPacket = ^TAVPacket;
PPAVPacket = ^PAVPacket;
TAVPacket = record
we_do_not_use_buf: pointer;
pts: cint64;
Expand All @@ -71,11 +72,6 @@ TAVPacket = record
we_do_not_use_opaque_ref: pointer;
we_do_not_use_time_base: TAVRational;
end;
PAVPacketList = ^TAVPacketList;
TAVPacketList = record
pkt: TAVPacket;
next: ^TAVPacketList;
end;
PAVCodecDescriptor = ^TAVCodecDescriptor;
TAVCodecDescriptor = record
we_do_not_use_id: TAVCodecID;
Expand Down Expand Up @@ -238,7 +234,6 @@ TAVCodecContext = record
end;
function av_packet_ref(dst: PAVPacket; src: PAVPacket): cint; cdecl; external av__codec;
procedure av_packet_unref(pkt: PAVPacket); cdecl; external av__codec;
procedure av_init_packet(var pkt: TAVPacket); cdecl; external av__codec; deprecated;
function avcodec_version(): cuint; cdecl; external av__codec;
function av_codec_is_decoder(codec: PAVCodec): cint; cdecl; external av__codec;
function av_codec_iterate(opaque: ppointer): PAVCodec; cdecl; external av__codec;
Expand All @@ -253,5 +248,7 @@ function avcodec_send_packet(avctx: PAVCodecContext; avpkt: PAVPacket): cint; cd
function avcodec_alloc_context3(codec: PAVCodec): PAVCodecContext; cdecl; external av__codec;
procedure avcodec_free_context(avctx: PPAVCodecContext); cdecl; external av__codec;
function avcodec_parameters_to_context(codec: PAVCodecContext; par: PAVCodecParameters): cint; cdecl; external av__codec;
function av_packet_alloc(): PAVPacket; cdecl; external av__codec;
procedure av_packet_free(pkt: PPAVPacket); cdecl; external av__codec;
implementation
end.
2 changes: 1 addition & 1 deletion src/lib/ffmpeg-6.0/avformat.pas
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ function avformat_open_input(ps: PPAVFormatContext; url: PAnsiChar; fmt: PAVInpu
procedure avformat_close_input(s: PPAVFormatContext); cdecl; external av__format;
function avformat_version(): cuint; cdecl; external av__format;
function avformat_find_stream_info(ic: PAVFormatContext; options: PPAVDictionary): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; pkt: PAVPacket): cint; cdecl; external av__format;
function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint64; flags: cint): cint; cdecl; external av__format;
implementation
end.
13 changes: 7 additions & 6 deletions src/lib/ffmpeg-7.0/avcodec.pas
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ interface
AV_CODEC_ID_NONE
);
PAVPacket = ^TAVPacket;
PPAVPacket = ^PAVPacket;
TAVPacket = record
we_do_not_use_buf: pointer;
pts: cint64;
Expand All @@ -70,11 +71,10 @@ TAVPacket = record
opaque: pointer;
we_do_not_use_opaque_ref: pointer;
we_do_not_use_time_base: TAVRational;
end;
PAVPacketList = ^TAVPacketList;
TAVPacketList = record
pkt: TAVPacket;
next: ^TAVPacketList;
(* According to the FFmpeg documentation, sizeof(AVPacket) is
* deprecated for the public ABI. However, TAVPacket is still a member of
* TAVStream. So we can't put the incomplete record member because that will
* change the memory layout of TAVStream *)
end;
PAVCodecDescriptor = ^TAVCodecDescriptor;
TAVCodecDescriptor = record
Expand Down Expand Up @@ -227,7 +227,6 @@ TAVCodecContext = record
end;
function av_packet_ref(dst: PAVPacket; src: PAVPacket): cint; cdecl; external av__codec;
procedure av_packet_unref(pkt: PAVPacket); cdecl; external av__codec;
procedure av_init_packet(var pkt: TAVPacket); cdecl; external av__codec; deprecated;
function avcodec_version(): cuint; cdecl; external av__codec;
function av_codec_is_decoder(codec: PAVCodec): cint; cdecl; external av__codec;
function av_codec_iterate(opaque: ppointer): PAVCodec; cdecl; external av__codec;
Expand All @@ -241,5 +240,7 @@ function avcodec_send_packet(avctx: PAVCodecContext; avpkt: PAVPacket): cint; cd
function avcodec_alloc_context3(codec: PAVCodec): PAVCodecContext; cdecl; external av__codec;
procedure avcodec_free_context(avctx: PPAVCodecContext); cdecl; external av__codec;
function avcodec_parameters_to_context(codec: PAVCodecContext; par: PAVCodecParameters): cint; cdecl; external av__codec;
function av_packet_alloc(): PAVPacket; cdecl; external av__codec;
procedure av_packet_free(pkt: PPAVPacket); cdecl; external av__codec;
implementation
end.
2 changes: 1 addition & 1 deletion src/lib/ffmpeg-7.0/avformat.pas
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ function avformat_open_input(ps: PPAVFormatContext; url: PAnsiChar; fmt: PAVInpu
procedure avformat_close_input(s: PPAVFormatContext); cdecl; external av__format;
function avformat_version(): cuint; cdecl; external av__format;
function avformat_find_stream_info(ic: PAVFormatContext; options: PPAVDictionary): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; var pkt: TAVPacket): cint; cdecl; external av__format;
function av_read_frame(s: PAVFormatContext; pkt: PAVPacket): cint; cdecl; external av__format;
function av_seek_frame(s: PAVFormatContext; stream_index: cint; timestamp: cint64; flags: cint): cint; cdecl; external av__format;
implementation
end.
71 changes: 27 additions & 44 deletions src/media/UAudioDecoder_FFmpeg.pas
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,6 @@ TFFmpegDecodeStream = class(TAudioDecodeStream)
fDecoderResumeCond: PSDL_Cond;

// state-vars for DecodeFrame (locked by DecoderLock)
fAudioPaket: TAVPacket;
fAudioPaketSize: integer;
fAudioPaketSilence: integer; // number of bytes of silence to return

Expand Down Expand Up @@ -244,12 +243,6 @@ procedure TFFmpegDecodeStream.Reset();
fParserPauseRequestCount := 0;
fDecoderLocked := false;
fDecoderPauseRequestCount := 0;

FillChar(fAudioPaket, SizeOf(TAVPacket), 0);
{$IF (LIBAVFORMAT_VERSION >= 59000000)}
// avoid calling av_packet_unref before fetching first frame
fAudioPaket.data := Pointer(STATUS_PACKET);
{$ENDIF}
end;

{*
Expand Down Expand Up @@ -515,14 +508,6 @@ procedure TFFmpegDecodeStream.Close();
fFormatCtx := nil;
end;

{$IF (LIBAVFORMAT_VERSION < 59000000)}
if (fAudioPaket.data <> nil) then
av_free_packet(@fAudioPaket);
{$ELSE}
if (PAnsiChar(fAudioPaket.data) <> STATUS_PACKET) then
av_packet_unref(@fAudioPaket);
{$ENDIF}

PerformOnClose();

FreeAndNil(fPacketQueue);
Expand Down Expand Up @@ -741,7 +726,7 @@ procedure TFFmpegDecodeStream.Parse();
*)
function TFFmpegDecodeStream.ParseLoop(): boolean;
var
Packet: TAVPacket;
Packet: PAVPacket;
SeekTarget: int64;
ErrorCode: integer;
StartSilence: double; // duration of silence at start of stream
Expand Down Expand Up @@ -773,6 +758,7 @@ function TFFmpegDecodeStream.ParseLoop(): boolean;

begin
Result := true;
Packet := nil;

while LockParser() do
begin
Expand Down Expand Up @@ -858,6 +844,8 @@ function TFFmpegDecodeStream.ParseLoop(): boolean;
Continue;
end;

if (Packet = nil) then
Packet := av_packet_alloc();
errnum := av_read_frame(fFormatCtx, Packet);
if (errnum < 0) then
begin
Expand Down Expand Up @@ -896,20 +884,20 @@ function TFFmpegDecodeStream.ParseLoop(): boolean;
Break;
end;

if (Packet.stream_index = fAudioStreamIndex) then
fPacketQueue.Put(@Packet)
if (Packet^.stream_index = fAudioStreamIndex) then
begin
fPacketQueue.Put(Packet);
Packet := nil;
end
else
{$IF (LIBAVFORMAT_VERSION < 59000000)}
av_free_packet(@Packet);
{$ELSE}
av_packet_unref(@Packet);
{$ENDIF}
av_packet_unref(Packet);
complexlogic marked this conversation as resolved.
Show resolved Hide resolved

finally
SDL_LockMutex(fStateLock);
UnlockParser();
end;
end;
av_packet_free(@Packet);
if (IsQuit()) then
begin
Result := false;
Expand Down Expand Up @@ -989,6 +977,7 @@ procedure TFFmpegDecodeStream.FlushCodecBuffers();

function TFFmpegDecodeStream.DecodeFrame(): integer;
var
Packet: PAVPacket;
PaketDecodedSize: integer; // size of packet data used for decoding
DataSize: integer; // size of output data decoded by FFmpeg
BlockQueue: boolean;
Expand All @@ -999,6 +988,7 @@ function TFFmpegDecodeStream.DecodeFrame(): integer;
{$ENDIF}
begin
Result := -1;
Packet := nil;

if (EOF) then
Exit;
Expand Down Expand Up @@ -1061,15 +1051,6 @@ function TFFmpegDecodeStream.DecodeFrame(): integer;
Exit;
end;

// free old packet data
{$IF (LIBAVFORMAT_VERSION < 59000000)}
if (fAudioPaket.data <> nil) then
av_free_packet(@fAudioPaket);
{$ELSE}
if (PAnsiChar(fAudioPaket.data) <> STATUS_PACKET) then
av_packet_unref(@fAudioPaket);
{$ENDIF}

// do not block queue on seeking (to avoid deadlocks on the DecoderLock)
if (IsSeeking()) then
BlockQueue := false
Expand All @@ -1078,18 +1059,15 @@ function TFFmpegDecodeStream.DecodeFrame(): integer;

// request a new packet and block if none available.
// If this fails, the queue was aborted.
if (fPacketQueue.Get(fAudioPaket, BlockQueue) <= 0) then
if (fPacketQueue.Get(Packet, BlockQueue) <= 0) then
Exit;

// handle Status-packet
if (PAnsiChar(fAudioPaket.data) = STATUS_PACKET) then
if (PAnsiChar(Packet^.data) = STATUS_PACKET) then
begin
{$IF (LIBAVFORMAT_VERSION < 59000000)}
fAudioPaket.data := nil;
{$ENDIF}
fAudioPaketSize := 0;

case (fAudioPaket.flags) of
case (Packet^.flags) of
PKT_STATUS_FLAG_FLUSH:
begin
// just used if SetPositionIntern was called without the flush flag.
Expand All @@ -1101,46 +1079,51 @@ function TFFmpegDecodeStream.DecodeFrame(): integer;
if (not IsSeeking()) then
SetEOF(true);
// buffer contains no data -> result = -1
av_packet_free(@Packet);
Exit;
end;
PKT_STATUS_FLAG_ERROR:
begin
SetError(true);
Log.LogStatus('I/O Error', 'TFFmpegDecodeStream.DecodeFrame');
av_packet_free(@Packet);
Exit;
end;
PKT_STATUS_FLAG_EMPTY:
begin
SilenceDuration := PDouble(fPacketQueue.GetStatusInfo(fAudioPaket))^;
SilenceDuration := PDouble(fPacketQueue.GetStatusInfo(Packet))^;
fAudioPaketSilence := Round(SilenceDuration * fFormatInfo.SampleRate) * fFormatInfo.FrameSize;
fPacketQueue.FreeStatusInfo(fAudioPaket);
fPacketQueue.FreeStatusInfo(Packet);
end
else
begin
Log.LogStatus('Unknown status', 'TFFmpegDecodeStream.DecodeFrame');
end;
end;

av_packet_free(@Packet);
Continue;
end;

fAudioPaketSize := fAudioPaket.size;
fAudioPaketSize := Packet^.size;

avcodec_send_packet(fCodecCtx, @fAudioPaket);
avcodec_send_packet(fCodecCtx, Packet);

// if available, update the stream position to the presentation time of this package
if(fAudioPaket.pts <> AV_NOPTS_VALUE) then
if(Packet^.pts <> AV_NOPTS_VALUE) then
begin
{$IFDEF DebugFFmpegDecode}
TmpPos := fAudioStreamPos;
{$ENDIF}
fAudioStreamPos := av_q2d(fAudioStream^.time_base) * fAudioPaket.pts;
fAudioStreamPos := av_q2d(fAudioStream^.time_base) * Packet^.pts;
{$IFDEF DebugFFmpegDecode}
DebugWriteln('Timestamp: ' + floattostrf(fAudioStreamPos, ffFixed, 15, 3) + ' ' +
'(Calc: ' + floattostrf(TmpPos, ffFixed, 15, 3) + '), ' +
'Diff: ' + floattostrf(fAudioStreamPos-TmpPos, ffFixed, 15, 3));
{$ENDIF}
end;

av_packet_free(@Packet);
end;
end;

Expand Down
Loading
Loading