mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-libstb-hal.git
synced 2025-08-26 15:02:43 +02:00
Enable aac writer and use resmpling for some AAC streams thx Taapat and technik
Origin commit data
------------------
Branch: master
Commit: 73483990f8
Author: schpuntik <schpuntik@freenet.de>
Date: 2016-10-28 (Fri, 28 Oct 2016)
Origin message was:
------------------
Enable aac writer and use resmpling for some AAC streams thx Taapat and technik
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
@@ -49,7 +49,7 @@ class Output
|
||||
int audiofd;
|
||||
Writer *videoWriter, *audioWriter;
|
||||
Mutex audioMutex, videoMutex;
|
||||
AVStream *audioStream, *videoStream;
|
||||
Track *audioTrack, *videoTrack;
|
||||
Player *player;
|
||||
public:
|
||||
Output();
|
||||
@@ -70,8 +70,8 @@ class Output
|
||||
bool ClearVideo();
|
||||
bool GetPts(int64_t &pts);
|
||||
bool GetFrameCount(int64_t &framecount);
|
||||
bool SwitchAudio(AVStream *stream);
|
||||
bool SwitchVideo(AVStream *stream);
|
||||
bool SwitchAudio(Track *track);
|
||||
bool SwitchVideo(Track *track);
|
||||
bool Write(AVStream *stream, AVPacket *packet, int64_t Pts);
|
||||
};
|
||||
|
||||
|
@@ -49,7 +49,7 @@ class Writer
|
||||
static void Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding);
|
||||
static video_encoding_t GetVideoEncoding(enum AVCodecID id);
|
||||
static audio_encoding_t GetAudioEncoding(enum AVCodecID id);
|
||||
static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type);
|
||||
static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type, int track_type);
|
||||
|
||||
virtual void Init(int _fd, AVStream * /*stream*/, Player *_player ) { fd = _fd; player = _player; }
|
||||
virtual bool Write(AVPacket *packet, int64_t pts);
|
||||
|
@@ -215,7 +215,7 @@ bool Input::Play()
|
||||
if (_videoTrack && (_videoTrack->stream == stream)) {
|
||||
int64_t pts = calcPts(stream, packet.pts);
|
||||
if (audioSeen && !player->output.Write(stream, &packet, pts))
|
||||
logprintf("writing data to %s device failed\n", "video");
|
||||
logprintf("writing data to video device failed\n");
|
||||
} else if (_audioTrack && (_audioTrack->stream == stream)) {
|
||||
if (restart_audio_resampling) {
|
||||
restart_audio_resampling = false;
|
||||
@@ -224,7 +224,7 @@ bool Input::Play()
|
||||
if (!player->isBackWard) {
|
||||
int64_t pts = calcPts(stream, packet.pts);
|
||||
if (!player->output.Write(stream, &packet, _videoTrack ? pts : 0))
|
||||
logprintf("writing data to %s device failed\n", "audio");
|
||||
logprintf("writing data to audio device failed\n");
|
||||
}
|
||||
audioSeen = true;
|
||||
} else if (_subtitleTrack && (_subtitleTrack->stream == stream)) {
|
||||
@@ -493,9 +493,9 @@ again:
|
||||
}
|
||||
|
||||
if (videoTrack)
|
||||
player->output.SwitchVideo(videoTrack->stream);
|
||||
player->output.SwitchVideo(videoTrack);
|
||||
if (audioTrack)
|
||||
player->output.SwitchAudio(audioTrack->stream);
|
||||
player->output.SwitchAudio(audioTrack);
|
||||
|
||||
ReadSubtitles(filename);
|
||||
|
||||
@@ -544,6 +544,7 @@ bool Input::UpdateTracks()
|
||||
}
|
||||
|
||||
track.pid = use_index_as_pid ? n + 1: stream->id;
|
||||
track.ac3flags = 0;
|
||||
|
||||
switch (stream->codec->codec_type) {
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
@@ -553,26 +554,43 @@ bool Input::UpdateTracks()
|
||||
break;
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
switch(stream->codec->codec_id) {
|
||||
case AV_CODEC_ID_MP2:
|
||||
track.ac3flags = 9;
|
||||
break;
|
||||
case AV_CODEC_ID_MP3:
|
||||
track.ac3flags = 4;
|
||||
break;
|
||||
case AV_CODEC_ID_AC3:
|
||||
track.ac3flags = 1;
|
||||
break;
|
||||
case AV_CODEC_ID_EAC3:
|
||||
track.ac3flags = 7;
|
||||
break;
|
||||
case AV_CODEC_ID_DTS:
|
||||
track.ac3flags = 6;
|
||||
break;
|
||||
case AV_CODEC_ID_AAC:
|
||||
track.ac3flags = 5;
|
||||
break;
|
||||
case AV_CODEC_ID_MP2:
|
||||
track.ac3flags = 1;
|
||||
break;
|
||||
case AV_CODEC_ID_MP3:
|
||||
track.ac3flags = 2;
|
||||
break;
|
||||
case AV_CODEC_ID_AC3:
|
||||
track.ac3flags = 3;
|
||||
break;
|
||||
case AV_CODEC_ID_DTS:
|
||||
track.ac3flags = 4;
|
||||
break;
|
||||
case AV_CODEC_ID_AAC: {
|
||||
unsigned int extradata_size = stream->codec->extradata_size;
|
||||
unsigned int object_type = 2;
|
||||
if(extradata_size >= 2)
|
||||
object_type = stream->codec->extradata[0] >> 3;
|
||||
if (extradata_size <= 1 || object_type == 1 || object_type == 5) {
|
||||
fprintf(stderr, "use resampling for AAC\n");
|
||||
track.ac3flags = 6;
|
||||
}
|
||||
else
|
||||
track.ac3flags = 5;
|
||||
break;
|
||||
}
|
||||
case AV_CODEC_ID_FLAC:
|
||||
track.ac3flags = 8;
|
||||
break;
|
||||
case AV_CODEC_ID_WMAV1:
|
||||
case AV_CODEC_ID_WMAV2:
|
||||
case AV_CODEC_ID_WMAVOICE:
|
||||
case AV_CODEC_ID_WMAPRO:
|
||||
case AV_CODEC_ID_WMALOSSLESS:
|
||||
track.ac3flags = 9;
|
||||
break;
|
||||
default:
|
||||
track.ac3flags = 0;
|
||||
track.ac3flags = 0;
|
||||
}
|
||||
player->manager.addAudioTrack(track);
|
||||
if (!audioTrack)
|
||||
@@ -686,7 +704,7 @@ bool Input::GetDuration(int64_t &duration)
|
||||
bool Input::SwitchAudio(Track *track)
|
||||
{
|
||||
audioTrack = track;
|
||||
player->output.SwitchAudio(track ? track->stream : NULL);
|
||||
player->output.SwitchAudio(track ? track : NULL);
|
||||
// player->Seek(-5000, false);
|
||||
return true;
|
||||
}
|
||||
@@ -706,7 +724,7 @@ bool Input::SwitchTeletext(Track *track)
|
||||
bool Input::SwitchVideo(Track *track)
|
||||
{
|
||||
videoTrack = track;
|
||||
player->output.SwitchVideo(track ? track->stream : NULL);
|
||||
player->output.SwitchVideo(track ? track : NULL);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@@ -58,7 +58,7 @@ Output::Output()
|
||||
{
|
||||
videofd = audiofd = -1;
|
||||
videoWriter = audioWriter = NULL;
|
||||
videoStream = audioStream = NULL;
|
||||
videoTrack = audioTrack = NULL;
|
||||
}
|
||||
|
||||
Output::~Output()
|
||||
@@ -114,8 +114,8 @@ bool Output::Close()
|
||||
audiofd = -1;
|
||||
}
|
||||
|
||||
videoStream = NULL;
|
||||
audioStream = NULL;
|
||||
videoTrack = NULL;
|
||||
audioTrack = NULL;
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -129,18 +129,21 @@ bool Output::Play()
|
||||
|
||||
AVCodecContext *avcc;
|
||||
|
||||
if (videoStream && videofd > -1 && (avcc = videoStream->codec)) {
|
||||
videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
|
||||
videoWriter->Init(videofd, videoStream, player);
|
||||
if (videoTrack && videoTrack->stream && videofd > -1 && (avcc = videoTrack->stream->codec)) {
|
||||
videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, videoTrack->ac3flags);
|
||||
videoWriter->Init(videofd, videoTrack->stream, player);
|
||||
if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(avcc->codec_id))
|
||||
|| dioctl(videofd, VIDEO_PLAY, NULL))
|
||||
ret = false;
|
||||
}
|
||||
|
||||
if (audioStream && audiofd > -1 && (avcc = audioStream->codec)) {
|
||||
audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
|
||||
audioWriter->Init(audiofd, audioStream, player);
|
||||
if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(avcc->codec_id))
|
||||
if (audioTrack && audioTrack->stream && audiofd > -1 && (avcc = audioTrack->stream->codec)) {
|
||||
audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, audioTrack->ac3flags);
|
||||
audioWriter->Init(audiofd, audioTrack->stream, player);
|
||||
audio_encoding_t audioEncoding = AUDIO_ENCODING_LPCMA;
|
||||
if (audioTrack->ac3flags != 6)
|
||||
audioEncoding = audioWriter->GetAudioEncoding(avcc->codec_id);
|
||||
if (dioctl(audiofd, AUDIO_SET_ENCODING, audioEncoding)
|
||||
|| dioctl(audiofd, AUDIO_PLAY, NULL))
|
||||
ret = false;
|
||||
}
|
||||
@@ -297,46 +300,49 @@ bool Output::GetFrameCount(int64_t &framecount)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Output::SwitchAudio(AVStream *stream)
|
||||
bool Output::SwitchAudio(Track *track)
|
||||
{
|
||||
ScopedLock a_lock(audioMutex);
|
||||
if (stream == audioStream)
|
||||
if (audioTrack && track->stream == audioTrack->stream)
|
||||
return true;
|
||||
if (audiofd > -1) {
|
||||
dioctl(audiofd, AUDIO_STOP, NULL);
|
||||
ioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL);
|
||||
}
|
||||
audioStream = stream;
|
||||
if (stream) {
|
||||
AVCodecContext *avcc = stream->codec;
|
||||
audioTrack = track;
|
||||
if (track->stream) {
|
||||
AVCodecContext *avcc = track->stream->codec;
|
||||
if (!avcc)
|
||||
return false;
|
||||
audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
|
||||
audioWriter->Init(audiofd, audioStream, player);
|
||||
audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, audioTrack->ac3flags);
|
||||
audioWriter->Init(audiofd, audioTrack->stream, player);
|
||||
if (audiofd > -1) {
|
||||
dioctl(audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(avcc->codec_id));
|
||||
audio_encoding_t audioEncoding = AUDIO_ENCODING_LPCMA;
|
||||
if (audioTrack->ac3flags != 6)
|
||||
audioEncoding = Writer::GetAudioEncoding(avcc->codec_id);
|
||||
dioctl(audiofd, AUDIO_SET_ENCODING, audioEncoding);
|
||||
dioctl(audiofd, AUDIO_PLAY, NULL);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool Output::SwitchVideo(AVStream *stream)
|
||||
bool Output::SwitchVideo(Track *track)
|
||||
{
|
||||
ScopedLock v_lock(videoMutex);
|
||||
if (stream == videoStream)
|
||||
if (videoTrack && track->stream == videoTrack->stream)
|
||||
return true;
|
||||
if (videofd > -1) {
|
||||
dioctl(videofd, VIDEO_STOP, NULL);
|
||||
ioctl(videofd, VIDEO_CLEAR_BUFFER, NULL);
|
||||
}
|
||||
videoStream = stream;
|
||||
if (stream) {
|
||||
AVCodecContext *avcc = stream->codec;
|
||||
videoTrack = track;
|
||||
if (track->stream) {
|
||||
AVCodecContext *avcc = track->stream->codec;
|
||||
if (!avcc)
|
||||
return false;
|
||||
videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type);
|
||||
videoWriter->Init(videofd, videoStream, player);
|
||||
videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type, videoTrack->type);
|
||||
videoWriter->Init(videofd, videoTrack->stream, player);
|
||||
if (videofd > -1) {
|
||||
dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(avcc->codec_id));
|
||||
dioctl(videofd, VIDEO_PLAY, NULL);
|
||||
|
@@ -242,27 +242,36 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts)
|
||||
restart_audio_resampling = false;
|
||||
initialHeader = true;
|
||||
|
||||
if (swr) {
|
||||
swr_free(&swr);
|
||||
swr = NULL;
|
||||
}
|
||||
if (decoded_frame) {
|
||||
av_frame_free(&decoded_frame);
|
||||
decoded_frame = NULL;
|
||||
}
|
||||
|
||||
AVCodec *codec = avcodec_find_decoder(c->codec_id);
|
||||
if (!codec) {
|
||||
fprintf(stderr, "%s %d: avcodec_find_decoder(%llx)\n", __func__, __LINE__, (unsigned long long) c->codec_id);
|
||||
return false;
|
||||
if (!codec) {
|
||||
fprintf(stderr, "%s %d: avcodec_find_decoder(%llx)\n", __func__, __LINE__, (unsigned long long) c->codec_id);
|
||||
return false;
|
||||
}
|
||||
avcodec_close(c);
|
||||
if (avcodec_open2(c, codec, NULL)) {
|
||||
fprintf(stderr, "%s %d: avcodec_open2 failed\n", __func__, __LINE__);
|
||||
return false;
|
||||
if (avcodec_open2(c, codec, NULL)) {
|
||||
fprintf(stderr, "%s %d: avcodec_open2 failed\n", __func__, __LINE__);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (!swr) {
|
||||
int rates[] = { 48000, 96000, 192000, 44100, 88200, 176400, 0 };
|
||||
int *rate = rates;
|
||||
int in_rate = c->sample_rate;
|
||||
while (*rate && ((*rate / in_rate) * in_rate != *rate) && (in_rate / *rate) * *rate != in_rate)
|
||||
rate++;
|
||||
out_sample_rate = *rate ? *rate : 44100;
|
||||
// rates in descending order
|
||||
int rates[] = {192000, 176400, 96000, 88200, 48000, 44100, 0};
|
||||
int i = 0;
|
||||
// find the next equal or smallest rate
|
||||
while (rates[i] && in_rate < rates[i])
|
||||
i++;
|
||||
out_sample_rate = rates[i] ? rates[i] : 44100;
|
||||
out_channels = c->channels;
|
||||
if (c->channel_layout == 0) {
|
||||
// FIXME -- need to guess, looks pretty much like a bug in the FFMPEG WMA decoder
|
||||
@@ -304,9 +313,16 @@ bool WriterPCM::Write(AVPacket *packet, int64_t pts)
|
||||
|
||||
unsigned int packet_size = packet->size;
|
||||
while (packet_size > 0 || (!packet_size && !packet->data)) {
|
||||
av_frame_unref(decoded_frame);
|
||||
|
||||
int got_frame = 0;
|
||||
|
||||
if (!decoded_frame) {
|
||||
if (!(decoded_frame = av_frame_alloc())) {
|
||||
fprintf(stderr, "out of memory\n");
|
||||
exit(1);
|
||||
}
|
||||
} else
|
||||
av_frame_unref(decoded_frame);
|
||||
|
||||
int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, packet);
|
||||
if (len < 0) {
|
||||
restart_audio_resampling = true;
|
||||
|
@@ -53,8 +53,8 @@ int InsertPesHeader(uint8_t *data, int size, uint8_t stream_id, int64_t pts, int
|
||||
{
|
||||
BitPacker_t ld2 = { data, 0, 32 };
|
||||
|
||||
if (size > MAX_PES_PACKET_SIZE)
|
||||
size = 0; // unbounded
|
||||
/* if (size > MAX_PES_PACKET_SIZE)
|
||||
size = 0; // unbounded */
|
||||
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
PutBits(&ld2, 0x0, 8);
|
||||
|
@@ -66,20 +66,23 @@ bool Writer::Write(AVPacket * /* packet */, int64_t /* pts */)
|
||||
|
||||
static Writer writer __attribute__ ((init_priority (300)));
|
||||
|
||||
Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type)
|
||||
Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type, int track_type)
|
||||
{
|
||||
std::map<enum AVCodecID,Writer*>::iterator it = writers.find(id);
|
||||
fprintf(stderr, "GETWRITER %d %d %d", id, codec_type, track_type);
|
||||
if (track_type != 6) { // hack for ACC resampling
|
||||
std::map<enum AVCodecID,Writer*>::iterator it = writers.find(id);
|
||||
if (it != writers.end())
|
||||
return it->second;
|
||||
}
|
||||
switch (codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
if (id == AV_CODEC_ID_INJECTPCM) // should not happen
|
||||
break;
|
||||
return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type);
|
||||
return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type, 100);
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if (id == AV_CODEC_ID_MPEG2TS) // should not happen
|
||||
break;
|
||||
return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type);
|
||||
return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type, 100);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
Reference in New Issue
Block a user