libeplayer3: fix audio switching on already terminated playback

This commit is contained in:
martii
2014-05-01 12:52:38 +02:00
parent 6eea7139a4
commit c3ad6b5b23
2 changed files with 42 additions and 32 deletions

View File

@@ -150,8 +150,7 @@ bool Input::Play()
restart_audio_resampling = true; restart_audio_resampling = true;
// clear streams // clear streams
unsigned int i; for (unsigned int i = 0; i < avfc->nb_streams; i++)
for (i = 0; i < avfc->nb_streams; i++)
if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec) if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec)
avcodec_flush_buffers(avfc->streams[i]->codec); avcodec_flush_buffers(avfc->streams[i]->codec);
player->output.ClearAudio(); player->output.ClearAudio();
@@ -239,17 +238,8 @@ bool Input::Play()
if (player->abortRequested) if (player->abortRequested)
player->output.Clear(); player->output.Clear();
else { else
Track *_audioTrack = audioTrack;
if (_audioTrack) {
// flush audio decoder
AVPacket packet;
packet.data = NULL;
packet.size = 0;
player->output.Write(_audioTrack->stream, &packet, 0);
}
player->output.Flush(); player->output.Flush();
}
dvbsub_ass_clear(); dvbsub_ass_clear();
abortPlayback = true; abortPlayback = true;
@@ -324,6 +314,7 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid)
av_free_packet(&packet); av_free_packet(&packet);
} }
avformat_close_input(&subavfc); avformat_close_input(&subavfc);
avcodec_close(c);
avformat_free_context(subavfc); avformat_free_context(subavfc);
Track track; Track track;
@@ -523,8 +514,11 @@ bool Input::Stop()
while (hasPlayThreadStarted != 0) while (hasPlayThreadStarted != 0)
usleep(100000); usleep(100000);
if (avfc) if (avfc) {
for (unsigned int i = 0; i < avfc->nb_streams; i++)
avcodec_close(avfc->streams[i]->codec);
avformat_close_input(&avfc); avformat_close_input(&avfc);
}
avformat_network_deinit(); avformat_network_deinit();
@@ -554,7 +548,7 @@ bool Input::SwitchAudio(Track *track)
{ {
audioTrack = track; audioTrack = track;
player->output.SwitchAudio(track ? track->stream : NULL); player->output.SwitchAudio(track ? track->stream : NULL);
player->Seek(-5000, false); // player->Seek(-5000, false);
return true; return true;
} }

View File

@@ -129,18 +129,20 @@ bool Output::Play()
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
if (videoStream && videofd > -1) { AVCodecContext *avcc;
videoWriter = Writer::GetWriter(videoStream->codec->codec_id, videoStream->codec->codec_type);
videoWriter->Init(); if (videoStream && videofd > -1 && (avcc = videoStream->codec)) {
if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(videoStream->codec->codec_id)) videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
videoWriter->Init(videofd, videoStream);
if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(avcc->codec_id))
|| dioctl(videofd, VIDEO_PLAY, NULL)) || dioctl(videofd, VIDEO_PLAY, NULL))
ret = false; ret = false;
} }
if (audioStream && audiofd > -1) { if (audioStream && audiofd > -1 && (avcc = audioStream->codec)) {
audioWriter = Writer::GetWriter(audioStream->codec->codec_id, audioStream->codec->codec_type); audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
audioWriter->Init(); audioWriter->Init(audiofd, audioStream);
if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(audioStream->codec->codec_id)) if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(avcc->codec_id))
|| dioctl(audiofd, AUDIO_PLAY, NULL)) || dioctl(audiofd, AUDIO_PLAY, NULL))
ret = false; ret = false;
} }
@@ -227,8 +229,16 @@ bool Output::Flush()
if (videofd > -1 && ioctl(videofd, VIDEO_FLUSH, NULL)) if (videofd > -1 && ioctl(videofd, VIDEO_FLUSH, NULL))
ret = false; ret = false;
if (audiofd > -1 && ioctl(audiofd, AUDIO_FLUSH, NULL)) if (audiofd > -1 && audioWriter) {
// flush audio decoder
AVPacket packet;
packet.data = NULL;
packet.size = 0;
audioWriter->Write(&packet, 0);
if (ioctl(audiofd, AUDIO_FLUSH, NULL))
ret = false; ret = false;
}
return ret; return ret;
} }
@@ -300,10 +310,13 @@ bool Output::SwitchAudio(AVStream *stream)
} }
audioStream = stream; audioStream = stream;
if (stream) { if (stream) {
audioWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); AVCodecContext *avcc = stream->codec;
audioWriter->Init(); if (!avcc)
return false;
audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
audioWriter->Init(audiofd, audioStream);
if (audiofd > -1) { if (audiofd > -1) {
dioctl (audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(stream->codec->codec_id)); dioctl(audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(avcc->codec_id));
dioctl(audiofd, AUDIO_PLAY, NULL); dioctl(audiofd, AUDIO_PLAY, NULL);
} }
} }
@@ -321,10 +334,13 @@ bool Output::SwitchVideo(AVStream *stream)
} }
videoStream = stream; videoStream = stream;
if (stream) { if (stream) {
videoWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); AVCodecContext *avcc = stream->codec;
videoWriter->Init(); if (!avcc)
return false;
videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
videoWriter->Init(videofd, videoStream);
if (videofd > -1) { if (videofd > -1) {
dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(stream->codec->codec_id)); dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(avcc->codec_id));
dioctl(videofd, VIDEO_PLAY, NULL); dioctl(videofd, VIDEO_PLAY, NULL);
} }
} }
@@ -336,11 +352,11 @@ bool Output::Write(AVStream *stream, AVPacket *packet, int64_t pts)
switch (stream->codec->codec_type) { switch (stream->codec->codec_type) {
case AVMEDIA_TYPE_VIDEO: { case AVMEDIA_TYPE_VIDEO: {
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
return videofd > -1 && videoWriter && videoWriter->Write(videofd, stream, packet, pts); return videofd > -1 && videoWriter && videoWriter->Write(packet, pts);
} }
case AVMEDIA_TYPE_AUDIO: { case AVMEDIA_TYPE_AUDIO: {
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
return audiofd > -1 && audioWriter && audioWriter->Write(audiofd, stream, packet, pts); return audiofd > -1 && audioWriter && audioWriter->Write(packet, pts);
} }
default: default:
return false; return false;