From c689d87d07ecd182b63be4d2f4aa80e34e7e5ee0 Mon Sep 17 00:00:00 2001 From: martii Date: Sun, 3 Mar 2013 13:38:39 +0100 Subject: [PATCH] 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 ... Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/fbb9dcbb037a7d6a51ca97fab8ddb2e7decabfce Author: martii Date: 2013-03-03 (Sun, 03 Mar 2013) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3/container/container_ffmpeg.c | 106 ++++++++++++++++++++++- libeplayer3/output/writer/pcm.c | 3 + 2 files changed, 108 insertions(+), 1 deletion(-) diff --git a/libeplayer3/container/container_ffmpeg.c b/libeplayer3/container/container_ffmpeg.c index d592a66..f101c37 100644 --- a/libeplayer3/container/container_ffmpeg.c +++ b/libeplayer3/container/container_ffmpeg.c @@ -190,7 +190,11 @@ static char* Codec2Encoding(enum CodecID id, int* version) case CODEC_ID_MP3: return "A_MP3"; case CODEC_ID_AAC: +#ifdef MARTII + return "A_IPCM"; +#else return "A_AAC"; +#endif case CODEC_ID_AC3: return "A_AC3"; case CODEC_ID_DTS: @@ -339,8 +343,10 @@ static void FFMPEGThread(Context_t *context) { int err = 0, gotlastPts = 0, audioMute = 0; AudioVideoOut_t avOut; +#ifndef MARTII /* Softdecoding buffer*/ unsigned char *samples = NULL; +#endif ffmpeg_printf(10, "\n"); @@ -630,6 +636,93 @@ static void FFMPEGThread(Context_t *context) { } 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; unsigned int samples_size = AVCODEC_MAX_AUDIO_FRAME_SIZE; AVPacket avpkt; @@ -646,7 +739,6 @@ static void FFMPEGThread(Context_t *context) { bytesDone = avcodec_decode_audio3(( (AVStream*) audioTrack->stream)->codec, (short *)(samples), &decoded_data_size, &avpkt); - if(bytesDone < 0) // Error Happend break; @@ -684,6 +776,7 @@ static void FFMPEGThread(Context_t *context) { if (context->output->audio->Write(context, &avOut) < 0) ffmpeg_err("writing data to audio device failed\n"); } +#endif } else if (audioTrack->have_aacheader == 1) { @@ -915,11 +1008,13 @@ static void FFMPEGThread(Context_t *context) { } /* while */ +#ifndef MARTII // Freeing the allocated buffer for softdecoding if (samples != NULL) { free(samples); samples = NULL; } +#endif hasPlayThreadStarted = 0; @@ -1138,6 +1233,9 @@ int container_ffmpeg_init(Context_t *context, char * filename) track.inject_raw_pcm = 1; ffmpeg_printf(10, " Handle inject_raw_pcm = %d\n", track.inject_as_pcm); } +#ifdef MARTII + else +#endif if(!strncmp(encoding, "A_IPCM", 6)) { track.inject_as_pcm = 1; @@ -1150,6 +1248,7 @@ int container_ffmpeg_init(Context_t *context, char * filename) printf("AVCODEC__INIT__SUCCESS\n"); else printf("AVCODEC__INIT__FAILED\n"); +#ifndef MARTII } else if(stream->codec->codec_id == CODEC_ID_AAC) { ffmpeg_printf(10,"Create AAC ExtraData\n"); @@ -1201,9 +1300,14 @@ int container_ffmpeg_init(Context_t *context, char * filename) Hexdump(track.aacbuf,7); track.have_aacheader = 1; +#endif } else if(stream->codec->codec_id == CODEC_ID_WMAV1 || 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) +#endif { ffmpeg_printf(10,"Create WMA ExtraData\n"); track.aacbuflen = 104 + stream->codec->extradata_size; diff --git a/libeplayer3/output/writer/pcm.c b/libeplayer3/output/writer/pcm.c index 16e14c4..5e212a9 100644 --- a/libeplayer3/output/writer/pcm.c +++ b/libeplayer3/output/writer/pcm.c @@ -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 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 0, 0, //resvd and UPC_EAN_ISRC stuff, unused 0x0A, //private header length