mirror of
				https://gitlab.alpinelinux.org/alpine/aports.git
				synced 2025-10-31 08:21:49 +01:00 
			
		
		
		
	
		
			
				
	
	
		
			356 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			356 lines
		
	
	
		
			16 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| # source: https://github.com/FFMS/ffms2/pull/380
 | |
| diff --git a/configure.ac b/configure.ac
 | |
| index b35ef80bcd..d19714d0f6 100644
 | |
| --- a/configure.ac
 | |
| +++ b/configure.ac
 | |
| @@ -102,10 +102,10 @@ CFLAGS="$_CFLAGS $FFMPEG_CFLAGS"
 | |
|  
 | |
|  AC_DEFUN([TEST_FFMPEG],
 | |
|           [AC_LINK_IFELSE([AC_LANG_PROGRAM([[
 | |
| -            #include <libavcodec/avcodec.h>
 | |
| +            #include <libavformat/avformat.h>
 | |
|              #include <libswscale/swscale.h>
 | |
|              ]],[[
 | |
| -                avcodec_register_all();
 | |
| +                avformat_network_init();
 | |
|                  swscale_version();
 | |
|              ]])], [eval $1=yes], [eval $1=no])
 | |
|          ])
 | |
| diff --git a/src/core/audiosource.cpp b/src/core/audiosource.cpp
 | |
| index 37cf9aeefd..ac0966636f 100644
 | |
| --- a/src/core/audiosource.cpp
 | |
| +++ b/src/core/audiosource.cpp
 | |
| @@ -285,10 +285,15 @@ FFMS_AudioSource::AudioBlock *FFMS_AudioSource::CacheBlock(CacheIterator &pos) {
 | |
|  int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
 | |
|      CurrentFrame = &Frames[PacketNumber];
 | |
|  
 | |
| -    AVPacket Packet;
 | |
| -    if (!ReadPacket(&Packet))
 | |
| +    AVPacket *Packet = av_packet_alloc();
 | |
| +    if (!Packet)
 | |
| +        throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_ALLOCATION_FAILED,
 | |
| +            "Could not allocate packet.");
 | |
| +    if (!ReadPacket(Packet)) {
 | |
| +        av_packet_free(&Packet);
 | |
|          throw FFMS_Exception(FFMS_ERROR_PARSER, FFMS_ERROR_UNKNOWN,
 | |
|              "ReadPacket unexpectedly failed to read a packet");
 | |
| +    }
 | |
|  
 | |
|      // ReadPacket may have changed the packet number
 | |
|      CurrentFrame = &Frames[PacketNumber];
 | |
