mirror of
https://github.com/tuxbox-neutrino/libstb-hal.git
synced 2025-08-27 15:33:00 +02:00
libeplayer3: switch back to software decoding for AAC; crude fix for PCM injection (newer ffmpeg versions return floats instead of shorts), injected PCM streams (OGG, for example), will now work again. I'd be grateful if anybody with a deeper understanding of the FFMPEG API would supply a cleaner fix ...
This commit is contained in:
@@ -190,7 +190,11 @@ static char* Codec2Encoding(enum CodecID id, int* version)
|
|||||||
case CODEC_ID_MP3:
|
case CODEC_ID_MP3:
|
||||||
return "A_MP3";
|
return "A_MP3";
|
||||||
case CODEC_ID_AAC:
|
case CODEC_ID_AAC:
|
||||||
|
#ifdef MARTII
|
||||||
|
return "A_IPCM";
|
||||||
|
#else
|
||||||
return "A_AAC";
|
return "A_AAC";
|
||||||
|
#endif
|
||||||
case CODEC_ID_AC3:
|
case CODEC_ID_AC3:
|
||||||
return "A_AC3";
|
return "A_AC3";
|
||||||
case CODEC_ID_DTS:
|
case CODEC_ID_DTS:
|
||||||
@@ -339,8 +343,10 @@ static void FFMPEGThread(Context_t *context) {
|
|||||||
int err = 0, gotlastPts = 0, audioMute = 0;
|
int err = 0, gotlastPts = 0, audioMute = 0;
|
||||||
AudioVideoOut_t avOut;
|
AudioVideoOut_t avOut;
|
||||||
|
|
||||||
|
#ifndef MARTII
|
||||||
/* Softdecoding buffer*/
|
/* Softdecoding buffer*/
|
||||||
unsigned char *samples = NULL;
|
unsigned char *samples = NULL;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
ffmpeg_printf(10, "\n");
|
ffmpeg_printf(10, "\n");
|
||||||
@@ -630,6 +636,93 @@ static void FFMPEGThread(Context_t *context) {
|
|||||||
}
|
}
|
||||||
else if (audioTrack->inject_as_pcm == 1)
|
else if (audioTrack->inject_as_pcm == 1)
|
||||||
{
|
{
|
||||||
|
#ifdef MARTII
|
||||||
|
int bytesDone = 0;
|
||||||
|
unsigned int samples_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||||
|
AVPacket avpkt;
|
||||||
|
avpkt = packet;
|
||||||
|
|
||||||
|
int is_planar = av_sample_fmt_is_planar(((AVStream*) audioTrack->stream)->codec->sample_fmt);
|
||||||
|
int nc = ((AVStream*) audioTrack->stream)->codec->channels;
|
||||||
|
if (is_planar)
|
||||||
|
samples_size *= nc;
|
||||||
|
|
||||||
|
uint8_t *samples = (unsigned char *)malloc(samples_size);
|
||||||
|
|
||||||
|
while(avpkt.size > 0)
|
||||||
|
{
|
||||||
|
int decoded_data_size = samples_size;
|
||||||
|
|
||||||
|
bytesDone = avcodec_decode_audio3(( (AVStream*) audioTrack->stream)->codec,
|
||||||
|
(short *)(samples), &decoded_data_size, &avpkt);
|
||||||
|
if(bytesDone < 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
avpkt.data += bytesDone;
|
||||||
|
avpkt.size -= bytesDone;
|
||||||
|
|
||||||
|
if(decoded_data_size <= 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
int i;
|
||||||
|
if (is_planar && nc > 1) {
|
||||||
|
int ds = decoded_data_size/sizeof(float)/nc;
|
||||||
|
short *shortSamples = (short *)malloc(nc * ds * sizeof(short));
|
||||||
|
float *floatSamples = (float *)samples;
|
||||||
|
int j;
|
||||||
|
|
||||||
|
for (i = 0; i < ds; i++)
|
||||||
|
for (j = 0; j < nc; j++)
|
||||||
|
shortSamples[i * nc + j] = floatSamples[j * ds + i] * 32767.0;
|
||||||
|
|
||||||
|
free(samples);
|
||||||
|
samples = (unsigned char *) shortSamples;
|
||||||
|
} else if (nc == 1) {
|
||||||
|
// mono doesn't seem to work ... convert to stereo
|
||||||
|
int ds = decoded_data_size/sizeof(float);
|
||||||
|
short *shortSamples = (short *)samples;
|
||||||
|
float *floatSamples = (float *)samples;
|
||||||
|
|
||||||
|
for (i = 0; i < ds; i++)
|
||||||
|
shortSamples[2 * i] = shortSamples[2 * i + 1] = floatSamples[i] * 32767.0;
|
||||||
|
|
||||||
|
decoded_data_size *= 2;
|
||||||
|
nc++;
|
||||||
|
} else {
|
||||||
|
int ds = decoded_data_size/sizeof(float);
|
||||||
|
short *shortSamples = (short *)samples;
|
||||||
|
float *floatSamples = (float *)samples;
|
||||||
|
|
||||||
|
for (i = 0; i < ds; i++)
|
||||||
|
shortSamples[i] = floatSamples[i] * 32767.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
pcmPrivateData_t extradata;
|
||||||
|
extradata.uNoOfChannels = nc;
|
||||||
|
extradata.uSampleRate = ((AVStream*) audioTrack->stream)->codec->sample_rate;
|
||||||
|
extradata.uBitsPerSample = 16;
|
||||||
|
extradata.bLittleEndian = 1;
|
||||||
|
|
||||||
|
avOut.data = samples;
|
||||||
|
avOut.len = (decoded_data_size * sizeof(short))/sizeof(float);
|
||||||
|
|
||||||
|
avOut.pts = pts;
|
||||||
|
avOut.extradata = (unsigned char *) &extradata;
|
||||||
|
avOut.extralen = sizeof(extradata);
|
||||||
|
avOut.frameRate = 0;
|
||||||
|
avOut.timeScale = 0;
|
||||||
|
avOut.width = 0;
|
||||||
|
avOut.height = 0;
|
||||||
|
avOut.type = "audio";
|
||||||
|
|
||||||
|
#ifdef reverse_playback_3
|
||||||
|
if (!context->playback->BackWard)
|
||||||
|
#endif
|
||||||
|
if (context->output->audio->Write(context, &avOut) < 0)
|
||||||
|
ffmpeg_err("writing data to audio device failed\n");
|
||||||
|
}
|
||||||
|
free(samples);
|
||||||
|
#else
|
||||||
int bytesDone = 0;
|
int bytesDone = 0;
|
||||||
unsigned int samples_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
unsigned int samples_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
|
||||||
AVPacket avpkt;
|
AVPacket avpkt;
|
||||||
@@ -646,7 +739,6 @@ static void FFMPEGThread(Context_t *context) {
|
|||||||
bytesDone = avcodec_decode_audio3(( (AVStream*) audioTrack->stream)->codec,
|
bytesDone = avcodec_decode_audio3(( (AVStream*) audioTrack->stream)->codec,
|
||||||
(short *)(samples), &decoded_data_size, &avpkt);
|
(short *)(samples), &decoded_data_size, &avpkt);
|
||||||
|
|
||||||
|
|
||||||
if(bytesDone < 0) // Error Happend
|
if(bytesDone < 0) // Error Happend
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -684,6 +776,7 @@ static void FFMPEGThread(Context_t *context) {
|
|||||||
if (context->output->audio->Write(context, &avOut) < 0)
|
if (context->output->audio->Write(context, &avOut) < 0)
|
||||||
ffmpeg_err("writing data to audio device failed\n");
|
ffmpeg_err("writing data to audio device failed\n");
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
else if (audioTrack->have_aacheader == 1)
|
else if (audioTrack->have_aacheader == 1)
|
||||||
{
|
{
|
||||||
@@ -915,11 +1008,13 @@ static void FFMPEGThread(Context_t *context) {
|
|||||||
|
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
|
#ifndef MARTII
|
||||||
// Freeing the allocated buffer for softdecoding
|
// Freeing the allocated buffer for softdecoding
|
||||||
if (samples != NULL) {
|
if (samples != NULL) {
|
||||||
free(samples);
|
free(samples);
|
||||||
samples = NULL;
|
samples = NULL;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
hasPlayThreadStarted = 0;
|
hasPlayThreadStarted = 0;
|
||||||
|
|
||||||
@@ -1138,6 +1233,9 @@ int container_ffmpeg_init(Context_t *context, char * filename)
|
|||||||
track.inject_raw_pcm = 1;
|
track.inject_raw_pcm = 1;
|
||||||
ffmpeg_printf(10, " Handle inject_raw_pcm = %d\n", track.inject_as_pcm);
|
ffmpeg_printf(10, " Handle inject_raw_pcm = %d\n", track.inject_as_pcm);
|
||||||
}
|
}
|
||||||
|
#ifdef MARTII
|
||||||
|
else
|
||||||
|
#endif
|
||||||
if(!strncmp(encoding, "A_IPCM", 6))
|
if(!strncmp(encoding, "A_IPCM", 6))
|
||||||
{
|
{
|
||||||
track.inject_as_pcm = 1;
|
track.inject_as_pcm = 1;
|
||||||
@@ -1150,6 +1248,7 @@ int container_ffmpeg_init(Context_t *context, char * filename)
|
|||||||
printf("AVCODEC__INIT__SUCCESS\n");
|
printf("AVCODEC__INIT__SUCCESS\n");
|
||||||
else
|
else
|
||||||
printf("AVCODEC__INIT__FAILED\n");
|
printf("AVCODEC__INIT__FAILED\n");
|
||||||
|
#ifndef MARTII
|
||||||
}
|
}
|
||||||
else if(stream->codec->codec_id == CODEC_ID_AAC) {
|
else if(stream->codec->codec_id == CODEC_ID_AAC) {
|
||||||
ffmpeg_printf(10,"Create AAC ExtraData\n");
|
ffmpeg_printf(10,"Create AAC ExtraData\n");
|
||||||
@@ -1201,9 +1300,14 @@ int container_ffmpeg_init(Context_t *context, char * filename)
|
|||||||
Hexdump(track.aacbuf,7);
|
Hexdump(track.aacbuf,7);
|
||||||
track.have_aacheader = 1;
|
track.have_aacheader = 1;
|
||||||
|
|
||||||
|
#endif
|
||||||
} else if(stream->codec->codec_id == CODEC_ID_WMAV1
|
} else if(stream->codec->codec_id == CODEC_ID_WMAV1
|
||||||
|| stream->codec->codec_id == CODEC_ID_WMAV2
|
|| stream->codec->codec_id == CODEC_ID_WMAV2
|
||||||
|
#ifdef MARTII
|
||||||
|
|| stream->codec->codec_id == 86056 ) //CODEC_ID_WMAPRO) //if (stream->codec->extradata_size > 0)
|
||||||
|
#else
|
||||||
|| 86056 ) //CODEC_ID_WMAPRO) //if (stream->codec->extradata_size > 0)
|
|| 86056 ) //CODEC_ID_WMAPRO) //if (stream->codec->extradata_size > 0)
|
||||||
|
#endif
|
||||||
{
|
{
|
||||||
ffmpeg_printf(10,"Create WMA ExtraData\n");
|
ffmpeg_printf(10,"Create WMA ExtraData\n");
|
||||||
track.aacbuflen = 104 + stream->codec->extradata_size;
|
track.aacbuflen = 104 + stream->codec->extradata_size;
|
||||||
|
@@ -88,6 +88,9 @@ static const unsigned char clpcm_pes[18] = { 0x00, 0x00, 0x01, 0xBD, //start c
|
|||||||
0x1E, 0x60, 0x0A, //first pes only, 0xFF after
|
0x1E, 0x60, 0x0A, //first pes only, 0xFF after
|
||||||
0xFF
|
0xFF
|
||||||
};
|
};
|
||||||
|
#ifdef MARTII
|
||||||
|
// reference: search for TypeLpcmDVDAudio in player/frame_parser/frame_parser_audio_lpcm.cpp
|
||||||
|
#endif
|
||||||
static const unsigned char clpcm_prv[14] = { 0xA0, //sub_stream_id
|
static const unsigned char clpcm_prv[14] = { 0xA0, //sub_stream_id
|
||||||
0, 0, //resvd and UPC_EAN_ISRC stuff, unused
|
0, 0, //resvd and UPC_EAN_ISRC stuff, unused
|
||||||
0x0A, //private header length
|
0x0A, //private header length
|
||||||
|
Reference in New Issue
Block a user