Parcourir la source

新增音频数据回调

huihui il y a 3 mois
Parent
commit
b4849aa175

+ 2 - 0
module/VideoPlayer/src/PcmPlayer/PcmPlayer.h

@@ -32,6 +32,7 @@ public:
 
     uint32_t getCurrentPts(){return m_current_pts;}
 
+    void setSpeed(float speed){m_play_speed = speed;}    
     void setMute(const bool is_mute){m_is_mute = is_mute;}
     void setVolume(float value){m_volume = value;}
     float getVolume(){return m_volume;}
@@ -43,6 +44,7 @@ protected:
     std::mutex m_mutex_audio;
     std::condition_variable m_cond_audio;
     std::list<PCMFramePtr> m_pcm_frame_list;
+    float m_play_speed = 1.0f; //倍速播放
     
     /// 用于存放上一次未处理完的数据
     uint8_t m_last_frame_buffer[10240];

+ 98 - 3
module/VideoPlayer/src/VideoPlayer/VideoPlayer.cpp

@@ -22,6 +22,7 @@ VideoPlayer::VideoPlayer()
     mVolume = 1;
 
     m_pcm_player = new PcmPlayer_SDL();
+    m_pcm_player->setSpeed(m_speed);
 
     this->setSingleMode(true);
 
@@ -166,10 +167,12 @@ void VideoPlayer::seek(int64_t pos)
     }
 }
 
-void VideoPlayer::setAbility(bool video_decode, bool encoded_video_callback)
+void VideoPlayer::setAbility(bool video_decode, bool encoded_video_callback, bool audio_play, bool encoded_audio_callback)
 {
     m_enable_video_decode = video_decode;
     m_enable_encoded_video_callback = encoded_video_callback;
+    m_enable_audio_play = audio_play;
+    m_enable_encoded_audio_callback = encoded_audio_callback;
 }
 
 void VideoPlayer::setMute(bool isMute)
@@ -307,6 +310,7 @@ void VideoPlayer::run()
 
     swrCtx = nullptr;
 
+    AVBSFContext *bsf_ctx = nullptr;
     mAudioStream = nullptr;
     mVideoStream = nullptr;
 
@@ -394,6 +398,53 @@ printf("%s:%d pFormatCtx->nb_streams=%d \n", __FILE__, __LINE__, pFormatCtx->nb_
 
         mVideoStream = video_stream;
 
+        if (!m_is_live_mode && m_enable_encoded_video_callback)
+        {
+            ///如果需要回调解码前的数据,则需要设置AVBitStreamFilter
+            ///用于添加起始码和sps/pps
+            do{
+                //设置AVBitStreamFilter
+                int ret;
+                const AVBitStreamFilter *filter = nullptr;
+
+                if (mVideoStream->codecpar->codec_id == AV_CODEC_ID_H264) 
+                {
+                    filter = av_bsf_get_by_name("h264_mp4toannexb");
+                } 
+                else if (mVideoStream->codecpar->codec_id == AV_CODEC_ID_HEVC) 
+                {
+                    filter = av_bsf_get_by_name("hevc_mp4toannexb");
+                }
+
+                if (!filter) 
+                {
+                    printf("Unkonw bitstream filter");
+                    break;
+                }
+
+                ret = av_bsf_alloc(filter, &bsf_ctx);
+                if (ret < 0) 
+                {
+                    printf("alloc bsf error");
+                    break;
+                }
+
+                ret = avcodec_parameters_copy(bsf_ctx->par_in, mVideoStream->codecpar);
+                if (ret < 0)
+                {
+                    printf("copy bsf error");
+
+                    av_bsf_free(&bsf_ctx);
+                    bsf_ctx = nullptr;
+
+                    break;
+                }
+
+                av_bsf_init(bsf_ctx);
+
+            }while(0);
+        }
+
         ///启动视频解码线程
         m_thread_video->start();
     }