| @@ -297,8 +302,9 @@ int FFMS_AudioSource::DecodeNextBlock(CacheIterator *pos) {
 | |
|      int NumberOfSamples = 0;
 | |
|      AudioBlock *CachedBlock = nullptr;
 | |
|      
 | |
| -    int Ret = avcodec_send_packet(CodecContext, &Packet);
 | |
| -    av_packet_unref(&Packet);
 | |
| +    int Ret = avcodec_send_packet(CodecContext, Packet);
 | |
| +    av_packet_unref(Packet);
 | |
| +    av_packet_free(&Packet);
 | |
|  
 | |
|      av_frame_unref(DecodeFrame);
 | |
|      Ret = avcodec_receive_frame(CodecContext, DecodeFrame);
 | |
| @@ -463,7 +469,7 @@ void FFMS_AudioSource::OpenFile() {
 | |
|  
 | |
|      LAVFOpenFile(SourceFile.c_str(), FormatContext, TrackNumber);
 | |
|  
 | |
| -    AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
 | |
| +    auto *Codec = avcodec_find_decoder(FormatContext->streams[TrackNumber]->codecpar->codec_id);
 | |
|      if (Codec == nullptr)
 | |
|          throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
 | |
|              "Audio codec not found");
 | |
| @@ -513,8 +519,6 @@ void FFMS_AudioSource::Seek() {
 | |
|  }
 | |
|  
 | |
|  bool FFMS_AudioSource::ReadPacket(AVPacket *Packet) {
 | |
| -    InitNullPacket(*Packet);
 | |
| -
 | |
|      while (av_read_frame(FormatContext, Packet) >= 0) {
 | |
|          if (Packet->stream_index == TrackNumber) {
 | |
|              // Required because not all audio packets, especially in ogg, have a pts. Use the previous valid packet's pts instead.
 | |
| diff --git a/src/core/indexing.cpp b/src/core/indexing.cpp
 | |
| index 23fb95b128..59fb4e8ea8 100644
 | |
| --- a/src/core/indexing.cpp
 | |
| +++ b/src/core/indexing.cpp
 | |
| @@ -320,7 +320,7 @@ void FFMS_Indexer::CheckAudioProperties(int Track, AVCodecContext *Context) {
 | |
|      }
 | |
|  }
 | |
|  
 | |
| -void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict,
 | |
| +void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict,
 | |
|                                      int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct) {
 | |
|      if (VideoContext.Parser) {
 | |
|          uint8_t *OB;
 | |
| @@ -330,8 +330,8 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
 | |
|          av_parser_parse2(VideoContext.Parser,
 | |
|              VideoContext.CodecContext,
 | |
|              &OB, &OBSize,
 | |
| -            pkt.data, pkt.size,
 | |
| -            pkt.pts, pkt.dts, pkt.pos);
 | |
| +            pkt->data, pkt->size,
 | |
| +            pkt->pts, pkt->dts, pkt->pos);
 | |
|  
 | |
|          // H.264 (PAFF) and HEVC may have one field per packet, so we need to track
 | |
|          // when we have a full or half frame available, and mark one of them as
 | |
| @@ -351,15 +351,15 @@ void FFMS_Indexer::ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt
 | |
|  
 | |
|          *RepeatPict = VideoContext.Parser->repeat_pict;
 | |
|          *FrameType = VideoContext.Parser->pict_type;
 | |
| -        *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt.flags & AV_PKT_FLAG_DISCARD));
 | |
| +        *Invisible = (IncompleteFrame || VideoContext.Parser->repeat_pict < 0 || (pkt->flags & AV_PKT_FLAG_DISCARD));
 | |
|      } else {
 | |
| -        *Invisible = !!(pkt.flags & AV_PKT_FLAG_DISCARD);
 | |
| +        *Invisible = !!(pkt->flags & AV_PKT_FLAG_DISCARD);
 | |
|      }
 | |
|  
 | |
|      if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP8)
 | |
| -        ParseVP8(pkt.data[0], Invisible, FrameType);
 | |
| +        ParseVP8(pkt->data[0], Invisible, FrameType);
 | |
|      else if (VideoContext.CodecContext->codec_id == AV_CODEC_ID_VP9)
 | |
| -        ParseVP9(pkt.data[0], Invisible, FrameType);
 | |
| +        ParseVP9(pkt->data[0], Invisible, FrameType);
 | |
|  }
 | |
|  
 | |
|  void FFMS_Indexer::Free() {
 | |
| @@ -384,7 +384,7 @@ FFMS_TrackType FFMS_Indexer::GetTrackType(int Track) {
 | |
|  }
 | |
|  
 | |
|  const char *FFMS_Indexer::GetTrackCodec(int Track) {
 | |
| -    AVCodec *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
 | |
| +    auto *codec = avcodec_find_decoder(FormatContext->streams[Track]->codecpar->codec_id);
 | |
|      return codec ? codec->name : nullptr;
 | |
|  }
 | |
|  
 | |
| @@ -402,7 +402,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|              UseDTS);
 | |
|  
 | |
|          if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
 | |
| -            AVCodec *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
 | |
| +            auto *VideoCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
 | |
|              if (!VideoCodec) {
 | |
|                  FormatContext->streams[i]->discard = AVDISCARD_ALL;
 | |
|                  IndexMask.erase(i);
 | |
| @@ -433,7 +433,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|                  IndexMask.insert(i);
 | |
|              }
 | |
|          } else if (IndexMask.count(i) && FormatContext->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
 | |
| -            AVCodec *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
 | |
| +            auto *AudioCodec = avcodec_find_decoder(FormatContext->streams[i]->codecpar->codec_id);
 | |
|              if (AudioCodec == nullptr)
 | |
|                  throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_UNSUPPORTED,
 | |
|                      "Audio codec not found");
 | |
| @@ -458,32 +458,36 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|          }
 | |
|      }
 | |
|  
 | |
| -    AVPacket Packet;
 | |
| -    InitNullPacket(Packet);
 | |
