#include <pthread.h>
#ifndef DECODEAUDIO_DEMUX_H
#define DECODEAUDIO_DEMUX_H
extern "C" {
#include <libavcodec/avcodec.h>
#include <libavutil/avutil.h>
#include <libavformat/avformat.h>
#include <libswresample/swresample.h>
#include <libswscale/swscale.h>
}
class Demux {
public:
Demux ( ) ;
Demux ( const char * url_) ;
~ Demux ( ) ;
void setFile ( const char * url) ;
int demux ( ) ;
bool exit = false;
AVCodecParameters * get_audio_param ( ) ;
AVCodecParameters * get_video_param ( ) ;
int get_audio_index ( ) ;
int get_video_index ( ) ;
AVRational get_audio_time_base ( ) ;
int64_t get_duration ( ) ;
AVPacket * read_frame ( ) ;
int seek ( int ts) ;
void close ( ) ;
pthread_mutex_t seek_mutex;
AVFormatContext * Format_ctx = nullptr;
private:
const char * url = nullptr;
int ret = 0 ;
int audio_index = - 1 ;
int video_index = - 1 ;
AVCodecParameters * audio_codec_param = nullptr;
AVCodecParameters * video_codec_param = nullptr;
AVCodec * codec = nullptr;
AVCodecContext * codec_ctx = nullptr;
pthread_mutex_t mutex;
} ;
#endif
#endif
#include "Demux.h"
Demux: : Demux ( ) {
pthread_mutex_init ( & mutex, NULL ) ;
pthread_mutex_init ( & seek_mutex, NULL ) ;
LOGD ( "demux !初始化!" ) ;
}
Demux: : Demux ( const char * url_) {
this-> url = url_;
}
Demux: : ~ Demux ( ) {
close ( ) ;
LOGD ( "demux 退出1" ) ;
}
void Demux: : setFile ( const char * url) {
this-> url = url;
LOGD ( "url : %s" , url) ;
}
int Demux: : demux ( ) {
av_register_all ( ) ;
avformat_network_init ( ) ;
pthread_mutex_lock ( & mutex) ;
Format_ctx = avformat_alloc_context ( ) ;
if ( ! Format_ctx)
{
pthread_mutex_unlock ( & mutex) ;
LOGE ( "avformat_alloc_context err " ) ;
return - 1 ;
}
ret = avformat_open_input ( & Format_ctx, url, nullptr, nullptr) ;
if ( ret < 0 )
{
pthread_mutex_unlock ( & mutex) ;
char buf[ 1024 ] = { 0 } ;
av_strerror ( ret, buf, sizeof ( buf) ) ;
LOGE ( "avformat_open_input err, %s" , buf) ;
return - 1 ;
}
ret = avformat_find_stream_info ( Format_ctx, nullptr) ;
if ( ret < 0 )
{
LOGE ( "avformat_find_stream_info err" ) ;
pthread_mutex_unlock ( & mutex) ;
return - 1 ;
}
audio_index = av_find_best_stream ( Format_ctx, AVMEDIA_TYPE_AUDIO, - 1 , - 1 , nullptr, 0 ) ;
video_index = av_find_best_stream ( Format_ctx, AVMEDIA_TYPE_VIDEO, - 1 , - 1 , nullptr, 0 ) ;
audio_codec_param = avcodec_parameters_alloc ( ) ;
audio_codec_param = Format_ctx-> streams[ audio_index] -> codecpar;
if ( ! audio_codec_param)
{
LOGD ( " Format_ctx->streams[audio_index]->codecpar err" ) ;
pthread_mutex_unlock ( & mutex) ;
return - 1 ;
}
pthread_mutex_unlock ( & mutex) ;
return 0 ;
}
AVPacket * Demux: : read_frame ( ) {
pthread_mutex_lock ( & mutex) ;
AVPacket * pkt = av_packet_alloc ( ) ;
if ( ! Format_ctx)
{
pthread_mutex_unlock ( & mutex) ;
return nullptr;
}
ret = av_read_frame ( Format_ctx, pkt) ;
if ( ret < 0 )
{
char buf[ 1024 ] = { 0 } ;
av_strerror ( ret, buf, sizeof ( buf) ) ;
pthread_mutex_unlock ( & mutex) ;
LOGD ( "av_read_frame err %s" , buf) ;
pthread_mutex_unlock ( & mutex) ;
return nullptr;
}
if ( pkt-> stream_index == video_index)
{
pkt-> pts = pkt-> pts* ( 1000 * ( av_q2d ( Format_ctx-> streams[ pkt-> stream_index] -> time_base) ) ) ;
pkt-> dts = pkt-> dts* ( 1000 * ( av_q2d ( Format_ctx-> streams[ pkt-> stream_index] -> time_base) ) ) ;
}
pthread_mutex_unlock ( & mutex) ;
return pkt;
}