@@ -671,8 +722,26 @@ std::cout<<" video:"<<pFormatCtx->streams[videoStream]->duration<<" "<<pFormatCt
 // fprintf(stderr, "%s mIsQuit=%d mIsPause=%d packet.stream_index=%d videoStream=%d audioStream=%d \n", __FUNCTION__, mIsQuit, mIsPause, packet.stream_index, videoStream, audioStream);
         if (packet.stream_index == videoStream)
         {
-            inputVideoQuene(packet);
-            //这里我们将数据存入队列 因此不调用 av_free_packet 释放
+            if (bsf_ctx)
+            {
+                if (av_bsf_send_packet(bsf_ctx, &packet) < 0) 
+                {
+                    // JLOGE("send_packet error");
+                    av_packet_unref(&packet);
+                    continue;
+                }
+
+                while (av_bsf_receive_packet(bsf_ctx, &packet) == 0) 
+                {
+                    inputVideoQuene(packet);
+                    //这里我们将数据存入队列 因此不调用 av_free_packet 释放
+                    //av_packet_unref(&packet);
+                }
+            }
+            else
+            {
+                inputVideoQuene(packet);
+            }
         }
         else if(packet.stream_index == audioStream)
         {
@@ -695,6 +764,26 @@ std::cout<<" video:"<<pFormatCtx->streams[videoStream]->duration<<" "<<pFormatCt
 // fprintf(stderr, "%s:%d \n", __FILE__, __LINE__);
     }
 
+    if (bsf_ctx)
+    {
+        //flush
+        if (av_bsf_send_packet(bsf_ctx, NULL) < 0)
+        {
+            // fprintf(stderr, "send_packet error");
+            // break;
+        }
+
+        AVPacket pkt;
+        while (av_bsf_receive_packet(bsf_ctx, &pkt) == 0)
+        {
+            av_packet_unref(&pkt);
+        }
+
+        // av_bsf_free(&bsf_ctx);
+
+    //    printf("bsf_ctx fflush finish\n");
+    }
+
     ///文件读取结束 跳出循环的情况
     ///等待播放完毕
     while (!mIsQuit)