| +    AVPacket *Packet = av_packet_alloc();
 | |
| +    if (!Packet)
 | |
| +        throw FFMS_Exception(FFMS_ERROR_CODEC, FFMS_ERROR_ALLOCATION_FAILED,
 | |
| +            "Could not allocate packet.");
 | |
|      std::vector<int64_t> LastValidTS(FormatContext->nb_streams, AV_NOPTS_VALUE);
 | |
|  
 | |
|      int64_t filesize = avio_size(FormatContext->pb);
 | |
|      enum AVPictureStructure LastPicStruct = AV_PICTURE_STRUCTURE_UNKNOWN;
 | |
| -    while (av_read_frame(FormatContext, &Packet) >= 0) {
 | |
| +    while (av_read_frame(FormatContext, Packet) >= 0) {
 | |
|          // Update progress
 | |
|          // FormatContext->pb can apparently be NULL when opening images.
 | |
|          if (IC && FormatContext->pb) {
 | |
| -            if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate))
 | |
| +            if ((*IC)(FormatContext->pb->pos, filesize, ICPrivate)) {
 | |
| +                av_packet_free(&Packet);
 | |
|                  throw FFMS_Exception(FFMS_ERROR_CANCELLED, FFMS_ERROR_USER,
 | |
|                      "Cancelled by user");
 | |
| +            }
 | |
|          }
 | |
| -        if (!IndexMask.count(Packet.stream_index)) {
 | |
| -            av_packet_unref(&Packet);
 | |
| +        if (!IndexMask.count(Packet->stream_index)) {
 | |
| +            av_packet_unref(Packet);
 | |
|              continue;
 | |
|          }
 | |
|  
 | |
| -        int Track = Packet.stream_index;
 | |
| +        int Track = Packet->stream_index;
 | |
|          FFMS_Track &TrackInfo = (*TrackIndices)[Track];
 | |
| -        bool KeyFrame = !!(Packet.flags & AV_PKT_FLAG_KEY);
 | |
| +        bool KeyFrame = !!(Packet->flags & AV_PKT_FLAG_KEY);
 | |
|          ReadTS(Packet, LastValidTS[Track], (*TrackIndices)[Track].UseDTS);
 | |
|  
 | |
|          if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
 | |
| -            int64_t PTS = TrackInfo.UseDTS ? Packet.dts : Packet.pts;
 | |
| +            int64_t PTS = TrackInfo.UseDTS ? Packet->dts : Packet->pts;
 | |
|              if (PTS == AV_NOPTS_VALUE) {
 | |
|                  // VPx alt-refs are output as packets which lack timestmps or durations, since
 | |
|                  // they are invisible. Currently, the timestamp mangling code in libavformat
 | |
| @@ -495,9 +499,11 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|                  // FFMS2 currently sorts packets by PTS, which will break decoding, otherwise.
 | |
|                  bool HasAltRefs = (FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP8 ||
 | |
|                                     FormatContext->streams[Track]->codecpar->codec_id == AV_CODEC_ID_VP9);
 | |
| -                if (Packet.duration == 0 && !HasAltRefs)
 | |
| +                if (Packet->duration == 0 && !HasAltRefs) {
 | |
| +                    av_packet_free(&Packet);
 | |
|                      throw FFMS_Exception(FFMS_ERROR_INDEXING, FFMS_ERROR_PARSER,
 | |
|                          "Invalid packet pts, dts, and duration");
 | |
| +                }
 | |
|  
 | |
|                  if (TrackInfo.empty())
 | |
|                      PTS = 0;
 | |
| @@ -513,7 +519,7 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|              ParseVideoPacket(AVContexts[Track], Packet, &RepeatPict, &FrameType, &Invisible, &LastPicStruct);
 | |
|  
 | |
|              TrackInfo.AddVideoFrame(PTS, RepeatPict, KeyFrame,
 | |
| -                FrameType, Packet.pos, Invisible);
 | |
| +                FrameType, Packet->pos, Invisible);
 | |
|          } else if (FormatContext->streams[Track]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
 | |
|              // For video seeking timestamps are used only if all packets have
 | |
|              // timestamps, while for audio they're used if any have timestamps,
 | |
| @@ -522,28 +528,29 @@ FFMS_Index *FFMS_Indexer::DoIndexing() {
 | |
|                  TrackInfo.HasTS = true;
 | |
|  
 | |
|              int64_t StartSample = AVContexts[Track].CurrentSample;
 | |
| -            uint32_t SampleCount = IndexAudioPacket(Track, &Packet, AVContexts[Track], *TrackIndices);
 | |
| +            uint32_t SampleCount = IndexAudioPacket(Track, Packet, AVContexts[Track], *TrackIndices);
 | |
|              TrackInfo.SampleRate = AVContexts[Track].CodecContext->sample_rate;
 | |
|  
 | |
|              TrackInfo.AddAudioFrame(LastValidTS[Track],
 | |
| -                StartSample, SampleCount, KeyFrame, Packet.pos, Packet.flags & AV_PKT_FLAG_DISCARD);
 | |
| +                StartSample, SampleCount, KeyFrame, Packet->pos, Packet->flags & AV_PKT_FLAG_DISCARD);
 | |
|          }
 | |
