|  | @@ -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);
 |