@@ -724,6 +813,12 @@ fprintf(stderr, "%s:%d mIsVideoThreadFinished=%d mIsAudioThreadFinished=%d \n",
     m_pcm_player->stopPlay();
     m_pcm_player->clearFrame();
 
+    if (bsf_ctx)
+    {
+        av_bsf_free(&bsf_ctx);
+        bsf_ctx = nullptr;
+    }
+
     if (swrCtx != nullptr)
     {
         swr_free(&swrCtx);

+ 11 - 7
module/VideoPlayer/src/VideoPlayer/VideoPlayer.h

@@ -36,9 +36,10 @@ extern "C"
 ///启用滤镜,用于旋转带角度的视频
 #define CONFIG_AVFILTER 1
 
-#include "types.h"
-#include "PcmPlayer/PcmPlayer.h"
+#include "../types.h"
 #include "util/thread.h"
+#include "PcmPlayer/PcmPlayer.h"
+#include "frame/AudioFrame/AACFrame.h"
 #include "frame/VideoFrame/VideoFrame.h"
 
 #define SDL_AUDIO_BUFFER_SIZE 1024
@@ -84,8 +85,9 @@ public:
         ///播放视频,此函数不宜做耗时操作,否则会影响播放的流畅性。
         virtual void onDisplayVideo(VideoRawFramePtr videoFrame) = 0;
 
-        virtual void onVideoBuffer(VideoEncodedFramePtr videoFrame){};
-        // virtual void onAudioBuffer(VideoRawFramePtr videoFrame) = 0;
+        virtual void onVideoBuffer(VideoEncodedFramePtr video_frame){};
+        virtual void onAudioBuffer(AACFramePtr audio_frame){};
+        virtual void onAudioBuffer(PCMFramePtr audio_frame){};
     };
 
 public:
@@ -120,7 +122,7 @@ public:
      * 此函数用于配置对象的视频处理能力,包括是否支持视频解码和是否支持编码后视频的回调
      * 通过设置这些参数,可以控制对象在视频处理过程中的行为和功能
      */
-    void setAbility(bool video_decode, bool encoded_video_callback);
+    void setAbility(bool video_decode, bool encoded_video_callback, bool audio_play, bool encoded_audio_callback);
 
     void setMute(bool isMute);
     void setVolume(float value);
@@ -145,6 +147,7 @@ protected:
 private:
     std::string m_file_path; //视频文件路径
     bool m_is_live_mode = false; //是否为直播流
+    float m_speed = 1; //倍速播放
 
     State m_state; //播放状态
 
@@ -231,7 +234,7 @@ private:
     bool inputVideoQuene(const AVPacket &pkt);
     void clearVideoQuene();
     bool m_enable_video_decode = true;
-    bool m_enable_encoded_video_callback = false; //是否回调解码之前的数据
+    bool m_enable_encoded_video_callback = false; //是否回调解码之前的视频数据
 
     ///音频帧队列
     Thread *m_thread_audio = nullptr;
@@ -240,7 +243,8 @@ private:
     std::list<AVPacket> m_audio_pkt_list;
     bool inputAudioQuene(const AVPacket &pkt);
     void clearAudioQuene();
-    // bool m_enable_audio_decode = false;
+    bool m_enable_audio_play = true; //是否播放音频
+    bool m_enable_encoded_audio_callback = false; //是否回调解码之前的音频数据
 
 //    ///本播放器中SDL仅用于播放音频,不用做别的用途
 //    ///SDL播放音频相关

+ 118 - 12
module/VideoPlayer/src/VideoPlayer/VideoPlayer_AudioThread.cpp

@@ -11,6 +11,47 @@
 #include <iostream>
 #include <stdio.h>
 
+static void addADTStoPacket(uint8_t* packet, int packetLen, int channel, int sample_rate)
+{
+    int profile = 2;  //AAC LC,MediaCodecInfo.CodecProfileLevel.AACObjectLC;
+    int freqIdx = 8;  //16K, 见后面注释avpriv_mpeg4audio_sample_rates中32000对应的数组下标,来自ffmpeg源码
+    int chanCfg = channel;  //见后面注释channel_configuration,Stero双声道立体声
+
+    int avpriv_mpeg4audio_sample_rates[] = {
+        96000, 88200, 64000, 48000, 44100, 32000,
+        24000, 22050, 16000, 12000, 11025, 8000, 7350
+    };
+    /*channel_configuration: 表示声道数chanCfg
+    0: Defined in AOT Specifc Config
+    1: 1 channel: front-center
+    2: 2 channels: front-left, front-right
+    3: 3 channels: front-center, front-left, front-right
+    4: 4 channels: front-center, front-left, front-right, back-center
+    5: 5 channels: front-center, front-left, front-right, back-left, back-right
+    6: 6 channels: front-center, front-left, front-right, back-left, back-right, LFE-channel
+    7: 8 channels: front-center, front-left, front-right, side-left, side-right, back-left, back-right, LFE-channel
+    8-15: Reserved
+    */
+
+    for (int i=0; i<13; i++)
+    {
+        if (avpriv_mpeg4audio_sample_rates[i] == sample_rate)
+        {
+            freqIdx = i;
+            break;
+        }
+    }
+
+    // fill in ADTS data
+    packet[0] = (uint8_t)0xFF;
+    packet[1] = (uint8_t)0xF9;
+    packet[2] = (uint8_t)(((profile-1)<<6) + (freqIdx<<2) +(chanCfg>>2));
+    packet[3] = (uint8_t)(((chanCfg&3)<<6) + (packetLen>>11));
+    packet[4] = (uint8_t)((packetLen&0x7FF) >> 3);
+    packet[5] = (uint8_t)(((packetLen&7)<<5) + 0x1F);
+    packet[6] = (uint8_t)0xFC;
+}
+
 void VideoPlayer::decodeAudioThread()
 {
     fprintf(stderr, "%s start \n", __FUNCTION__);
@@ -47,23 +88,89 @@ void VideoPlayer::decodeAudioThread()
             continue;
         }
 
-        AVPacket packet = m_audio_pkt_list.front();
+        AVPacket pkt = m_audio_pkt_list.front();
         m_audio_pkt_list.pop_front();
         lck.unlock();
 
-        AVPacket *pkt = &packet;
+        AVPacket *packet = &pkt;
 
         /* if update, update the audio clock w/pts */
-        if (pkt->pts != AV_NOPTS_VALUE)
+        if (packet->pts != AV_NOPTS_VALUE)
+        {
+            pts_ms = av_q2d(mAudioStream->time_base) * packet->pts * 1000;
+        }
+
+        if (!m_enable_audio_play) //音频播放未启用,则把音频同步到外部时钟
+        {
+            int64_t audio_pts = 0; //音频pts
+            if (packet->dts != AV_NOPTS_VALUE)
+            {
+                audio_pts = packet->dts;
+            }
+            else
+            {
+                audio_pts = 0;
+            }
+
+            if (audio_pts < 0)
+            {
+                audio_pts = 0;
+            }
+
+            audio_pts *= av_q2d(mAudioStream->time_base) * m_speed * 1000;
+            audio_clock = audio_pts;
+            ///音频同步到外部时钟
+            uint64_t realTime = 0;
+            do
+            {
+                mSleep(5);
+                realTime = (av_gettime() - mVideoStartTime) * m_speed / 1000; //毫秒
+            }while(!m_is_stop && audio_pts > (realTime-10));
+        }
+
+        if (m_event_handle && m_enable_encoded_audio_callback)
         {
-            pts_ms = av_q2d(mAudioStream->time_base) * pkt->pts * 1000;
+            // printf("%s:%d mAudioStream->codecpar->codec_id=%d %d\n", __FILE__, __LINE__, mAudioStream->codecpar->codec_id, AV_CODEC_ID_AAC);
+            if (mAudioStream->codecpar->codec_id == AV_CODEC_ID_AAC) 
+            {
+                //回调AAC数据
+                uint8_t adtsBuffer[7] = {0};
+                addADTStoPacket(adtsBuffer, 7 + packet->size, aCodecCtx->channels, aCodecCtx->sample_rate);
+
+                AACFramePtr aac_frame = std::make_shared<AACFrame>();
+                aac_frame->setFrameBuffer(adtsBuffer, 7, packet->data, packet->size);
+
+                m_event_handle->onAudioBuffer(aac_frame);
+            }
+            else if(mAudioStream->codecpar->codec_id == AV_CODEC_ID_PCM_MULAW)
+            {
+                //回调PCMU数据
+                PCMFramePtr audio_frame = std::make_shared<PCMFrame>();
+                audio_frame->setFrameBuffer(packet->data, packet->size);
+                audio_frame->setFrameInfo(aCodecCtx->sample_rate, aCodecCtx->channels, audio_clock, PCMFrame::PCMFRAME_TYPE_PCMU);
+                m_event_handle->onAudioBuffer(audio_frame);
+            }
+            else if(mAudioStream->codecpar->codec_id == AV_CODEC_ID_PCM_ALAW)
+            {
+                //回调PCMA数据
+                PCMFramePtr audio_frame = std::make_shared<PCMFrame>();
+                audio_frame->setFrameBuffer(packet->data, packet->size);
+                audio_frame->setFrameInfo(aCodecCtx->sample_rate, aCodecCtx->channels, audio_clock, PCMFrame::PCMFRAME_TYPE_PCMA);
+                m_event_handle->onAudioBuffer(audio_frame);
+            }
+        }
+
+        if (!m_enable_audio_play)
+        {
+            av_packet_unref(packet);
+            continue;
         }
 
         //收到这个数据 说明刚刚执行过跳转 现在需要把解码器的数据 清除一下
-        if(strcmp((char*)pkt->data,FLUSH_DATA) == 0)
+        if(strcmp((char*)packet->data,FLUSH_DATA) == 0)
         {
             avcodec_flush_buffers(aCodecCtx);
-            av_packet_unref(pkt);
+            av_packet_unref(packet);
             continue;
         }
 
@@ -91,7 +198,7 @@ void VideoPlayer::decodeAudioThread()
         }
 
         //解码AVPacket->AVFrame