|  
 | |
| -        if (!(Packet.flags & AV_PKT_FLAG_DISCARD))
 | |
| -            TrackInfo.LastDuration = Packet.duration;
 | |
| +        if (!(Packet->flags & AV_PKT_FLAG_DISCARD))
 | |
| +            TrackInfo.LastDuration = Packet->duration;
 | |
|  
 | |
| -        av_packet_unref(&Packet);
 | |
| +        av_packet_unref(Packet);
 | |
|      }
 | |
| +    av_packet_free(&Packet);
 | |
|  
 | |
|      TrackIndices->Finalize(AVContexts, FormatContext->iformat->name);
 | |
|      return TrackIndices.release();
 | |
|  }
 | |
|  
 | |
| -void FFMS_Indexer::ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS) {
 | |
| -    if (!UseDTS && Packet.pts != AV_NOPTS_VALUE)
 | |
| -        TS = Packet.pts;
 | |
| +void FFMS_Indexer::ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS) {
 | |
| +    if (!UseDTS && Packet->pts != AV_NOPTS_VALUE)
 | |
| +        TS = Packet->pts;
 | |
|      if (TS == AV_NOPTS_VALUE)
 | |
|          UseDTS = true;
 | |
| -    if (UseDTS && Packet.dts != AV_NOPTS_VALUE)
 | |
| -        TS = Packet.dts;
 | |
| +    if (UseDTS && Packet->dts != AV_NOPTS_VALUE)
 | |
| +        TS = Packet->dts;
 | |
|  }
 | |
| diff --git a/src/core/indexing.h b/src/core/indexing.h
 | |
| index 3cfc3c30b3..5c06868890 100644
 | |
| --- a/src/core/indexing.h
 | |
| +++ b/src/core/indexing.h
 | |
| @@ -80,10 +80,10 @@ struct FFMS_Indexer {
 | |
|      int64_t Filesize;
 | |
|      uint8_t Digest[20];
 | |
|  
 | |
| -    void ReadTS(const AVPacket &Packet, int64_t &TS, bool &UseDTS);
 | |
| +    void ReadTS(const AVPacket *Packet, int64_t &TS, bool &UseDTS);
 | |
|      void CheckAudioProperties(int Track, AVCodecContext *Context);
 | |
|      uint32_t IndexAudioPacket(int Track, AVPacket *Packet, SharedAVContext &Context, FFMS_Index &TrackIndices);
 | |
| -    void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket &pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
 | |
| +    void ParseVideoPacket(SharedAVContext &VideoContext, AVPacket *pkt, int *RepeatPict, int *FrameType, bool *Invisible, enum AVPictureStructure *LastPicStruct);
 | |
|      void Free();
 | |
|  public:
 | |
|      FFMS_Indexer(const char *Filename);
 | |
| diff --git a/src/core/utils.cpp b/src/core/utils.cpp
 | |
| index ce67533fd7..8a2e99710e 100644
 | |
| --- a/src/core/utils.cpp
 | |
| +++ b/src/core/utils.cpp
 | |
| @@ -62,12 +62,6 @@ void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo) {
 | |
|      }
 | |
|  }
 | |
|  
 | |
| -void InitNullPacket(AVPacket &pkt) {
 | |
| -    av_init_packet(&pkt);
 | |
| -    pkt.data = nullptr;
 | |
| -    pkt.size = 0;
 | |
| -}
 | |
| -
 | |
