裸指针包装  
struct  AVIOContextDeleter  { void  operator ( ) ( AVIOContext * ptr)  {  avio_closep ( & ptr) ;  } 
} ; 
using  AVIOContextPtr =  std:: unique_ptr< AVIOContext, AVIOContextDeleter> ; struct  AVFormatCtxDeleter  { void  operator ( ) ( AVFormatContext * ptr)  {  avformat_close_input ( & ptr) ;  } 
} ; 
using  AVFormatCtxPtr =  std:: unique_ptr< AVFormatContext, AVFormatCtxDeleter> ; struct  AVCodecCtxDeleter  { void  operator ( ) ( AVCodecContext * ptr)  {  avcodec_free_context ( & ptr) ;  } 
} ; 
using  AVCodecCtxPtr =  std:: unique_ptr< AVCodecContext, AVCodecCtxDeleter> ; struct  AVPacketDeleter  { void  operator ( ) ( AVPacket * pkt)  {  av_packet_free ( & pkt) ;  } 
} ; 
using  AVPacketPtr =  std:: unique_ptr< AVPacket, AVPacketDeleter> ; struct  AVFrameDeleter  { void  operator ( ) ( AVFrame * ptr)  {  av_frame_free ( & ptr) ;  } 
} ; 
using  AVFramePtr =  std:: unique_ptr< AVFrame, AVFrameDeleter> ; struct  SwrContextDeleter  { void  operator ( ) ( SwrContext * ptr)  {  swr_free ( & ptr) ;  } 
} ; 
using  SwrContextPtr =  std:: unique_ptr< SwrContext, SwrContextDeleter> ; struct  SwsContextDeleter  { void  operator ( ) ( SwsContext * ptr)  {  sws_freeContext ( ptr) ;  } 
} ; 
using  SwsContextPtr =  std:: unique_ptr< SwsContext, SwsContextDeleter> ;   
 对象  
struct  ChannelLayout  :  public  AVChannelLayout   { ChannelLayout ( )  :  AVChannelLayout{ }  {  } ~ ChannelLayout ( )  {  av_channel_layout_uninit ( this ) ;  } 
} ; 
  
 智能指针使用和轮子—解包队列  
template < size_t SizeLimit> 
class  DataQueue  { std:: mutex mPacketMutex,  mFrameMutex; std:: condition_variable mPacketCond; std:: condition_variable mInFrameCond,  mOutFrameCond; std:: deque< AVPacketPtr>  mPackets; size_t mTotalSize{ 0 } ; bool  mFinished{ false } ; AVPacketPtr getPacket ( ) { std:: unique_lock< std:: mutex>  plock{ mPacketMutex} ; while ( mPackets. empty ( )  &&  ! mFinished) mPacketCond. wait ( plock) ; if ( mPackets. empty ( ) ) return  nullptr ; auto  ret =  std:: move ( mPackets. front ( ) ) ; mPackets. pop_front ( ) ; mTotalSize -=  static_cast < unsigned  int > ( ret-> size) ; return  ret; } public : int  sendPacket ( AVCodecContext * codecctx) { AVPacketPtr packet{ getPacket ( ) } ; int  ret{ } ; { std:: unique_lock< std:: mutex>  flock{ mFrameMutex} ; while ( ( ret= avcodec_send_packet ( codecctx,  packet. get ( ) ) )  ==  AVERROR ( EAGAIN) ) mInFrameCond. wait_for ( flock,  milliseconds{ 50 } ) ; } mOutFrameCond. notify_one ( ) ; if ( ! packet) { if ( ! ret)  return  AVErrorEOF; std:: cerr<<  "Failed to send flush packet: " << ret << std:: endl; return  ret; } if ( ret <  0 ) std:: cerr<<  "Failed to send packet: " << ret << std:: endl; return  ret; } int  receiveFrame ( AVCodecContext * codecctx,  AVFrame * frame) { int  ret{ } ; { std:: unique_lock< std:: mutex>  flock{ mFrameMutex} ; while ( ( ret= avcodec_receive_frame ( codecctx,  frame) )  ==  AVERROR ( EAGAIN) ) mOutFrameCond. wait_for ( flock,  milliseconds{ 50 } ) ; } mInFrameCond. notify_one ( ) ; return  ret; } void  setFinished ( ) { { std:: lock_guard< std:: mutex>  _{ mPacketMutex} ; mFinished =  true ; } mPacketCond. notify_one ( ) ; } void  flush ( ) { { std:: lock_guard< std:: mutex>  _{ mPacketMutex} ; mFinished =  true ; mPackets. clear ( ) ; mTotalSize =  0 ; } mPacketCond. notify_one ( ) ; } bool  put ( const  AVPacket * pkt) { { std:: unique_lock< std:: mutex>  lock{ mPacketMutex} ; if ( mTotalSize >=  SizeLimit ||  mFinished) return  false ; mPackets. push_back ( AVPacketPtr{ av_packet_alloc ( ) } ) ; if ( av_packet_ref ( mPackets. back ( ) . get ( ) ,  pkt)  !=  0 ) { mPackets. pop_back ( ) ; return  true ; } mTotalSize +=  static_cast < unsigned  int > ( mPackets. back ( ) -> size) ; } mPacketCond. notify_one ( ) ; return  true ; } 
} ;