-        if (int ret = avcodec_send_packet(aCodecCtx, &packet) && ret != 0)
+        if (int ret = avcodec_send_packet(aCodecCtx, packet) && ret != 0)
         {
            char buffer[1024] = {0};
            av_strerror(ret, buffer, 1024);
@@ -198,11 +305,10 @@ void VideoPlayer::decodeAudioThread()
                     
 // std::cout<<resampled_data_size<<" "<<audio_frame_size<<" "<<audio_clock<<" "<<pts_ms<<std::endl;
                 }
-
             }
         }
 
-        av_packet_unref(&packet);
+        av_packet_unref(packet);
     }
 
     ///等待播放完成
@@ -259,13 +365,13 @@ void VideoPlayer::decodeAudioThread()
 //         AVPacket *pkt = &packet;
 
 //         /* if update, update the audio clock w/pts */
-//         if (pkt->pts != AV_NOPTS_VALUE)
+//         if (packet->pts != AV_NOPTS_VALUE)
 //         {
-//             pts_s = av_q2d(mAudioStream->time_base) * pkt->pts;
+//             pts_s = av_q2d(mAudioStream->time_base) * packet->pts;
 //         }
 
 //         //收到这个数据 说明刚刚执行过跳转 现在需要把解码器的数据 清除一下
