mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-26 23:13:16 +02:00
libeplayer3: add aac_adtstoasc bitstream filter
Add the aac_adtstoasc bitstream filter for AAC streams. In the cases where it is not needed, it does not seem to hurt, and in other cases it fixes audio playback. TODO: improve the handling of the bsfc allocation / deallocation, this should go in a Track() destructor or similar.
This commit is contained in:
@@ -49,8 +49,9 @@ struct Track
|
||||
bool hidden; // not part of currently selected program
|
||||
bool is_static;
|
||||
int ac3flags;
|
||||
AVBitStreamFilterContext *bsfc;
|
||||
int type, mag, page; // for teletext
|
||||
Track() : pid(-1), stream(NULL), inactive(false), hidden(false), is_static(false), ac3flags(0) {}
|
||||
Track() : pid(-1), stream(NULL), inactive(false), hidden(false), is_static(false), ac3flags(0), bsfc(NULL) {}
|
||||
};
|
||||
|
||||
struct Program
|
||||
|
@@ -123,6 +123,8 @@ bool Input::Play()
|
||||
// Oddly, this seems to be necessary for network streaming only ...
|
||||
bool audioSeen = !audioTrack || !player->isHttp;
|
||||
|
||||
int reinit_audio = 0;
|
||||
|
||||
while (player->isPlaying && !player->abortRequested) {
|
||||
|
||||
//IF MOVIE IS PAUSED, WAIT
|
||||
@@ -221,6 +223,53 @@ bool Input::Play()
|
||||
restart_audio_resampling = false;
|
||||
player->output.Write(stream, NULL, 0);
|
||||
}
|
||||
if (_audioTrack->bsfc) {
|
||||
/* this code is more or less copied from ffmpeg.c */
|
||||
AVBitStreamFilterContext *bsfc = _audioTrack->bsfc;
|
||||
av_packet_split_side_data(&packet);
|
||||
AVPacket new_pkt = packet;
|
||||
AVCodecContext *avcc = stream->codec;
|
||||
|
||||
int a = av_bitstream_filter_filter(bsfc, avcc, NULL,
|
||||
&new_pkt.data, &new_pkt.size,
|
||||
packet.data, packet.size,
|
||||
packet.flags & AV_PKT_FLAG_KEY);
|
||||
if (a == 0 && new_pkt.data != packet.data) {
|
||||
if (reinit_audio < 2)
|
||||
reinit_audio++;
|
||||
uint8_t *t = (uint8_t *)av_malloc(new_pkt.size + FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
if(t) {
|
||||
memcpy(t, new_pkt.data, new_pkt.size);
|
||||
memset(t + new_pkt.size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
|
||||
new_pkt.data = t;
|
||||
new_pkt.buf = NULL;
|
||||
a = 1;
|
||||
} else {
|
||||
/* TODO: what happens here? */
|
||||
a = AVERROR(ENOMEM);
|
||||
}
|
||||
}
|
||||
if (a > 0) {
|
||||
packet.side_data = NULL;
|
||||
packet.side_data_elems = 0;
|
||||
av_free_packet(&packet);
|
||||
new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size,
|
||||
av_buffer_default_free, NULL, 0);
|
||||
if (! new_pkt.buf)
|
||||
logprintf("eplayer3:input %d no memory\n", __LINE__);
|
||||
} else if (a < 0) {
|
||||
logprintf("eplayer3:input: failed to open bitstream filter\n");
|
||||
}
|
||||
packet = new_pkt;
|
||||
}
|
||||
|
||||
if (reinit_audio == 1) { /* only run once on start */
|
||||
/* we need to reprogram the AAC header in Writer::Init()
|
||||
* this is a cheap hack to do that */
|
||||
logprintf("eplayer3:input: reset audio stream\n");
|
||||
player->output.SwitchAudio(NULL);
|
||||
player->output.SwitchAudio(stream);
|
||||
}
|
||||
if (!player->isBackWard) {
|
||||
int64_t pts = calcPts(stream, packet.pts);
|
||||
if (!player->output.Write(stream, &packet, _videoTrack ? pts : 0))
|
||||
@@ -524,6 +573,9 @@ bool Input::UpdateTracks()
|
||||
break;
|
||||
case AV_CODEC_ID_AAC:
|
||||
track.ac3flags = 5;
|
||||
track.bsfc = av_bitstream_filter_init("aac_adtstoasc");
|
||||
logprintf("adding AAC STREAM %d, bsfc: %p (aac_adtstoasc)\n",
|
||||
track.pid, track.bsfc);
|
||||
break;
|
||||
default:
|
||||
track.ac3flags = 0;
|
||||
|
@@ -31,8 +31,14 @@ void Manager::addTrack(std::map<int,Track*> &tracks, Track &track)
|
||||
Track *t = new Track;
|
||||
*t = track;
|
||||
tracks[track.pid] = t;
|
||||
} else
|
||||
} else {
|
||||
/* this should be handled by Track() itself, instead of special casing here... */
|
||||
if ((*it->second).bsfc) {
|
||||
fprintf(stderr, "eplayer3:%s: closing bsf %p\n", __func__, (*it->second).bsfc);
|
||||
av_bitstream_filter_close((*it->second).bsfc);
|
||||
}
|
||||
*it->second = track;
|
||||
}
|
||||
}
|
||||
|
||||
void Manager::addVideoTrack(Track &track)
|
||||
@@ -238,8 +244,14 @@ void Manager::clearTracks()
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||
|
||||
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
|
||||
for (std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) {
|
||||
/* see comment in addTrack() :-) */
|
||||
if (it->second->bsfc) {
|
||||
fprintf(stderr, "eplayer3:%s: closing bsf %p\n", __func__, it->second->bsfc);
|
||||
av_bitstream_filter_close(it->second->bsfc);
|
||||
}
|
||||
delete it->second;
|
||||
}
|
||||
audioTracks.clear();
|
||||
|
||||
for (std::map<int, Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
|
||||
|
Reference in New Issue
Block a user