|  void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames) {
 | |
|      AP.SampleFormat = static_cast<FFMS_SampleFormat>(av_get_packed_sample_fmt(CTX->sample_fmt));
 | |
|      AP.BitsPerSample = av_get_bytes_per_sample(CTX->sample_fmt) * 8;
 | |
| diff --git a/src/core/utils.h b/src/core/utils.h
 | |
| index 9819dc7c9e..003ab794e9 100644
 | |
| --- a/src/core/utils.h
 | |
| +++ b/src/core/utils.h
 | |
| @@ -58,7 +58,6 @@ std::unique_ptr<T> make_unique(Args&&... args) {
 | |
|  }
 | |
|  
 | |
|  void ClearErrorInfo(FFMS_ErrorInfo *ErrorInfo);
 | |
| -void InitNullPacket(AVPacket &pkt);
 | |
|  void FillAP(FFMS_AudioProperties &AP, AVCodecContext *CTX, FFMS_Track &Frames);
 | |
|  
 | |
|  void LAVFOpenFile(const char *SourceFile, AVFormatContext *&FormatContext, int Track);
 | |
| diff --git a/src/core/videosource.cpp b/src/core/videosource.cpp
 | |
| index 06bd1610e1..8956c22566 100644
 | |
| --- a/src/core/videosource.cpp
 | |
| +++ b/src/core/videosource.cpp
 | |
| @@ -171,7 +171,7 @@ FFMS_VideoSource::FFMS_VideoSource(const char *SourceFile, FFMS_Index &Index, in
 | |
|  
 | |
|          LAVFOpenFile(SourceFile, FormatContext, VideoTrack);
 | |
|  
 | |
| -        AVCodec *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
 | |
| +        auto *Codec = avcodec_find_decoder(FormatContext->streams[VideoTrack]->codecpar->codec_id);
 | |
|          if (Codec == nullptr)
 | |
|              throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_CODEC,
 | |
|                  "Video codec not found");
 | |
| @@ -673,30 +673,34 @@ void FFMS_VideoSource::DecodeNextFrame(int64_t &AStartTime, int64_t &Pos) {
 | |
|      if (HasPendingDelayedFrames())
 | |
|          return;
 | |
|  
 | |
| -    AVPacket Packet;
 | |
| -    InitNullPacket(Packet);
 | |
| +    AVPacket *Packet = av_packet_alloc();
 | |
| +    if (!Packet)
 | |
| +        throw FFMS_Exception(FFMS_ERROR_DECODING, FFMS_ERROR_ALLOCATION_FAILED,
 | |
| +            "Could not allocate packet.");
 | |
|  
 | |
| -    while (ReadFrame(&Packet) >= 0) {
 | |
| -        if (Packet.stream_index != VideoTrack) {
 | |
| -            av_packet_unref(&Packet);
 | |
| +    while (ReadFrame(Packet) >= 0) {
 | |
| +        if (Packet->stream_index != VideoTrack) {
 | |
| +            av_packet_unref(Packet);
 | |
|              continue;
 | |
|          }
 | |
|  
 | |
|          if (AStartTime < 0)
 | |
| -            AStartTime = Frames.UseDTS ? Packet.dts : Packet.pts;
 | |
| +            AStartTime = Frames.UseDTS ? Packet->dts : Packet->pts;
 | |
|  
 | |
|          if (Pos < 0)
 | |
| -            Pos = Packet.pos;
 | |
| +            Pos = Packet->pos;
 | |
|  
 | |
| -        bool FrameFinished = DecodePacket(&Packet);
 | |
| -        av_packet_unref(&Packet);
 | |
| -        if (FrameFinished)
 | |
| +        bool FrameFinished = DecodePacket(Packet);
 | |
| +        av_packet_unref(Packet);
 | |
| +        if (FrameFinished) {
 | |
| +            av_packet_free(&Packet);
 | |
|              return;
 | |
| +        }
 | |
|      }
 | |
|  
 | |
|      // Flush final frames
 | |
| -    InitNullPacket(Packet);
 | |
| -    DecodePacket(&Packet);
 | |
| +    DecodePacket(Packet);
 | |
| +    av_packet_free(&Packet);
 | |
|  }
 | |
|  
 | |
|  bool FFMS_VideoSource::SeekTo(int n, int SeekOffset) {
 |