-//         if(strcmp((char*)pkt->data,FLUSH_DATA) == 0)
+//         if(strcmp((char*)packet->data,FLUSH_DATA) == 0)
 //         {
 //             avcodec_flush_buffers(aCodecCtx);
 //             av_packet_unref(pkt);

+ 29 - 3
module/VideoPlayer/src/VideoPlayer/VideoPlayer_VideoThread.cpp

@@ -252,6 +252,7 @@ void VideoPlayer::decodeVideoThread()
 
     auto avSyncFunc = [&]
     {
+        ///视频同步到音频
         ///音视频同步,实现的原理就是,判断是否到显示此帧图像的时间了,没到则休眠5ms,然后继续判断
         while(1)
         {
@@ -275,7 +276,7 @@ void VideoPlayer::decodeVideoThread()
             else
             {
                 ///没有音频或者音频设备打开失败的情况下,直接同步到外部时钟
-                audio_pts = (av_gettime() - mVideoStartTime) / 1000; //毫秒
+                audio_pts = (av_gettime() - mVideoStartTime) * m_speed / 1000; //毫秒
                 // std::lock_guard<std::mutex> lck(m_mutex_audio_clk);
                 audio_clock = audio_pts;
             }
@@ -358,10 +359,35 @@ void VideoPlayer::decodeVideoThread()
             //处理视频数据,直接回调未解码前的数据
             int key_frame = (packet->flags & AV_PKT_FLAG_KEY);
 
+            T_NALU_TYPE nalu_type = T_NALU_H264;
+
+            if (mVideoStream->codecpar->codec_id == AV_CODEC_ID_H264) 
+            {
+                nalu_type = T_NALU_H264;
+            } 
+            else if (mVideoStream->codecpar->codec_id == AV_CODEC_ID_HEVC) 
+            {
+                nalu_type = T_NALU_H265;
+            }
+
             VideoEncodedFramePtr videoFrame = std::make_shared<VideoEncodedFrame>();
-            videoFrame->setNalu(packet->data, packet->size, true, T_NALU_H265, video_clock);
-            videoFrame->setIsKeyFrame(key_frame);
 
+            if (key_frame && mVideoStream->codec->extradata_size > 0)
+            {
+                int buffer_size = mVideoStream->codec->extradata_size + packet->size;
+                uint8_t *buffer = (uint8_t*)malloc(buffer_size);
+                printf("mVideoStream->codec->extradata_size=%d \n", mVideoStream->codec->extradata_size);
+                memcpy(buffer, mVideoStream->codec->extradata, mVideoStream->codec->extradata_size);
+                memcpy(buffer + mVideoStream->codec->extradata_size, packet->data, packet->size);
+
+                videoFrame->setNalu(buffer, buffer_size, false, nalu_type, video_clock);
+            }
+            else
+            {
+                videoFrame->setNalu(packet->data, packet->size, true, nalu_type, video_clock);
+            }   
+
+            videoFrame->setIsKeyFrame(key_frame);
             m_event_handle->onVideoBuffer(videoFrame);
         }
 

+ 56 - 0
module/VideoPlayer/src/frame/AudioFrame/AACFrame.cpp

@@ -0,0 +1,56 @@
+#include "AACFrame.h"
+
+AACFrame::AACFrame()
+{
+    mFrameBuffer = nullptr;
+    mFrameBufferSize = 0;
+}
+
+AACFrame::~AACFrame()
+{
+    if (mFrameBuffer != nullptr)
+    {
+        free(mFrameBuffer);
+
+        mFrameBuffer = nullptr;
+        mFrameBufferSize = 0;
+    }
+}
+
+void AACFrame::setAdtsHeader(const ADTS_HEADER &adts)
+{
+    mAdtsHeader = adts;
+}
+
+void AACFrame::setFrameBuffer(const uint8_t * const buffer, const unsigned int &size)
+{
+    if (mFrameBufferSize < size)
+    {
+        if (mFrameBuffer != nullptr)
+        {
+            free(mFrameBuffer);
+        }
+
+        mFrameBuffer = static_cast<uint8_t*>(malloc(size));
+    }
+
+    memcpy(mFrameBuffer, buffer, size);
+    mFrameBufferSize = size;
+}
+
+void AACFrame::setFrameBuffer(const uint8_t * const adtsBuffer, const unsigned int &adtsSize, const uint8_t * const buffer, const unsigned int &size)
+{
+    if (mFrameBufferSize < (size+adtsSize))
+    {
+        if (mFrameBuffer != nullptr)
+        {
+            free(mFrameBuffer);
+        }
+
+        mFrameBuffer = static_cast<uint8_t*>(malloc(size+adtsSize));
+    }
+
+    memcpy(mFrameBuffer, adtsBuffer, adtsSize);
+    memcpy(mFrameBuffer+adtsSize, buffer, size);
+    mFrameBufferSize = (size+adtsSize);
+}

+ 85 - 0
module/VideoPlayer/src/frame/AudioFrame/AACFrame.h

@@ -0,0 +1,85 @@
+#ifndef AACFRAME_H
+#define AACFRAME_H
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <memory>
+
+#define ADTS_HEADER_LENTH 7
+
+/*
+sampling_frequency_index sampling frequeny [Hz]
+0x0                           96000
+0x1                           88200
+0x2                           64000
+0x3                           48000
+0x4                           44100
+0x5                           32000
+0x6                           24000
+0x7                           22050
+0x8                           16000
+0x9                           2000
+0xa                           11025
+0xb                           8000
+0xc                           reserved
+0xd                           reserved
+0xe                           reserved
+0xf                           reserved
+*/
+typedef struct
+{
+    unsigned int syncword;  //12 bslbf 同步字The bit string ‘1111 1111 1111’,说明一个ADTS帧的开始
+    unsigned int id;        //1 bslbf   MPEG 标示符, 设置为1
+    unsigned int layer;     //2 uimsbf Indicates which layer is used. Set to ‘00’
+    unsigned int protection_absent;  //1 bslbf  表示是否误码校验
+    unsigned int profile;            //2 uimsbf  表示使用哪个级别的AAC,如01 Low Complexity(LC)--- AACLC
+    unsigned int sf_index;           //4 uimsbf  表示使用的采样率下标
+    unsigned int private_bit;        //1 bslbf
+    unsigned int channel_configuration;  //3 uimsbf  表示声道数
+    unsigned int original;               //1 bslbf
+    unsigned int home;                   //1 bslbf
+    /*下面的为改变的参数即每一帧都不同*/
+    unsigned int copyright_identification_bit;   //1 bslbf
+    unsigned int copyright_identification_start; //1 bslbf
+    unsigned int aac_frame_length;               // 13 bslbf  一个ADTS帧的长度包括ADTS头和raw data block
+    unsigned int adts_buffer_fullness;           //11 bslbf     0x7FF 说明是码率可变的码流
+
+    /*no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧.
+    所以说number_of_raw_data_blocks_in_frame == 0
+    表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
+    */
+    unsigned int no_raw_data_blocks_in_frame;    //2 uimsfb
+} ADTS_HEADER;
+
+
+#define AACFramePtr std::shared_ptr<AACFrame>
+
+class AACFrame
+{
+public:
+    AACFrame();
+    ~AACFrame();
+
+    void setAdtsHeader(const ADTS_HEADER &adts);
+    void setFrameBuffer(const uint8_t * const buffer, const unsigned int &size);
+    void setFrameBuffer(const uint8_t * const adtsBuffer, const unsigned int &adtsSize, const uint8_t * const buffer, const unsigned int &size);
+
+    uint8_t *getBuffer(){return mFrameBuffer;}
+    unsigned int getSize(){return  mFrameBufferSize;}
+
+    void setTimeStamp(uint64_t t){m_timestamp_ms = t;}
+    uint64_t getTimeStamp(){return m_timestamp_ms;}
+
+private:
+    ADTS_HEADER mAdtsHeader;
+
+    uint8_t *mFrameBuffer; //aac数据(包括adts头)
+    unsigned int mFrameBufferSize; //aac数据长度(包括adts头的大小)
+
+    uint64_t m_timestamp_ms = 0; //本地绝对时间(UTC时间戳-毫秒)
+
+};
+
+#endif // AACFRAME_H

+ 2 - 1
module/VideoPlayer/src/frame/AudioFrame/PCMFrame.cpp

@@ -17,11 +17,12 @@ PCMFrame::~PCMFrame()
     }
 }
 
