|
@@ -7,11 +7,11 @@ static void sdl_audio_callback(void *opaque, Uint8 *stream, int len);
|
|
|
// 从packet_queue中取一个packet,解码生成frame
|
|
|
static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt_queue, AVFrame *frame, CMediaHostApi* hostapi)
|
|
|
{
|
|
|
- int ret;
|
|
|
+ int ret = -1;
|
|
|
|
|
|
while (1)
|
|
|
{
|
|
|
- AVPacket pkt;
|
|
|
+ AVPacket pkt = {0};
|
|
|
|
|
|
while (1)
|
|
|
{
|
|
@@ -32,29 +32,25 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //av_log(NULL, AV_LOG_WARNING, "frame->pts no.\n");
|
|
|
- //rvclog("frame->pts no.");
|
|
|
+ hostapi->Debug("frame->pts no.");
|
|
|
}
|
|
|
|
|
|
return 1;
|
|
|
}
|
|
|
else if (ret == AVERROR_EOF)
|
|
|
{
|
|
|
- //av_log(NULL, AV_LOG_INFO, "audio avcodec_receive_frame(): the decoder has been flushed.\n");
|
|
|
- //rvclog("audio avcodec_receive_frame(): the decoder has been flushed.");
|
|
|
+ hostapi->Debug("audio avcodec_receive_frame(): the decoder has been flushed.");
|
|
|
avcodec_flush_buffers(p_codec_ctx);
|
|
|
- return 0;
|
|
|
+ return -1;
|
|
|
}
|
|
|
else if (ret == AVERROR(EAGAIN))
|
|
|
{
|
|
|
- //av_log(NULL, AV_LOG_INFO, "audio avcodec_receive_frame(): input is not accepted in the current state.\n");
|
|
|
- //rvclog("audio avcodec_receive_frame(): input is not accepted in the current state.");
|
|
|
+ hostapi->Debug("audio avcodec_receive_frame(): input is not accepted in the current state.");
|
|
|
break;
|
|
|
}
|
|
|
else
|
|
|
{
|
|
|
- //av_log(NULL, AV_LOG_ERROR, "audio avcodec_receive_frame(): other errors.\n");
|
|
|
- //rvclog( "audio avcodec_receive_frame(): other errors.");
|
|
|
+ hostapi->Debug( "audio avcodec_receive_frame(): other errors.");
|
|
|
continue;
|
|
|
}
|
|
|
}
|
|
@@ -76,15 +72,23 @@ static int audio_decode_frame(AVCodecContext *p_codec_ctx, packet_queue_t *p_pkt
|
|
|
// 2. 将packet发送给解码器
|
|
|
// 发送packet的顺序是按dts递增的顺序,如IPBBPBB
|
|
|
// pkt.pos变量可以标识当前packet在视频文件中的地址偏移
|
|
|
- if (avcodec_send_packet(p_codec_ctx, &pkt) == AVERROR(EAGAIN))
|
|
|
+ int iresult = avcodec_send_packet(p_codec_ctx, &pkt);
|
|
|
+ hostapi->Debug("avcodec_send_packet result is %d", iresult);
|
|
|
+ if (AVERROR(EAGAIN) == iresult)
|
|
|
{
|
|
|
//av_log(NULL, AV_LOG_ERROR, "receive_frame and send_packet both returned EAGAIN, which is an API violation.\n");
|
|
|
- //rvclog("receive_frame and send_packet both returned EAGAIN, which is an API violation.");
|
|
|
+ hostapi->Debug("receive_frame and send_packet both returned EAGAIN, which is an API violation.");
|
|
|
}
|
|
|
-
|
|
|
- av_packet_unref(&pkt);
|
|
|
+ if (0 == iresult)
|
|
|
+ {
|
|
|
+ av_packet_unref(&pkt);
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ printf("audio_decode_frame exit\n");
|
|
|
+
|
|
|
+ return ret;
|
|
|
}
|
|
|
|
|
|
// 音频解码线程:从音频packet_queue中取数据,解码后放入音频frame_queue
|
|
@@ -103,7 +107,6 @@ static int audio_decode_thread(void *arg)
|
|
|
return AVERROR(ENOMEM);
|
|
|
}
|
|
|
|
|
|
- //is->rvc_log("audio_decode_thread is->abort_request == %d.", is->abort_request);
|
|
|
while (0 == is->abort_request)
|
|
|
{
|
|
|
got_frame = audio_decode_frame(is->p_acodec_ctx, &is->audio_pkt_queue, p_frame, is->rvc_hostapi);
|
|
@@ -132,6 +135,7 @@ static int audio_decode_thread(void *arg)
|
|
|
frame_queue_push(&is->audio_frm_queue);
|
|
|
}
|
|
|
}
|
|
|
+ is->rvc_hostapi->Debug("audio_decode_thread exit, and is->abort_request == %d.", is->abort_request);
|
|
|
|
|
|
the_end:
|
|
|
av_frame_free(&p_frame);
|
|
@@ -389,6 +393,21 @@ static int open_audio_playing(void *arg)
|
|
|
// 这样就可以在打开音频设备后先为回调函数安全初始化数据,一切就绪后再启动音频回调。
|
|
|
// 在暂停期间,会将静音值往音频设备写。
|
|
|
SDL_PauseAudio(0);
|
|
|
+
|
|
|
+ SDL_Event event;
|
|
|
+ while (true)
|
|
|
+ {
|
|
|
+ SDL_PumpEvents();
|
|
|
+ while (!SDL_PeepEvents(&event, 1, SDL_GETEVENT, SDL_FIRSTEVENT, SDL_LASTEVENT))
|
|
|
+ {
|
|
|
+ SDL_Delay(100);
|
|
|
+ SDL_PumpEvents();
|
|
|
+ }
|
|
|
+ is->rvc_hostapi->Debug("event.type = 0x%0x.\n", event.type);
|
|
|
+ if (FF_QUIT_EVENT == event.type) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
// 音频处理回调函数。读队列获取音频包,解码,播放
|