-void PCMFrame::setFrameInfo(int sample_rate, int channels, uint32_t pts)
+void PCMFrame::setFrameInfo(int sample_rate, int channels, uint32_t pts, FrameType type)
 {
     m_sample_rate = sample_rate;
     m_channels = channels;
     m_pts = pts;
+    m_type = type;    
 }
 
 void PCMFrame::setFrameBuffer(const uint8_t * const buffer, const unsigned int &size)

+ 15 - 1
module/VideoPlayer/src/frame/AudioFrame/PCMFrame.h

@@ -18,6 +18,16 @@
 class PCMFrame
 {
 public:
+    enum FrameType
+    {
+        PCMFRAME_TYPE_NONE = -1,
+        PCMFRAME_TYPE_PCM,
+        PCMFRAME_TYPE_PCMU, 
+        PCMFRAME_TYPE_PCMA,
+        PCMFRAME_TYPE_G711U,
+        PCMFRAME_TYPE_G711A, 
+    };
+
     PCMFrame();
     ~PCMFrame();
 
@@ -25,11 +35,13 @@ public:
     uint8_t *getBuffer(){return mFrameBuffer;}
     unsigned int getSize(){return  mFrameBufferSize;}
 
-    void setFrameInfo(int sample_rate, int channels, uint32_t pts);
+    void setFrameInfo(int sample_rate, int channels, uint32_t pts, FrameType type = PCMFRAME_TYPE_PCM);
     uint32_t pts(){return m_pts;}
     int sampleRate(){return m_sample_rate;}
     int channels(){return m_channels;}
 
+    FrameType type(){return m_type;}
+
 private:
     uint8_t *mFrameBuffer = nullptr; //pcm数据
     unsigned int mFrameBufferSize = 0; //pcm数据长度
@@ -39,6 +51,8 @@ private:
     int m_sample_rate = 0;//采样率
     int m_channels = 0; //声道数
 
+    FrameType m_type = PCMFRAME_TYPE_NONE;
+
 };
 
 #endif // PCMFRAME_H

+ 2 - 3
module/VideoPlayer/src/types.h

@@ -1,5 +1,4 @@
-#ifndef TYPES_H
-#define TYPES_H
+#pragma once
 
 #include <stdio.h>
 #include <stdint.h>
@@ -24,4 +23,4 @@ void mSleep(int mSecond);
 
 int64_t getTimeStamp_MilliSecond(); //获取时间戳(毫秒)
 
-#endif // TYPES_H
+