From c5d1b0438268ed347ab37295beae8a0c88be5e74 Mon Sep 17 00:00:00 2001 From: Frankenstone Date: Fri, 19 Jan 2018 15:09:41 +0100 Subject: [PATCH 01/38] libeplayer3-arm: fix fast forward (thx DboxOldie) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/fd5025a5070d9b84fe7f0ad6552df9ee055fd4bf Author: Frankenstone Date: 2018-01-19 (Fri, 19 Jan 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/output/linuxdvb_mipsel.c | 4 ++++ libeplayer3-arm/playback/playback.c | 5 +++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index fd8cd56..8990c5b 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -401,6 +401,10 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); if (video && videofd != -1) { + if (context->playback->isForwarding == 0) + { + ioctl(videofd, VIDEO_FAST_FORWARD, 0); + } if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 1c8a668..986017e 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -310,15 +310,15 @@ static int32_t PlaybackContinue(Context_t *context) (context->playback->isPaused || context->playback->isForwarding || context->playback->BackWard || context->playback->SlowMotion)) { - if (context->playback->SlowMotion) + if (context->playback->SlowMotion || context->playback->isForwarding) context->output->Command(context, OUTPUT_CLEAR, NULL); - context->output->Command(context, OUTPUT_CONTINUE, NULL); context->playback->isPaused = 0; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 1; + context->output->Command(context, OUTPUT_CONTINUE, NULL); } else { @@ -425,6 +425,7 @@ static int PlaybackFastForward(Context_t *context, int *speed) context->playback->Speed = *speed; playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed); context->output->Command(context, OUTPUT_FASTFORWARD, NULL); + context->output->Command(context, OUTPUT_CONTINUE, NULL); } else { From 1631c866199186546b4826ea85426cfeedd2bd7b Mon Sep 17 00:00:00 2001 From: TangoCash Date: Sun, 21 Jan 2018 15:46:53 +0100 Subject: [PATCH 02/38] arm try fix fast backward Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2c7c605ff5af7aef7e3ce32f077c873e7139d220 Author: TangoCash Date: 2018-01-21 (Sun, 21 Jan 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 30 +++++++++++--------- libeplayer3-arm/playback/playback.c | 28 ++++++++++++++---- 2 files changed, 39 insertions(+), 19 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 12cd061..67dd742 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -59,7 +59,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#if (LIBAVFORMAT_VERSION_MAJOR > 57) +#if (LIBAVFORMAT_VERSION_MAJOR > 56) #define TS_BYTES_SEEKING 0 #else #define TS_BYTES_SEEKING 1 @@ -2365,9 +2365,10 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab Track_t *audioTrack = NULL; Track_t *current = NULL; seek_target_flag = 0; + sec *= AV_TIME_BASE; if (!absolute) { - ffmpeg_printf(10, "seeking %f sec\n", sec); + ffmpeg_printf(10, "seeking %lld sec\n", sec / AV_TIME_BASE); if (sec == 0) { ffmpeg_err("sec = 0 ignoring\n"); @@ -2382,14 +2383,15 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_err("fail to get current PTS\n"); return cERR_CONTAINER_FFMPEG_ERR; } - sec += currPts / 90000; + sec += (currPts / 90000 * AV_TIME_BASE); + } + + if (sec < 0) + { + sec = 0; } } - ffmpeg_printf(10, "goto %d sec\n", sec); - if (sec < 0) - { - sec = 0; - } + ffmpeg_printf(10, "goto %lld sec\n", sec / AV_TIME_BASE); context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); if (videoTrack != NULL) @@ -2415,7 +2417,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags); + ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags); #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) { @@ -2426,11 +2428,11 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab * about 10 seconds, backward does not work. */ off_t pos = avio_tell(avContextTab[0]->pb); - ffmpeg_printf(10, "pos %lld %d\n", pos, avContextTab[0]->bit_rate); + ffmpeg_printf(10, "pos %lld %lld\n", pos, avContextTab[0]->bit_rate); if (avContextTab[0]->bit_rate) { sec *= avContextTab[0]->bit_rate / 8; - ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate); + ffmpeg_printf(10, "bit_rate %lld\n", avContextTab[0]->bit_rate); } else { @@ -2441,14 +2443,14 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab { pos = 0; } - ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %d\n", pos, sec); - seek_target_bytes = pos; + ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE); + seek_target_bytes = pos / AV_TIME_BASE; do_seek_target_bytes = 1; } else #endif { - seek_target_seconds = sec * AV_TIME_BASE; + seek_target_seconds = sec; do_seek_target_seconds = 1; } releaseMutex(__FILE__, __FUNCTION__, __LINE__); diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 986017e..0ea3ad3 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -95,7 +95,22 @@ static void SupervisorThread(Context_t *context) hasThreadStarted = 1; playback_printf(10, ">\n"); while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) - usleep(100000); + { + if (context->playback->BackWard != 0) + { + /* Offset -3 seconds for backward + * so initial backward speed is 4x */ + int64_t pos = (int64_t)context->playback->Speed - 3; + playback_printf(10, "Speed %d BackWard %d to seek %lld\n", context->playback->Speed, context->playback->BackWard, pos); + context->playback->isSeeking = 1; + context->output->Command(context, OUTPUT_CLEAR, NULL); + context->container->selectedContainer->Command(context, CONTAINER_SEEK, &pos); + context->playback->isSeeking = 0; + usleep(350000); + } else { + usleep(100000); + } + } playback_printf(10, "<\n"); hasThreadStarted = 2; PlaybackTerminate(context); @@ -310,8 +325,10 @@ static int32_t PlaybackContinue(Context_t *context) (context->playback->isPaused || context->playback->isForwarding || context->playback->BackWard || context->playback->SlowMotion)) { - if (context->playback->SlowMotion || context->playback->isForwarding) + if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard) context->output->Command(context, OUTPUT_CLEAR, NULL); + if (context->playback->BackWard) + context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); context->playback->isPaused = 0; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; @@ -453,15 +470,16 @@ static int PlaybackFastBackward(Context_t *context, int *speed) { context->playback->BackWard = 0; context->playback->Speed = 0; /* reverse end */ + context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); } else { context->playback->isSeeking = 1; context->playback->Speed = *speed; - context->playback->BackWard = 2 ^ (*speed); - playback_printf(1, "S %d B %f\n", context->playback->Speed, context->playback->BackWard); + context->playback->BackWard = 1; + context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); + playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); } - context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); context->output->Command(context, OUTPUT_CLEAR, NULL); if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0) { From bbedc17e753f0862c510297d2e9f3c2848dab0c3 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Wed, 3 Jan 2018 19:33:40 +0100 Subject: [PATCH 03/38] remove double AV_CODEC_ID_EAC3 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/a364f5ef05890b352a7a2d8ab990c805b0afcb9c Author: Jacek Jendrzej Date: 2018-01-03 (Wed, 03 Jan 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 1 - 1 file changed, 1 deletion(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 67dd742..eb47aff 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -391,7 +391,6 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra case AV_CODEC_ID_WMAV1: case AV_CODEC_ID_WMAV2: return (wma_software_decode) ? "A_IPCM" : "A_WMA"; - case 86056: case AV_CODEC_ID_WMAPRO: return (wma_software_decode) ? "A_IPCM" : "A_WMA/PRO"; case AV_CODEC_ID_WMALOSSLESS: From 960f78ea17ec93507d9ebf08bfff138752e11226 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 24 Jan 2018 01:11:57 +0100 Subject: [PATCH 04/38] arm try improve fast backward Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/785f0bee1c647a534c3e9c9f72fd8aa1ef05c46d Author: max_10 Date: 2018-01-24 (Wed, 24 Jan 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 48 ++++++++++++++++++-- libeplayer3-arm/playback/playback.c | 15 +----- 2 files changed, 46 insertions(+), 17 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index eb47aff..ed39ac1 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -588,8 +588,48 @@ static void FFMPEGThread(Context_t *context) } continue; } + if (context->playback->BackWard && av_gettime() >= showtime) { + context->output->Command(context, OUTPUT_CLEAR, "video"); + + if (bofcount == 1) { + showtime = av_gettime(); + usleep(100000); + continue; + } + + if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) { + off_t pos = avio_tell(avContextTab[0]->pb); + + if (pos > 0) { + float br; + if (avContextTab[0]->bit_rate) + br = avContextTab[0]->bit_rate / 8.0; + else + br = 180000.0; + seek_target_bytes = (double)pos + (double)context->playback->Speed * 8.0 * br; + if (seek_target_bytes < 0) + seek_target_bytes = 1; + do_seek_target_bytes = 1; + } + } + else + { + int64_t currPts = -1; + context->playback->Command(context, PLAYBACK_PTS, &currPts); + seek_target_seconds = ((double)currPts / 90000.0 + context->playback->Speed) * AV_TIME_BASE; + if (seek_target_seconds < 0) + seek_target_seconds = AV_TIME_BASE; + do_seek_target_seconds = 1; + } + showtime = av_gettime() + 300000; //jump back every 300ms + } + else + { + bofcount = 0; + } if (do_seek_target_seconds || do_seek_target_bytes) { + int res = -1; isWaitingForFinish = 0; if (do_seek_target_seconds) { @@ -607,8 +647,9 @@ static void FFMPEGThread(Context_t *context) { seek_target_seconds += avContextTab[i]->start_time; } - //av_seek_frame(avContextTab[i], -1, seek_target_seconds, 0); - avformat_seek_file(avContextTab[i], -1, INT64_MIN, seek_target_seconds, INT64_MAX, 0); + res = avformat_seek_file(avContextTab[i], -1, INT64_MIN, seek_target_seconds, INT64_MAX, 0); + if (res < 0 && context->playback->BackWard) + bofcount = 1; } else { @@ -1784,7 +1825,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { track.TimeScale = 1000; } - ffmpeg_printf(10, "bit_rate [%d]\n", get_codecpar(stream)->bit_rate); + ffmpeg_printf(10, "bit_rate [%lld]\n", get_codecpar(stream)->bit_rate); ffmpeg_printf(10, "time_base.den [%d]\n", stream->time_base.den); ffmpeg_printf(10, "time_base.num [%d]\n", stream->time_base.num); ffmpeg_printf(10, "width [%d]\n", get_codecpar(stream)->width); @@ -1803,6 +1844,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); track.duration = (int64_t) avContext->duration / 1000; } + ffmpeg_printf(10, "duration [%lld]\n", track.duration); if (context->manager->video) { if (get_codecpar(stream)->codec_id == AV_CODEC_ID_MPEG4) diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 0ea3ad3..071ef40 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -96,20 +96,7 @@ static void SupervisorThread(Context_t *context) playback_printf(10, ">\n"); while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) { - if (context->playback->BackWard != 0) - { - /* Offset -3 seconds for backward - * so initial backward speed is 4x */ - int64_t pos = (int64_t)context->playback->Speed - 3; - playback_printf(10, "Speed %d BackWard %d to seek %lld\n", context->playback->Speed, context->playback->BackWard, pos); - context->playback->isSeeking = 1; - context->output->Command(context, OUTPUT_CLEAR, NULL); - context->container->selectedContainer->Command(context, CONTAINER_SEEK, &pos); - context->playback->isSeeking = 0; - usleep(350000); - } else { - usleep(100000); - } + usleep(100000); } playback_printf(10, "<\n"); hasThreadStarted = 2; From f598dbc93c09755b42e446f837f9afc2248fabf8 Mon Sep 17 00:00:00 2001 From: Frankenstone Date: Mon, 29 Jan 2018 22:19:37 +0100 Subject: [PATCH 05/38] arm different tuner authorization (thx DboxOldie) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/009f1b7c1ee248dde727146140d1eb0e1cf4861c Author: Frankenstone Date: 2018-01-29 (Mon, 29 Jan 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- common/ca_ci.cpp | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/common/ca_ci.cpp b/common/ca_ci.cpp index deaa4e5..aa1fbc6 100644 --- a/common/ca_ci.cpp +++ b/common/ca_ci.cpp @@ -43,6 +43,7 @@ ca_slot_info_t info; #endif #if HAVE_ARM_HARDWARE const char ci_path[] = "/dev/ci%d"; +static int last_source = -1; #endif static bool checkLiveSlot = false; static bool CertChecked = false; @@ -927,6 +928,8 @@ bool cCA::SendCAPMT(u64 tpid, u8 source, u8 camask, const unsigned char * cabuf, setInputSource((eDVBCISlot*)(*it), false); } } + if (!(*it)->init) + last_source = (int)source; } #endif printf("No free ci-slot\n"); @@ -1192,6 +1195,7 @@ void cCA::ModuleReset(enum CA_SLOT_TYPE, uint32_t slot) (*it)->status = eStatusReset; usleep(200000); #if HAVE_ARM_HARDWARE + last_source = (int)(*it)->source; setInputSource((eDVBCISlot*)(*it), false); #endif if ((*it)->hasCCManager) @@ -1284,6 +1288,7 @@ void cCA::ci_removed(eDVBCISlot* slot) { printf("cam (%d) status changed ->cam now _not_ present\n", slot->slot); #if HAVE_ARM_HARDWARE + last_source = (int)slot->source; setInputSource(slot, false); #endif if (slot->hasCCManager) @@ -1383,7 +1388,7 @@ void cCA::slot_pollthread(void *c) } #endif ci_inserted(slot); - setInputSource(slot, true); + //setInputSource(slot, true); goto FROM_FIRST; } } @@ -1594,6 +1599,14 @@ FROM_FIRST: break; } /* switch(slot->status) */ #endif /* end Duckbox */ +#if HAVE_ARM_HARDWARE + if (!slot->init && slot->camIsReady && last_source > -1) + { + slot->source = (u8)last_source; + setInputSource(slot, true); + last_source = -1; + } +#endif if (slot->hasCAManager && slot->hasAppManager && !slot->init) { slot->init = true; @@ -1631,7 +1644,7 @@ FROM_FIRST: slot->ccmgrSession->resendKey(slot); } /* slow down for hd51 to avoid high cpu load */ - if (wait && slot->init) + if (wait && slot->init && !slot->mmiOpened) usleep(300000); } } From baceff16bbbbdad6dc107312e1d34acf15d31829 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 8 Feb 2018 20:42:15 +0100 Subject: [PATCH 06/38] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/0d4262e8e90456d749d5b489664ecb6a9fcf6869 Author: max_10 Date: 2018-02-08 (Thu, 08 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/playback_libeplayer3.cpp | 10 ++--- libarmbox/playback_libeplayer3.h | 4 +- libarmbox/video.cpp | 2 +- libeplayer3-arm/container/buff_ffmpeg.c | 20 ++++----- libeplayer3-arm/container/container_ffmpeg.c | 45 +++++++++++-------- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 8 ++-- libeplayer3-arm/container/wrapped_ffmpeg.c | 6 +-- libeplayer3-arm/external/ffmpeg/get_bits.h | 2 +- .../external/ffmpeg/src/mpeg4audio.c | 5 +-- libeplayer3-arm/include/aac.h | 2 +- libeplayer3-arm/main/exteplayer.c | 16 +++---- libeplayer3-arm/output/linuxdvb_mipsel.c | 17 +++---- libeplayer3-arm/output/output_subtitle.c | 12 ++--- libeplayer3-arm/output/writer/mipsel/aac.c | 6 +-- libeplayer3-arm/output/writer/mipsel/divx3.c | 2 +- libeplayer3-arm/output/writer/mipsel/h264.c | 13 ++++-- libeplayer3-arm/output/writer/mipsel/h265.c | 7 ++- libeplayer3-arm/output/writer/mipsel/pcm.c | 4 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 2 +- libeplayer3-arm/output/writer/mipsel/wma.c | 2 +- libeplayer3-arm/output/writer/mipsel/writer.c | 2 +- libeplayer3-arm/playback/playback.c | 5 +-- 22 files changed, 105 insertions(+), 87 deletions(-) diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index 846190d..c5acdba 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -87,7 +87,7 @@ bool cPlayback::Start(std::string filename, std::string headers) return Start((char *) filename.c_str(), 0, 0, 0, 0, 0, headers); } -bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int, std::string headers) +bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int, std::string headers __attribute__((unused))) { bool ret = false; bool isHTTP = false; @@ -247,7 +247,7 @@ bool cPlayback::SetAPid(int pid, bool /* ac3 */) return true; } -bool cPlayback::SetVPid(int pid) +bool cPlayback::SetVPid(int /*pid*/) { lt_info("%s\n", __func__); return true; @@ -269,7 +269,7 @@ bool cPlayback::SetSubtitlePid(int pid) bool cPlayback::SetTeletextPid(int pid) { lt_info("%s\n", __func__); - int i = pid; + //int i = pid; if (pid != mTeletextStream) { //if(player && player->playback) @@ -534,10 +534,10 @@ void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::strin } } -void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, std::string *language, int *mags, int *pages) +void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids, std::string */*language*/, int */*mags*/, int */*pages*/) { lt_info("%s\n", __func__); - int max_numpids = *numpids; + //int max_numpids = *numpids; *numpids = 0; /* if (player && player->manager && player->manager->teletext) diff --git a/libarmbox/playback_libeplayer3.h b/libarmbox/playback_libeplayer3.h index 15b1b16..0709384 100644 --- a/libarmbox/playback_libeplayer3.h +++ b/libarmbox/playback_libeplayer3.h @@ -40,7 +40,7 @@ class cPlayback bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = ""); bool Start(std::string filename, std::string headers = ""); bool SetAPid(int pid, bool ac3 = false); - bool SetVPid(int pid); + bool SetVPid(int /*pid*/); bool SetSubtitlePid(int pid); bool SetTeletextPid(int pid); int GetAPid(void) { return mAudioStream; } @@ -54,7 +54,7 @@ class cPlayback bool SetPosition(int position, bool absolute = false); void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language); void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language); - void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages); + void FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpidt, std::string */*tlanguage*/, int */*mags*/, int */*pages*/); void RequestAbort(void); bool IsPlaying(void); uint64_t GetReadCount(void); diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 56bf050..ef8bc55 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -290,7 +290,7 @@ int image_to_mpeg2(const char *image_name, int fd) uint8_t endcode[] = { 0, 0, 1, 0xb7 }; write_all(fd,endcode, sizeof(endcode)); } - av_free_packet(&packet); + av_packet_unref(&packet); } avcodec_close(codecContext); } diff --git a/libeplayer3-arm/container/buff_ffmpeg.c b/libeplayer3-arm/container/buff_ffmpeg.c index 7d6cc96..61ac32d 100644 --- a/libeplayer3-arm/container/buff_ffmpeg.c +++ b/libeplayer3-arm/container/buff_ffmpeg.c @@ -163,33 +163,33 @@ static int32_t ffmpeg_read_wrapper(void *opaque, uint8_t *buf, int32_t buf_size) return ffmpeg_real_read_org(opaque, buf, buf_size); } } - +#if 0 static int32_t ffmpeg_read_wrapper2(void *opaque, uint8_t *buf, int32_t buf_size) { return ffmpeg_read_wrapper_base(opaque, buf, buf_size, 1); } - +#endif //for buffered io -void getfillerMutex(const char *filename, const char *function, int line) +void getfillerMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); pthread_mutex_lock(&fillermutex); ffmpeg_printf(100, "::%d received mutex\n", line); } -void releasefillerMutex(const char *filename, const const char *function, int line) +void releasefillerMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int line __attribute__((unused))) { pthread_mutex_unlock(&fillermutex); ffmpeg_printf(100, "::%d released mutex\n", line); } //for buffered io (end)encoding - +#if 0 static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time) { ffmpeg_buf_seek_time = (*time); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#endif static int32_t container_set_ffmpeg_buf_size(int32_t *size) { if (ffmpeg_buf == NULL) @@ -229,13 +229,13 @@ static int32_t container_get_fillbufstatus(int32_t *size) } return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#if 0 static int32_t container_stop_buffer() { ffmpeg_buf_stop = 1; return 0; } - +#endif //flag 0: start direct //flag 1: from thread static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int32_t flag) @@ -414,7 +414,7 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) return ret; } -static int32_t ffmpeg_read_real(void *opaque, uint8_t *buf, int32_t buf_size) +static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *buf, int32_t buf_size) { int32_t len = buf_size; int32_t rwdiff = 0; @@ -495,7 +495,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size) return sumlen; } -static int64_t ffmpeg_seek(void *opaque, int64_t offset, int32_t whence) +static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, int32_t whence) { int64_t diff; int32_t rwdiff = 0; diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index ed39ac1..69eb4e9 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -147,7 +147,7 @@ static int32_t seek_target_flag = 0; /* ***************************** */ static int32_t container_ffmpeg_seek_bytes(off_t pos); static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute); -static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec); +//static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec); static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length); static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts); @@ -204,7 +204,7 @@ static int32_t flv2mpeg4_converter = 0; /* MISC Functions */ /* ***************************** */ -static void ffmpeg_silen_callback(void *avcl, int level, const char *fmt, va_list vl) +static void ffmpeg_silen_callback(void *avcl __attribute__((unused)), int level __attribute__((unused)), const char *fmt __attribute__((unused)), va_list vl __attribute__((unused))) { return; } @@ -287,7 +287,7 @@ static void initMutex(void) mutexInitialized = 1; } -static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line) +static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); if (!mutexInitialized) @@ -298,13 +298,13 @@ static void getMutex(const char *filename __attribute__((unused)), const char *f ffmpeg_printf(100, "::%d received mutex\n", line); } -static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line) +static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { pthread_mutex_unlock(&mutex); ffmpeg_printf(100, "::%d released mutex\n", line); } -static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile, int32_t *version) +static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile __attribute__((unused)), int32_t *version) { ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id); switch (codec_id) @@ -524,8 +524,8 @@ static void FFMPEGThread(Context_t *context) threadname[16] = 0; prctl(PR_SET_NAME, (unsigned long)&threadname); AVPacket packet; - off_t lastSeek = -1; - int64_t lastPts = -1; + //off_t lastSeek = -1; + //int64_t lastPts = -1; int64_t currentVideoPts = -1; int64_t currentAudioPts = -1; /* lastVideoDts and lastAudioDts @@ -535,7 +535,7 @@ static void FFMPEGThread(Context_t *context) int64_t lastAudioDts = -1; int64_t showtime = 0; int64_t bofcount = 0; - int32_t err = 0; + //int32_t err = 0; AudioVideoOut_t avOut; g_context = context; SwrContext *swr = NULL; @@ -737,7 +737,7 @@ static void FFMPEGThread(Context_t *context) ffmpeg_err("error getting subtitle track\n"); } ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid); - if (videoTrack && (videoTrack->AVIdx == cAVIdx) && (videoTrack->Id == pid)) + if (videoTrack && (videoTrack->AVIdx == (int)cAVIdx) && (videoTrack->Id == pid)) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) AVCodecContext *codec_context = videoTrack->avCodecCtx; @@ -826,7 +826,7 @@ static void FFMPEGThread(Context_t *context) } } } - else if (audioTrack && (audioTrack->AVIdx == cAVIdx) && (audioTrack->Id == pid)) + else if (audioTrack && (audioTrack->AVIdx == (int)cAVIdx) && (audioTrack->Id == pid)) { uint8_t skipPacket = 0; currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, packet.pts); @@ -1111,7 +1111,7 @@ static void FFMPEGThread(Context_t *context) else if (subtitleTrack && (subtitleTrack->Id == pid)) { int64_t duration = -1; - int64_t pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts); + pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts); AVStream *stream = subtitleTrack->stream; if (packet.duration != 0) { @@ -1604,7 +1604,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) { - int32_t err = 0; + //int32_t err = 0; ffmpeg_printf(10, ">\n"); if (playFilesNames == NULL) { @@ -1741,7 +1741,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } } - int32_t n = 0; + uint32_t n = 0; for (n = 0; n < avContext->nb_streams; n++) { Track_t track; @@ -2323,7 +2323,7 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos) ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb)); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#if 0 //unused /* seeking relative to a given byteposition N seconds ->for reverse playback needed */ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec) { @@ -2399,12 +2399,12 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#endif static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute) { Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; - Track_t *current = NULL; +// Track_t *current = NULL; seek_target_flag = 0; sec *= AV_TIME_BASE; if (!absolute) @@ -2435,6 +2435,13 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_printf(10, "goto %lld sec\n", sec / AV_TIME_BASE); context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if (!videoTrack && !audioTrack) + { + ffmpeg_err("no track available to seek\n"); + return cERR_CONTAINER_FFMPEG_ERR; + } + +#if 0 if (videoTrack != NULL) { current = videoTrack; @@ -2448,6 +2455,8 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_err("no track available to seek\n"); return cERR_CONTAINER_FFMPEG_ERR; } +#endif + if (sec < 0) { seek_target_flag |= AVSEEK_FLAG_BACKWARD; @@ -2546,7 +2555,7 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg) +static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); /* Hellmaster1024: nothing to do here! */ @@ -2555,7 +2564,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg) +static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); /* This is made to flush inside the buffer because diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index 174d11e..bf5a0b0 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -87,12 +87,12 @@ static void mpeg4p2_context_reset(Mpeg4P2Context *context) context->packet_duration = 0; } -static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *currentVideoPts, int64_t *latestPts, AVPacket *pkt) +static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt) { - *currentVideoPts = track->pts = calcPts(avContextIdx, track->stream, pkt->pts); - if ((*currentVideoPts > *latestPts) && (*currentVideoPts != INVALID_PTS_VALUE)) + *pts_current = track->pts = calcPts(avContextIdx, track->stream, pkt->pts); + if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE)) { - *latestPts = *currentVideoPts; + *pts_latest = *pts_current; } track->dts = calcPts(avContextIdx, track->stream, pkt->dts); AudioVideoOut_t avOut; diff --git a/libeplayer3-arm/container/wrapped_ffmpeg.c b/libeplayer3-arm/container/wrapped_ffmpeg.c index 589311a..3ca4738 100644 --- a/libeplayer3-arm/container/wrapped_ffmpeg.c +++ b/libeplayer3-arm/container/wrapped_ffmpeg.c @@ -39,7 +39,7 @@ static void wrapped_packet_unref(void *param) #endif } -static void wrapped_set_max_analyze_duration(void *param, int val) +static void wrapped_set_max_analyze_duration(void *param, int val __attribute__((unused))) { #if (LIBAVFORMAT_VERSION_MAJOR > 55) && (LIBAVFORMAT_VERSION_MAJOR < 56) ((AVFormatContext *)param)->max_analyze_duration2 = val; @@ -114,7 +114,7 @@ void free_all_stored_avcodec_context() } } -int store_avcodec_context(AVCodecContext *avCodecCtx, uint32_t cAVIdx, int id) +int store_avcodec_context(AVCodecContext *avCodecCtx __attribute__((unused)), uint32_t cAVIdx __attribute__((unused)), int id __attribute__((unused))) { CodecCtxStoreItem_t *ptr = malloc(sizeof(CodecCtxStoreItem_t)); if (!ptr) @@ -152,8 +152,8 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st } av_codec_set_pkt_timebase(avCodecCtx, stream->time_base); store_avcodec_context(avCodecCtx, cAVIdx, stream->id); - return avCodecCtx; } + return avCodecCtx; #else return stream->codec; #endif diff --git a/libeplayer3-arm/external/ffmpeg/get_bits.h b/libeplayer3-arm/external/ffmpeg/get_bits.h index fd99374..b0f49e3 100644 --- a/libeplayer3-arm/external/ffmpeg/get_bits.h +++ b/libeplayer3-arm/external/ffmpeg/get_bits.h @@ -368,7 +368,7 @@ static inline unsigned int show_bits_long(GetBitContext *s, int n) } } -static inline int check_marker(void *logctx, GetBitContext *s, const char *msg) +static inline int check_marker(void *logctx __attribute__((unused)), GetBitContext *s, const char *msg __attribute__((unused))) { int bit = get_bits1(s); return bit; diff --git a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c index 8bbd7eb..f43a568 100644 --- a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c +++ b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c @@ -71,8 +71,7 @@ static inline int get_object_type(GetBitContext *gb) static inline int get_sample_rate(GetBitContext *gb, int *index) { *index = get_bits(gb, 4); - return *index == 0x0f ? get_bits(gb, 24) : - avpriv_mpeg4audio_sample_rates[*index]; + return *index == 0x0f ? (int)get_bits(gb, 24) : avpriv_mpeg4audio_sample_rates[*index]; } int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, @@ -88,7 +87,7 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, c->object_type = get_object_type(&gb); c->sample_rate = get_sample_rate(&gb, &c->sampling_index); c->chan_config = get_bits(&gb, 4); - if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) + if (c->chan_config < (int)FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) c->channels = ff_mpeg4audio_channels[c->chan_config]; c->sbr = -1; c->ps = -1; diff --git a/libeplayer3-arm/include/aac.h b/libeplayer3-arm/include/aac.h index 402087b..4455043 100644 --- a/libeplayer3-arm/include/aac.h +++ b/libeplayer3-arm/include/aac.h @@ -24,7 +24,7 @@ static inline int HasADTSHeader(uint8_t *data, int size) { - if (size >= AAC_HEADER_LENGTH && 0xFF == data[0] && 0xF0 == 0xF0 & data[1] && + if (size >= AAC_HEADER_LENGTH && 0xFF == data[0] && 0xF0 == (0xF0 & data[1]) && size == ((data[3] & 0x3) << 11 | data[4] << 3 | data[5] >> 5)) { return 1; diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 17b3146..adc0c2f 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -88,7 +88,7 @@ static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread */ static int isPlaybackStarted = 0; static pthread_mutex_t playbackStartMtx; -static void *TermThreadFun(void *arg) +static void *TermThreadFun(void *arg __attribute__((unused))) { const char *socket_path = "/tmp/iptvplayer_extplayer_term_fd"; struct sockaddr_un addr; @@ -211,7 +211,7 @@ static void SetNice(int prio) }; sched_setscheduler(0, SCHED_RR, ¶m); #else - int prevPrio = getpriority(PRIO_PROCESS, 0); + //int prevPrio = getpriority(PRIO_PROCESS, 0); if (-1 == setpriority(PRIO_PROCESS, 0, prio)) { printf("setpriority - failed\n"); @@ -484,9 +484,9 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int { int ret = 0; int c; - int digit_optind = 0; - int aopt = 0, bopt = 0; - char *copt = 0, *dopt = 0; + //int digit_optind = 0; + //int aopt = 0, bopt = 0; + //char *copt = 0, *dopt = 0; while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:")) != -1) { switch (c) @@ -877,7 +877,7 @@ int main(int argc, char *argv[]) CurrentSec = (int32_t)(pts / 90000); if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal); + fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); } if (0 == commandRetVal || force) { @@ -922,7 +922,7 @@ int main(int argc, char *argv[]) commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal); + fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); } break; } @@ -941,7 +941,7 @@ int main(int argc, char *argv[]) } case 'n': { - uint8_t loop = 0; + //uint8_t loop = 0; if ('1' == argvBuff[1] || '0' == argvBuff[1]) { PlaybackHandler_t *ptrP = g_player->playback; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 8990c5b..56cbc91 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -54,12 +54,11 @@ #ifdef SAM_WITH_DEBUG #define LINUXDVB_DEBUG +static unsigned short debug_level = 20; #else #define LINUXDVB_SILENT #endif -static unsigned short debug_level = 20; - static const char FILENAME[] = __FILE__; #ifdef LINUXDVB_DEBUG @@ -311,8 +310,9 @@ int LinuxDvbPlay(Context_t *context, char *type) } free(Encoding); } - //return ret; - return 0; + ret = cERR_LINUXDVB_NO_ERROR; + return ret; + //return 0; } int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) @@ -425,7 +425,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) return ret; } -int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus) +int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; @@ -474,7 +474,7 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) return ret; } -int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) +int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { // unsigned char video = !strcmp("video", type); // unsigned char audio = !strcmp("audio", type); @@ -507,6 +507,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + if (audio) {} linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); if (video && videofd != -1) { @@ -601,7 +602,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) return ret; } -int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused))) +int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; /* konfetti: this one is dedicated to audiofd so we @@ -691,7 +692,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i return ret; } -int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount) +int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; return ret; diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index 411a30d..ef740f2 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -97,14 +97,14 @@ static int isSubtitleOpened = 0; /* Functions */ /* ***************************** */ -static void getMutex(int line) +static void getMutex(int line __attribute__((unused))) { subtitle_printf(100, "%d requesting mutex\n", line); pthread_mutex_lock(&mutex); subtitle_printf(100, "%d received mutex\n", line); } -static void releaseMutex(int line) +static void releaseMutex(int line __attribute__((unused))) { pthread_mutex_unlock(&mutex); subtitle_printf(100, "%d released mutex\n", line); @@ -202,7 +202,7 @@ static int Write(void *_context, void *data) } out = (SubtitleOut_t *) data; context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); - if (curtrackid != out->trackId) + if (curtrackid != (int32_t)out->trackId) { Flush(); } @@ -232,7 +232,7 @@ static int Write(void *_context, void *data) static int32_t subtitle_Open(Context_t *context __attribute__((unused))) { - uint32_t i = 0 ; + //uint32_t i = 0 ; subtitle_printf(10, "\n"); if (isSubtitleOpened == 1) { @@ -248,7 +248,7 @@ static int32_t subtitle_Open(Context_t *context __attribute__((unused))) static int32_t subtitle_Close(Context_t *context __attribute__((unused))) { - uint32_t i = 0 ; + //uint32_t i = 0 ; subtitle_printf(10, "\n"); getMutex(__LINE__); isSubtitleOpened = 0; @@ -257,7 +257,7 @@ static int32_t subtitle_Close(Context_t *context __attribute__((unused))) return cERR_SUBTITLE_NO_ERROR; } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(void *_context, OutputCmd_t command, void *argument __attribute__((unused))) { Context_t *context = (Context_t *) _context; int ret = cERR_SUBTITLE_NO_ERROR; diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index 3b6945b..c8e1b2f 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -182,7 +182,7 @@ static int _writeData(void *_call, int type) else // check LOAS header { if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe && - (AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len)) + ((uint32_t)(AV_RB16(call->data + 1) & 0x1FFF) + 3) == call->len)) { aac_err("parsing Data with wrong latm header. ignoring...\n"); return 0; @@ -218,7 +218,7 @@ static int writeDataADTS(void *_call) aac_err("file pointer < 0. ignoring ...\n"); return 0; } - if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) || + if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { return _writeData(_call, 0); @@ -272,7 +272,7 @@ static int writeDataLATM(void *_call) aac_err("parsing NULL Data. ignoring...\n"); return 0; } - if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size)) + if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) { return _writeData(_call, 1); } diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index cc9f93a..44a822d 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -117,7 +117,7 @@ static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; - unsigned char Version = 5; +// unsigned char Version = 5; // unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; divx_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 1f766e7..77e45c1 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -195,12 +195,14 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne if (cd_len > 7 && data[0] == 1) { unsigned short len = (data[6] << 8) | data[7]; - if (cd_len >= (len + 8)) + if (cd_len >= (uint32_t)(len + 8)) { unsigned int i = 0; uint8_t profile_num[] = { 66, 77, 88, 100 }; uint8_t profile_cmp[2] = { 0x67, 0x00 }; const char *profile_str[] = { "baseline", "main", "extended", "high" }; + /* avoid compiler warning */ + if (*profile_str) {} memcpy(tmp, Head, sizeof(Head)); tmp_len += 4; memcpy(tmp + tmp_len, data + 8, len); @@ -289,7 +291,7 @@ static int writeData(void *_call) unsigned long long int VideoPts; unsigned int TimeDelta; unsigned int TimeScale; - int len = 0; + unsigned int len = 0; int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); @@ -300,6 +302,9 @@ static int writeData(void *_call) } TimeDelta = call->FrameRate; TimeScale = call->FrameScale; + /* avoid compiler warnings */ + if (TimeDelta) {} + if (TimeScale) {} VideoPts = call->Pts; h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); if ((call->data == NULL) || (call->len <= 0)) @@ -314,8 +319,8 @@ static int writeData(void *_call) } /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || - (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) + ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) { uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index 87cc830..aa80678 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -116,7 +116,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne } *NalLength = (data[21] & 3) + 1; int num_param_sets = data[22]; - int pos = 23; + uint32_t pos = 23; for (i = 0; i < num_param_sets; i++) { int j; @@ -175,7 +175,7 @@ static int writeData(void *_call) unsigned long long int VideoPts; unsigned int TimeDelta; unsigned int TimeScale; - int len = 0; + unsigned int len = 0; int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); @@ -186,6 +186,9 @@ static int writeData(void *_call) } TimeDelta = call->FrameRate; TimeScale = call->FrameScale; + /* avoid compiler warnings */ + if (TimeDelta) {} + if (TimeScale) {} VideoPts = call->Pts; h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); if ((call->data == NULL) || (call->len <= 0)) diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index 00e6f31..3a0045b 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -152,7 +152,7 @@ static int32_t writeData(void *_call) int32_t block_align = 0; int32_t byterate = 0; uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; - uint8_t dataPrecision = 0; + //uint8_t dataPrecision = 0; uint8_t LE = 0; switch (codecID) { @@ -224,6 +224,8 @@ static int32_t writeData(void *_call) fixed_buffer = malloc(fixed_buffersize); } fixed_bufferfilled = 0; + /* avoid compiler warning */ + if (LE) {} //printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE"); } while (size > 0) diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index c591011..845afb5 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -110,7 +110,7 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - int len = 0; + //int len = 0; vc1_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index c82acef..5324836 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -106,7 +106,7 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - int len = 0; + //int len = 0; wma_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index fa9afe2..2d7f70a 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -145,7 +145,7 @@ ssize_t write_with_retry(int fd, const void *buf, size_t size) ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic) { ssize_t len = 0; - int i = 0; + uint32_t i = 0; for (i = 0; i < ic; ++i) { write_with_retry(fd, iov[i].iov_base, iov[i].iov_len); diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 071ef40..602d265 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -32,12 +32,11 @@ #ifdef SAM_WITH_DEBUG #define PLAYBACK_DEBUG +static short debug_level = 20; #else #define PLAYBACK_SILENT #endif -static short debug_level = 20; - #ifdef PLAYBACK_DEBUG #define playback_printf(level, fmt, x...) do { \ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) @@ -565,7 +564,7 @@ static int32_t PlaybackPts(Context_t *context, int64_t *pts) return ret; } -static int32_t PlaybackGetFrameCount(Context_t *context, int64_t *frameCount) +static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount) { int ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "\n"); From e27a6fb95110b1c41143f7d4f6e5293a5f8f0bac Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 8 Feb 2018 20:42:15 +0100 Subject: [PATCH 07/38] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/d526ddba8b8a13c2ce71bb1dde5f1d48d5051826 Author: max_10 Date: 2018-02-08 (Thu, 08 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/playback_libeplayer3.cpp | 10 ++--- libarmbox/playback_libeplayer3.h | 4 +- libarmbox/video.cpp | 2 +- libeplayer3-arm/container/buff_ffmpeg.c | 20 ++++----- libeplayer3-arm/container/container_ffmpeg.c | 45 +++++++++++-------- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 8 ++-- libeplayer3-arm/container/wrapped_ffmpeg.c | 6 +-- libeplayer3-arm/external/ffmpeg/get_bits.h | 2 +- .../external/ffmpeg/src/mpeg4audio.c | 5 +-- libeplayer3-arm/include/aac.h | 2 +- libeplayer3-arm/main/exteplayer.c | 16 +++---- libeplayer3-arm/output/linuxdvb_mipsel.c | 17 +++---- libeplayer3-arm/output/output_subtitle.c | 12 ++--- libeplayer3-arm/output/writer/mipsel/aac.c | 6 +-- libeplayer3-arm/output/writer/mipsel/divx3.c | 2 +- libeplayer3-arm/output/writer/mipsel/h264.c | 13 ++++-- libeplayer3-arm/output/writer/mipsel/h265.c | 7 ++- libeplayer3-arm/output/writer/mipsel/pcm.c | 4 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 2 +- libeplayer3-arm/output/writer/mipsel/wma.c | 2 +- libeplayer3-arm/output/writer/mipsel/writer.c | 2 +- libeplayer3-arm/playback/playback.c | 5 +-- 22 files changed, 105 insertions(+), 87 deletions(-) diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index 846190d..c5acdba 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -87,7 +87,7 @@ bool cPlayback::Start(std::string filename, std::string headers) return Start((char *) filename.c_str(), 0, 0, 0, 0, 0, headers); } -bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int, std::string headers) +bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, int, std::string headers __attribute__((unused))) { bool ret = false; bool isHTTP = false; @@ -247,7 +247,7 @@ bool cPlayback::SetAPid(int pid, bool /* ac3 */) return true; } -bool cPlayback::SetVPid(int pid) +bool cPlayback::SetVPid(int /*pid*/) { lt_info("%s\n", __func__); return true; @@ -269,7 +269,7 @@ bool cPlayback::SetSubtitlePid(int pid) bool cPlayback::SetTeletextPid(int pid) { lt_info("%s\n", __func__); - int i = pid; + //int i = pid; if (pid != mTeletextStream) { //if(player && player->playback) @@ -534,10 +534,10 @@ void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::strin } } -void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, std::string *language, int *mags, int *pages) +void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids, std::string */*language*/, int */*mags*/, int */*pages*/) { lt_info("%s\n", __func__); - int max_numpids = *numpids; + //int max_numpids = *numpids; *numpids = 0; /* if (player && player->manager && player->manager->teletext) diff --git a/libarmbox/playback_libeplayer3.h b/libarmbox/playback_libeplayer3.h index 15b1b16..0709384 100644 --- a/libarmbox/playback_libeplayer3.h +++ b/libarmbox/playback_libeplayer3.h @@ -40,7 +40,7 @@ class cPlayback bool Start(char *filename, int vpid, int vtype, int apid, int ac3, int duration, std::string headers = ""); bool Start(std::string filename, std::string headers = ""); bool SetAPid(int pid, bool ac3 = false); - bool SetVPid(int pid); + bool SetVPid(int /*pid*/); bool SetSubtitlePid(int pid); bool SetTeletextPid(int pid); int GetAPid(void) { return mAudioStream; } @@ -54,7 +54,7 @@ class cPlayback bool SetPosition(int position, bool absolute = false); void FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language); void FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language); - void FindAllTeletextsubtitlePids(int *pids, unsigned int *numpidt, std::string *tlanguage, int *mags, int *pages); + void FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpidt, std::string */*tlanguage*/, int */*mags*/, int */*pages*/); void RequestAbort(void); bool IsPlaying(void); uint64_t GetReadCount(void); diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 56bf050..ef8bc55 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -290,7 +290,7 @@ int image_to_mpeg2(const char *image_name, int fd) uint8_t endcode[] = { 0, 0, 1, 0xb7 }; write_all(fd,endcode, sizeof(endcode)); } - av_free_packet(&packet); + av_packet_unref(&packet); } avcodec_close(codecContext); } diff --git a/libeplayer3-arm/container/buff_ffmpeg.c b/libeplayer3-arm/container/buff_ffmpeg.c index 7d6cc96..61ac32d 100644 --- a/libeplayer3-arm/container/buff_ffmpeg.c +++ b/libeplayer3-arm/container/buff_ffmpeg.c @@ -163,33 +163,33 @@ static int32_t ffmpeg_read_wrapper(void *opaque, uint8_t *buf, int32_t buf_size) return ffmpeg_real_read_org(opaque, buf, buf_size); } } - +#if 0 static int32_t ffmpeg_read_wrapper2(void *opaque, uint8_t *buf, int32_t buf_size) { return ffmpeg_read_wrapper_base(opaque, buf, buf_size, 1); } - +#endif //for buffered io -void getfillerMutex(const char *filename, const char *function, int line) +void getfillerMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); pthread_mutex_lock(&fillermutex); ffmpeg_printf(100, "::%d received mutex\n", line); } -void releasefillerMutex(const char *filename, const const char *function, int line) +void releasefillerMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int line __attribute__((unused))) { pthread_mutex_unlock(&fillermutex); ffmpeg_printf(100, "::%d released mutex\n", line); } //for buffered io (end)encoding - +#if 0 static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time) { ffmpeg_buf_seek_time = (*time); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#endif static int32_t container_set_ffmpeg_buf_size(int32_t *size) { if (ffmpeg_buf == NULL) @@ -229,13 +229,13 @@ static int32_t container_get_fillbufstatus(int32_t *size) } return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#if 0 static int32_t container_stop_buffer() { ffmpeg_buf_stop = 1; return 0; } - +#endif //flag 0: start direct //flag 1: from thread static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int32_t flag) @@ -414,7 +414,7 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) return ret; } -static int32_t ffmpeg_read_real(void *opaque, uint8_t *buf, int32_t buf_size) +static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *buf, int32_t buf_size) { int32_t len = buf_size; int32_t rwdiff = 0; @@ -495,7 +495,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size) return sumlen; } -static int64_t ffmpeg_seek(void *opaque, int64_t offset, int32_t whence) +static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, int32_t whence) { int64_t diff; int32_t rwdiff = 0; diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index ed39ac1..69eb4e9 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -147,7 +147,7 @@ static int32_t seek_target_flag = 0; /* ***************************** */ static int32_t container_ffmpeg_seek_bytes(off_t pos); static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute); -static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec); +//static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec); static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length); static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts); @@ -204,7 +204,7 @@ static int32_t flv2mpeg4_converter = 0; /* MISC Functions */ /* ***************************** */ -static void ffmpeg_silen_callback(void *avcl, int level, const char *fmt, va_list vl) +static void ffmpeg_silen_callback(void *avcl __attribute__((unused)), int level __attribute__((unused)), const char *fmt __attribute__((unused)), va_list vl __attribute__((unused))) { return; } @@ -287,7 +287,7 @@ static void initMutex(void) mutexInitialized = 1; } -static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line) +static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); if (!mutexInitialized) @@ -298,13 +298,13 @@ static void getMutex(const char *filename __attribute__((unused)), const char *f ffmpeg_printf(100, "::%d received mutex\n", line); } -static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line) +static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { pthread_mutex_unlock(&mutex); ffmpeg_printf(100, "::%d released mutex\n", line); } -static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile, int32_t *version) +static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile __attribute__((unused)), int32_t *version) { ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id); switch (codec_id) @@ -524,8 +524,8 @@ static void FFMPEGThread(Context_t *context) threadname[16] = 0; prctl(PR_SET_NAME, (unsigned long)&threadname); AVPacket packet; - off_t lastSeek = -1; - int64_t lastPts = -1; + //off_t lastSeek = -1; + //int64_t lastPts = -1; int64_t currentVideoPts = -1; int64_t currentAudioPts = -1; /* lastVideoDts and lastAudioDts @@ -535,7 +535,7 @@ static void FFMPEGThread(Context_t *context) int64_t lastAudioDts = -1; int64_t showtime = 0; int64_t bofcount = 0; - int32_t err = 0; + //int32_t err = 0; AudioVideoOut_t avOut; g_context = context; SwrContext *swr = NULL; @@ -737,7 +737,7 @@ static void FFMPEGThread(Context_t *context) ffmpeg_err("error getting subtitle track\n"); } ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid); - if (videoTrack && (videoTrack->AVIdx == cAVIdx) && (videoTrack->Id == pid)) + if (videoTrack && (videoTrack->AVIdx == (int)cAVIdx) && (videoTrack->Id == pid)) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) AVCodecContext *codec_context = videoTrack->avCodecCtx; @@ -826,7 +826,7 @@ static void FFMPEGThread(Context_t *context) } } } - else if (audioTrack && (audioTrack->AVIdx == cAVIdx) && (audioTrack->Id == pid)) + else if (audioTrack && (audioTrack->AVIdx == (int)cAVIdx) && (audioTrack->Id == pid)) { uint8_t skipPacket = 0; currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, packet.pts); @@ -1111,7 +1111,7 @@ static void FFMPEGThread(Context_t *context) else if (subtitleTrack && (subtitleTrack->Id == pid)) { int64_t duration = -1; - int64_t pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts); + pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts); AVStream *stream = subtitleTrack->stream; if (packet.duration != 0) { @@ -1604,7 +1604,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) { - int32_t err = 0; + //int32_t err = 0; ffmpeg_printf(10, ">\n"); if (playFilesNames == NULL) { @@ -1741,7 +1741,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } } - int32_t n = 0; + uint32_t n = 0; for (n = 0; n < avContext->nb_streams; n++) { Track_t track; @@ -2323,7 +2323,7 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos) ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb)); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#if 0 //unused /* seeking relative to a given byteposition N seconds ->for reverse playback needed */ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec) { @@ -2399,12 +2399,12 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } - +#endif static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute) { Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; - Track_t *current = NULL; +// Track_t *current = NULL; seek_target_flag = 0; sec *= AV_TIME_BASE; if (!absolute) @@ -2435,6 +2435,13 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_printf(10, "goto %lld sec\n", sec / AV_TIME_BASE); context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if (!videoTrack && !audioTrack) + { + ffmpeg_err("no track available to seek\n"); + return cERR_CONTAINER_FFMPEG_ERR; + } + +#if 0 if (videoTrack != NULL) { current = videoTrack; @@ -2448,6 +2455,8 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_err("no track available to seek\n"); return cERR_CONTAINER_FFMPEG_ERR; } +#endif + if (sec < 0) { seek_target_flag |= AVSEEK_FLAG_BACKWARD; @@ -2546,7 +2555,7 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg) +static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); /* Hellmaster1024: nothing to do here! */ @@ -2555,7 +2564,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg) +static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); /* This is made to flush inside the buffer because diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index 174d11e..bf5a0b0 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -87,12 +87,12 @@ static void mpeg4p2_context_reset(Mpeg4P2Context *context) context->packet_duration = 0; } -static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *currentVideoPts, int64_t *latestPts, AVPacket *pkt) +static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt) { - *currentVideoPts = track->pts = calcPts(avContextIdx, track->stream, pkt->pts); - if ((*currentVideoPts > *latestPts) && (*currentVideoPts != INVALID_PTS_VALUE)) + *pts_current = track->pts = calcPts(avContextIdx, track->stream, pkt->pts); + if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE)) { - *latestPts = *currentVideoPts; + *pts_latest = *pts_current; } track->dts = calcPts(avContextIdx, track->stream, pkt->dts); AudioVideoOut_t avOut; diff --git a/libeplayer3-arm/container/wrapped_ffmpeg.c b/libeplayer3-arm/container/wrapped_ffmpeg.c index 589311a..3ca4738 100644 --- a/libeplayer3-arm/container/wrapped_ffmpeg.c +++ b/libeplayer3-arm/container/wrapped_ffmpeg.c @@ -39,7 +39,7 @@ static void wrapped_packet_unref(void *param) #endif } -static void wrapped_set_max_analyze_duration(void *param, int val) +static void wrapped_set_max_analyze_duration(void *param, int val __attribute__((unused))) { #if (LIBAVFORMAT_VERSION_MAJOR > 55) && (LIBAVFORMAT_VERSION_MAJOR < 56) ((AVFormatContext *)param)->max_analyze_duration2 = val; @@ -114,7 +114,7 @@ void free_all_stored_avcodec_context() } } -int store_avcodec_context(AVCodecContext *avCodecCtx, uint32_t cAVIdx, int id) +int store_avcodec_context(AVCodecContext *avCodecCtx __attribute__((unused)), uint32_t cAVIdx __attribute__((unused)), int id __attribute__((unused))) { CodecCtxStoreItem_t *ptr = malloc(sizeof(CodecCtxStoreItem_t)); if (!ptr) @@ -152,8 +152,8 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st } av_codec_set_pkt_timebase(avCodecCtx, stream->time_base); store_avcodec_context(avCodecCtx, cAVIdx, stream->id); - return avCodecCtx; } + return avCodecCtx; #else return stream->codec; #endif diff --git a/libeplayer3-arm/external/ffmpeg/get_bits.h b/libeplayer3-arm/external/ffmpeg/get_bits.h index fd99374..b0f49e3 100644 --- a/libeplayer3-arm/external/ffmpeg/get_bits.h +++ b/libeplayer3-arm/external/ffmpeg/get_bits.h @@ -368,7 +368,7 @@ static inline unsigned int show_bits_long(GetBitContext *s, int n) } } -static inline int check_marker(void *logctx, GetBitContext *s, const char *msg) +static inline int check_marker(void *logctx __attribute__((unused)), GetBitContext *s, const char *msg __attribute__((unused))) { int bit = get_bits1(s); return bit; diff --git a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c index 8bbd7eb..f43a568 100644 --- a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c +++ b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c @@ -71,8 +71,7 @@ static inline int get_object_type(GetBitContext *gb) static inline int get_sample_rate(GetBitContext *gb, int *index) { *index = get_bits(gb, 4); - return *index == 0x0f ? get_bits(gb, 24) : - avpriv_mpeg4audio_sample_rates[*index]; + return *index == 0x0f ? (int)get_bits(gb, 24) : avpriv_mpeg4audio_sample_rates[*index]; } int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, @@ -88,7 +87,7 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, c->object_type = get_object_type(&gb); c->sample_rate = get_sample_rate(&gb, &c->sampling_index); c->chan_config = get_bits(&gb, 4); - if (c->chan_config < FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) + if (c->chan_config < (int)FF_ARRAY_ELEMS(ff_mpeg4audio_channels)) c->channels = ff_mpeg4audio_channels[c->chan_config]; c->sbr = -1; c->ps = -1; diff --git a/libeplayer3-arm/include/aac.h b/libeplayer3-arm/include/aac.h index 402087b..4455043 100644 --- a/libeplayer3-arm/include/aac.h +++ b/libeplayer3-arm/include/aac.h @@ -24,7 +24,7 @@ static inline int HasADTSHeader(uint8_t *data, int size) { - if (size >= AAC_HEADER_LENGTH && 0xFF == data[0] && 0xF0 == 0xF0 & data[1] && + if (size >= AAC_HEADER_LENGTH && 0xFF == data[0] && 0xF0 == (0xF0 & data[1]) && size == ((data[3] & 0x3) << 11 | data[4] << 3 | data[5] >> 5)) { return 1; diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 17b3146..adc0c2f 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -88,7 +88,7 @@ static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread */ static int isPlaybackStarted = 0; static pthread_mutex_t playbackStartMtx; -static void *TermThreadFun(void *arg) +static void *TermThreadFun(void *arg __attribute__((unused))) { const char *socket_path = "/tmp/iptvplayer_extplayer_term_fd"; struct sockaddr_un addr; @@ -211,7 +211,7 @@ static void SetNice(int prio) }; sched_setscheduler(0, SCHED_RR, ¶m); #else - int prevPrio = getpriority(PRIO_PROCESS, 0); + //int prevPrio = getpriority(PRIO_PROCESS, 0); if (-1 == setpriority(PRIO_PROCESS, 0, prio)) { printf("setpriority - failed\n"); @@ -484,9 +484,9 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int { int ret = 0; int c; - int digit_optind = 0; - int aopt = 0, bopt = 0; - char *copt = 0, *dopt = 0; + //int digit_optind = 0; + //int aopt = 0, bopt = 0; + //char *copt = 0, *dopt = 0; while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:")) != -1) { switch (c) @@ -877,7 +877,7 @@ int main(int argc, char *argv[]) CurrentSec = (int32_t)(pts / 90000); if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal); + fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); } if (0 == commandRetVal || force) { @@ -922,7 +922,7 @@ int main(int argc, char *argv[]) commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90, commandRetVal); + fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); } break; } @@ -941,7 +941,7 @@ int main(int argc, char *argv[]) } case 'n': { - uint8_t loop = 0; + //uint8_t loop = 0; if ('1' == argvBuff[1] || '0' == argvBuff[1]) { PlaybackHandler_t *ptrP = g_player->playback; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 8990c5b..56cbc91 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -54,12 +54,11 @@ #ifdef SAM_WITH_DEBUG #define LINUXDVB_DEBUG +static unsigned short debug_level = 20; #else #define LINUXDVB_SILENT #endif -static unsigned short debug_level = 20; - static const char FILENAME[] = __FILE__; #ifdef LINUXDVB_DEBUG @@ -311,8 +310,9 @@ int LinuxDvbPlay(Context_t *context, char *type) } free(Encoding); } - //return ret; - return 0; + ret = cERR_LINUXDVB_NO_ERROR; + return ret; + //return 0; } int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) @@ -425,7 +425,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) return ret; } -int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus) +int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; @@ -474,7 +474,7 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) return ret; } -int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) +int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { // unsigned char video = !strcmp("video", type); // unsigned char audio = !strcmp("audio", type); @@ -507,6 +507,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + if (audio) {} linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); if (video && videofd != -1) { @@ -601,7 +602,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) return ret; } -int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused))) +int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; /* konfetti: this one is dedicated to audiofd so we @@ -691,7 +692,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i return ret; } -int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount) +int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; return ret; diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index 411a30d..ef740f2 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -97,14 +97,14 @@ static int isSubtitleOpened = 0; /* Functions */ /* ***************************** */ -static void getMutex(int line) +static void getMutex(int line __attribute__((unused))) { subtitle_printf(100, "%d requesting mutex\n", line); pthread_mutex_lock(&mutex); subtitle_printf(100, "%d received mutex\n", line); } -static void releaseMutex(int line) +static void releaseMutex(int line __attribute__((unused))) { pthread_mutex_unlock(&mutex); subtitle_printf(100, "%d released mutex\n", line); @@ -202,7 +202,7 @@ static int Write(void *_context, void *data) } out = (SubtitleOut_t *) data; context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); - if (curtrackid != out->trackId) + if (curtrackid != (int32_t)out->trackId) { Flush(); } @@ -232,7 +232,7 @@ static int Write(void *_context, void *data) static int32_t subtitle_Open(Context_t *context __attribute__((unused))) { - uint32_t i = 0 ; + //uint32_t i = 0 ; subtitle_printf(10, "\n"); if (isSubtitleOpened == 1) { @@ -248,7 +248,7 @@ static int32_t subtitle_Open(Context_t *context __attribute__((unused))) static int32_t subtitle_Close(Context_t *context __attribute__((unused))) { - uint32_t i = 0 ; + //uint32_t i = 0 ; subtitle_printf(10, "\n"); getMutex(__LINE__); isSubtitleOpened = 0; @@ -257,7 +257,7 @@ static int32_t subtitle_Close(Context_t *context __attribute__((unused))) return cERR_SUBTITLE_NO_ERROR; } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(void *_context, OutputCmd_t command, void *argument __attribute__((unused))) { Context_t *context = (Context_t *) _context; int ret = cERR_SUBTITLE_NO_ERROR; diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index 3b6945b..c8e1b2f 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -182,7 +182,7 @@ static int _writeData(void *_call, int type) else // check LOAS header { if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe && - (AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len)) + ((uint32_t)(AV_RB16(call->data + 1) & 0x1FFF) + 3) == call->len)) { aac_err("parsing Data with wrong latm header. ignoring...\n"); return 0; @@ -218,7 +218,7 @@ static int writeDataADTS(void *_call) aac_err("file pointer < 0. ignoring ...\n"); return 0; } - if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) || + if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { return _writeData(_call, 0); @@ -272,7 +272,7 @@ static int writeDataLATM(void *_call) aac_err("parsing NULL Data. ignoring...\n"); return 0; } - if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size)) + if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) { return _writeData(_call, 1); } diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index cc9f93a..44a822d 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -117,7 +117,7 @@ static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; - unsigned char Version = 5; +// unsigned char Version = 5; // unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; divx_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 1f766e7..77e45c1 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -195,12 +195,14 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne if (cd_len > 7 && data[0] == 1) { unsigned short len = (data[6] << 8) | data[7]; - if (cd_len >= (len + 8)) + if (cd_len >= (uint32_t)(len + 8)) { unsigned int i = 0; uint8_t profile_num[] = { 66, 77, 88, 100 }; uint8_t profile_cmp[2] = { 0x67, 0x00 }; const char *profile_str[] = { "baseline", "main", "extended", "high" }; + /* avoid compiler warning */ + if (*profile_str) {} memcpy(tmp, Head, sizeof(Head)); tmp_len += 4; memcpy(tmp + tmp_len, data + 8, len); @@ -289,7 +291,7 @@ static int writeData(void *_call) unsigned long long int VideoPts; unsigned int TimeDelta; unsigned int TimeScale; - int len = 0; + unsigned int len = 0; int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); @@ -300,6 +302,9 @@ static int writeData(void *_call) } TimeDelta = call->FrameRate; TimeScale = call->FrameScale; + /* avoid compiler warnings */ + if (TimeDelta) {} + if (TimeScale) {} VideoPts = call->Pts; h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); if ((call->data == NULL) || (call->len <= 0)) @@ -314,8 +319,8 @@ static int writeData(void *_call) } /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || - (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) + ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) { uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index 87cc830..aa80678 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -116,7 +116,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne } *NalLength = (data[21] & 3) + 1; int num_param_sets = data[22]; - int pos = 23; + uint32_t pos = 23; for (i = 0; i < num_param_sets; i++) { int j; @@ -175,7 +175,7 @@ static int writeData(void *_call) unsigned long long int VideoPts; unsigned int TimeDelta; unsigned int TimeScale; - int len = 0; + unsigned int len = 0; int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); @@ -186,6 +186,9 @@ static int writeData(void *_call) } TimeDelta = call->FrameRate; TimeScale = call->FrameScale; + /* avoid compiler warnings */ + if (TimeDelta) {} + if (TimeScale) {} VideoPts = call->Pts; h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); if ((call->data == NULL) || (call->len <= 0)) diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index 00e6f31..3a0045b 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -152,7 +152,7 @@ static int32_t writeData(void *_call) int32_t block_align = 0; int32_t byterate = 0; uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; - uint8_t dataPrecision = 0; + //uint8_t dataPrecision = 0; uint8_t LE = 0; switch (codecID) { @@ -224,6 +224,8 @@ static int32_t writeData(void *_call) fixed_buffer = malloc(fixed_buffersize); } fixed_bufferfilled = 0; + /* avoid compiler warning */ + if (LE) {} //printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE"); } while (size > 0) diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index c591011..845afb5 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -110,7 +110,7 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - int len = 0; + //int len = 0; vc1_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index c82acef..5324836 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -106,7 +106,7 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - int len = 0; + //int len = 0; wma_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index fa9afe2..2d7f70a 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -145,7 +145,7 @@ ssize_t write_with_retry(int fd, const void *buf, size_t size) ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic) { ssize_t len = 0; - int i = 0; + uint32_t i = 0; for (i = 0; i < ic; ++i) { write_with_retry(fd, iov[i].iov_base, iov[i].iov_len); diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 071ef40..602d265 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -32,12 +32,11 @@ #ifdef SAM_WITH_DEBUG #define PLAYBACK_DEBUG +static short debug_level = 20; #else #define PLAYBACK_SILENT #endif -static short debug_level = 20; - #ifdef PLAYBACK_DEBUG #define playback_printf(level, fmt, x...) do { \ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) @@ -565,7 +564,7 @@ static int32_t PlaybackPts(Context_t *context, int64_t *pts) return ret; } -static int32_t PlaybackGetFrameCount(Context_t *context, int64_t *frameCount) +static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount) { int ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "\n"); From 712542335e2f63c35c981b6dbea5ff679fe00578 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:34:01 +0100 Subject: [PATCH 08/38] fix OUTPUT_PLAY error handling Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e1b49ab042532c02c439cb28b8602e71fa57fcfc Author: Jacek Jendrzej Date: 2018-02-10 (Sat, 10 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/output/output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index cf3640e..548c1d6 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -224,6 +224,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) { ret = context->output->video->Command(context, OUTPUT_PLAY, "video"); } + else + ret = cERR_OUTPUT_INTERNAL_ERROR; + // success or not executed, dunn care if (!ret) { From 53e6502bb1f5e4beb18af40364cccfd3854845a5 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:41:24 +0100 Subject: [PATCH 09/38] remove isContainerRunning, this break next file play aufter eof stop Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/216e1f37cd35a35018648614a558fbf9c9f4d1f6 Author: Jacek Jendrzej Date: 2018-02-10 (Sat, 10 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 69eb4e9..58f4e9e 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -127,8 +127,6 @@ static AVFormatContext *avContextTab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL}; static int32_t use_custom_io[IPTV_AV_CONTEXT_MAX_NUM] = {0, 0}; static AVDictionary *avio_opts = NULL; -static uint8_t isContainerRunning = 0; - static int64_t latestPts = 0; static int32_t restart_audio_resampling = 0; @@ -1626,12 +1624,6 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) { ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile); } - if (isContainerRunning) - { - ffmpeg_err("ups already running?\n"); - releaseMutex(__FILE__, __FUNCTION__, __LINE__); - return cERR_CONTAINER_FFMPEG_RUNNING; - } /* initialize ffmpeg */ avcodec_register_all(); av_register_all(); @@ -1656,7 +1648,6 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) } terminating = 0; latestPts = 0; - isContainerRunning = 1; res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1); return res; } @@ -2241,11 +2232,6 @@ static int32_t container_ffmpeg_stop(Context_t *context) * and causes in most cases a segfault */ ffmpeg_printf(10, "\n"); - if (!isContainerRunning) - { - ffmpeg_err("Container not running\n"); - return cERR_CONTAINER_FFMPEG_ERR; - } if (context->playback) { context->playback->isPlaying = 0; @@ -2298,7 +2284,6 @@ static int32_t container_ffmpeg_stop(Context_t *context) { av_dict_free(&avio_opts); } - isContainerRunning = 0; avformat_network_deinit(); ffmpeg_buf_free(); releaseMutex(__FILE__, __FUNCTION__, __LINE__); From b0be1f03bc8383710b36a8685511e94e9de670c3 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:34:01 +0100 Subject: [PATCH 10/38] fix OUTPUT_PLAY error handling Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2fafb6c8023b109851db35521e9042f8fe2d3301 Author: Jacek Jendrzej Date: 2018-02-10 (Sat, 10 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/output/output.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index cf3640e..548c1d6 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -224,6 +224,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) { ret = context->output->video->Command(context, OUTPUT_PLAY, "video"); } + else + ret = cERR_OUTPUT_INTERNAL_ERROR; + // success or not executed, dunn care if (!ret) { From cfb2469c980e37ba85eb22cd338d7a9a849d5584 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:41:24 +0100 Subject: [PATCH 11/38] remove isContainerRunning, this break next file play aufter eof stop Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2e2ab97363a20c27f42272f6ddd80f14790d8ca1 Author: Jacek Jendrzej Date: 2018-02-10 (Sat, 10 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 69eb4e9..58f4e9e 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -127,8 +127,6 @@ static AVFormatContext *avContextTab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL}; static int32_t use_custom_io[IPTV_AV_CONTEXT_MAX_NUM] = {0, 0}; static AVDictionary *avio_opts = NULL; -static uint8_t isContainerRunning = 0; - static int64_t latestPts = 0; static int32_t restart_audio_resampling = 0; @@ -1626,12 +1624,6 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) { ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile); } - if (isContainerRunning) - { - ffmpeg_err("ups already running?\n"); - releaseMutex(__FILE__, __FUNCTION__, __LINE__); - return cERR_CONTAINER_FFMPEG_RUNNING; - } /* initialize ffmpeg */ avcodec_register_all(); av_register_all(); @@ -1656,7 +1648,6 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) } terminating = 0; latestPts = 0; - isContainerRunning = 1; res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1); return res; } @@ -2241,11 +2232,6 @@ static int32_t container_ffmpeg_stop(Context_t *context) * and causes in most cases a segfault */ ffmpeg_printf(10, "\n"); - if (!isContainerRunning) - { - ffmpeg_err("Container not running\n"); - return cERR_CONTAINER_FFMPEG_ERR; - } if (context->playback) { context->playback->isPlaying = 0; @@ -2298,7 +2284,6 @@ static int32_t container_ffmpeg_stop(Context_t *context) { av_dict_free(&avio_opts); } - isContainerRunning = 0; avformat_network_deinit(); ffmpeg_buf_free(); releaseMutex(__FILE__, __FUNCTION__, __LINE__); From d7d500b2a5db065fb9b1e2fd7e6838113e0f7631 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sun, 11 Feb 2018 12:01:19 +0100 Subject: [PATCH 12/38] supplement to 4bd66ae15da86b413d6de64c51b3471dd8bc801a, fix segfault with only audio stream Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/de6090c29e6956d95d4a162bc11190ddea667422 Author: Jacek Jendrzej Date: 2018-02-11 (Sun, 11 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/output/output.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 548c1d6..4943a11 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -228,12 +228,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) ret = cERR_OUTPUT_INTERNAL_ERROR; // success or not executed, dunn care - if (!ret) + if (context->playback->isAudio) { - if (context->playback->isAudio) - { - ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); - } + ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); } if (!ret) { From db37e1698512b67e993f6d3ccd01791977bdb83c Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sun, 11 Feb 2018 12:01:19 +0100 Subject: [PATCH 13/38] supplement to 4bd66ae15da86b413d6de64c51b3471dd8bc801a, fix segfault with only audio stream Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2fb06ae3478fc7520cf0178989392c88cfe53284 Author: Jacek Jendrzej Date: 2018-02-11 (Sun, 11 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/output/output.c | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 548c1d6..4943a11 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -228,12 +228,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) ret = cERR_OUTPUT_INTERNAL_ERROR; // success or not executed, dunn care - if (!ret) + if (context->playback->isAudio) { - if (context->playback->isAudio) - { - ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); - } + ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); } if (!ret) { From 72f70359b285d852d85438e0e295b7fd4bd872e2 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 6 Mar 2018 19:08:31 +0100 Subject: [PATCH 14/38] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/afda7fff3eaaabd5e2907a39df5a97613ca2a95c Author: max_10 Date: 2018-03-06 (Tue, 06 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index bf5a0b0..c27056e 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -24,7 +24,7 @@ static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src) av_free(*pkt_dest); } *pkt_dest = av_malloc(sizeof(AVPacket)); - av_copy_packet(*pkt_dest, pkt_src); + av_packet_ref(*pkt_dest, pkt_src); } static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ctx, AVPacket *pkt) @@ -37,7 +37,7 @@ static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ pkt->flags & AV_PKT_FLAG_KEY); if (ret == 0 && new_pkt.data != pkt->data) { - if ((ret = av_copy_packet(&new_pkt, pkt)) < 0) + if ((ret = av_packet_ref(&new_pkt, pkt)) < 0) return -1; ret = 1; } From a51ed97fb2252b66cffc904d4ce08057e8af6599 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 7 Mar 2018 23:59:23 +0100 Subject: [PATCH 15/38] libeplayer3-arm: cleanup types, use Context_t in commands Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/76ff23f48735d119c8f152e7c3d82a91d18796a0 Author: max_10 Date: 2018-03-07 (Wed, 07 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container.c | 3 +- libeplayer3-arm/container/container_ffmpeg.c | 37 +++-- libeplayer3-arm/include/container.h | 7 +- libeplayer3-arm/include/manager.h | 15 +- libeplayer3-arm/include/output.h | 9 +- libeplayer3-arm/include/playback.h | 5 +- libeplayer3-arm/include/writer.h | 8 +- libeplayer3-arm/manager/audio.c | 10 +- libeplayer3-arm/manager/chapter.c | 8 +- libeplayer3-arm/manager/subtitle.c | 4 +- libeplayer3-arm/manager/video.c | 7 +- libeplayer3-arm/output/linuxdvb_mipsel.c | 165 ++++++++++--------- libeplayer3-arm/output/output.c | 3 +- libeplayer3-arm/output/output_subtitle.c | 6 +- libeplayer3-arm/output/writer/mipsel/aac.c | 13 +- libeplayer3-arm/output/writer/mipsel/ac3.c | 3 +- libeplayer3-arm/output/writer/mipsel/amr.c | 5 +- libeplayer3-arm/output/writer/mipsel/divx3.c | 9 +- libeplayer3-arm/output/writer/mipsel/dts.c | 3 +- libeplayer3-arm/output/writer/mipsel/h263.c | 3 +- libeplayer3-arm/output/writer/mipsel/h264.c | 3 +- libeplayer3-arm/output/writer/mipsel/h265.c | 3 +- libeplayer3-arm/output/writer/mipsel/lpcm.c | 3 +- libeplayer3-arm/output/writer/mipsel/mp3.c | 5 +- libeplayer3-arm/output/writer/mipsel/mpeg2.c | 5 +- libeplayer3-arm/output/writer/mipsel/mpeg4.c | 5 +- libeplayer3-arm/output/writer/mipsel/pcm.c | 3 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 3 +- libeplayer3-arm/output/writer/mipsel/vp.c | 11 +- libeplayer3-arm/output/writer/mipsel/wma.c | 3 +- libeplayer3-arm/output/writer/mipsel/wmv.c | 3 +- libeplayer3-arm/playback/playback.c | 6 +- 32 files changed, 194 insertions(+), 182 deletions(-) diff --git a/libeplayer3-arm/container/container.c b/libeplayer3-arm/container/container.c index de71ef8..3f56f21 100644 --- a/libeplayer3-arm/container/container.c +++ b/libeplayer3-arm/container/container.c @@ -98,9 +98,8 @@ static int32_t selectContainer(Context_t *context, char *extension) return ret; } -static int Command(void *_context, ContainerCmd_t command, void *argument) +static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused))) { - Context_t *context = (Context_t *) _context; int ret = 0; container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 58f4e9e..d5a9ae1 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -42,12 +42,6 @@ #include #include -#include -#include -#include -#include -#include - #include #include "common.h" @@ -56,9 +50,11 @@ #include "aac.h" #include "pcm.h" #include "ffmpeg_metadata.h" + /* ***************************** */ /* Makros/Constants */ /* ***************************** */ + #if (LIBAVFORMAT_VERSION_MAJOR > 56) #define TS_BYTES_SEEKING 0 #else @@ -1343,7 +1339,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int void *opaque = NULL; const char *protoName = NULL; uint8_t haveNativeProto = 0; - while (protoName = avio_enum_protocols(&opaque, 1)) + while ((protoName = avio_enum_protocols(&opaque, 1))) { if (0 == strcmp("rtmp", protoName)) { @@ -2625,12 +2621,14 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) size_t psize = 1; char **pp; - if (!context) { + if (!context) + { fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } - if (!p || *p) { + if (!p || *p) + { fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } @@ -2646,28 +2644,34 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) psize += av_dict_count(((AVStream *)(audioTrack->stream))->metadata); *p = malloc(sizeof(char *) * psize * 2); - if (!*p) { + if (!*p) + { fprintf(stderr, "MALLOC %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } pp = *p; if (avContextTab[0]->metadata) - while ((tag = av_dict_get(avContextTab[0]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(avContextTab[0]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } - if (videoTrack) { + if (videoTrack) + { tag = NULL; - while ((tag = av_dict_get(((AVStream *)(videoTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(((AVStream *)(videoTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } } - if (audioTrack) { + if (audioTrack) + { tag = NULL; - while ((tag = av_dict_get(((AVStream *)(audioTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(((AVStream *)(audioTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } @@ -2678,9 +2682,8 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t Command(void *_context, ContainerCmd_t command, void *argument) +static int32_t Command(Context_t *context, ContainerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_CONTAINER_FFMPEG_NO_ERROR; ffmpeg_printf(50, "Command %d\n", command); if (command != CONTAINER_SET_BUFFER_SEEK_TIME && diff --git a/libeplayer3-arm/include/container.h b/libeplayer3-arm/include/container.h index 5a4b5fd..a8a87e0 100644 --- a/libeplayer3-arm/include/container.h +++ b/libeplayer3-arm/include/container.h @@ -28,10 +28,13 @@ typedef enum CONTAINER_GET_METADATA } ContainerCmd_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Container_s { char *Name; - int (* Command)(/*Context_t*/void *, ContainerCmd_t, void *); + int (* Command)(Context_t *, ContainerCmd_t, void *); char **Capabilities; } Container_t; @@ -43,7 +46,7 @@ typedef struct ContainerHandler_s char *Name; Container_t *selectedContainer; - int (* Command)(/*Context_t*/void *, ContainerCmd_t, void *); + int (* Command)(Context_t *, ContainerCmd_t, void *); } ContainerHandler_t; #endif diff --git a/libeplayer3-arm/include/manager.h b/libeplayer3-arm/include/manager.h index 0d9fd76..d5eea58 100644 --- a/libeplayer3-arm/include/manager.h +++ b/libeplayer3-arm/include/manager.h @@ -4,6 +4,12 @@ #include #include +#include +#include +#include +#include +#include + typedef enum { MANAGER_ADD, @@ -54,11 +60,11 @@ typedef struct Track_s int32_t aspect_ratio_den; /* stream from ffmpeg */ - void *stream; + AVStream *stream; /* AVCodecContext for steam */ void *avCodecCtx; /* codec extra data (header or some other stuff) */ - void *extraData; + uint8_t *extraData; int extraSize; uint8_t *aacbuf; @@ -88,10 +94,13 @@ typedef struct TrackDescription_s int progressive; } TrackDescription_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Manager_s { char *Name; - int (* Command)(/*Context_t*/void *, ManagerCmd_t, void *); + int (* Command)(Context_t *, ManagerCmd_t, void *); char **Capabilities; } Manager_t; diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index dd0bb93..ac0c0bf 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -64,11 +64,14 @@ typedef struct char *type; } SubtitleOut_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Output_s { char *Name; - int32_t (* Command)(/*Context_t*/void *, OutputCmd_t, void *); - int32_t (* Write)(/*Context_t*/void *, void *privateData); + int32_t (* Command)(Context_t *, OutputCmd_t, void *); + int32_t (* Write)(Context_t *, void *privateData); char **Capabilities; } Output_t; @@ -81,7 +84,7 @@ typedef struct OutputHandler_s Output_t *audio; Output_t *video; Output_t *subtitle; - int32_t (* Command)(/*Context_t*/void *, OutputCmd_t, void *); + int32_t (* Command)(Context_t *, OutputCmd_t, void *); } OutputHandler_t; #endif diff --git a/libeplayer3-arm/include/playback.h b/libeplayer3-arm/include/playback.h index 5e80c8c..e817e38 100644 --- a/libeplayer3-arm/include/playback.h +++ b/libeplayer3-arm/include/playback.h @@ -26,6 +26,9 @@ typedef enum { PLAYBACK_METADATA } PlaybackCmd_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct PlaybackHandler_s { char *Name; @@ -51,7 +54,7 @@ typedef struct PlaybackHandler_s uint8_t isSubtitle; uint8_t abortRequested; - int32_t (* Command)(/*Context_t*/void *, PlaybackCmd_t, void *); + int32_t (* Command)(Context_t *, PlaybackCmd_t, void *); char *uri; off_t size; uint8_t noprobe; /* hack: only minimal probing in av_find_stream_info */ diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index b50c158..c027899 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -10,11 +10,11 @@ typedef enum { eNone, eAudio, eVideo} eWriterType_t; typedef struct { int fd; - unsigned char *data; + uint8_t *data; unsigned int len; - unsigned long long int Pts; + uint64_t Pts; unsigned long long int Dts; - unsigned char *private_data; + uint8_t *private_data; unsigned int private_size; unsigned int FrameRate; unsigned int FrameScale; @@ -38,7 +38,7 @@ typedef struct WriterCaps_s typedef struct Writer_s { int (* reset)(); - int (* writeData)(void *); + int (* writeData)(WriterAVCallData_t *); WriterCaps_t *caps; } Writer_t; diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index a29687e..c527480 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -71,7 +71,7 @@ if (debug_level >= level) printf("[%s:%s] \n" fmt, __FILE__, __FUNCTION__, ## x) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. /* ***************************** */ /* Prototypes */ @@ -212,9 +212,8 @@ static int ManagerDel(Context_t *context) return cERR_AUDIO_MGR_NO_ERROR; } -static int Command(void *_context, ManagerCmd_t command, void *argument) +static int Command(Context_t *context, ManagerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_AUDIO_MGR_NO_ERROR; audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); switch (command) @@ -228,7 +227,8 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) case MANAGER_LIST: { container_ffmpeg_update_tracks(context, context->playback->uri, 0); - *((TrackDescription_t **)argument) = ManagerList(context); +// *((TrackDescription_t **)argument) = ManagerList(context); + *((char ** *) argument) = (char **) ManagerList(context); break; } case MANAGER_GET: @@ -269,7 +269,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/manager/chapter.c b/libeplayer3-arm/manager/chapter.c index c09a0f2..14167a9 100644 --- a/libeplayer3-arm/manager/chapter.c +++ b/libeplayer3-arm/manager/chapter.c @@ -66,7 +66,7 @@ static const char FILENAME[] = __FILE__; static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. /* ***************************** */ /* Prototypes */ @@ -76,7 +76,7 @@ static int CurrentTrack = 0; //TRACK[0] as default. /* Functions */ /* ***************************** */ -static int ManagerAdd(Context_t * context __attribute__((unused)), Track_t track) +static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) { chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); @@ -121,7 +121,7 @@ static int ManagerAdd(Context_t * context __attribute__((unused)), Track_t track return cERR_CHAPTER_MGR_NO_ERROR; } -static char **ManagerList(Context_t * context __attribute__ ((unused))) +static char **ManagerList(Context_t *context __attribute__((unused))) { int i = 0, j = 0; char **tracklist = NULL; @@ -157,7 +157,7 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) return tracklist; } -static int ManagerDel(Context_t * context __attribute__((unused))) +static int ManagerDel(Context_t *context __attribute__((unused))) { int i = 0; diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index 4b64cd6..4cff07c 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -69,7 +69,7 @@ if (debug_level >= level) printf(x); } while (0) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = -1; //no as default. +static int CurrentTrack = -1; //no as default. /* ***************************** */ /* Prototypes */ @@ -256,7 +256,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) { if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/manager/video.c b/libeplayer3-arm/manager/video.c index 1c8fcc3..adaa841 100644 --- a/libeplayer3-arm/manager/video.c +++ b/libeplayer3-arm/manager/video.c @@ -69,7 +69,7 @@ if (debug_level >= level) printf(x); } while (0) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. static void (* updatedTrackInfoFnc)(void) = NULL; @@ -181,9 +181,8 @@ static int ManagerDel(Context_t *context) return cERR_VIDEO_MGR_NO_ERROR; } -static int Command(void *_context, ManagerCmd_t command, void *argument) +static int Command(Context_t *context, ManagerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_VIDEO_MGR_NO_ERROR; video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); switch (command) @@ -243,7 +242,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 56cbc91..1699f7d 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -228,9 +228,9 @@ int LinuxDvbPlay(Context_t *context, char *type) /* if (0 != ioctl(videofd, VIDEO_STOP)) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; } */ if (writer == NULL) @@ -276,9 +276,9 @@ int LinuxDvbPlay(Context_t *context, char *type) /* if (0 != ioctl(audiofd, AUDIO_STOP)) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; } */ if (writer == NULL) @@ -347,11 +347,13 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); } /* set back to normal speed (end trickmodes) */ - // if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - // } + /* + if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); + } + */ if (ioctl(audiofd, AUDIO_STOP) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); @@ -428,14 +430,16 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; - // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; - // linuxdvb_printf(50, "\n"); - // if (ioctl(videofd, VIDEO_DISCONTINUITY, (void*) dis_type) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); - // } - // linuxdvb_printf(50, "exiting\n"); + /* + int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; + linuxdvb_printf(50, "\n"); + if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); + } + linuxdvb_printf(50, "exiting\n"); + */ return ret; } @@ -476,28 +480,33 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { - // unsigned char video = !strcmp("video", type); - // unsigned char audio = !strcmp("audio", type); - // linuxdvb_printf(10, "v%d a%d\n", video, audio); - // if ((video && videofd != -1) || (audio && audiofd != -1)) { - // getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - // if (video && videofd != -1) { - // if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); - // } - // } - // if (audio && audiofd != -1) { - // if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); - // } - // } - // releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - // } - // linuxdvb_printf(10, "exiting\n"); + /* + unsigned char video = !strcmp("video", type); + unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) + { + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) + { + if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); + } + } + if (audio && audiofd != -1) + { + if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); + } + } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + } + linuxdvb_printf(10, "exiting\n"); + */ return cERR_LINUXDVB_NO_ERROR; } @@ -546,12 +555,14 @@ int LinuxDvbFastForward(Context_t *context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - // if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); - // ret = cERR_LINUXDVB_ERROR; - // } + /* + if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + */ releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } if (audio && audiofd != -1) @@ -559,12 +570,14 @@ int LinuxDvbFastForward(Context_t *context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - // if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - // ret = cERR_LINUXDVB_ERROR; - // } + /* + if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + */ releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -728,11 +741,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - // if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void*) AUDIO_ENCODING_MP3) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); - // } + /* + if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) AUDIO_ENCODING_MP3) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); + } + */ } else { @@ -776,11 +791,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - // if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void*) VIDEO_ENCODING_AUTO) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); - // } + /* + if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) VIDEO_ENCODING_AUTO) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); + } + */ } else { @@ -812,15 +829,14 @@ int LinuxDvbSwitch(Context_t *context, char *type) return cERR_LINUXDVB_NO_ERROR; } -static int Write(void *_context, void *_out) +static int Write(Context_t *context, void *_out) { - Context_t *context = (Context_t *) _context; - AudioVideoOut_t *out = (AudioVideoOut_t *) _out; - int ret = cERR_LINUXDVB_NO_ERROR; - int res = 0; - unsigned char video = 0; - unsigned char audio = 0; - Writer_t *writer; + AudioVideoOut_t *out = (AudioVideoOut_t *) _out; + int ret = cERR_LINUXDVB_NO_ERROR; + int res = 0; + unsigned char video = 0; + unsigned char audio = 0; + Writer_t *writer; WriterAVCallData_t call; if (out == NULL) { @@ -905,7 +921,7 @@ static int Write(void *_context, void *_out) call.Width = out->width; call.Height = out->height; call.InfoFlags = out->infoFlags; - call.Version = 0; // is unsingned char + call.Version = 0; // is unsingned char if (writer->writeData) { res = writer->writeData(&call); @@ -947,7 +963,7 @@ static int Write(void *_context, void *_out) call.FrameRate = out->frameRate; call.FrameScale = out->timeScale; call.InfoFlags = out->infoFlags; - call.Version = 0; /* -1; unsigned char cannot be negative */ + call.Version = 0; /* -1; unsigned char cannot be negative */ if (writer->writeData) { res = writer->writeData(&call); @@ -996,9 +1012,8 @@ static int reset(Context_t *context) return ret; } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(Context_t *context, OutputCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_LINUXDVB_NO_ERROR; linuxdvb_printf(50, "Command %d\n", command); switch (command) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 4943a11..168c203 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -147,9 +147,8 @@ static void OutputDel(Context_t *context, char *port) } } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(Context_t *context, OutputCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_OUTPUT_NO_ERROR; output_printf(10, "%s::%s Command %d\n", __FILE__, __FUNCTION__, command); switch (command) diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index ef740f2..726d230 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -188,9 +188,8 @@ static int Flush() return cERR_SUBTITLE_NO_ERROR; } -static int Write(void *_context, void *data) +static int Write(Context_t *context, void *data) { - Context_t *context = (Context_t *)_context; char *Encoding = NULL; SubtitleOut_t *out = NULL; int32_t curtrackid = -1; @@ -257,9 +256,8 @@ static int32_t subtitle_Close(Context_t *context __attribute__((unused))) return cERR_SUBTITLE_NO_ERROR; } -static int Command(void *_context, OutputCmd_t command, void *argument __attribute__((unused))) +static int Command(Context_t *context, OutputCmd_t command, void *argument __attribute__((unused))) { - Context_t *context = (Context_t *) _context; int ret = cERR_SUBTITLE_NO_ERROR; subtitle_printf(50, "%d\n", command); switch (command) diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index c8e1b2f..8e6d163 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -156,9 +156,8 @@ static int reset() return 0; } -static int _writeData(void *_call, int type) +static int _writeData(WriterAVCallData_t *call, int type) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n _writeData type[%d]\n", type); if (call == NULL) { @@ -199,9 +198,8 @@ static int _writeData(void *_call, int type) return writev_with_retry(call->fd, iov, 2); } -static int writeDataADTS(void *_call) +static int writeDataADTS(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n"); if (call == NULL) { @@ -221,7 +219,7 @@ static int writeDataADTS(void *_call) if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { - return _writeData(_call, 0); + return _writeData(call, 0); } uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; @@ -258,9 +256,8 @@ static int writeDataADTS(void *_call) return writev_with_retry(call->fd, iov, 2); } -static int writeDataLATM(void *_call) +static int writeDataLATM(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n"); if (call == NULL) { @@ -274,7 +271,7 @@ static int writeDataLATM(void *_call) } if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) { - return _writeData(_call, 1); + return _writeData(call, 1); } aac_printf(10, "AudioPts %lld\n", call->Pts); if (!pLATMCtx) diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index 017b2b2..b71b089 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -95,9 +95,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; ac3_printf(10, "\n"); unsigned char PesHeader[PES_MAX_HEADER_SIZE]; if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/amr.c b/libeplayer3-arm/output/writer/mipsel/amr.c index c94dead..cb843b5 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -96,10 +96,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; amr_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index 44a822d..98f1f4a 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -113,12 +113,11 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; -// unsigned char Version = 5; -// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; +// unsigned char Version = 5; +// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; divx_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index 06f0efb..b56969b 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -100,9 +100,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; dts_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/h263.c index ab79368..152b026 100644 --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/h263.c @@ -91,9 +91,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; int32_t len = 0; h263_printf(10, "\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 77e45c1..04b3d2f 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -284,9 +284,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned long long int VideoPts; unsigned int TimeDelta; diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index aa80678..cb21d99 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -168,9 +168,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned long long int VideoPts; unsigned int TimeDelta; diff --git a/libeplayer3-arm/output/writer/mipsel/lpcm.c b/libeplayer3-arm/output/writer/mipsel/lpcm.c index a0ef5ee..aca119e 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -132,9 +132,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; lpcm_printf(10, "\n"); if (!call) { diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index ee8a83a..88c5a82 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -91,10 +91,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; mp3_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index 9ccce6d..daa9daf 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -92,10 +92,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; int len = 0; unsigned int Position = 0; mpeg2_printf(10, "\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 9d9d8e4..7abce59 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -100,10 +100,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; mpeg4_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index 3a0045b..bc63b09 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -110,9 +110,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; pcm_printf(10, "\n"); if (!call) { diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index 845afb5..f6997ab 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -107,9 +107,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; //int len = 0; vc1_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index d315358..2e31151 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -98,9 +98,8 @@ static int reset() return 0; } -static int writeData(void *_call, int is_vp6) +static int writeData(WriterAVCallData_t *call, int is_vp6) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; vp_printf(10, "\n"); if (call == NULL) { @@ -142,14 +141,14 @@ static int writeData(void *_call, int is_vp6) return writev_with_retry(call->fd, iov, 2); } -static int writeDataVP6(void *_call) +static int writeDataVP6(WriterAVCallData_t *call) { - return writeData(_call, 1); + return writeData(call, 1); } -static int writeDataVP89(void *_call) +static int writeDataVP89(WriterAVCallData_t *call) { - return writeData(_call, 0); + return writeData(call, 0); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 5324836..6500c7e 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -103,9 +103,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; //int len = 0; wma_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 7722818..96db958 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -105,9 +105,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; wmv_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 602d265..f9364e9 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -27,6 +27,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ + // SULGE DEBUG //#define SAM_WITH_DEBUG @@ -53,7 +54,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define cERR_PLAYBACK_NO_ERROR 0 #define cERR_PLAYBACK_ERROR -1 -#define cMaxSpeed_ff 128 /* fixme: revise */ +#define cMaxSpeed_ff 128 /* fixme: revise */ #define cMaxSpeed_fr -320 /* fixme: revise */ /* ***************************** */ @@ -711,9 +712,8 @@ static int PlaybackMetadata(Context_t *context, char ***metadata) return ret; } -static int32_t Command(void *_context, PlaybackCmd_t command, void *argument) +static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; /* to satisfy compiler */ int32_t ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "Command %d\n", command); switch (command) From 9d075a522aba64dee8f0a675d5093ffe37eaa20d Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 8 Mar 2018 01:24:36 +0100 Subject: [PATCH 16/38] Revert "fix video policy" This reverts commit 959688031782ef187219b46400dcc43a366f00b3. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/eee8a524dfb4c23613b36477dba715726575ba4a Author: max_10 Date: 2018-03-08 (Thu, 08 Mar 2018) ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index ef8bc55..6c894c0 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -361,7 +361,7 @@ void cVideo::closeDevice(void) int cVideo::setAspectRatio(int aspect, int mode) { static const char *a[] = { "n/a", "4:3", "14:9", "16:9" }; - static const char *m[] = { "panscan", "bestfit", "letterbox", "nonlinear", "(unset)" }; + static const char *m[] = { "panscan", "letterbox", "bestfit", "nonlinear", "(unset)" }; int n; lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[(mode < 0||mode > 3) ? 4 : mode]); From 35be0d8f778ba2e5d63b0ceb56691a7c4cf02ec0 Mon Sep 17 00:00:00 2001 From: BPanther Date: Sat, 10 Mar 2018 23:20:23 +0100 Subject: [PATCH 17/38] missing brightness added for ufs922, hdbox, octagon1008, mini2, av7500 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/88be707a191907c584f06b75a8bdf68b00d4061a Author: BPanther Date: 2018-03-10 (Sat, 10 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libduckbox/hardware_caps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libduckbox/hardware_caps.c b/libduckbox/hardware_caps.c index 9794338..56e9254 100644 --- a/libduckbox/hardware_caps.c +++ b/libduckbox/hardware_caps.c @@ -47,6 +47,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 1; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "ufs912", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -79,6 +80,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 1; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "ufs910", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -100,6 +102,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "octagon1008", 11)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -110,6 +113,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "hs7110", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -175,6 +179,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 1; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "cuberevo-250hd", 4)) { strcpy(caps.boxvendor, "DUCKBOX"); From bd55f57faad3249325373c9629a524b21bb8b52c Mon Sep 17 00:00:00 2001 From: BPanther Date: Sat, 10 Mar 2018 23:20:23 +0100 Subject: [PATCH 18/38] missing brightness added for ufs922, hdbox, octagon1008, mini2, av7500 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/c43602246922709e6d59417523e94e02a523cb6a Author: BPanther Date: 2018-03-10 (Sat, 10 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libduckbox/hardware_caps.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/libduckbox/hardware_caps.c b/libduckbox/hardware_caps.c index 9794338..56e9254 100644 --- a/libduckbox/hardware_caps.c +++ b/libduckbox/hardware_caps.c @@ -47,6 +47,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 1; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "ufs912", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -79,6 +80,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 1; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "ufs910", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -100,6 +102,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "octagon1008", 11)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -110,6 +113,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 0; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "hs7110", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -175,6 +179,7 @@ hw_caps_t *get_hwcaps(void) caps.can_cec = 0; caps.has_fan = 1; caps.has_CI = 2; + caps.display_can_set_brightness = 1; } else if (!strncmp(buf, "cuberevo-250hd", 4)) { strcpy(caps.boxvendor, "DUCKBOX"); From bcc9767a59135c532effb209002eacff266132a8 Mon Sep 17 00:00:00 2001 From: vanhofen Date: Sun, 11 Mar 2018 22:41:07 +0100 Subject: [PATCH 19/38] introduce caps.has_button_timer Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/8e2bf5a58730198309bfd6811261ab884dab4807 Author: vanhofen Date: 2018-03-11 (Sun, 11 Mar 2018) Origin message was: ------------------ - introduce caps.has_button_timer ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- include/hardware_caps.h | 1 + libarmbox/hardware_caps.c | 1 + 2 files changed, 2 insertions(+) diff --git a/include/hardware_caps.h b/include/hardware_caps.h index 92da189..3a553ca 100644 --- a/include/hardware_caps.h +++ b/include/hardware_caps.h @@ -39,6 +39,7 @@ typedef struct hw_caps int display_can_set_brightness; int display_can_deepstandby; int display_has_statusline; + int has_button_timer; char boxvendor[64]; char boxname[64]; char boxarch[64]; diff --git a/libarmbox/hardware_caps.c b/libarmbox/hardware_caps.c index 7ec40c8..1190939 100644 --- a/libarmbox/hardware_caps.c +++ b/libarmbox/hardware_caps.c @@ -37,6 +37,7 @@ hw_caps_t *get_hwcaps(void) caps.display_can_deepstandby = 0; caps.display_can_set_brightness = 1; caps.display_has_statusline = 0; + caps.has_button_timer = 1; caps.has_HDMI = 1; strcpy(caps.boxvendor, "AX-Technologies"); strcpy(caps.boxname, "HD51"); From 3433ec3f634128a44e7899291e7608eccb897198 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 6 Mar 2018 19:08:31 +0100 Subject: [PATCH 20/38] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/6069156883d0e38f231a6f23ebdbc8d61704767c Author: max_10 Date: 2018-03-06 (Tue, 06 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index bf5a0b0..c27056e 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -24,7 +24,7 @@ static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src) av_free(*pkt_dest); } *pkt_dest = av_malloc(sizeof(AVPacket)); - av_copy_packet(*pkt_dest, pkt_src); + av_packet_ref(*pkt_dest, pkt_src); } static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ctx, AVPacket *pkt) @@ -37,7 +37,7 @@ static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ pkt->flags & AV_PKT_FLAG_KEY); if (ret == 0 && new_pkt.data != pkt->data) { - if ((ret = av_copy_packet(&new_pkt, pkt)) < 0) + if ((ret = av_packet_ref(&new_pkt, pkt)) < 0) return -1; ret = 1; } From 579bfb2a3a355806a412d28ae1366a8f6d725fe0 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 7 Mar 2018 23:59:23 +0100 Subject: [PATCH 21/38] libeplayer3-arm: cleanup types, use Context_t in commands Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/443d2d6b6cfe85c93c143638450ec5882f13a9ae Author: max_10 Date: 2018-03-07 (Wed, 07 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container.c | 3 +- libeplayer3-arm/container/container_ffmpeg.c | 37 +++-- libeplayer3-arm/include/container.h | 7 +- libeplayer3-arm/include/manager.h | 15 +- libeplayer3-arm/include/output.h | 9 +- libeplayer3-arm/include/playback.h | 5 +- libeplayer3-arm/include/writer.h | 8 +- libeplayer3-arm/manager/audio.c | 10 +- libeplayer3-arm/manager/chapter.c | 8 +- libeplayer3-arm/manager/subtitle.c | 4 +- libeplayer3-arm/manager/video.c | 7 +- libeplayer3-arm/output/linuxdvb_mipsel.c | 165 ++++++++++--------- libeplayer3-arm/output/output.c | 3 +- libeplayer3-arm/output/output_subtitle.c | 6 +- libeplayer3-arm/output/writer/mipsel/aac.c | 13 +- libeplayer3-arm/output/writer/mipsel/ac3.c | 3 +- libeplayer3-arm/output/writer/mipsel/amr.c | 5 +- libeplayer3-arm/output/writer/mipsel/divx3.c | 9 +- libeplayer3-arm/output/writer/mipsel/dts.c | 3 +- libeplayer3-arm/output/writer/mipsel/h263.c | 3 +- libeplayer3-arm/output/writer/mipsel/h264.c | 3 +- libeplayer3-arm/output/writer/mipsel/h265.c | 3 +- libeplayer3-arm/output/writer/mipsel/lpcm.c | 3 +- libeplayer3-arm/output/writer/mipsel/mp3.c | 5 +- libeplayer3-arm/output/writer/mipsel/mpeg2.c | 5 +- libeplayer3-arm/output/writer/mipsel/mpeg4.c | 5 +- libeplayer3-arm/output/writer/mipsel/pcm.c | 3 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 3 +- libeplayer3-arm/output/writer/mipsel/vp.c | 11 +- libeplayer3-arm/output/writer/mipsel/wma.c | 3 +- libeplayer3-arm/output/writer/mipsel/wmv.c | 3 +- libeplayer3-arm/playback/playback.c | 6 +- 32 files changed, 194 insertions(+), 182 deletions(-) diff --git a/libeplayer3-arm/container/container.c b/libeplayer3-arm/container/container.c index de71ef8..3f56f21 100644 --- a/libeplayer3-arm/container/container.c +++ b/libeplayer3-arm/container/container.c @@ -98,9 +98,8 @@ static int32_t selectContainer(Context_t *context, char *extension) return ret; } -static int Command(void *_context, ContainerCmd_t command, void *argument) +static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused))) { - Context_t *context = (Context_t *) _context; int ret = 0; container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 58f4e9e..d5a9ae1 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -42,12 +42,6 @@ #include #include -#include -#include -#include -#include -#include - #include #include "common.h" @@ -56,9 +50,11 @@ #include "aac.h" #include "pcm.h" #include "ffmpeg_metadata.h" + /* ***************************** */ /* Makros/Constants */ /* ***************************** */ + #if (LIBAVFORMAT_VERSION_MAJOR > 56) #define TS_BYTES_SEEKING 0 #else @@ -1343,7 +1339,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int void *opaque = NULL; const char *protoName = NULL; uint8_t haveNativeProto = 0; - while (protoName = avio_enum_protocols(&opaque, 1)) + while ((protoName = avio_enum_protocols(&opaque, 1))) { if (0 == strcmp("rtmp", protoName)) { @@ -2625,12 +2621,14 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) size_t psize = 1; char **pp; - if (!context) { + if (!context) + { fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } - if (!p || *p) { + if (!p || *p) + { fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } @@ -2646,28 +2644,34 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) psize += av_dict_count(((AVStream *)(audioTrack->stream))->metadata); *p = malloc(sizeof(char *) * psize * 2); - if (!*p) { + if (!*p) + { fprintf(stderr, "MALLOC %s:%d\n", __func__, __LINE__); return cERR_CONTAINER_FFMPEG_ERR; } pp = *p; if (avContextTab[0]->metadata) - while ((tag = av_dict_get(avContextTab[0]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(avContextTab[0]->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } - if (videoTrack) { + if (videoTrack) + { tag = NULL; - while ((tag = av_dict_get(((AVStream *)(videoTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(((AVStream *)(videoTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } } - if (audioTrack) { + if (audioTrack) + { tag = NULL; - while ((tag = av_dict_get(((AVStream *)(audioTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + while ((tag = av_dict_get(((AVStream *)(audioTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) + { *pp++ = strdup(tag->key); *pp++ = strdup(tag->value); } @@ -2678,9 +2682,8 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int32_t Command(void *_context, ContainerCmd_t command, void *argument) +static int32_t Command(Context_t *context, ContainerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_CONTAINER_FFMPEG_NO_ERROR; ffmpeg_printf(50, "Command %d\n", command); if (command != CONTAINER_SET_BUFFER_SEEK_TIME && diff --git a/libeplayer3-arm/include/container.h b/libeplayer3-arm/include/container.h index 5a4b5fd..a8a87e0 100644 --- a/libeplayer3-arm/include/container.h +++ b/libeplayer3-arm/include/container.h @@ -28,10 +28,13 @@ typedef enum CONTAINER_GET_METADATA } ContainerCmd_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Container_s { char *Name; - int (* Command)(/*Context_t*/void *, ContainerCmd_t, void *); + int (* Command)(Context_t *, ContainerCmd_t, void *); char **Capabilities; } Container_t; @@ -43,7 +46,7 @@ typedef struct ContainerHandler_s char *Name; Container_t *selectedContainer; - int (* Command)(/*Context_t*/void *, ContainerCmd_t, void *); + int (* Command)(Context_t *, ContainerCmd_t, void *); } ContainerHandler_t; #endif diff --git a/libeplayer3-arm/include/manager.h b/libeplayer3-arm/include/manager.h index 0d9fd76..d5eea58 100644 --- a/libeplayer3-arm/include/manager.h +++ b/libeplayer3-arm/include/manager.h @@ -4,6 +4,12 @@ #include #include +#include +#include +#include +#include +#include + typedef enum { MANAGER_ADD, @@ -54,11 +60,11 @@ typedef struct Track_s int32_t aspect_ratio_den; /* stream from ffmpeg */ - void *stream; + AVStream *stream; /* AVCodecContext for steam */ void *avCodecCtx; /* codec extra data (header or some other stuff) */ - void *extraData; + uint8_t *extraData; int extraSize; uint8_t *aacbuf; @@ -88,10 +94,13 @@ typedef struct TrackDescription_s int progressive; } TrackDescription_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Manager_s { char *Name; - int (* Command)(/*Context_t*/void *, ManagerCmd_t, void *); + int (* Command)(Context_t *, ManagerCmd_t, void *); char **Capabilities; } Manager_t; diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index dd0bb93..ac0c0bf 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -64,11 +64,14 @@ typedef struct char *type; } SubtitleOut_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct Output_s { char *Name; - int32_t (* Command)(/*Context_t*/void *, OutputCmd_t, void *); - int32_t (* Write)(/*Context_t*/void *, void *privateData); + int32_t (* Command)(Context_t *, OutputCmd_t, void *); + int32_t (* Write)(Context_t *, void *privateData); char **Capabilities; } Output_t; @@ -81,7 +84,7 @@ typedef struct OutputHandler_s Output_t *audio; Output_t *video; Output_t *subtitle; - int32_t (* Command)(/*Context_t*/void *, OutputCmd_t, void *); + int32_t (* Command)(Context_t *, OutputCmd_t, void *); } OutputHandler_t; #endif diff --git a/libeplayer3-arm/include/playback.h b/libeplayer3-arm/include/playback.h index 5e80c8c..e817e38 100644 --- a/libeplayer3-arm/include/playback.h +++ b/libeplayer3-arm/include/playback.h @@ -26,6 +26,9 @@ typedef enum { PLAYBACK_METADATA } PlaybackCmd_t; +struct Context_s; +typedef struct Context_s Context_t; + typedef struct PlaybackHandler_s { char *Name; @@ -51,7 +54,7 @@ typedef struct PlaybackHandler_s uint8_t isSubtitle; uint8_t abortRequested; - int32_t (* Command)(/*Context_t*/void *, PlaybackCmd_t, void *); + int32_t (* Command)(Context_t *, PlaybackCmd_t, void *); char *uri; off_t size; uint8_t noprobe; /* hack: only minimal probing in av_find_stream_info */ diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index b50c158..c027899 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -10,11 +10,11 @@ typedef enum { eNone, eAudio, eVideo} eWriterType_t; typedef struct { int fd; - unsigned char *data; + uint8_t *data; unsigned int len; - unsigned long long int Pts; + uint64_t Pts; unsigned long long int Dts; - unsigned char *private_data; + uint8_t *private_data; unsigned int private_size; unsigned int FrameRate; unsigned int FrameScale; @@ -38,7 +38,7 @@ typedef struct WriterCaps_s typedef struct Writer_s { int (* reset)(); - int (* writeData)(void *); + int (* writeData)(WriterAVCallData_t *); WriterCaps_t *caps; } Writer_t; diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index a29687e..c527480 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -71,7 +71,7 @@ if (debug_level >= level) printf("[%s:%s] \n" fmt, __FILE__, __FUNCTION__, ## x) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. /* ***************************** */ /* Prototypes */ @@ -212,9 +212,8 @@ static int ManagerDel(Context_t *context) return cERR_AUDIO_MGR_NO_ERROR; } -static int Command(void *_context, ManagerCmd_t command, void *argument) +static int Command(Context_t *context, ManagerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_AUDIO_MGR_NO_ERROR; audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); switch (command) @@ -228,7 +227,8 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) case MANAGER_LIST: { container_ffmpeg_update_tracks(context, context->playback->uri, 0); - *((TrackDescription_t **)argument) = ManagerList(context); +// *((TrackDescription_t **)argument) = ManagerList(context); + *((char ** *) argument) = (char **) ManagerList(context); break; } case MANAGER_GET: @@ -269,7 +269,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/manager/chapter.c b/libeplayer3-arm/manager/chapter.c index c09a0f2..14167a9 100644 --- a/libeplayer3-arm/manager/chapter.c +++ b/libeplayer3-arm/manager/chapter.c @@ -66,7 +66,7 @@ static const char FILENAME[] = __FILE__; static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. /* ***************************** */ /* Prototypes */ @@ -76,7 +76,7 @@ static int CurrentTrack = 0; //TRACK[0] as default. /* Functions */ /* ***************************** */ -static int ManagerAdd(Context_t * context __attribute__((unused)), Track_t track) +static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) { chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); @@ -121,7 +121,7 @@ static int ManagerAdd(Context_t * context __attribute__((unused)), Track_t track return cERR_CHAPTER_MGR_NO_ERROR; } -static char **ManagerList(Context_t * context __attribute__ ((unused))) +static char **ManagerList(Context_t *context __attribute__((unused))) { int i = 0, j = 0; char **tracklist = NULL; @@ -157,7 +157,7 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) return tracklist; } -static int ManagerDel(Context_t * context __attribute__((unused))) +static int ManagerDel(Context_t *context __attribute__((unused))) { int i = 0; diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index 4b64cd6..4cff07c 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -69,7 +69,7 @@ if (debug_level >= level) printf(x); } while (0) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = -1; //no as default. +static int CurrentTrack = -1; //no as default. /* ***************************** */ /* Prototypes */ @@ -256,7 +256,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) { if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/manager/video.c b/libeplayer3-arm/manager/video.c index 1c8fcc3..adaa841 100644 --- a/libeplayer3-arm/manager/video.c +++ b/libeplayer3-arm/manager/video.c @@ -69,7 +69,7 @@ if (debug_level >= level) printf(x); } while (0) static Track_t *Tracks = NULL; static int TrackCount = 0; -static int CurrentTrack = 0; //TRACK[0] as default. +static int CurrentTrack = 0; //TRACK[0] as default. static void (* updatedTrackInfoFnc)(void) = NULL; @@ -181,9 +181,8 @@ static int ManagerDel(Context_t *context) return cERR_VIDEO_MGR_NO_ERROR; } -static int Command(void *_context, ManagerCmd_t command, void *argument) +static int Command(Context_t *context, ManagerCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_VIDEO_MGR_NO_ERROR; video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); switch (command) @@ -243,7 +242,7 @@ static int Command(void *_context, ManagerCmd_t command, void *argument) video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 56cbc91..1699f7d 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -228,9 +228,9 @@ int LinuxDvbPlay(Context_t *context, char *type) /* if (0 != ioctl(videofd, VIDEO_STOP)) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; } */ if (writer == NULL) @@ -276,9 +276,9 @@ int LinuxDvbPlay(Context_t *context, char *type) /* if (0 != ioctl(audiofd, AUDIO_STOP)) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; } */ if (writer == NULL) @@ -347,11 +347,13 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); } /* set back to normal speed (end trickmodes) */ - // if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - // } + /* + if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); + } + */ if (ioctl(audiofd, AUDIO_STOP) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); @@ -428,14 +430,16 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; - // int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; - // linuxdvb_printf(50, "\n"); - // if (ioctl(videofd, VIDEO_DISCONTINUITY, (void*) dis_type) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); - // } - // linuxdvb_printf(50, "exiting\n"); + /* + int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; + linuxdvb_printf(50, "\n"); + if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); + } + linuxdvb_printf(50, "exiting\n"); + */ return ret; } @@ -476,28 +480,33 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { - // unsigned char video = !strcmp("video", type); - // unsigned char audio = !strcmp("audio", type); - // linuxdvb_printf(10, "v%d a%d\n", video, audio); - // if ((video && videofd != -1) || (audio && audiofd != -1)) { - // getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - // if (video && videofd != -1) { - // if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); - // } - // } - // if (audio && audiofd != -1) { - // if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); - // } - // } - // releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - // } - // linuxdvb_printf(10, "exiting\n"); + /* + unsigned char video = !strcmp("video", type); + unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) + { + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) + { + if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); + } + } + if (audio && audiofd != -1) + { + if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); + } + } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + } + linuxdvb_printf(10, "exiting\n"); + */ return cERR_LINUXDVB_NO_ERROR; } @@ -546,12 +555,14 @@ int LinuxDvbFastForward(Context_t *context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - // if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); - // ret = cERR_LINUXDVB_ERROR; - // } + /* + if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + */ releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } if (audio && audiofd != -1) @@ -559,12 +570,14 @@ int LinuxDvbFastForward(Context_t *context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - // if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - // ret = cERR_LINUXDVB_ERROR; - // } + /* + if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + */ releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -728,11 +741,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - // if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void*) AUDIO_ENCODING_MP3) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); - // } + /* + if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) AUDIO_ENCODING_MP3) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); + } + */ } else { @@ -776,11 +791,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - // if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void*) VIDEO_ENCODING_AUTO) == -1) - // { - // linuxdvb_err("ioctl failed with errno %d\n", errno); - // linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); - // } + /* + if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) VIDEO_ENCODING_AUTO) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); + } + */ } else { @@ -812,15 +829,14 @@ int LinuxDvbSwitch(Context_t *context, char *type) return cERR_LINUXDVB_NO_ERROR; } -static int Write(void *_context, void *_out) +static int Write(Context_t *context, void *_out) { - Context_t *context = (Context_t *) _context; - AudioVideoOut_t *out = (AudioVideoOut_t *) _out; - int ret = cERR_LINUXDVB_NO_ERROR; - int res = 0; - unsigned char video = 0; - unsigned char audio = 0; - Writer_t *writer; + AudioVideoOut_t *out = (AudioVideoOut_t *) _out; + int ret = cERR_LINUXDVB_NO_ERROR; + int res = 0; + unsigned char video = 0; + unsigned char audio = 0; + Writer_t *writer; WriterAVCallData_t call; if (out == NULL) { @@ -905,7 +921,7 @@ static int Write(void *_context, void *_out) call.Width = out->width; call.Height = out->height; call.InfoFlags = out->infoFlags; - call.Version = 0; // is unsingned char + call.Version = 0; // is unsingned char if (writer->writeData) { res = writer->writeData(&call); @@ -947,7 +963,7 @@ static int Write(void *_context, void *_out) call.FrameRate = out->frameRate; call.FrameScale = out->timeScale; call.InfoFlags = out->infoFlags; - call.Version = 0; /* -1; unsigned char cannot be negative */ + call.Version = 0; /* -1; unsigned char cannot be negative */ if (writer->writeData) { res = writer->writeData(&call); @@ -996,9 +1012,8 @@ static int reset(Context_t *context) return ret; } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(Context_t *context, OutputCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_LINUXDVB_NO_ERROR; linuxdvb_printf(50, "Command %d\n", command); switch (command) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 4943a11..168c203 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -147,9 +147,8 @@ static void OutputDel(Context_t *context, char *port) } } -static int Command(void *_context, OutputCmd_t command, void *argument) +static int Command(Context_t *context, OutputCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; int ret = cERR_OUTPUT_NO_ERROR; output_printf(10, "%s::%s Command %d\n", __FILE__, __FUNCTION__, command); switch (command) diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index ef740f2..726d230 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -188,9 +188,8 @@ static int Flush() return cERR_SUBTITLE_NO_ERROR; } -static int Write(void *_context, void *data) +static int Write(Context_t *context, void *data) { - Context_t *context = (Context_t *)_context; char *Encoding = NULL; SubtitleOut_t *out = NULL; int32_t curtrackid = -1; @@ -257,9 +256,8 @@ static int32_t subtitle_Close(Context_t *context __attribute__((unused))) return cERR_SUBTITLE_NO_ERROR; } -static int Command(void *_context, OutputCmd_t command, void *argument __attribute__((unused))) +static int Command(Context_t *context, OutputCmd_t command, void *argument __attribute__((unused))) { - Context_t *context = (Context_t *) _context; int ret = cERR_SUBTITLE_NO_ERROR; subtitle_printf(50, "%d\n", command); switch (command) diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index c8e1b2f..8e6d163 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -156,9 +156,8 @@ static int reset() return 0; } -static int _writeData(void *_call, int type) +static int _writeData(WriterAVCallData_t *call, int type) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n _writeData type[%d]\n", type); if (call == NULL) { @@ -199,9 +198,8 @@ static int _writeData(void *_call, int type) return writev_with_retry(call->fd, iov, 2); } -static int writeDataADTS(void *_call) +static int writeDataADTS(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n"); if (call == NULL) { @@ -221,7 +219,7 @@ static int writeDataADTS(void *_call) if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { - return _writeData(_call, 0); + return _writeData(call, 0); } uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; @@ -258,9 +256,8 @@ static int writeDataADTS(void *_call) return writev_with_retry(call->fd, iov, 2); } -static int writeDataLATM(void *_call) +static int writeDataLATM(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; aac_printf(10, "\n"); if (call == NULL) { @@ -274,7 +271,7 @@ static int writeDataLATM(void *_call) } if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) { - return _writeData(_call, 1); + return _writeData(call, 1); } aac_printf(10, "AudioPts %lld\n", call->Pts); if (!pLATMCtx) diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index 017b2b2..b71b089 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -95,9 +95,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; ac3_printf(10, "\n"); unsigned char PesHeader[PES_MAX_HEADER_SIZE]; if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/amr.c b/libeplayer3-arm/output/writer/mipsel/amr.c index c94dead..cb843b5 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -96,10 +96,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; amr_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index 44a822d..98f1f4a 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -113,12 +113,11 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; -// unsigned char Version = 5; -// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; +// unsigned char Version = 5; +// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; divx_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index 06f0efb..b56969b 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -100,9 +100,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; dts_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/h263.c index ab79368..152b026 100644 --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/h263.c @@ -91,9 +91,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; int32_t len = 0; h263_printf(10, "\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 77e45c1..04b3d2f 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -284,9 +284,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned long long int VideoPts; unsigned int TimeDelta; diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index aa80678..cb21d99 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -168,9 +168,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned long long int VideoPts; unsigned int TimeDelta; diff --git a/libeplayer3-arm/output/writer/mipsel/lpcm.c b/libeplayer3-arm/output/writer/mipsel/lpcm.c index a0ef5ee..aca119e 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -132,9 +132,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; lpcm_printf(10, "\n"); if (!call) { diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index ee8a83a..88c5a82 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -91,10 +91,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; mp3_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index 9ccce6d..daa9daf 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -92,10 +92,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; int len = 0; unsigned int Position = 0; mpeg2_printf(10, "\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 9d9d8e4..7abce59 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -100,10 +100,9 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; mpeg4_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index 3a0045b..bc63b09 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -110,9 +110,8 @@ static int32_t reset() return 0; } -static int32_t writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; pcm_printf(10, "\n"); if (!call) { diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index 845afb5..f6997ab 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -107,9 +107,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; //int len = 0; vc1_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index d315358..2e31151 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -98,9 +98,8 @@ static int reset() return 0; } -static int writeData(void *_call, int is_vp6) +static int writeData(WriterAVCallData_t *call, int is_vp6) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; vp_printf(10, "\n"); if (call == NULL) { @@ -142,14 +141,14 @@ static int writeData(void *_call, int is_vp6) return writev_with_retry(call->fd, iov, 2); } -static int writeDataVP6(void *_call) +static int writeDataVP6(WriterAVCallData_t *call) { - return writeData(_call, 1); + return writeData(call, 1); } -static int writeDataVP89(void *_call) +static int writeDataVP89(WriterAVCallData_t *call) { - return writeData(_call, 0); + return writeData(call, 0); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 5324836..6500c7e 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -103,9 +103,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; //int len = 0; wma_printf(10, "\n"); if (call == NULL) diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 7722818..96db958 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -105,9 +105,8 @@ static int reset() return 0; } -static int writeData(void *_call) +static int writeData(WriterAVCallData_t *call) { - WriterAVCallData_t *call = (WriterAVCallData_t *) _call; wmv_printf(10, "\n"); if (call == NULL) { diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 602d265..f9364e9 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -27,6 +27,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ + // SULGE DEBUG //#define SAM_WITH_DEBUG @@ -53,7 +54,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define cERR_PLAYBACK_NO_ERROR 0 #define cERR_PLAYBACK_ERROR -1 -#define cMaxSpeed_ff 128 /* fixme: revise */ +#define cMaxSpeed_ff 128 /* fixme: revise */ #define cMaxSpeed_fr -320 /* fixme: revise */ /* ***************************** */ @@ -711,9 +712,8 @@ static int PlaybackMetadata(Context_t *context, char ***metadata) return ret; } -static int32_t Command(void *_context, PlaybackCmd_t command, void *argument) +static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument) { - Context_t *context = (Context_t *) _context; /* to satisfy compiler */ int32_t ret = cERR_PLAYBACK_NO_ERROR; playback_printf(20, "Command %d\n", command); switch (command) From 52ff2909c5ee0e4452169f739aa796efd7cc3632 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 13 Mar 2018 12:03:28 +0100 Subject: [PATCH 22/38] h264 writer - do not inject prive codec data if the Sequence Parameter Set (SPS) and the Picture Parameter Set (PPS) are available in the bitstreamThis should fix playback of stream http://www.djing.com/tv/live.m3u8 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/4d7df28b2a4b8b1fd85d2b4dda02e2cbc27890f1 Author: samsamsam Date: 2018-03-13 (Tue, 13 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/output/writer/mipsel/h264.c | 24 +++++++++++++++------ 2 files changed, 19 insertions(+), 7 deletions(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index adc0c2f..dd0c7ab 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -635,7 +635,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 36); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 37); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 04b3d2f..617a7af 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -88,6 +88,7 @@ static unsigned int NalLengthBytes = 1; static unsigned char *CodecData = NULL; static unsigned int CodecDataLen = 0; static int avc3 = 0; +static int sps_pps_in_stream = 0; /* ***************************** */ /* Prototypes */ @@ -281,6 +282,7 @@ static int reset() { initialHeader = 1; avc3 = 0; + sps_pps_in_stream = 0; return 0; } @@ -319,21 +321,31 @@ static int writeData(WriterAVCallData_t *call) /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) + (call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x01) || + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) { + uint32_t i = 0; + uint8_t InsertPrivData = !sps_pps_in_stream; uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; iov[ic++].iov_base = PesHeader; - initialHeader = 0; - //if (initialHeader) // some rtsp streams can update codec data at runtime + while (InsertPrivData && i < 36 && (call->len - i) > 5) + { + if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68)) || + (call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && (call->data[i + 3] == 0x67 || call->data[i + 3] == 0x68))) + { + InsertPrivData = 0; + sps_pps_in_stream = 1; + } + i += 1; + } + if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime { initialHeader = 0; iov[ic].iov_base = call->private_data; iov[ic++].iov_len = call->private_size; PacketLength += call->private_size; } - iov[ic].iov_base = ""; - iov[ic++].iov_len = 1; iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; @@ -348,7 +360,7 @@ static int writeData(WriterAVCallData_t *call) uint32_t PacketLength = 0; ic = 0; iov[ic++].iov_base = PesHeader; - if (initialHeader) + //if (initialHeader) { if (CodecData) { From ac20ae8192324499776f87ff9433b266a2c695a3 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 13 Mar 2018 12:55:59 +0100 Subject: [PATCH 23/38] h264 writer - Revert not intended test change Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/f1725779b5bf96594350c024ee9349bf5bfd9bdb Author: samsamsam Date: 2018-03-13 (Tue, 13 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/output/writer/mipsel/h264.c | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index dd0c7ab..55f2d00 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -635,7 +635,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 37); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 38); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 617a7af..9855288 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -321,8 +321,7 @@ static int writeData(WriterAVCallData_t *call) /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) { uint32_t i = 0; uint8_t InsertPrivData = !sps_pps_in_stream; @@ -331,8 +330,7 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_base = PesHeader; while (InsertPrivData && i < 36 && (call->len - i) > 5) { - if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68)) || - (call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && (call->data[i + 3] == 0x67 || call->data[i + 3] == 0x68))) + if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68))) { InsertPrivData = 0; sps_pps_in_stream = 1; From 9b429d8497bad42f8887be5917ef52d44feb83aa Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sun, 18 Mar 2018 01:16:08 +0100 Subject: [PATCH 24/38] Set discard flag to all not active streams, do not process packets from discarded streams Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/ac23fcc6a91383d81d3c4acfd55dc9cdd03deb09 Author: samsamsam Date: 2018-03-18 (Sun, 18 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 184 ++++++++++++++----- libeplayer3-arm/container/flv2mpeg4_ffmpeg.c | 2 +- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 2 +- libeplayer3-arm/include/manager.h | 2 + libeplayer3-arm/include/output.h | 2 +- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/manager/audio.c | 10 + 7 files changed, 152 insertions(+), 52 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index d5a9ae1..a931176 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -136,6 +136,8 @@ static int64_t prev_seek_time_sec = -1; static int32_t seek_target_flag = 0; +static int32_t mutexInitialized = 0; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -155,6 +157,43 @@ void progressive_playback_set(int32_t val) progressive_playback = val; } +static void initMutex(void) +{ + pthread_mutex_init(&mutex, NULL); + mutexInitialized = 1; +} + +static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line __attribute__((unused))) +{ + ffmpeg_printf(100, "::%d requesting mutex\n", line); + if (!mutexInitialized) + { + initMutex(); + } + pthread_mutex_lock(&mutex); + ffmpeg_printf(100, "::%d received mutex\n", line); +} + +static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line __attribute__((unused))) +{ + pthread_mutex_unlock(&mutex); + ffmpeg_printf(100, "::%d released mutex\n", line); +} + +typedef int32_t (* Write_FN)(void *, void *); + +static int32_t Write(Write_FN WriteFun, void *context, void *privateData) +{ + /* Because Write is blocking we will release mutex which protect + * avformat structures, during write time + */ + int32_t ret = 0; + releaseMutex(__FILE__, __FUNCTION__, __LINE__); + ret = WriteFun(context, privateData); + getMutex(__FILE__, __FUNCTION__, __LINE__); + return ret; +} + #include "buff_ffmpeg.c" #include "wrapped_ffmpeg.c" #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) @@ -203,8 +242,6 @@ static void ffmpeg_silen_callback(void *avcl __attribute__((unused)), int level return; } -static int32_t mutexInitialized = 0; - void sel_program_id_set(const int32_t val) { g_sel_program_id = val; @@ -275,29 +312,6 @@ int32_t ffmpeg_av_dict_set(const char *key, const char *value, int32_t flags) return av_dict_set(&avio_opts, key, value, flags); } -static void initMutex(void) -{ - pthread_mutex_init(&mutex, NULL); - mutexInitialized = 1; -} - -static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line __attribute__((unused))) -{ - ffmpeg_printf(100, "::%d requesting mutex\n", line); - if (!mutexInitialized) - { - initMutex(); - } - pthread_mutex_lock(&mutex); - ffmpeg_printf(100, "::%d received mutex\n", line); -} - -static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line __attribute__((unused))) -{ - pthread_mutex_unlock(&mutex); - ffmpeg_printf(100, "::%d released mutex\n", line); -} - static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extradata, int extradata_size, int profile __attribute__((unused)), int32_t *version) { ffmpeg_printf(10, "Codec ID: %d (%.8lx)\n", codec_id, codec_id); @@ -718,17 +732,24 @@ static void FFMPEGThread(Context_t *context) Track_t *subtitleTrack = NULL; int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id; reset_finish_timeout(); - if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) + if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL) { - ffmpeg_err("error getting video track\n"); + if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) + { + ffmpeg_err("error getting video track\n"); + } + if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0) + { + ffmpeg_err("error getting audio track\n"); + } + if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0) + { + ffmpeg_err("error getting subtitle track\n"); + } } - if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0) + else { - ffmpeg_err("error getting audio track\n"); - } - if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0) - { - ffmpeg_err("error getting subtitle track\n"); + ffmpeg_printf(1, "SKIP DISCARDED PACKET stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid); } ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid); if (videoTrack && (videoTrack->AVIdx == (int)cAVIdx) && (videoTrack->Id == pid)) @@ -814,7 +835,7 @@ static void FFMPEGThread(Context_t *context) { avOut.infoFlags = 1; // TS container } - if (context->output->video->Write(context, &avOut) < 0) + if (Write(context->output->video->Write, context, &avOut) < 0) { ffmpeg_err("writing data to video device failed\n"); } @@ -882,7 +903,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (context->output->audio->Write(context, &avOut) < 0) + if (Write(context->output->audio->Write, context, &avOut) < 0) { ffmpeg_err("(raw pcm) writing data to audio device failed\n"); } @@ -1058,7 +1079,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) { ffmpeg_err("writing data to audio device failed\n"); } @@ -1079,7 +1100,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) { ffmpeg_err("(aac) writing data to audio device failed\n"); } @@ -1096,7 +1117,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) { ffmpeg_err("writing data to audio device failed\n"); } @@ -1125,7 +1146,7 @@ static void FFMPEGThread(Context_t *context) subOut.data = (uint8_t *)packet.data; subOut.pts = pts; subOut.durationMS = duration; - if (context->output->subtitle->Write(context, &subOut) < 0) + if (Write(context->output->subtitle->Write, context, &subOut) < 0) { ffmpeg_err("writing data to teletext fifo failed\n"); } @@ -1650,19 +1671,21 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial) { - Track_t *audioTrack = NULL; - Track_t *subtitleTrack = NULL; + Track_t *currAudioTrack = NULL; + Track_t *currSubtitleTrack = NULL; + uint32_t addedVideoTracksCount = 0; if (terminating) { return cERR_CONTAINER_FFMPEG_NO_ERROR; } + getMutex(__FILE__, __FUNCTION__, __LINE__); if (initial && context->manager->subtitle) { - context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack); + context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &currSubtitleTrack); } if (context->manager->audio) { - context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + context->manager->audio->Command(context, MANAGER_GET_TRACK, &currAudioTrack); } if (context->manager->video) { @@ -1748,7 +1771,11 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } if (!isStreamFromSelProg) + { + stream->discard = AVDISCARD_ALL; + ffmpeg_printf(1, "cAVIdx[%d]: add DISCARD flag to stream index[%d]\n", cAVIdx, stream->index); continue; // skip this stream + } } encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \ (uint8_t *)get_codecpar(stream)->extradata, \ @@ -1775,6 +1802,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { case AVMEDIA_TYPE_VIDEO: ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type); + stream->discard = AVDISCARD_ALL; /* by default we discard all video streams */ if (encoding != NULL) { track.type = eTypeES; @@ -1844,6 +1872,14 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 /* konfetti: fixme: is this a reason to return with error? */ ffmpeg_err("failed to add track %d\n", n); } + else + { + if (addedVideoTracksCount == 0) /* at now we can handle only first video track */ + { + stream->discard = AVDISCARD_DEFAULT; + } + addedVideoTracksCount += 1; + } } } else @@ -1853,6 +1889,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 break; case AVMEDIA_TYPE_AUDIO: ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", get_codecpar(stream)->codec_type); + stream->discard = AVDISCARD_ALL; if (encoding != NULL) { AVDictionaryEntry *lang; @@ -2172,11 +2209,45 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 case AVMEDIA_TYPE_ATTACHMENT: case AVMEDIA_TYPE_NB: default: + stream->discard = AVDISCARD_ALL; ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type); break; } } /* for */ } + if (context->manager->audio) + { + Track_t *Tracks = NULL; + int32_t TrackCount = 0; + int32_t selTrackIdx = -1; + context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); + context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); + if (Tracks && TrackCount) + { + int32_t i; + for (i = 0; i < TrackCount; ++i) + { + if (Tracks[i].pending || Tracks[i].Id < 0) + continue; + if (selTrackIdx == -1) + selTrackIdx = i; + if (currAudioTrack && currAudioTrack->Id == Tracks[i].Id) + { + selTrackIdx = i; + break; + } + } + if (selTrackIdx > -1) + { + ((AVStream *)Tracks[selTrackIdx].stream)->discard = AVDISCARD_DEFAULT; + if (!currAudioTrack || currAudioTrack->Id != Tracks[selTrackIdx].Id) + { + context->manager->audio->Command(context, MANAGER_SET, &Tracks[selTrackIdx].Id); + } + } + } + } + releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2442,7 +2513,6 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab { seek_target_flag |= AVSEEK_FLAG_BACKWARD; } - getMutex(__FILE__, __FUNCTION__, __LINE__); if (!context->playback || !context->playback->isPlaying) { releaseMutex(__FILE__, __FUNCTION__, __LINE__); @@ -2458,7 +2528,9 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab * seeking per HTTP does still not work very good. forward seeks everytime * about 10 seconds, backward does not work. */ + getMutex(__FILE__, __FUNCTION__, __LINE__); off_t pos = avio_tell(avContextTab[0]->pb); + releaseMutex(__FILE__, __FUNCTION__, __LINE__); ffmpeg_printf(10, "pos %lld %lld\n", pos, avContextTab[0]->bit_rate); if (avContextTab[0]->bit_rate) { @@ -2484,7 +2556,6 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab seek_target_seconds = sec; do_seek_target_seconds = 1; } - releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2539,8 +2610,25 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); + getMutex(__FILE__, __FUNCTION__, __LINE__); + if (context->manager->audio) + { + Track_t *Tracks = NULL; + int32_t TrackCount = 0; + context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); + context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); + if (Tracks && TrackCount) + { + int32_t i; + for (i = 0; i < TrackCount; ++i) + { + ((AVStream *)Tracks[i].stream)->discard = Tracks[i].Id == *arg ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + } + } + } + releaseMutex(__FILE__, __FUNCTION__, __LINE__); /* Hellmaster1024: nothing to do here! */ - int64_t sec = -5; + int64_t sec = -1; context->playback->Command(context, PLAYBACK_SEEK, (void *)&sec); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2553,7 +2641,7 @@ static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg * we seek to force ffmpeg to read once again the same data * but now we will not ignore subtitle frame */ - int64_t sec = -5; + int64_t sec = -1; context->playback->Command(context, PLAYBACK_SEEK, (void *)&sec); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2788,4 +2876,4 @@ Container_t FFMPEGContainer = "FFMPEG", &Command, FFMPEG_Capabilities -}; +}; \ No newline at end of file diff --git a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c index 968ba56..a96e055 100644 --- a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c +++ b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c @@ -34,7 +34,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p avOut.width = ctx->track->width; avOut.height = ctx->track->height; avOut.type = "video"; - if (ctx->out_ctx->output->video->Write(ctx->out_ctx, &avOut) < 0) + if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut) < 0) { ffmpeg_err("writing data to video device failed\n"); } diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index c27056e..f77ef73 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -107,7 +107,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6 avOut.width = track->width; avOut.height = track->height; avOut.type = "video"; - if (ctx->output->video->Write(ctx, &avOut) < 0) + if (Write(ctx->output->video->Write, ctx, &avOut) < 0) { ffmpeg_err("writing data to video device failed\n"); } diff --git a/libeplayer3-arm/include/manager.h b/libeplayer3-arm/include/manager.h index d5eea58..81515bc 100644 --- a/libeplayer3-arm/include/manager.h +++ b/libeplayer3-arm/include/manager.h @@ -24,6 +24,8 @@ typedef enum MANAGER_INIT_UPDATE, MANAGER_UPDATED_TRACK_INFO, MANAGER_REGISTER_UPDATED_TRACK_INFO, + MANAGER_REF_LIST, + MANAGER_REF_LIST_SIZE, } ManagerCmd_t; typedef enum diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index ac0c0bf..5b0fedb 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -71,7 +71,7 @@ typedef struct Output_s { char *Name; int32_t (* Command)(Context_t *, OutputCmd_t, void *); - int32_t (* Write)(Context_t *, void *privateData); + int32_t (* Write)(Context_t *, void *); char **Capabilities; } Output_t; diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 55f2d00..d7c2c19 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -635,7 +635,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 38); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 39); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index c527480..6e5abde 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -231,6 +231,16 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) *((char ** *) argument) = (char **) ManagerList(context); break; } + case MANAGER_REF_LIST: + { + *((Track_t **)argument) = Tracks; + break; + } + case MANAGER_REF_LIST_SIZE: + { + *((int *)argument) = TrackCount; + break; + } case MANAGER_GET: { audio_mgr_printf(20, "%s::%s MANAGER_GET\n", __FILE__, __FUNCTION__); From cdc3ad2fa9fe560b176949444ee0c52b708cb9ec Mon Sep 17 00:00:00 2001 From: max_10 Date: Sun, 18 Mar 2018 01:21:50 +0100 Subject: [PATCH 25/38] container_ffmpeg: fix Write from incompatible pointer type Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/8c8cd8b0f79ed8b7b8cd0d87eb4821590b21aaee Author: max_10 Date: 2018-03-18 (Sun, 18 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index a931176..5fec340 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -180,9 +180,9 @@ static void releaseMutex(const char *filename __attribute__((unused)), const con ffmpeg_printf(100, "::%d released mutex\n", line); } -typedef int32_t (* Write_FN)(void *, void *); +typedef int32_t (* Write_FN)(Context_t *context, void *); -static int32_t Write(Write_FN WriteFun, void *context, void *privateData) +static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData) { /* Because Write is blocking we will release mutex which protect * avformat structures, during write time From 9542f761f5a21964dd354f313c2ff583ed199f58 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 20 Mar 2018 11:42:39 +0100 Subject: [PATCH 26/38] armbox: fix video policy again Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b8e3478be2e3a265db2e469056b88b2e105797c3 Author: max_10 Date: 2018-03-20 (Tue, 20 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 6c894c0..482ddc5 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -361,7 +361,8 @@ void cVideo::closeDevice(void) int cVideo::setAspectRatio(int aspect, int mode) { static const char *a[] = { "n/a", "4:3", "14:9", "16:9" }; - static const char *m[] = { "panscan", "letterbox", "bestfit", "nonlinear", "(unset)" }; +// static const char *m[] = { "panscan", "letterbox", "bestfit", "nonlinear", "(unset)" }; + static const char *m[] = { "letterbox", "panscan", "bestfit", "nonlinear", "(unset)" }; int n; lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[(mode < 0||mode > 3) ? 4 : mode]); From 4e54f05b87133f3ca8431381bd5614bdd3d7ab22 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 21 Mar 2018 01:53:22 +0100 Subject: [PATCH 27/38] all: clean up cDemux headers Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/0d867e7c7ed2b36632a03026c93b8f930e357c28 Author: max_10 Date: 2018-03-21 (Wed, 21 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- Makefile.am | 23 ++- azbox/cs_api.h | 1 - azbox/dmx.cpp | 28 ++-- azbox/dmx_cs.h | 1 - azbox/dmx_lib.h | 70 -------- azbox/init.cpp | 4 +- azbox/init_lib.h | 5 - azbox/video_lib.h | 16 +- common/Makefile.am | 6 +- common/hardware_caps.h | 1 - generic-pc/Makefile.am | 8 +- generic-pc/audio.cpp | 2 +- generic-pc/audio_lib.h | 38 ++--- generic-pc/cs_api.h | 1 - generic-pc/dmx.cpp | 29 ++-- generic-pc/dmx_cs.h | 1 - generic-pc/dmx_lib.h | 70 -------- generic-pc/init.cpp | 5 +- generic-pc/init_lib.h | 5 - generic-pc/video.cpp | 2 +- generic-pc/video_lib.h | 12 +- {common => include}/ca.h | 0 {common => include}/ca_ci.h | 0 include/ca_cs.h | 2 +- include/cs_api.h | 51 ++++-- {common => include}/cs_types.h | 0 include/dmx_hal.h | 115 ++++++++++--- include/mmi.h | 8 +- libarmbox/Makefile.am | 7 +- libarmbox/audio.cpp | 5 +- libarmbox/audio_lib.h | 7 +- libarmbox/cs_api.h | 67 -------- libarmbox/dmx.cpp | 286 ++++++++++++++++++--------------- libarmbox/dmx_cs.h | 1 - libarmbox/dmx_lib.h | 72 --------- libarmbox/init.cpp | 2 +- libarmbox/init_cs.h | 2 - libarmbox/init_lib.h | 5 - libarmbox/record.cpp | 30 +++- libarmbox/record_lib.h | 7 +- libarmbox/video.cpp | 48 +++--- libarmbox/video_lib.h | 15 +- libduckbox/Makefile.am | 5 +- libduckbox/cs_api.h | 31 ---- libduckbox/dmx_cs.h | 1 - libduckbox/dmx_lib.h | 1 - libduckbox/init.cpp | 2 +- libduckbox/init_cs.h | 1 - libduckbox/init_lib.h | 1 - libspark/Makefile.am | 5 +- libspark/README.libtriple | 72 --------- libspark/audio.cpp | 3 +- libspark/audio_lib.h | 2 +- libspark/cs_api.h | 67 -------- libspark/dmx.cpp | 255 +++++++++++++++-------------- libspark/dmx_cs.h | 1 - libspark/dmx_lib.h | 73 --------- libspark/init.cpp | 2 +- libspark/init_cs.h | 2 - libspark/init_lib.h | 5 - libspark/record.cpp | 14 +- libspark/record_lib.h | 7 +- libspark/video_lib.h | 8 +- libtriple/Makefile.am | 1 + libtriple/audio_td.h | 2 +- libtriple/cs_api.h | 67 -------- libtriple/dmx_cs.h | 1 - libtriple/dmx_td.cpp | 110 +++++++------ libtriple/dmx_td.h | 78 --------- libtriple/init_cs.h | 2 - libtriple/init_td.cpp | 2 +- libtriple/init_td.h | 5 - libtriple/lt_dfbinput.cpp | 2 +- libtriple/playback_td.cpp | 7 +- libtriple/record_td.cpp | 8 +- libtriple/record_td.h | 2 +- libtriple/video_td.h | 2 +- raspi/audio.cpp | 3 +- raspi/audio_lib.h | 37 ++--- raspi/cs_api.h | 1 - raspi/dmx.cpp | 41 +++-- raspi/dmx_lib.h | 37 +++-- raspi/init.cpp | 2 +- raspi/init_lib.h | 5 - raspi/video_lib.h | 13 +- 85 files changed, 759 insertions(+), 1285 deletions(-) delete mode 120000 azbox/cs_api.h delete mode 100644 azbox/dmx_cs.h delete mode 100644 azbox/dmx_lib.h delete mode 100644 azbox/init_lib.h delete mode 120000 common/hardware_caps.h delete mode 120000 generic-pc/cs_api.h delete mode 100644 generic-pc/dmx_cs.h delete mode 100644 generic-pc/dmx_lib.h delete mode 100644 generic-pc/init_lib.h rename {common => include}/ca.h (100%) rename {common => include}/ca_ci.h (100%) rename {common => include}/cs_types.h (100%) delete mode 100644 libarmbox/cs_api.h delete mode 100644 libarmbox/dmx_cs.h delete mode 100644 libarmbox/dmx_lib.h delete mode 100644 libarmbox/init_cs.h delete mode 100644 libarmbox/init_lib.h delete mode 100644 libduckbox/cs_api.h delete mode 120000 libduckbox/dmx_cs.h delete mode 120000 libduckbox/dmx_lib.h delete mode 120000 libduckbox/init_cs.h delete mode 120000 libduckbox/init_lib.h delete mode 100644 libspark/README.libtriple delete mode 100644 libspark/cs_api.h delete mode 100644 libspark/dmx_cs.h delete mode 100644 libspark/dmx_lib.h delete mode 100644 libspark/init_cs.h delete mode 100644 libspark/init_lib.h delete mode 100644 libtriple/cs_api.h delete mode 100644 libtriple/dmx_cs.h delete mode 100644 libtriple/dmx_td.h delete mode 100644 libtriple/init_cs.h delete mode 100644 libtriple/init_td.h delete mode 120000 raspi/cs_api.h delete mode 100644 raspi/init_lib.h diff --git a/Makefile.am b/Makefile.am index 20428de..5466534 100644 --- a/Makefile.am +++ b/Makefile.am @@ -9,8 +9,6 @@ libstb_hal_la_LIBADD = \ common/libcommon.la \ libthread/libthread.la -AM_CPPFLAGS = \ - -I$(top_srcdir)/include #libstb_hal_test_SOURCES = libtest.cpp #libstb_hal_test_LDADD = libstb-hal.la @@ -67,3 +65,24 @@ libstb_hal_la_LIBADD += \ endif endif + +pkginclude_HEADERS = \ + include/audio_hal.h \ + include/ca_cs.h \ + include/ca.h \ + include/cs_api.h \ + include/ca_ci.h \ + include/cs_types.h \ + include/dmx_cs.h \ + include/dmx_hal.h \ + include/glfb.h \ + include/hardware_caps.h \ + include/init_cs.h \ + include/init_td.h \ + include/mmi.h \ + include/playback.h \ + include/playback_hal.h \ + include/pwrmngr.h \ + include/record_hal.h \ + include/video_cs.h \ + include/video_hal.h diff --git a/azbox/cs_api.h b/azbox/cs_api.h deleted file mode 120000 index a794ffd..0000000 --- a/azbox/cs_api.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/cs_api.h \ No newline at end of file diff --git a/azbox/dmx.cpp b/azbox/dmx.cpp index cacd823..a6ca5ed 100644 --- a/azbox/dmx.cpp +++ b/azbox/dmx.cpp @@ -30,11 +30,12 @@ #include #include #include -#include "dmx_lib.h" +#include +#include "dmx_hal.h" #include "lt_debug.h" -/* Ugh... see comment in destructor for details... */ #include "video_lib.h" +/* needed for getSTC... */ extern cVideo *videoDecoder; #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) @@ -42,14 +43,8 @@ extern cVideo *videoDecoder; #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; @@ -88,9 +83,6 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; } cDemux::~cDemux() @@ -165,8 +157,6 @@ void cDemux::Close(void) ioctl(fd, DMX_STOP); close(fd); fd = -1; - if (measure) - return; if (dmx_type == DMX_TP_CHANNEL) { dmx_tp_count--; @@ -273,11 +263,13 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { + struct dmx_sct_filter_params s_flt; memset(&s_flt, 0, sizeof(s_flt)); + pid = _pid; if (len > DMX_FILTER_SIZE) { @@ -286,6 +278,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte } s_flt.pid = pid; s_flt.timeout = timeout; + flt = filter[0]; memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.mask, mask, len); if (negmask != NULL) @@ -389,8 +382,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + struct dmx_pes_filter_params p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... diff --git a/azbox/dmx_cs.h b/azbox/dmx_cs.h deleted file mode 100644 index 175d8cb..0000000 --- a/azbox/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -#include "dmx_lib.h" diff --git a/azbox/dmx_lib.h b/azbox/dmx_lib.h deleted file mode 100644 index 754511e..0000000 --- a/azbox/dmx_lib.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H - -#include -#include -#include -#include -#include -#include "../common/cs_types.h" - -#define MAX_DMX_UNITS 4 - -typedef enum -{ - DMX_INVALID = 0, - DMX_VIDEO_CHANNEL = 1, - DMX_AUDIO_CHANNEL, - DMX_PES_CHANNEL, - DMX_PSI_CHANNEL, - DMX_PIP_CHANNEL, - DMX_TP_CHANNEL, - DMX_PCR_ONLY_CHANNEL -} DMX_CHANNEL_TYPE; - -typedef struct -{ - int fd; - unsigned short pid; -} pes_pids; - -class cDemux -{ - private: - int num; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct dmx_sct_filter_params s_flt; - struct dmx_pes_filter_params p_flt; - public: - - bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); - void Close(void); - bool Start(bool record = false); - bool Stop(void); - int Read(unsigned char *buff, int len, int Timeout = 0); - bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); - bool pesFilter(const unsigned short pid); - void SetSyncMode(AVSYNC_TYPE mode); - void * getBuffer(); - void * getChannel(); - DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; - bool addPid(unsigned short pid); - void getSTC(int64_t * STC); - int getUnit(void); - static bool SetSource(int unit, int source); - static int GetSource(int unit); - // TD only functions - int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // - cDemux(int num = 0); - ~cDemux(); -}; - -#endif //__DEMUX_H diff --git a/azbox/init.cpp b/azbox/init.cpp index 273cc04..2029b4f 100644 --- a/azbox/init.cpp +++ b/azbox/init.cpp @@ -1,5 +1,7 @@ #include -#include "init_lib.h" + +#include "init_td.h" + #include "lt_debug.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args) diff --git a/azbox/init_lib.h b/azbox/init_lib.h deleted file mode 100644 index d9a6f09..0000000 --- a/azbox/init_lib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/azbox/video_lib.h b/azbox/video_lib.h index c7286e9..15f8bfc 100644 --- a/azbox/video_lib.h +++ b/azbox/video_lib.h @@ -1,9 +1,9 @@ -#ifndef _VIDEO_TD_H -#define _VIDEO_TD_H +#ifndef _VIDEO_LIB_H +#define _VIDEO_LIB_H #include -#include "../common/cs_types.h" -#include "dmx_lib.h" +#include "cs_types.h" +#include "dmx_hal.h" typedef enum { ANALOG_SD_RGB_CINCH = 0x00, @@ -97,7 +97,7 @@ typedef enum { /* not used, for dummy functions */ typedef enum { - VIDEO_HDMI_CEC_MODE_OFF = 0, + VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_RECORDER } VIDEO_HDMI_CEC_MODE; @@ -127,11 +127,11 @@ class cVideo int /*vidOutFmt_t*/ outputformat; int scartvoltage; - VIDEO_FORMAT StreamType; - VIDEO_DEFINITION VideoDefinition; + VIDEO_FORMAT StreamType; + VIDEO_DEFINITION VideoDefinition; DISPLAY_AR DisplayAR; VIDEO_PLAY_MODE SyncMode; - DISPLAY_AR_MODE ARMode; + DISPLAY_AR_MODE ARMode; VIDEO_DB_DR eDbDr; DISPLAY_AR PictureAR; VIDEO_FRAME_RATE FrameRate; diff --git a/common/Makefile.am b/common/Makefile.am index 23fb888..0fb4902 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -1,17 +1,19 @@ noinst_LTLIBRARIES = libcommon.la AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing + +AM_CXXFLAGS += \ + -I $(top_srcdir)/include + AM_LDFLAGS = -lpthread if BOXTYPE_DUCKBOX AM_CXXFLAGS += \ - -I $(top_srcdir)/include \ -I $(top_srcdir)/libdvbci endif if BOXTYPE_ARMBOX AM_CXXFLAGS += \ - -I $(top_srcdir)/include \ -I $(top_srcdir)/libdvbci endif diff --git a/common/hardware_caps.h b/common/hardware_caps.h deleted file mode 120000 index 3bb479b..0000000 --- a/common/hardware_caps.h +++ /dev/null @@ -1 +0,0 @@ -../include/hardware_caps.h \ No newline at end of file diff --git a/generic-pc/Makefile.am b/generic-pc/Makefile.am index 11f6db1..fdab1bf 100644 --- a/generic-pc/Makefile.am +++ b/generic-pc/Makefile.am @@ -1,9 +1,8 @@ noinst_LTLIBRARIES = libgeneric.la -AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -AM_CPPFLAGS += \ - -I$(top_srcdir)/include \ - -I$(top_srcdir)/common +AM_CPPFLAGS = \ + -I$(top_srcdir)/common \ + -I$(top_srcdir)/include AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing @@ -45,3 +44,4 @@ libgeneric_la_SOURCES += \ endif endif +AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 8b3ae48..1bba357 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -23,7 +23,7 @@ #include #include "audio_lib.h" -#include "dmx_lib.h" +#include "dmx_hal.h" #include "lt_debug.h" #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) diff --git a/generic-pc/audio_lib.h b/generic-pc/audio_lib.h index 8394cec..dc09c8d 100644 --- a/generic-pc/audio_lib.h +++ b/generic-pc/audio_lib.h @@ -5,13 +5,13 @@ #include #include -#include "../common/cs_types.h" +#include "cs_types.h" typedef enum { - AUDIO_SYNC_WITH_PTS, - AUDIO_NO_SYNC, - AUDIO_SYNC_AUDIO_MASTER + AUDIO_SYNC_WITH_PTS, + AUDIO_NO_SYNC, + AUDIO_SYNC_AUDIO_MASTER } AUDIO_SYNC_MODE; typedef enum { @@ -22,20 +22,20 @@ typedef enum { typedef enum { - AUDIO_FMT_AUTO = 0, - AUDIO_FMT_MPEG, - AUDIO_FMT_MP3, - AUDIO_FMT_DOLBY_DIGITAL, - AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, - AUDIO_FMT_AAC, - AUDIO_FMT_AAC_PLUS, - AUDIO_FMT_DD_PLUS, - AUDIO_FMT_DTS, - AUDIO_FMT_AVS, - AUDIO_FMT_MLP, - AUDIO_FMT_WMA, - AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback - AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP + AUDIO_FMT_AUTO = 0, + AUDIO_FMT_MPEG, + AUDIO_FMT_MP3, + AUDIO_FMT_DOLBY_DIGITAL, + AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, + AUDIO_FMT_AAC, + AUDIO_FMT_AAC_PLUS, + AUDIO_FMT_DD_PLUS, + AUDIO_FMT_DTS, + AUDIO_FMT_AVS, + AUDIO_FMT_MLP, + AUDIO_FMT_WMA, + AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback + AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP } AUDIO_FORMAT; class cAudio : public Thread @@ -63,6 +63,7 @@ class cAudio : public Thread int do_mute(bool enable, bool remember); void setBypassMode(bool disable); void run(); + public: /* construct & destruct */ cAudio(void *, void *, void *); @@ -102,4 +103,3 @@ class cAudio : public Thread }; #endif - diff --git a/generic-pc/cs_api.h b/generic-pc/cs_api.h deleted file mode 120000 index a794ffd..0000000 --- a/generic-pc/cs_api.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/cs_api.h \ No newline at end of file diff --git a/generic-pc/dmx.cpp b/generic-pc/dmx.cpp index 409c086..6609693 100644 --- a/generic-pc/dmx.cpp +++ b/generic-pc/dmx.cpp @@ -19,7 +19,6 @@ * along with this program. If not, see . */ - #include "config.h" #include #include @@ -32,11 +31,12 @@ #include #include #include -#include "dmx_lib.h" +#include +#include "dmx_hal.h" #include "lt_debug.h" -/* needed for getSTC :-( */ #include "video_lib.h" +/* needed for getSTC... */ extern cVideo *videoDecoder; #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) @@ -44,14 +44,8 @@ extern cVideo *videoDecoder; #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; @@ -95,9 +89,6 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; } cDemux::~cDemux() @@ -163,8 +154,6 @@ void cDemux::Close(void) ioctl(fd, DMX_STOP); close(fd); fd = -1; - if (measure) - return; if (dmx_type == DMX_TP_CHANNEL) { dmx_tp_count--; @@ -256,11 +245,13 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { + struct dmx_sct_filter_params s_flt; memset(&s_flt, 0, sizeof(s_flt)); + pid = _pid; if (len > DMX_FILTER_SIZE) { @@ -269,6 +260,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte } s_flt.pid = pid; s_flt.timeout = timeout; + flt = filter[0]; memcpy(s_flt.filter.filter, filter, len); memcpy(s_flt.filter.mask, mask, len); if (negmask != NULL) @@ -369,8 +361,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + struct dmx_pes_filter_params p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... diff --git a/generic-pc/dmx_cs.h b/generic-pc/dmx_cs.h deleted file mode 100644 index 175d8cb..0000000 --- a/generic-pc/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -#include "dmx_lib.h" diff --git a/generic-pc/dmx_lib.h b/generic-pc/dmx_lib.h deleted file mode 100644 index 754511e..0000000 --- a/generic-pc/dmx_lib.h +++ /dev/null @@ -1,70 +0,0 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H - -#include -#include -#include -#include -#include -#include "../common/cs_types.h" - -#define MAX_DMX_UNITS 4 - -typedef enum -{ - DMX_INVALID = 0, - DMX_VIDEO_CHANNEL = 1, - DMX_AUDIO_CHANNEL, - DMX_PES_CHANNEL, - DMX_PSI_CHANNEL, - DMX_PIP_CHANNEL, - DMX_TP_CHANNEL, - DMX_PCR_ONLY_CHANNEL -} DMX_CHANNEL_TYPE; - -typedef struct -{ - int fd; - unsigned short pid; -} pes_pids; - -class cDemux -{ - private: - int num; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct dmx_sct_filter_params s_flt; - struct dmx_pes_filter_params p_flt; - public: - - bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); - void Close(void); - bool Start(bool record = false); - bool Stop(void); - int Read(unsigned char *buff, int len, int Timeout = 0); - bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); - bool pesFilter(const unsigned short pid); - void SetSyncMode(AVSYNC_TYPE mode); - void * getBuffer(); - void * getChannel(); - DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; - bool addPid(unsigned short pid); - void getSTC(int64_t * STC); - int getUnit(void); - static bool SetSource(int unit, int source); - static int GetSource(int unit); - // TD only functions - int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // - cDemux(int num = 0); - ~cDemux(); -}; - -#endif //__DEMUX_H diff --git a/generic-pc/init.cpp b/generic-pc/init.cpp index 50f3ca5..b641fd8 100644 --- a/generic-pc/init.cpp +++ b/generic-pc/init.cpp @@ -1,9 +1,10 @@ #include #include -#include "init_lib.h" -#include "lt_debug.h" +#include "init_td.h" #include "glfb.h" + +#include "lt_debug.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_INIT, NULL, args) diff --git a/generic-pc/init_lib.h b/generic-pc/init_lib.h deleted file mode 100644 index d9a6f09..0000000 --- a/generic-pc/init_lib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index 8723940..abcfd75 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -40,7 +40,7 @@ extern "C" { #define DMX_BUF_SZ 0x20000 #include "video_lib.h" -#include "dmx_lib.h" +#include "dmx_hal.h" #include "glfb.h" #include "lt_debug.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args) diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index 832574d..a8274e8 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -1,12 +1,12 @@ -#ifndef _VIDEO_TD_H -#define _VIDEO_TD_H +#ifndef _VIDEO_LIB_H +#define _VIDEO_LIB_H #include #include #include #include -#include "../common/cs_types.h" -#include "dmx_lib.h" +#include "cs_types.h" +#include "dmx_hal.h" extern "C" { #include } @@ -60,7 +60,7 @@ typedef enum { DISPLAY_AR_14_9, DISPLAY_AR_16_9, DISPLAY_AR_20_9, - DISPLAY_AR_RAW, + DISPLAY_AR_RAW } DISPLAY_AR; typedef enum { @@ -104,7 +104,7 @@ typedef enum { /* not used, for dummy functions */ typedef enum { - VIDEO_HDMI_CEC_MODE_OFF = 0, + VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_RECORDER } VIDEO_HDMI_CEC_MODE; diff --git a/common/ca.h b/include/ca.h similarity index 100% rename from common/ca.h rename to include/ca.h diff --git a/common/ca_ci.h b/include/ca_ci.h similarity index 100% rename from common/ca_ci.h rename to include/ca_ci.h diff --git a/include/ca_cs.h b/include/ca_cs.h index f05f210..dae70d6 100644 --- a/include/ca_cs.h +++ b/include/ca_cs.h @@ -1 +1 @@ -#include "../common/ca.h" +#include "ca.h" diff --git a/include/cs_api.h b/include/cs_api.h index 58913c2..38ecf2c 100644 --- a/include/cs_api.h +++ b/include/cs_api.h @@ -1,20 +1,37 @@ +/* compatibility header for tripledragon. I'm lazy, so I just left it + as "cs_api.h" so that I don't need too many ifdefs in the code */ + +#ifndef __CS_API_H_ +#define __CS_API_H_ + +#include "init_td.h" #include -#if HAVE_TRIPLEDRAGON -#include "../libtriple/cs_api.h" -#elif HAVE_DUCKBOX_HARDWARE -#include "../libduckbox/cs_api.h" -#elif HAVE_SPARK_HARDWARE -#include "../libspark/cs_api.h" -#elif HAVE_ARM_HARDWARE -#include "../libarmbox/cs_api.h" -#elif HAVE_AZBOX_HARDWARE -#include "../azbox/cs_api.h" -#elif HAVE_GENERIC_HARDWARE -#if BOXMODEL_RASPI -#include "../raspi/cs_api.h" + +typedef void (*cs_messenger) (unsigned int msg, unsigned int data); + +inline void cs_api_init() +{ + init_td_api(); +}; + +inline void cs_api_exit() +{ + shutdown_td_api(); +}; + +#define cs_malloc_uncached malloc +#define cs_free_uncached free + +// Callback function helpers +#if HAVE_DUCKBOX_HARDWARE || HAVE_ARM_HARDWARE +void cs_register_messenger(cs_messenger messenger); #else -#include "../generic-pc/cs_api.h" -#endif -#else -#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined +static inline void cs_register_messenger(cs_messenger) { return; }; #endif +static inline void cs_deregister_messenger(void) { return; }; + +/* compat... HD1 seems to be version 6. everything newer ist > 6... */ +static inline unsigned int cs_get_revision(void) { return 1; }; +static inline unsigned int cs_get_chip_type(void) { return 0; }; +extern int cnxt_debug; +#endif //__CS_API_H_ diff --git a/common/cs_types.h b/include/cs_types.h similarity index 100% rename from common/cs_types.h rename to include/cs_types.h diff --git a/include/dmx_hal.h b/include/dmx_hal.h index db8ca72..4463b70 100644 --- a/include/dmx_hal.h +++ b/include/dmx_hal.h @@ -1,20 +1,97 @@ -#include -#if HAVE_TRIPLEDRAGON -#include "../libtriple/dmx_td.h" -#elif HAVE_DUCKBOX_HARDWARE -#include "../libduckbox/dmx_lib.h" -#elif HAVE_SPARK_HARDWARE -#include "../libspark/dmx_lib.h" -#elif HAVE_AZBOX_HARDWARE -#include "../azbox/dmx_lib.h" -#elif HAVE_ARM_HARDWARE -#include "../libarmbox/dmx_lib.h" -#elif HAVE_GENERIC_HARDWARE -#if BOXMODEL_RASPI -#include "../raspi/dmx_lib.h" -#else -#include "../generic-pc/dmx_lib.h" -#endif -#else -#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined +/* + * (C) 2010-2013 Stefan Seyfried + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __dmx_hal__ +#define __dmx_hal__ + +#include +#include +#include +/* at least on td, config.h needs to be included before... */ +#ifndef HAVE_TRIPLEDRAGON +#include +#else /* TRIPLEDRAGON */ +extern "C" { +#include +} +#if defined DMX_FILTER_SIZE +#undef DMX_FILTER_SIZE #endif +#define DMX_FILTER_SIZE FILTER_LENGTH +#endif /* TRIPLEDRAGON */ + +#include + +#define MAX_DMX_UNITS 4 + +typedef enum +{ + DMX_INVALID = 0, + DMX_VIDEO_CHANNEL = 1, + DMX_AUDIO_CHANNEL, + DMX_PES_CHANNEL, + DMX_PSI_CHANNEL, + DMX_PIP_CHANNEL, + DMX_TP_CHANNEL, + DMX_PCR_ONLY_CHANNEL +} DMX_CHANNEL_TYPE; + +typedef struct +{ + int fd; + unsigned short pid; +} pes_pids; + +class cRecord; +class cPlayback; +class cDemux +{ + friend class cRecord; + friend class cPlayback; + public: + bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); + void Close(void); + bool Start(bool record = false); + bool Stop(void); + int Read(unsigned char *buff, int len, int Timeout = 0); + bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); + bool pesFilter(const unsigned short pid); + void SetSyncMode(AVSYNC_TYPE mode); + void * getBuffer(); + void * getChannel(); + DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; + bool addPid(unsigned short pid); + void getSTC(int64_t * STC); + int getUnit(void); + static bool SetSource(int unit, int source); + static int GetSource(int unit); + int getFD(void) { return fd; }; /* needed by cPlayback class */ + cDemux(int num = 0); + ~cDemux(); + private: + void removePid(unsigned short Pid); /* needed by cRecord class */ + int num; + int fd; + int buffersize; + uint16_t pid; + uint8_t flt; + std::vector pesfds; + DMX_CHANNEL_TYPE dmx_type; + void *pdata; +}; + +#endif //__dmx_hal__ diff --git a/include/mmi.h b/include/mmi.h index 4f89482..afbf226 100644 --- a/include/mmi.h +++ b/include/mmi.h @@ -6,7 +6,7 @@ #define MAX_MMI_CHOICE_TEXT_LEN 255 typedef enum { - MMI_TOP_MENU_SUBS = 1, + MMI_TOP_MENU_SUBS = 1, MMI_TOP_MENU_EVENTS, MMI_TOP_MENU_TOKENS, MMI_TOP_MENU_PIN, @@ -15,13 +15,13 @@ typedef enum { } MMI_MENU_CURRENT; typedef enum { - MMI_MENU_LEVEL_MAIN = 0, + MMI_MENU_LEVEL_MAIN = 0, MMI_MENU_LEVEL_MATURE, MMI_MENU_LEVEL_ASK_PIN_MATURE } MMI_MENU_LEVEL; typedef enum { - MMI_PIN_LEVEL_ASK_OLD = 0, + MMI_PIN_LEVEL_ASK_OLD = 0, MMI_PIN_LEVEL_CHECK_CURRENT, MMI_PIN_LEVEL_ASK_REPEAT, MMI_PIN_LEVEL_CHECK_AND_CHANGE @@ -44,7 +44,7 @@ typedef struct { } MMI_ENQUIRY_INFO; /* compat */ -#define enguiryText enquiryText +#define enguiryText enquiryText #define MMI_ENGUIRY_INFO MMI_ENQUIRY_INFO #endif // __MMI_H_ diff --git a/libarmbox/Makefile.am b/libarmbox/Makefile.am index a9b63b3..227f506 100644 --- a/libarmbox/Makefile.am +++ b/libarmbox/Makefile.am @@ -1,7 +1,6 @@ noinst_LTLIBRARIES = libarmbox.la -AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -AM_CPPFLAGS += \ +AM_CPPFLAGS = \ -I$(top_srcdir)/common \ -I$(top_srcdir)/include @@ -13,7 +12,7 @@ AM_LDFLAGS = \ @AVUTIL_LIBS@ \ @AVCODEC_LIBS@ \ @SWRESAMPLE_LIBS@ \ - -lpthread -lasound -lrt + -lpthread -lass -lrt libarmbox_la_SOURCES = \ hardware_caps.c \ @@ -42,3 +41,5 @@ AM_CPPFLAGS += \ AM_LDFLAGS += \ -lass endif + +AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/libarmbox/audio.cpp b/libarmbox/audio.cpp index 79470a5..8265447 100644 --- a/libarmbox/audio.cpp +++ b/libarmbox/audio.cpp @@ -9,8 +9,8 @@ #include #include + #include "audio_lib.h" -//#include "audio_mixer.h" #include "lt_debug.h" #define AUDIO_DEVICE "/dev/dvb/adapter0/audio0" @@ -26,7 +26,6 @@ cAudio::cAudio(void *, void *, void *) fd = -1; clipfd = -1; mixer_fd = -1; - openDevice(); Muted = false; } @@ -147,8 +146,6 @@ void cAudio::SetSyncMode(AVSYNC_TYPE Mode) ioctl(fd, AUDIO_SET_AV_SYNC, Mode); } -// E2 streamtype values. These correspond to -// player2/linux/drivers/media/dvb/stm/dvb/dvb_audio.c:AudioIoctlSetBypassMode #define AUDIO_STREAMTYPE_AC3 0 #define AUDIO_STREAMTYPE_MPEG 1 #define AUDIO_STREAMTYPE_DTS 2 diff --git a/libarmbox/audio_lib.h b/libarmbox/audio_lib.h index 5aad2f5..1fb896f 100644 --- a/libarmbox/audio_lib.h +++ b/libarmbox/audio_lib.h @@ -1,8 +1,9 @@ /* public header file */ -#ifndef _AUDIO_TD_H_ -#define _AUDIO_TD_H_ -#include "../common/cs_types.h" +#ifndef _AUDIO_LIB_H_ +#define _AUDIO_LIB_H_ + +#include "cs_types.h" typedef enum { diff --git a/libarmbox/cs_api.h b/libarmbox/cs_api.h deleted file mode 100644 index 1532284..0000000 --- a/libarmbox/cs_api.h +++ /dev/null @@ -1,67 +0,0 @@ -/* compatibility header for tripledragon. I'm lazy, so I just left it - as "cs_api.h" so that I don't need too many ifdefs in the code */ - -#ifndef __CS_API_H_ -#define __CS_API_H_ - -#include "init_lib.h" -typedef void (*cs_messenger) (unsigned int msg, unsigned int data); - -#if 0 -enum CS_LOG_MODULE { - CS_LOG_CI = 0, - CS_LOG_HDMI_CEC, - CS_LOG_HDMI, - CS_LOG_VIDEO, - CS_LOG_VIDEO_DRM, - CS_LOG_AUDIO, - CS_LOG_DEMUX, - CS_LOG_DENC, - CS_LOG_PVR_RECORD, - CS_LOG_PVR_PLAY, - CS_LOG_POWER_CTRL, - CS_LOG_POWER_CLK, - CS_LOG_MEM, - CS_LOG_API, -}; -#endif - -inline void cs_api_init() -{ - init_td_api(); -}; - -inline void cs_api_exit() -{ - shutdown_td_api(); -}; - -#define cs_malloc_uncached malloc -#define cs_free_uncached free - -// Callback function helpers -void cs_register_messenger(cs_messenger messenger); -static inline void cs_deregister_messenger(void) { return; }; -//cs_messenger cs_get_messenger(void); - -#if 0 -// Logging functions -void cs_log_enable(void); -void cs_log_disable(void); -void cs_log_message(const char *prefix, const char *fmt, ...); -void cs_log_module_enable(enum CS_LOG_MODULE module); -void cs_log_module_disable(enum CS_LOG_MODULE module); -void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...); - -// TS Routing -unsigned int cs_get_ts_output(void); -int cs_set_ts_output(unsigned int port); - -// Serial nr and revision accessors -unsigned long long cs_get_serial(void); -#endif -/* compat... HD1 seems to be version 6. everything newer ist > 6... */ -static inline unsigned int cs_get_revision(void) { return 1; }; -static inline unsigned int cs_get_chip_type(void) { return 0; }; -extern int cnxt_debug; -#endif //__CS_API_H_ diff --git a/libarmbox/dmx.cpp b/libarmbox/dmx.cpp index dbd5ef4..10f2f32 100644 --- a/libarmbox/dmx.cpp +++ b/libarmbox/dmx.cpp @@ -31,7 +31,10 @@ #include #include #include -#include "dmx_lib.h" +#include +#include +#include +#include "dmx_hal.h" #include "lt_debug.h" #include "video_lib.h" @@ -40,21 +43,19 @@ extern cVideo *videoDecoder; #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) +#define lt_debug_c(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) +#define lt_info_z(args...) _lt_info(TRIPLE_DEBUG_DEMUX, thiz, args) +#define lt_debug_z(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, thiz, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; cDemux *audioDemux = NULL; +//cDemux *pcrDemux = NULL; static const char *DMX_T[] = { "DMX_INVALID", @@ -88,6 +89,12 @@ static const char *devname[NUM_DEMUXDEV] = { /* did we already DMX_SET_SOURCE on that demux device? */ static bool init[NUM_DEMUXDEV] = { false, false, false, false, false, false, false, false }; +typedef struct dmx_pdata { + int last_source; + OpenThreads::Mutex *mutex; +} dmx_pdata; +#define P ((dmx_pdata *)pdata) + cDemux::cDemux(int n) { if (n < 0 || n >= NUM_DEMUX) @@ -98,16 +105,22 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; - last_source = -1; + pdata = (void *)calloc(1, sizeof(dmx_pdata)); + P->last_source = -1; + P->mutex = new OpenThreads::Mutex; + dmx_type = DMX_INVALID; } cDemux::~cDemux() { lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd); Close(); + /* wait until Read() has released the mutex */ + (*P->mutex).lock(); + (*P->mutex).unlock(); + free(P->mutex); + free(pdata); + pdata = NULL; } bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize) @@ -122,18 +135,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe return true; } -bool cDemux::_open(void) +static bool _open(cDemux *thiz, int num, int &fd, int &last_source, DMX_CHANNEL_TYPE dmx_type, int buffersize) { int flags = O_RDWR|O_CLOEXEC; int devnum = dmx_source[num]; if (last_source == devnum) { - lt_debug("%s #%d: source (%d) did not change\n", __func__, num, last_source); + lt_debug_z("%s #%d: source (%d) did not change\n", __func__, num, last_source); if (fd > -1) return true; } if (fd > -1) { /* we changed source -> close and reopen the fd */ - lt_debug("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", + lt_debug_z("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", __func__, num, fd, last_source, devnum); close(fd); } @@ -144,10 +157,10 @@ bool cDemux::_open(void) fd = open(devname[devnum], flags); if (fd < 0) { - lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); + lt_info_z("%s %s: %m\n", __FUNCTION__, devname[devnum]); return false; } - lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, + lt_debug_z("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, num, DMX_T[dmx_type], dmx_type, buffersize, fd); /* this would actually need locking, but the worst that weill happen is, that @@ -156,9 +169,9 @@ bool cDemux::_open(void) { /* this should not change anything... */ int n = DMX_SOURCE_FRONT0 + devnum; - lt_info("%s: setting %s to source %d\n", __func__, devname[devnum], n); + lt_info_z("%s: setting %s to source %d\n", __func__, devname[devnum], n); if (ioctl(fd, DMX_SET_SOURCE, &n) < 0) - lt_info("%s DMX_SET_SOURCE failed!\n", __func__); + lt_info_z("%s DMX_SET_SOURCE failed!\n", __func__); else init[devnum] = true; } @@ -168,7 +181,7 @@ bool cDemux::_open(void) { /* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */ if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0) - lt_info("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); + lt_info_z("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); } last_source = devnum; @@ -188,12 +201,11 @@ void cDemux::Close(void) ioctl(fd, DMX_STOP); close(fd); fd = -1; - if (measure) - return; } bool cDemux::Start(bool) { + lt_debug("%s #%d fd: %d type: %s\n", __func__, num, fd, DMX_T[dmx_type]); if (fd < 0) { lt_info("%s #%d: not open!\n", __FUNCTION__, num); @@ -205,6 +217,7 @@ bool cDemux::Start(bool) bool cDemux::Stop(void) { + lt_debug("%s #%d fd: %d type: %s\n", __func__, num, fd, DMX_T[dmx_type]); if (fd < 0) { lt_info("%s #%d: not open!\n", __FUNCTION__, num); @@ -226,6 +239,8 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) lt_info("%s #%d: not open!\n", __func__, num); return -1; } + /* avoid race in destructor: ~cDemux needs to wait until Read() returns */ + OpenThreads::ScopedLock m_lock(*P->mutex); int rc; int to = timeout; struct pollfd ufds; @@ -243,6 +258,12 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) { retry: rc = ::poll(&ufds, 1, to); + if (ufds.fd != fd) + { + /* Close() will set fd to -1, this is normal. Everything else is not. */ + lt_info("%s:1 ========== fd has changed, %d->%d ==========\n", __func__, ufds.fd, fd); + return -1; + } if (!rc) { if (timeout == 0) /* we took the emergency exit */ @@ -280,6 +301,11 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return 0; } } + if (ufds.fd != fd) /* does this ever happen? and if, is it harmful? */ + { /* read(-1,...) will just return EBADF anyway... */ + lt_info("%s:2 ========== fd has changed, %d->%d ==========\n", __func__, ufds.fd, fd); + return -1; + } rc = ::read(fd, buff, len); //fprintf(stderr, "fd %d ret: %d\n", fd, rc); @@ -289,19 +315,22 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { + struct dmx_sct_filter_params s_flt; memset(&s_flt, 0, sizeof(s_flt)); + pid = _pid; - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); if (len > DMX_FILTER_SIZE) { lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); len = DMX_FILTER_SIZE; } + flt = filter[0]; s_flt.pid = pid; s_flt.timeout = timeout; memcpy(s_flt.filter.filter, filter, len); @@ -312,79 +341,80 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC; int to = 0; - switch (filter[0]) { - case 0x00: /* program_association_section */ - to = 2000; - break; - case 0x01: /* conditional_access_section */ - to = 6000; - break; - case 0x02: /* program_map_section */ - to = 1500; - break; - case 0x03: /* transport_stream_description_section */ - to = 10000; - break; - /* 0x04 - 0x3F: reserved */ - case 0x40: /* network_information_section - actual_network */ - to = 10000; - break; - case 0x41: /* network_information_section - other_network */ - to = 15000; - break; - case 0x42: /* service_description_section - actual_transport_stream */ - to = 10000; - break; - /* 0x43 - 0x45: reserved for future use */ - case 0x46: /* service_description_section - other_transport_stream */ - to = 10000; - break; - /* 0x47 - 0x49: reserved for future use */ - case 0x4A: /* bouquet_association_section */ - to = 11000; - break; - /* 0x4B - 0x4D: reserved for future use */ - case 0x4E: /* event_information_section - actual_transport_stream, present/following */ - to = 2000; - break; - case 0x4F: /* event_information_section - other_transport_stream, present/following */ - to = 10000; - break; - /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ - /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ - case 0x70: /* time_date_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - s_flt.flags |= DMX_ONESHOT; - //s_flt.pid = 0x0014; - to = 30000; - break; - case 0x71: /* running_status_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x72: /* stuffing_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x73: /* time_offset_section */ - s_flt.flags |= DMX_ONESHOT; - //s_flt.pid = 0x0014; - to = 30000; - break; - /* 0x74 - 0x7D: reserved for future use */ - case 0x7E: /* discontinuity_information_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x7F: /* selection_information_section */ - to = 0; - break; - /* 0x80 - 0x8F: ca_message_section */ - /* 0x90 - 0xFE: user defined */ - /* 0xFF: reserved */ - default: - break; -// return -1; + switch (filter[0]) + { + case 0x00: /* program_association_section */ + to = 2000; + break; + case 0x01: /* conditional_access_section */ + to = 6000; + break; + case 0x02: /* program_map_section */ + to = 1500; + break; + case 0x03: /* transport_stream_description_section */ + to = 10000; + break; + /* 0x04 - 0x3F: reserved */ + case 0x40: /* network_information_section - actual_network */ + to = 10000; + break; + case 0x41: /* network_information_section - other_network */ + to = 15000; + break; + case 0x42: /* service_description_section - actual_transport_stream */ + to = 10000; + break; + /* 0x43 - 0x45: reserved for future use */ + case 0x46: /* service_description_section - other_transport_stream */ + to = 10000; + break; + /* 0x47 - 0x49: reserved for future use */ + case 0x4A: /* bouquet_association_section */ + to = 11000; + break; + /* 0x4B - 0x4D: reserved for future use */ + case 0x4E: /* event_information_section - actual_transport_stream, present/following */ + to = 2000; + break; + case 0x4F: /* event_information_section - other_transport_stream, present/following */ + to = 10000; + break; + /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ + /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ + case 0x70: /* time_date_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + s_flt.flags |= DMX_ONESHOT; + //s_flt.pid = 0x0014; + to = 30000; + break; + case 0x71: /* running_status_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x72: /* stuffing_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x73: /* time_offset_section */ + s_flt.flags |= DMX_ONESHOT; + //s_flt.pid = 0x0014; + to = 30000; + break; + /* 0x74 - 0x7D: reserved for future use */ + case 0x7E: /* discontinuity_information_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x7F: /* selection_information_section */ + to = 0; + break; + /* 0x80 - 0x8F: ca_message_section */ + /* 0x90 - 0xFE: user defined */ + /* 0xFF: reserved */ + default: + //return -1; + break; } /* the negmask == NULL is a hack: the users of negmask are PMT-update * and sectionsd EIT-Version change. And they really want no timeout @@ -406,8 +436,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + struct dmx_pes_filter_params p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... @@ -419,7 +452,7 @@ bool cDemux::pesFilter(const unsigned short pid) lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); memset(&p_flt, 0, sizeof(p_flt)); p_flt.pid = pid; @@ -427,30 +460,31 @@ bool cDemux::pesFilter(const unsigned short pid) p_flt.input = DMX_IN_FRONTEND; p_flt.flags = 0; - switch (dmx_type) { - case DMX_PCR_ONLY_CHANNEL: - p_flt.pes_type = DMX_PES_PCR; - break; - case DMX_AUDIO_CHANNEL: - p_flt.pes_type = DMX_PES_AUDIO; - break; - case DMX_VIDEO_CHANNEL: - p_flt.pes_type = DMX_PES_VIDEO; - break; - case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ - p_flt.pes_type = DMX_PES_VIDEO1; - break; - case DMX_PES_CHANNEL: - p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TAP; - break; - case DMX_TP_CHANNEL: - p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TSDEMUX_TAP; - break; - default: - lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); - return false; + switch (dmx_type) + { + case DMX_PCR_ONLY_CHANNEL: + p_flt.pes_type = DMX_PES_PCR; + break; + case DMX_AUDIO_CHANNEL: + p_flt.pes_type = DMX_PES_AUDIO; + break; + case DMX_VIDEO_CHANNEL: + p_flt.pes_type = DMX_PES_VIDEO; + break; + case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ + p_flt.pes_type = DMX_PES_VIDEO1; + break; + case DMX_PES_CHANNEL: + p_flt.pes_type = DMX_PES_OTHER; + p_flt.output = DMX_OUT_TAP; + break; + case DMX_TP_CHANNEL: + p_flt.pes_type = DMX_PES_OTHER; + p_flt.output = DMX_OUT_TSDEMUX_TAP; + break; + default: + lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); + return false; } return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0); } @@ -482,7 +516,7 @@ bool cDemux::addPid(unsigned short Pid) lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); return false; } - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); if (fd == -1) lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); pfd.fd = fd; /* dummy */ @@ -540,7 +574,7 @@ bool cDemux::SetSource(int unit, int source) lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); return false; } - lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); + lt_debug_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); if (source < 0 || source >= NUM_DEMUXDEV) lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source); else @@ -554,6 +588,6 @@ int cDemux::GetSource(int unit) lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); return -1; } - lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); + lt_debug_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); return dmx_source[unit]; } diff --git a/libarmbox/dmx_cs.h b/libarmbox/dmx_cs.h deleted file mode 100644 index 175d8cb..0000000 --- a/libarmbox/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -#include "dmx_lib.h" diff --git a/libarmbox/dmx_lib.h b/libarmbox/dmx_lib.h deleted file mode 100644 index af87a02..0000000 --- a/libarmbox/dmx_lib.h +++ /dev/null @@ -1,72 +0,0 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H - -#include -#include -#include -#include -#include -#include "../common/cs_types.h" - -#define MAX_DMX_UNITS 4 - -typedef enum -{ - DMX_INVALID = 0, - DMX_VIDEO_CHANNEL = 1, - DMX_AUDIO_CHANNEL, - DMX_PES_CHANNEL, - DMX_PSI_CHANNEL, - DMX_PIP_CHANNEL, - DMX_TP_CHANNEL, - DMX_PCR_ONLY_CHANNEL -} DMX_CHANNEL_TYPE; - -typedef struct -{ - int fd; - unsigned short pid; -} pes_pids; - -class cDemux -{ - private: - int num; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct dmx_sct_filter_params s_flt; - struct dmx_pes_filter_params p_flt; - int last_source; - bool _open(void); - public: - - bool Open(DMX_CHANNEL_TYPE pes_type, void * unused = NULL, int bufsize = 0); - void Close(void); - bool Start(bool record = false); - bool Stop(void); - int Read(unsigned char *buff, int len, int Timeout = 0); - bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); - bool pesFilter(const unsigned short pid); - void SetSyncMode(AVSYNC_TYPE mode); - void * getBuffer(); - void * getChannel(); - DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; - bool addPid(unsigned short pid); - void getSTC(int64_t * STC); - int getUnit(void); - static bool SetSource(int unit, int source); - static int GetSource(int unit); - // TD only functions - int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // - cDemux(int num = 0); - ~cDemux(); -}; - -#endif //__DEMUX_H diff --git a/libarmbox/init.cpp b/libarmbox/init.cpp index 26b98c7..f7374d1 100644 --- a/libarmbox/init.cpp +++ b/libarmbox/init.cpp @@ -1,6 +1,5 @@ #include -#include "init_lib.h" #include #include #include @@ -9,6 +8,7 @@ #include #include +#include "init_td.h" #include "pwrmngr.h" #include diff --git a/libarmbox/init_cs.h b/libarmbox/init_cs.h deleted file mode 100644 index 7f9e341..0000000 --- a/libarmbox/init_cs.h +++ /dev/null @@ -1,2 +0,0 @@ -#warning using init_cs.h from libspark -#include "init_lib.h" diff --git a/libarmbox/init_lib.h b/libarmbox/init_lib.h deleted file mode 100644 index d9a6f09..0000000 --- a/libarmbox/init_lib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/libarmbox/record.cpp b/libarmbox/record.cpp index cae962b..b411e34 100644 --- a/libarmbox/record.cpp +++ b/libarmbox/record.cpp @@ -1,3 +1,19 @@ +/* + * (C) + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ #include #include #include @@ -8,6 +24,7 @@ #include #include +#include #include #include "record_lib.h" @@ -15,7 +32,7 @@ #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) -/* helper functions to call the cpp thread loops */ +/* helper function to call the cpp thread loop */ void *execute_record_thread(void *c) { cRecord *obj = (cRecord *)c; @@ -137,7 +154,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; /* the first PID is the video pid, so start with the second PID... */ for (std::vector::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { found = false; @@ -173,7 +190,7 @@ bool cRecord::AddPid(unsigned short pid) lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; for (std::vector::const_iterator i = pids.begin(); i != pids.end(); ++i) { if ((*i).pid == pid) return true; /* or is it an error to try to add the same PID twice? */ @@ -214,7 +231,7 @@ void cRecord::RecordThread() strncpy(threadname, "RecordThread", sizeof(threadname)); threadname[16] = 0; prctl (PR_SET_NAME, (unsigned long)&threadname); - int readsize = bufsize/16; + int readsize = bufsize / 16; int buf_pos = 0; int count = 0; int queued = 0; @@ -257,13 +274,15 @@ void cRecord::RecordThread() if (toread > readsize) toread = readsize; ssize_t s = dmx->Read(buf + buf_pos, toread, 50); - lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, buf_pos, (int)s, bufsize - buf_pos); + lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, + buf_pos, (int)s, bufsize - buf_pos); if (s < 0) { if (errno != EAGAIN && (errno != EOVERFLOW || !overflow)) { lt_info("%s: read failed: %m\n", __func__); exit_flag = RECORD_FAILED_READ; + state = REC_STATUS_OVERFLOW; break; } } @@ -289,6 +308,7 @@ void cRecord::RecordThread() overflow = true; if (!(overflow_count % 10)) lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count); + state = REC_STATUS_SLOW; } r = aio_error(&a); if (r == EINPROGRESS) diff --git a/libarmbox/record_lib.h b/libarmbox/record_lib.h index 5ff453e..75bb988 100644 --- a/libarmbox/record_lib.h +++ b/libarmbox/record_lib.h @@ -1,9 +1,8 @@ -#ifndef __RECORD_TD_H -#define __RECORD_TD_H +#ifndef __record_hal__ +#define __record_hal__ -#include #include -#include "dmx_lib.h" +#include "dmx_hal.h" #define REC_STATUS_OK 0 #define REC_STATUS_SLOW 1 diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 482ddc5..360b58c 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -478,30 +478,6 @@ int cVideo::setBlank(int) return Stop(1); } -int cVideo::GetVideoSystem(void) -{ - char current[32]; - proc_get("/proc/stb/video/videomode", current, 32); - for (int i = 0; vid_modes[i]; i++) - { - if (strcmp(current, vid_modes[i]) == 0) - return i; - } - lt_info("%s: could not find '%s' mode, returning VIDEO_STD_720P50\n", __func__, current); - return VIDEO_STD_720P50; -} - -void cVideo::GetVideoSystemFormatName(cs_vs_format_t *format, int system) -{ - if (system == -1) - system = GetVideoSystem(); - if (system < 0 || system > VIDEO_STD_1080P50) { - lt_info("%s: invalid system %d\n", __func__, system); - strcpy(format->format, "invalid"); - } else - strcpy(format->format, vid_modes[system]); -} - int cVideo::SetVideoSystem(int video_system, bool remember) { lt_debug("%s(%d, %d)\n", __func__, video_system, remember); @@ -533,6 +509,30 @@ int cVideo::SetVideoSystem(int video_system, bool remember) return ret; } +int cVideo::GetVideoSystem(void) +{ + char current[32]; + proc_get("/proc/stb/video/videomode", current, 32); + for (int i = 0; vid_modes[i]; i++) + { + if (strcmp(current, vid_modes[i]) == 0) + return i; + } + lt_info("%s: could not find '%s' mode, returning VIDEO_STD_720P50\n", __func__, current); + return VIDEO_STD_720P50; +} + +void cVideo::GetVideoSystemFormatName(cs_vs_format_t *format, int system) +{ + if (system == -1) + system = GetVideoSystem(); + if (system < 0 || system > VIDEO_STD_1080P50) { + lt_info("%s: invalid system %d\n", __func__, system); + strcpy(format->format, "invalid"); + } else + strcpy(format->format, vid_modes[system]); +} + int cVideo::getPlayState(void) { return playstate; diff --git a/libarmbox/video_lib.h b/libarmbox/video_lib.h index 09aba61..1631cb4 100644 --- a/libarmbox/video_lib.h +++ b/libarmbox/video_lib.h @@ -1,9 +1,9 @@ -#ifndef _VIDEO_TD_H -#define _VIDEO_TD_H +#ifndef _VIDEO_LIB_H +#define _VIDEO_LIB_H #include -#include "../common/cs_types.h" -#include "dmx_lib.h" +#include "cs_types.h" +#include "dmx_hal.h" typedef struct cs_vs_format_t { @@ -119,7 +119,7 @@ typedef enum { } VIDEO_STD; typedef enum { - VIDEO_HDMI_CEC_MODE_OFF = 0, + VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_TUNER = 3, VIDEO_HDMI_CEC_MODE_RECORDER = 1 } VIDEO_HDMI_CEC_MODE; @@ -148,10 +148,13 @@ struct addressinfo unsigned char type; }; +class cDemux; +class cPlayback; + class cVideo { - friend class cDemux; friend class cPlayback; + friend class cDemux; private: /* video device */ int fd; diff --git a/libduckbox/Makefile.am b/libduckbox/Makefile.am index ce5df2e..2568f0b 100644 --- a/libduckbox/Makefile.am +++ b/libduckbox/Makefile.am @@ -1,7 +1,6 @@ noinst_LTLIBRARIES = libduckbox.la -AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -AM_CPPFLAGS += \ +AM_CPPFLAGS = \ -I$(top_srcdir)/common \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libeplayer3/include @@ -25,3 +24,5 @@ libduckbox_la_SOURCES = \ playback_libeplayer3.cpp \ pwrmngr.cpp \ record.cpp + +AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/libduckbox/cs_api.h b/libduckbox/cs_api.h deleted file mode 100644 index 1082ab7..0000000 --- a/libduckbox/cs_api.h +++ /dev/null @@ -1,31 +0,0 @@ -/* compatibility header for tripledragon. I'm lazy, so I just left it - as "cs_api.h" so that I don't need too many ifdefs in the code */ - -#ifndef __CS_API_H_ -#define __CS_API_H_ - -#include "init_lib.h" -typedef void (*cs_messenger) (unsigned int msg, unsigned int data); - -inline void cs_api_init() -{ - init_td_api(); -}; - -inline void cs_api_exit() -{ - shutdown_td_api(); -}; - -#define cs_malloc_uncached malloc -#define cs_free_uncached free - -// Callback function helpers -void cs_register_messenger(cs_messenger messenger); -static inline void cs_deregister_messenger(void) { return; }; - -/* compat... HD1 seems to be version 6. everything newer ist > 6... */ -static inline unsigned int cs_get_revision(void) { return 1; }; -static inline unsigned int cs_get_chip_type(void) { return 0; }; -extern int cnxt_debug; -#endif //__CS_API_H_ diff --git a/libduckbox/dmx_cs.h b/libduckbox/dmx_cs.h deleted file mode 120000 index ff27353..0000000 --- a/libduckbox/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/dmx_cs.h \ No newline at end of file diff --git a/libduckbox/dmx_lib.h b/libduckbox/dmx_lib.h deleted file mode 120000 index a04eec1..0000000 --- a/libduckbox/dmx_lib.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/dmx_lib.h \ No newline at end of file diff --git a/libduckbox/init.cpp b/libduckbox/init.cpp index 41358e5..f429afe 100644 --- a/libduckbox/init.cpp +++ b/libduckbox/init.cpp @@ -1,6 +1,5 @@ #include -#include "init_lib.h" #include #include #include @@ -11,6 +10,7 @@ #include +#include "init_td.h" #include "pwrmngr.h" #include "lt_debug.h" diff --git a/libduckbox/init_cs.h b/libduckbox/init_cs.h deleted file mode 120000 index 359b1d6..0000000 --- a/libduckbox/init_cs.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/init_cs.h \ No newline at end of file diff --git a/libduckbox/init_lib.h b/libduckbox/init_lib.h deleted file mode 120000 index 8726e66..0000000 --- a/libduckbox/init_lib.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/init_lib.h \ No newline at end of file diff --git a/libspark/Makefile.am b/libspark/Makefile.am index 4b3e815..4864195 100644 --- a/libspark/Makefile.am +++ b/libspark/Makefile.am @@ -1,7 +1,6 @@ noinst_LTLIBRARIES = libspark.la -AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -AM_CPPFLAGS += \ +AM_CPPFLAGS = \ -I$(top_srcdir)/common \ -I$(top_srcdir)/include \ -I$(top_srcdir)/libeplayer3/include @@ -26,3 +25,5 @@ libspark_la_SOURCES = \ playback_libeplayer3.cpp \ pwrmngr.cpp \ record.cpp + +AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/libspark/README.libtriple b/libspark/README.libtriple deleted file mode 100644 index 89f65b7..0000000 --- a/libspark/README.libtriple +++ /dev/null @@ -1,72 +0,0 @@ -libtriple reimplements the interfaces of the libcoolstrem library for -the Tripledragon receiver. - -There are a few debugging or configuration helpers which affect the -way libtriple does some things. They are all configured by exporting -environment variables, which are described here: - -TRIPLE_NOSCART=1 - makes neutrino *not* do any voltage switching on - SCART pin 8, probably not useful for anyone but me - -TRIPLE_DEBUG=... - controls various debugging levels in libtriple - valid values for the different component: - audio 0x01 - video 0x02 - demux 0x04 - play 0x08 - power 0x10 - init 0x20 - ca 0x40 - record 0x80 - all 0xff - multiple levels are added / ORed together, so if you want to - debug record and playback code, do "export TRIPLE_DEBUG=0x88" - for audio & video use TRIPLE_DEBUG=0x3 - -DSP_DEVICE -MIX_DEVICE - alternative audio devices for the audioplayer and internet - radio. Those are used to output music to e.g. USB audio devices. - Here is what you need to do: - * look in /dev/sound which devices are already there. Probably - /dev/sound/dsp and /dev/sound/mixer, created by the tdoss driver - * make sure that the USB HC driver is loaded: - modprobe ohci-hcd - * load the USB audio driver: - modprobe audio - * plug in your USB audio device, check with "dmesg" that it is - recognised by the kernel - * look in /dev/sound which new devices are there. Probably it's - /dev/sound/dsp1 and /dev/sound/mixer1. If there are more - well - it's time to experiment ;) - * export DSP_DEVICE=/dev/sound/dsp1 and MIX_DEVICE=/dev/sound/mixer1 - (of course the devices you found in the last step) - * from the same shell you exported the variables, start neutrino - (make sure that an already running neutrino is stopped before you - do that) - * start the audioplayer, play a track. Look for log lines like - [LT:106b5788:audio ] PrepareClipPlay: dsp_dev /dev/sound/dsp1 mix_dev /dev/sound/mixer1 - * if it works - fine :-) - * if it does not work, look for: - PrepareClipPlay: DSP_DEVICE is set (/dev/sound/dsp1) but cannot be opened, fall back to /dev/sound/dsp - PrepareClipPlay: dsp_dev /dev/sound/dsp mix_dev /dev/sound/mixer1 - PrepareClipPlay: open mixer /dev/sound/mixer1 failed (No such file or directory) - * this basically means that the device is not there. Different errors - will get different messages - I cannot trigger those now, so you'll - need to find them out by yourself ;) - * another possible messag you may get is: - PrepareClipPlay: more than one mixer control: devmask 00000021 stereo 00000021 - This means that your device has more than one mixer. The set bit - numbers in the devmask are the different mixers, in this case - it would be number 0 and 5. To select one of those, export - MIX_NUMBER=5 or MIX_NUMBER=0 (this code is untested, there may - be bugs) - - So now I found out what devices to use, but how do I make that permanent? - That's easy: - * create or extend /etc/rcS.local with - modprobe ohci-hcd - modprobe audio - * create or extend /etc/profile.local with - export DSP_DEVICE=/dev/sound/dsp1 - export MIX_DEVICE=/dev/sound/mixer1 - * reboot. Enjoy. diff --git a/libspark/audio.cpp b/libspark/audio.cpp index 268377a..fed273a 100644 --- a/libspark/audio.cpp +++ b/libspark/audio.cpp @@ -9,6 +9,7 @@ #include #include + #include "audio_lib.h" #include "audio_mixer.h" #include "lt_debug.h" @@ -224,7 +225,7 @@ int cAudio::PrepareClipPlay(int ch, int srate, int bits, int little_endian) if ((!dsp_dev) || (access(dsp_dev, W_OK))) { if (dsp_dev) lt_info("%s: DSP_DEVICE is set (%s) but cannot be opened," - " fall back to /dev/dsp1\n", __func__, dsp_dev); + " fall back to /dev/dsp1\n", __func__, dsp_dev); dsp_dev = "/dev/dsp1"; } lt_info("%s: dsp_dev %s mix_dev %s\n", __func__, dsp_dev, mix_dev); /* NULL mix_dev is ok */ diff --git a/libspark/audio_lib.h b/libspark/audio_lib.h index b2b78d6..8622f52 100644 --- a/libspark/audio_lib.h +++ b/libspark/audio_lib.h @@ -2,7 +2,7 @@ #ifndef _AUDIO_TD_H_ #define _AUDIO_TD_H_ -#include "../common/cs_types.h" +#include "cs_types.h" typedef enum { diff --git a/libspark/cs_api.h b/libspark/cs_api.h deleted file mode 100644 index e4349dd..0000000 --- a/libspark/cs_api.h +++ /dev/null @@ -1,67 +0,0 @@ -/* compatibility header for tripledragon. I'm lazy, so I just left it - as "cs_api.h" so that I don't need too many ifdefs in the code */ - -#ifndef __CS_API_H_ -#define __CS_API_H_ - -#include "init_lib.h" -typedef void (*cs_messenger) (unsigned int msg, unsigned int data); - -#if 0 -enum CS_LOG_MODULE { - CS_LOG_CI = 0, - CS_LOG_HDMI_CEC, - CS_LOG_HDMI, - CS_LOG_VIDEO, - CS_LOG_VIDEO_DRM, - CS_LOG_AUDIO, - CS_LOG_DEMUX, - CS_LOG_DENC, - CS_LOG_PVR_RECORD, - CS_LOG_PVR_PLAY, - CS_LOG_POWER_CTRL, - CS_LOG_POWER_CLK, - CS_LOG_MEM, - CS_LOG_API, -}; -#endif - -inline void cs_api_init() -{ - init_td_api(); -}; - -inline void cs_api_exit() -{ - shutdown_td_api(); -}; - -#define cs_malloc_uncached malloc -#define cs_free_uncached free - -// Callback function helpers -static inline void cs_register_messenger(cs_messenger) { return; }; -static inline void cs_deregister_messenger(void) { return; }; -//cs_messenger cs_get_messenger(void); - -#if 0 -// Logging functions -void cs_log_enable(void); -void cs_log_disable(void); -void cs_log_message(const char *prefix, const char *fmt, ...); -void cs_log_module_enable(enum CS_LOG_MODULE module); -void cs_log_module_disable(enum CS_LOG_MODULE module); -void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...); - -// TS Routing -unsigned int cs_get_ts_output(void); -int cs_set_ts_output(unsigned int port); - -// Serial nr and revision accessors -unsigned long long cs_get_serial(void); -#endif -/* compat... HD1 seems to be version 6. everything newer ist > 6... */ -static inline unsigned int cs_get_revision(void) { return 1; }; -static inline unsigned int cs_get_chip_type(void) { return 0; }; -extern int cnxt_debug; -#endif //__CS_API_H_ diff --git a/libspark/dmx.cpp b/libspark/dmx.cpp index ec81e9a..68dc13e 100644 --- a/libspark/dmx.cpp +++ b/libspark/dmx.cpp @@ -66,9 +66,10 @@ #include #include #include +#include #include #include -#include "dmx_lib.h" +#include "dmx_hal.h" #include "lt_debug.h" #include "video_lib.h" @@ -77,17 +78,14 @@ extern cVideo *videoDecoder; #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) +#define lt_debug_c(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, NULL, args) #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) +#define lt_info_z(args...) _lt_info(TRIPLE_DEBUG_DEMUX, thiz, args) +#define lt_debug_z(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, thiz, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; @@ -137,11 +135,6 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; - last_source = -1; - pdata = (void *)calloc(1, sizeof(dmx_pdata)); P->last_source = -1; P->mutex = new OpenThreads::Mutex; @@ -172,18 +165,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe return true; } -bool cDemux::_open(void) +static bool _open(cDemux *thiz, int num, int &fd, int &last_source, DMX_CHANNEL_TYPE dmx_type, int buffersize) { int flags = O_RDWR|O_CLOEXEC; int devnum = dmx_source[num]; if (last_source == devnum) { - lt_debug("%s #%d: source (%d) did not change\n", __func__, num, last_source); + lt_debug_z("%s #%d: source (%d) did not change\n", __func__, num, last_source); if (fd > -1) return true; } if (fd > -1) { /* we changed source -> close and reopen the fd */ - lt_debug("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", + lt_debug_z("%s #%d: FD ALREADY OPENED fd = %d lastsource %d devnum %d\n", __func__, num, fd, last_source, devnum); close(fd); } @@ -194,10 +187,10 @@ bool cDemux::_open(void) fd = open(devname[devnum], flags); if (fd < 0) { - lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); + lt_info_z("%s %s: %m\n", __FUNCTION__, devname[devnum]); return false; } - lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, + lt_debug_z("%s #%d pes_type: %s(%d), uBufferSize: %d fd: %d\n", __func__, num, DMX_T[dmx_type], dmx_type, buffersize, fd); /* this would actually need locking, but the worst that weill happen is, that @@ -206,9 +199,9 @@ bool cDemux::_open(void) { /* this should not change anything... */ int n = DMX_SOURCE_FRONT0 + devnum; - lt_info("%s: setting %s to source %d\n", __func__, devname[devnum], n); + lt_info_z("%s: setting %s to source %d\n", __func__, devname[devnum], n); if (ioctl(fd, DMX_SET_SOURCE, &n) < 0) - lt_info("%s DMX_SET_SOURCE failed!\n", __func__); + lt_info_z("%s DMX_SET_SOURCE failed!\n", __func__); else init[devnum] = true; } @@ -218,7 +211,7 @@ bool cDemux::_open(void) { /* probably uBufferSize == 0 means "use default size". TODO: find a reasonable default */ if (ioctl(fd, DMX_SET_BUFFER_SIZE, buffersize) < 0) - lt_info("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); + lt_info_z("%s DMX_SET_BUFFER_SIZE failed (%m)\n", __func__); } last_source = devnum; @@ -238,8 +231,6 @@ void cDemux::Close(void) ioctl(fd, DMX_STOP); close(fd); fd = -1; - if (measure) - return; } bool cDemux::Start(bool) @@ -354,19 +345,22 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { + struct dmx_sct_filter_params s_flt; memset(&s_flt, 0, sizeof(s_flt)); + pid = _pid; - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); if (len > DMX_FILTER_SIZE) { lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); len = DMX_FILTER_SIZE; } + flt = filter[0]; s_flt.pid = pid; s_flt.timeout = timeout; memcpy(s_flt.filter.filter, filter, len); @@ -377,79 +371,80 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte s_flt.flags = DMX_IMMEDIATE_START|DMX_CHECK_CRC; int to = 0; - switch (filter[0]) { - case 0x00: /* program_association_section */ - to = 2000; - break; - case 0x01: /* conditional_access_section */ - to = 6000; - break; - case 0x02: /* program_map_section */ - to = 1500; - break; - case 0x03: /* transport_stream_description_section */ - to = 10000; - break; - /* 0x04 - 0x3F: reserved */ - case 0x40: /* network_information_section - actual_network */ - to = 10000; - break; - case 0x41: /* network_information_section - other_network */ - to = 15000; - break; - case 0x42: /* service_description_section - actual_transport_stream */ - to = 10000; - break; - /* 0x43 - 0x45: reserved for future use */ - case 0x46: /* service_description_section - other_transport_stream */ - to = 10000; - break; - /* 0x47 - 0x49: reserved for future use */ - case 0x4A: /* bouquet_association_section */ - to = 11000; - break; - /* 0x4B - 0x4D: reserved for future use */ - case 0x4E: /* event_information_section - actual_transport_stream, present/following */ - to = 2000; - break; - case 0x4F: /* event_information_section - other_transport_stream, present/following */ - to = 10000; - break; - /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ - /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ - case 0x70: /* time_date_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - s_flt.flags |= DMX_ONESHOT; - //s_flt.pid = 0x0014; - to = 30000; - break; - case 0x71: /* running_status_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x72: /* stuffing_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x73: /* time_offset_section */ - s_flt.flags |= DMX_ONESHOT; - //s_flt.pid = 0x0014; - to = 30000; - break; - /* 0x74 - 0x7D: reserved for future use */ - case 0x7E: /* discontinuity_information_section */ - s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ - to = 0; - break; - case 0x7F: /* selection_information_section */ - to = 0; - break; - /* 0x80 - 0x8F: ca_message_section */ - /* 0x90 - 0xFE: user defined */ - /* 0xFF: reserved */ - default: - break; -// return -1; + switch (filter[0]) + { + case 0x00: /* program_association_section */ + to = 2000; + break; + case 0x01: /* conditional_access_section */ + to = 6000; + break; + case 0x02: /* program_map_section */ + to = 1500; + break; + case 0x03: /* transport_stream_description_section */ + to = 10000; + break; + /* 0x04 - 0x3F: reserved */ + case 0x40: /* network_information_section - actual_network */ + to = 10000; + break; + case 0x41: /* network_information_section - other_network */ + to = 15000; + break; + case 0x42: /* service_description_section - actual_transport_stream */ + to = 10000; + break; + /* 0x43 - 0x45: reserved for future use */ + case 0x46: /* service_description_section - other_transport_stream */ + to = 10000; + break; + /* 0x47 - 0x49: reserved for future use */ + case 0x4A: /* bouquet_association_section */ + to = 11000; + break; + /* 0x4B - 0x4D: reserved for future use */ + case 0x4E: /* event_information_section - actual_transport_stream, present/following */ + to = 2000; + break; + case 0x4F: /* event_information_section - other_transport_stream, present/following */ + to = 10000; + break; + /* 0x50 - 0x5F: event_information_section - actual_transport_stream, schedule */ + /* 0x60 - 0x6F: event_information_section - other_transport_stream, schedule */ + case 0x70: /* time_date_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + s_flt.flags |= DMX_ONESHOT; + //s_flt.pid = 0x0014; + to = 30000; + break; + case 0x71: /* running_status_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x72: /* stuffing_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x73: /* time_offset_section */ + s_flt.flags |= DMX_ONESHOT; + //s_flt.pid = 0x0014; + to = 30000; + break; + /* 0x74 - 0x7D: reserved for future use */ + case 0x7E: /* discontinuity_information_section */ + s_flt.flags &= ~DMX_CHECK_CRC; /* section has no CRC */ + to = 0; + break; + case 0x7F: /* selection_information_section */ + to = 0; + break; + /* 0x80 - 0x8F: ca_message_section */ + /* 0x90 - 0xFE: user defined */ + /* 0xFF: reserved */ + default: + //return -1; + break; } /* the negmask == NULL is a hack: the users of negmask are PMT-update * and sectionsd EIT-Version change. And they really want no timeout @@ -471,8 +466,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + struct dmx_pes_filter_params p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... @@ -484,38 +482,39 @@ bool cDemux::pesFilter(const unsigned short pid) lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); memset(&p_flt, 0, sizeof(p_flt)); - p_flt.pid = pid; + p_flt.pid = pid; p_flt.output = DMX_OUT_DECODER; p_flt.input = DMX_IN_FRONTEND; p_flt.flags = DMX_IMMEDIATE_START; - switch (dmx_type) { - case DMX_PCR_ONLY_CHANNEL: - p_flt.pes_type = DMX_PES_PCR; - break; - case DMX_AUDIO_CHANNEL: - p_flt.pes_type = DMX_PES_AUDIO; - break; - case DMX_VIDEO_CHANNEL: - p_flt.pes_type = DMX_PES_VIDEO; - break; - case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ - p_flt.pes_type = DMX_PES_VIDEO1; - break; - case DMX_PES_CHANNEL: - p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TAP; - break; - case DMX_TP_CHANNEL: - p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TSDEMUX_TAP; - break; - default: - lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); - return false; + switch (dmx_type) + { + case DMX_PCR_ONLY_CHANNEL: + p_flt.pes_type = DMX_PES_PCR; + break; + case DMX_AUDIO_CHANNEL: + p_flt.pes_type = DMX_PES_AUDIO; + break; + case DMX_VIDEO_CHANNEL: + p_flt.pes_type = DMX_PES_VIDEO; + break; + case DMX_PIP_CHANNEL: /* PIP is a special version of DMX_VIDEO_CHANNEL */ + p_flt.pes_type = DMX_PES_VIDEO1; + break; + case DMX_PES_CHANNEL: + p_flt.pes_type = DMX_PES_OTHER; + p_flt.output = DMX_OUT_TAP; + break; + case DMX_TP_CHANNEL: + p_flt.pes_type = DMX_PES_OTHER; + p_flt.output = DMX_OUT_TSDEMUX_TAP; + break; + default: + lt_info("%s #%d invalid dmx_type %d!\n", __func__, num, dmx_type); + return false; } return (ioctl(fd, DMX_SET_PES_FILTER, &p_flt) >= 0); } @@ -547,7 +546,7 @@ bool cDemux::addPid(unsigned short Pid) lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); return false; } - _open(); + _open(this, num, fd, P->last_source, dmx_type, buffersize); if (fd == -1) lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); pfd.fd = fd; /* dummy */ @@ -605,7 +604,7 @@ bool cDemux::SetSource(int unit, int source) lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); return false; } - lt_info_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); + lt_debug_c("%s(%d, %d) => %d to %d\n", __func__, unit, source, dmx_source[unit], source); if (source < 0 || source >= NUM_DEMUXDEV) lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source); else @@ -619,6 +618,6 @@ int cDemux::GetSource(int unit) lt_info_c("%s: unit (%d) out of range, NUM_DEMUX %d\n", __func__, unit, NUM_DEMUX); return -1; } - lt_info_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); + lt_debug_c("%s(%d) => %d\n", __func__, unit, dmx_source[unit]); return dmx_source[unit]; } diff --git a/libspark/dmx_cs.h b/libspark/dmx_cs.h deleted file mode 100644 index 175d8cb..0000000 --- a/libspark/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -#include "dmx_lib.h" diff --git a/libspark/dmx_lib.h b/libspark/dmx_lib.h deleted file mode 100644 index 056cb71..0000000 --- a/libspark/dmx_lib.h +++ /dev/null @@ -1,73 +0,0 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H - -#include -#include -#include -#include -#include -#include "../common/cs_types.h" - -#define MAX_DMX_UNITS 4 - -typedef enum -{ - DMX_INVALID = 0, - DMX_VIDEO_CHANNEL = 1, - DMX_AUDIO_CHANNEL, - DMX_PES_CHANNEL, - DMX_PSI_CHANNEL, - DMX_PIP_CHANNEL, - DMX_TP_CHANNEL, - DMX_PCR_ONLY_CHANNEL -} DMX_CHANNEL_TYPE; - -typedef struct -{ - int fd; - unsigned short pid; -} pes_pids; - -class cDemux -{ - private: - int num; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct dmx_sct_filter_params s_flt; - struct dmx_pes_filter_params p_flt; - int last_source; - bool _open(void); - void *pdata; - public: - - bool Open(DMX_CHANNEL_TYPE pes_type, void * unused = NULL, int bufsize = 0); - void Close(void); - bool Start(bool record = false); - bool Stop(void); - int Read(unsigned char *buff, int len, int Timeout = 0); - bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); - bool pesFilter(const unsigned short pid); - void SetSyncMode(AVSYNC_TYPE mode); - void * getBuffer(); - void * getChannel(); - DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; - bool addPid(unsigned short pid); - void getSTC(int64_t * STC); - int getUnit(void); - static bool SetSource(int unit, int source); - static int GetSource(int unit); - // TD only functions - int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // - cDemux(int num = 0); - ~cDemux(); -}; - -#endif //__DEMUX_H diff --git a/libspark/init.cpp b/libspark/init.cpp index 1e6ac3b..cea952f 100644 --- a/libspark/init.cpp +++ b/libspark/init.cpp @@ -3,7 +3,6 @@ #include -#include "init_lib.h" #include #include #include @@ -14,6 +13,7 @@ #include +#include "init_td.h" #include "pwrmngr.h" #include "lt_debug.h" diff --git a/libspark/init_cs.h b/libspark/init_cs.h deleted file mode 100644 index 7f9e341..0000000 --- a/libspark/init_cs.h +++ /dev/null @@ -1,2 +0,0 @@ -#warning using init_cs.h from libspark -#include "init_lib.h" diff --git a/libspark/init_lib.h b/libspark/init_lib.h deleted file mode 100644 index d9a6f09..0000000 --- a/libspark/init_lib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/libspark/record.cpp b/libspark/record.cpp index cae962b..7b626c7 100644 --- a/libspark/record.cpp +++ b/libspark/record.cpp @@ -8,6 +8,7 @@ #include #include +#include #include #include "record_lib.h" @@ -15,7 +16,7 @@ #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) -/* helper functions to call the cpp thread loops */ +/* helper function to call the cpp thread loop */ void *execute_record_thread(void *c) { cRecord *obj = (cRecord *)c; @@ -137,7 +138,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; /* the first PID is the video pid, so start with the second PID... */ for (std::vector::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { found = false; @@ -173,7 +174,7 @@ bool cRecord::AddPid(unsigned short pid) lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; for (std::vector::const_iterator i = pids.begin(); i != pids.end(); ++i) { if ((*i).pid == pid) return true; /* or is it an error to try to add the same PID twice? */ @@ -214,7 +215,7 @@ void cRecord::RecordThread() strncpy(threadname, "RecordThread", sizeof(threadname)); threadname[16] = 0; prctl (PR_SET_NAME, (unsigned long)&threadname); - int readsize = bufsize/16; + int readsize = bufsize / 16; int buf_pos = 0; int count = 0; int queued = 0; @@ -257,13 +258,15 @@ void cRecord::RecordThread() if (toread > readsize) toread = readsize; ssize_t s = dmx->Read(buf + buf_pos, toread, 50); - lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, buf_pos, (int)s, bufsize - buf_pos); + lt_debug("%s: buf_pos %6d s %6d / %6d\n", __func__, + buf_pos, (int)s, bufsize - buf_pos); if (s < 0) { if (errno != EAGAIN && (errno != EOVERFLOW || !overflow)) { lt_info("%s: read failed: %m\n", __func__); exit_flag = RECORD_FAILED_READ; + state = REC_STATUS_OVERFLOW; break; } } @@ -289,6 +292,7 @@ void cRecord::RecordThread() overflow = true; if (!(overflow_count % 10)) lt_info("%s: buffer full! Overflow? (%d)\n", __func__, ++overflow_count); + state = REC_STATUS_SLOW; } r = aio_error(&a); if (r == EINPROGRESS) diff --git a/libspark/record_lib.h b/libspark/record_lib.h index 5ff453e..75bb988 100644 --- a/libspark/record_lib.h +++ b/libspark/record_lib.h @@ -1,9 +1,8 @@ -#ifndef __RECORD_TD_H -#define __RECORD_TD_H +#ifndef __record_hal__ +#define __record_hal__ -#include #include -#include "dmx_lib.h" +#include "dmx_hal.h" #define REC_STATUS_OK 0 #define REC_STATUS_SLOW 1 diff --git a/libspark/video_lib.h b/libspark/video_lib.h index d4bb5f7..73ee6e5 100644 --- a/libspark/video_lib.h +++ b/libspark/video_lib.h @@ -1,9 +1,9 @@ -#ifndef _VIDEO_TD_H -#define _VIDEO_TD_H +#ifndef _VIDEO_LIB_H +#define _VIDEO_LIB_H #include -#include "../common/cs_types.h" -#include "dmx_lib.h" +#include "cs_types.h" +#include "dmx_hal.h" typedef struct cs_vs_format_t { diff --git a/libtriple/Makefile.am b/libtriple/Makefile.am index fa3064e..4d14aaa 100644 --- a/libtriple/Makefile.am +++ b/libtriple/Makefile.am @@ -2,6 +2,7 @@ noinst_LTLIBRARIES = libtriple.la AM_CPPFLAGS = \ -I$(top_srcdir)/common \ + -I$(top_srcdir)/include \ @DIRECTFB_CFLAGS@ AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing diff --git a/libtriple/audio_td.h b/libtriple/audio_td.h index bc320f1..8fe0e7d 100644 --- a/libtriple/audio_td.h +++ b/libtriple/audio_td.h @@ -4,7 +4,7 @@ #define _AUDIO_TD_H_ #include -#include "../common/cs_types.h" +#include "cs_types.h" typedef enum { diff --git a/libtriple/cs_api.h b/libtriple/cs_api.h deleted file mode 100644 index 47890e0..0000000 --- a/libtriple/cs_api.h +++ /dev/null @@ -1,67 +0,0 @@ -/* compatibility header for tripledragon. I'm lazy, so I just left it - as "cs_api.h" so that I don't need too many ifdefs in the code */ - -#ifndef __CS_API_H_ -#define __CS_API_H_ - -#include "init_td.h" -typedef void (*cs_messenger) (unsigned int msg, unsigned int data); - -#if 0 -enum CS_LOG_MODULE { - CS_LOG_CI = 0, - CS_LOG_HDMI_CEC, - CS_LOG_HDMI, - CS_LOG_VIDEO, - CS_LOG_VIDEO_DRM, - CS_LOG_AUDIO, - CS_LOG_DEMUX, - CS_LOG_DENC, - CS_LOG_PVR_RECORD, - CS_LOG_PVR_PLAY, - CS_LOG_POWER_CTRL, - CS_LOG_POWER_CLK, - CS_LOG_MEM, - CS_LOG_API, -}; -#endif - -inline void cs_api_init() -{ - init_td_api(); -}; - -inline void cs_api_exit() -{ - shutdown_td_api(); -}; - -#define cs_malloc_uncached malloc -#define cs_free_uncached free - -// Callback function helpers -static inline void cs_register_messenger(cs_messenger) { return; }; -static inline void cs_deregister_messenger(void) { return; }; -//cs_messenger cs_get_messenger(void); - -#if 0 -// Logging functions -void cs_log_enable(void); -void cs_log_disable(void); -void cs_log_message(const char *prefix, const char *fmt, ...); -void cs_log_module_enable(enum CS_LOG_MODULE module); -void cs_log_module_disable(enum CS_LOG_MODULE module); -void cs_log_module_message(enum CS_LOG_MODULE module, const char *fmt, ...); - -// TS Routing -unsigned int cs_get_ts_output(void); -int cs_set_ts_output(unsigned int port); - -// Serial nr and revision accessors -unsigned long long cs_get_serial(void); -#endif -/* compat... HD1 seems to be version 6. everything newer ist > 6... */ -static inline unsigned int cs_get_revision(void) { return 1; }; -static inline unsigned int cs_get_chip_type(void) { return 0; }; -extern int cnxt_debug; -#endif //__CS_API_H_ diff --git a/libtriple/dmx_cs.h b/libtriple/dmx_cs.h deleted file mode 100644 index 4f0dbc1..0000000 --- a/libtriple/dmx_cs.h +++ /dev/null @@ -1 +0,0 @@ -#include "dmx_td.h" diff --git a/libtriple/dmx_td.cpp b/libtriple/dmx_td.cpp index 92242d3..f160f83 100644 --- a/libtriple/dmx_td.cpp +++ b/libtriple/dmx_td.cpp @@ -17,18 +17,21 @@ * along with this program. If not, see . */ +#include #include #include #include #include +#include #include #include +#include #include #include #include #include -#include "dmx_td.h" +#include "dmx_hal.h" #include "lt_debug.h" /* Ugh... see comment in destructor for details... */ @@ -39,14 +42,8 @@ extern cVideo *videoDecoder; #define lt_info(args...) _lt_info(TRIPLE_DEBUG_DEMUX, this, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; @@ -75,6 +72,15 @@ static const char *devname[] = { static int dmx_tp_count = 0; #define MAX_TS_COUNT 1 +typedef struct dmx_pdata { + bool measure; + int last_measure; + int last_data; + int devnum; + bool running; +} dmx_pdata; +#define P ((dmx_pdata *)pdata) + cDemux::cDemux(int n) { if (n < 0 || n > 2) @@ -85,32 +91,24 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; + pdata = calloc(1, sizeof(dmx_pdata)); + P->measure = false; + P->last_measure = 0; + P->last_data = 0; + P->running = false; } cDemux::~cDemux() { lt_debug("%s #%d fd: %d\n", __FUNCTION__, num, fd); Close(); - /* in zapit.cpp, videoDemux is deleted after videoDecoder - * in the video watchdog, we access videoDecoder - * the thread still runs after videoDecoder has been deleted - * => set videoDecoder to NULL here to make the check in the - * watchdog thread pick this up. - * This is ugly, but it saves me from changing neutrino - * - * if the delete order in neutrino will ever be changed, this - * will blow up badly :-( - */ - if (dmx_type == DMX_VIDEO_CHANNEL) - videoDecoder = NULL; + free(pdata); + pdata = NULL; } bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBufferSize) { - devnum = num; + P->devnum = num; int flags = O_RDWR; if (fd > -1) lt_info("%s FD ALREADY OPENED? fd = %d\n", __FUNCTION__, fd); @@ -120,10 +118,10 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe if (num == 0 && uBufferSize == 3 * 3008 * 62) /* streaminfo measurement, let's cheat... */ { lt_info("%s num=0 and DMX_TP_CHANNEL => measurement demux\n", __func__); - devnum = 2; /* demux 0 is used for live, demux 1 for recording */ - measure = true; - last_measure = 0; - last_data = 0; + P->devnum = 2; /* demux 0 is used for live, demux 1 for recording */ + P->measure = true; + P->last_measure = 0; + P->last_data = 0; flags |= O_NONBLOCK; } else @@ -137,18 +135,18 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe return false; } dmx_tp_count++; - devnum = dmx_tp_count; + P->devnum = dmx_tp_count; } } - fd = open(devname[devnum], flags); + fd = open(devname[P->devnum], flags); if (fd < 0) { - lt_info("%s %s: %m\n", __FUNCTION__, devname[devnum]); + lt_info("%s %s: %m\n", __FUNCTION__, devname[P->devnum]); return false; } fcntl(fd, F_SETFD, FD_CLOEXEC); lt_debug("%s #%d pes_type: %s(%d), uBufferSize: %d dev:%s fd: %d\n", __func__, - num, DMX_T[pes_type], pes_type, uBufferSize, devname[devnum] + strlen("/dev/stb/"), fd); + num, DMX_T[pes_type], pes_type, uBufferSize, devname[P->devnum] + strlen("/dev/stb/"), fd); dmx_type = pes_type; @@ -159,7 +157,7 @@ bool cDemux::Open(DMX_CHANNEL_TYPE pes_type, void * /*hVideoBuffer*/, int uBuffe } if (pes_type == DMX_TP_CHANNEL) { - if (measure) + if (P->measure) return true; struct demux_bucket_para bp; bp.unloader.unloader_type = UNLOADER_TYPE_TRANSPORT; @@ -201,7 +199,7 @@ void cDemux::Close(void) ioctl(fd, DEMUX_STOP); close(fd); fd = -1; - if (measure) + if (P->measure) return; if (dmx_type == DMX_TP_CHANNEL) { @@ -229,6 +227,7 @@ bool cDemux::Start(bool) perror("DEMUX_START"); } ioctl(fd, DEMUX_START); + P->running = true; return true; } @@ -246,6 +245,7 @@ bool cDemux::Stop(void) perror("DEMUX_STOP"); } ioctl(fd, DEMUX_STOP); + P->running = false; return true; } @@ -262,7 +262,15 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) ufds.events = POLLIN; ufds.revents = 0; - if (measure) + if (dmx_type == DMX_INVALID) /* happens, if too many DMX_TP are requested, because */ + { /* nobody checks the return value of Open or Start... */ + lt_debug("%s #%d: DMX_INVALID\n", __func__, num); + usleep(timeout * 1000); /* rate-limit the debug message */ + errno = EINVAL; + return -1; + } + + if (P->measure) { if (timeout) usleep(timeout * 1000); @@ -271,7 +279,7 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) clock_gettime(CLOCK_MONOTONIC, &t); now = t.tv_sec * 1000; now += t.tv_nsec / 1000000; - if (now - last_measure < 333) + if (now - P->last_measure < 333) return 0; unsigned char dummy[12]; unsigned long long bit_s = 0; @@ -295,17 +303,17 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) bit_s = (m.rx_bytes * 7816793ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us; */ bit_s = (m.rx_bytes * 8000ULL + (m.rx_time_us / 2ULL)) / m.rx_time_us; - if (now - last_data < 5000) - rc = bit_s * (now - last_data) / 8ULL; + if (now - P->last_data < 5000) + rc = bit_s * (now - P->last_data) / 8ULL; else rc = 0; lt_debug("%s measure bit_s: %llu rc: %d timediff: %lld\n", - __func__, bit_s, rc, (now - last_data)); - last_data = now; + __func__, bit_s, rc, (now - P->last_data)); + P->last_data = now; } else rc = 0; } - last_measure = now; + P->last_measure = now; ioctl(fd, DEMUX_START); return rc; } @@ -350,13 +358,14 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { int length; + struct demux_filter_para s_flt; memset(&s_flt, 0, sizeof(s_flt)); - + pid = _pid; if (len > FILTER_LENGTH - 2) lt_info("%s #%d: len too long: %d, FILTER_LENGTH: %d\n", __func__, num, len, FILTER_LENGTH); if (len < 1) /* memcpy below will be unhappy */ @@ -365,6 +374,7 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte length = (len + 2 + 1) & 0xfe; /* reportedly, the TD drivers don't handle odd filter */ if (length > FILTER_LENGTH) /* lengths well. So make sure the length is a multiple */ length = FILTER_LENGTH; /* of 2. The unused mask is zeroed anyway. */ + flt = filter[0]; s_flt.pid = pid; s_flt.filter_length = length; s_flt.filter[0] = filter[0]; @@ -467,11 +477,15 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte if (ioctl(fd, DEMUX_FILTER_SET, &s_flt) < 0) return false; + P->running = true; return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + demux_pes_para p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... @@ -483,7 +497,7 @@ bool cDemux::pesFilter(const unsigned short pid) lt_debug("%s #%d pid: 0x%04hx fd: %d type: %s\n", __FUNCTION__, num, pid, fd, DMX_T[dmx_type]); - if (dmx_type == DMX_TP_CHANNEL && !measure) + if (dmx_type == DMX_TP_CHANNEL && !P->measure) { unsigned int n = pesfds.size(); addPid(pid); @@ -533,6 +547,8 @@ void cDemux::SetSyncMode(AVSYNC_TYPE /*mode*/) void *cDemux::getBuffer() { lt_debug("%s #%d\n", __FUNCTION__, num); + if (P->running) + return (void *)1; return NULL; } @@ -552,14 +568,14 @@ bool cDemux::addPid(unsigned short Pid) lt_info("%s pes_type %s not implemented yet! pid=%hx\n", __FUNCTION__, DMX_T[dmx_type], Pid); return false; } - if (measure) + if (P->measure) { lt_info("%s measurement demux -> skipping\n", __func__); return true; } if (fd == -1) lt_info("%s bucketfd not yet opened? pid=%hx\n", __FUNCTION__, Pid); - pfd.fd = open(devname[devnum], O_RDWR); + pfd.fd = open(devname[P->devnum], O_RDWR); if (pfd.fd < 0) { lt_info("%s #%d Pid = %hx open failed (%m)\n", __FUNCTION__, num, Pid); diff --git a/libtriple/dmx_td.h b/libtriple/dmx_td.h deleted file mode 100644 index a253f3c..0000000 --- a/libtriple/dmx_td.h +++ /dev/null @@ -1,78 +0,0 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H - -#include -#include -extern "C" { -#include -#include -#include -} -#include "../common/cs_types.h" -#if defined DMX_FILTER_SIZE -#undef DMX_FILTER_SIZE -#endif -#define DMX_FILTER_SIZE FILTER_LENGTH - -#define MAX_DMX_UNITS 4 - -typedef enum -{ - DMX_INVALID = 0, - DMX_VIDEO_CHANNEL = 1, - DMX_AUDIO_CHANNEL, - DMX_PES_CHANNEL, - DMX_PSI_CHANNEL, - DMX_PIP_CHANNEL, - DMX_TP_CHANNEL, - DMX_PCR_ONLY_CHANNEL -} DMX_CHANNEL_TYPE; - -typedef struct -{ - int fd; - unsigned short pid; -} pes_pids; - -class cDemux -{ - private: - int num; - int devnum; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct demux_filter_para s_flt; - demux_pes_para p_flt; - public: - - bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); - void Close(void); - bool Start(bool record = false); - bool Stop(void); - int Read(unsigned char *buff, int len, int Timeout = 0); - bool sectionFilter(unsigned short pid, const unsigned char * const filter, const unsigned char * const mask, int len, int Timeout = 0, const unsigned char * const negmask = NULL); - bool pesFilter(const unsigned short pid); - void SetSyncMode(AVSYNC_TYPE mode); - void * getBuffer(); - void * getChannel(); - DMX_CHANNEL_TYPE getChannelType(void) { return dmx_type; }; - bool addPid(unsigned short pid); - void getSTC(int64_t * STC); - int getUnit(void); - /* tripledragon is unlikely to get a second tuner, so stub it out right here */ - static bool SetSource(int /*unit*/, int /*source*/) { return true; }; - static int GetSource(int /*unit*/) { return 0; }; - // TD only functions - int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // - cDemux(int num = 0); - ~cDemux(); -}; - -#endif //__DEMUX_H diff --git a/libtriple/init_cs.h b/libtriple/init_cs.h deleted file mode 100644 index 5894a14..0000000 --- a/libtriple/init_cs.h +++ /dev/null @@ -1,2 +0,0 @@ -#warning using init_cs.h from libtriple -#include "init_td.h" diff --git a/libtriple/init_td.cpp b/libtriple/init_td.cpp index 121297d..8015839 100644 --- a/libtriple/init_td.cpp +++ b/libtriple/init_td.cpp @@ -36,7 +36,7 @@ int gfxfd = -1; #define DFBCHECK(x...) \ err = x; \ if (err != DFB_OK) { \ - fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + fprintf(stderr, "init_td.cpp:%d:\n\t", __LINE__); \ DirectFBErrorFatal(#x, err ); \ } diff --git a/libtriple/init_td.h b/libtriple/init_td.h deleted file mode 100644 index d9a6f09..0000000 --- a/libtriple/init_td.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/libtriple/lt_dfbinput.cpp b/libtriple/lt_dfbinput.cpp index 6000ff8..e61915a 100644 --- a/libtriple/lt_dfbinput.cpp +++ b/libtriple/lt_dfbinput.cpp @@ -58,7 +58,7 @@ extern cVideo *videoDecoder; #define DFBCHECK(x...) \ err = x; \ if (err != DFB_OK) { \ - fprintf(stderr, "%s <%d>:\n\t", __FILE__, __LINE__ ); \ + fprintf(stderr, "lt_dfbinput.cpp:%d:\n\t", __LINE__); \ DirectFBErrorFatal(#x, err ); \ } diff --git a/libtriple/playback_td.cpp b/libtriple/playback_td.cpp index 2fee33a..f726e22 100644 --- a/libtriple/playback_td.cpp +++ b/libtriple/playback_td.cpp @@ -1,13 +1,18 @@ +#include + #include #include #include #include #include +#include #include #include +#include + #include "playback_td.h" -#include "dmx_td.h" +#include "dmx_hal.h" #include "audio_td.h" #include "video_td.h" #include "lt_debug.h" diff --git a/libtriple/record_td.cpp b/libtriple/record_td.cpp index 584aba7..6d1f2e1 100644 --- a/libtriple/record_td.cpp +++ b/libtriple/record_td.cpp @@ -6,7 +6,11 @@ #include #include #include + +#include + #include "record_td.h" +#include "dmx_hal.h" #include "lt_debug.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_RECORD, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_RECORD, this, args) @@ -121,7 +125,7 @@ bool cRecord::ChangePids(unsigned short /*vpid*/, unsigned short *apids, int num lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; /* the first PID is the video pid, so start with the second PID... */ for (std::vector::const_iterator i = pids.begin() + 1; i != pids.end(); ++i) { found = false; @@ -157,7 +161,7 @@ bool cRecord::AddPid(unsigned short pid) lt_info("%s: DMX = NULL\n", __func__); return false; } - pids = dmx->getPesPids(); + pids = dmx->pesfds; for (std::vector::const_iterator i = pids.begin(); i != pids.end(); ++i) { if ((*i).pid == pid) return true; /* or is it an error to try to add the same PID twice? */ diff --git a/libtriple/record_td.h b/libtriple/record_td.h index c2f60ea..fdb2013 100644 --- a/libtriple/record_td.h +++ b/libtriple/record_td.h @@ -2,7 +2,7 @@ #define __RECORD_TD_H #include -#include "dmx_td.h" +#include "dmx_hal.h" #define REC_STATUS_OK 0 #define REC_STATUS_SLOW 1 diff --git a/libtriple/video_td.h b/libtriple/video_td.h index d689420..567df13 100644 --- a/libtriple/video_td.h +++ b/libtriple/video_td.h @@ -4,7 +4,7 @@ #include #define video_format_t vidDispSize_t //#define video_displayformat_t vidDispMode_t -#include "../common/cs_types.h" +#include "cs_types.h" #include "dmx_td.h" #define STB_HAL_VIDEO_HAS_GETSCREENIMAGE 1 diff --git a/raspi/audio.cpp b/raspi/audio.cpp index 73e0ec2..da85d47 100644 --- a/raspi/audio.cpp +++ b/raspi/audio.cpp @@ -21,7 +21,7 @@ #include #include "audio_lib.h" -#include "dmx_lib.h" +#include "dmx_hal.h" #include "lt_debug.h" #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) @@ -151,4 +151,3 @@ void cAudio::setBypassMode(bool disable) { lt_debug("%s %d\n", __func__, disable); } - diff --git a/raspi/audio_lib.h b/raspi/audio_lib.h index cfd1b81..835609d 100644 --- a/raspi/audio_lib.h +++ b/raspi/audio_lib.h @@ -4,13 +4,13 @@ #define _AUDIO_LIB_H_ #include -#include "../common/cs_types.h" +#include "cs_types.h" typedef enum { - AUDIO_SYNC_WITH_PTS, - AUDIO_NO_SYNC, - AUDIO_SYNC_AUDIO_MASTER + AUDIO_SYNC_WITH_PTS, + AUDIO_NO_SYNC, + AUDIO_SYNC_AUDIO_MASTER } AUDIO_SYNC_MODE; typedef enum { @@ -21,20 +21,20 @@ typedef enum { typedef enum { - AUDIO_FMT_AUTO = 0, - AUDIO_FMT_MPEG, - AUDIO_FMT_MP3, - AUDIO_FMT_DOLBY_DIGITAL, - AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, - AUDIO_FMT_AAC, - AUDIO_FMT_AAC_PLUS, - AUDIO_FMT_DD_PLUS, - AUDIO_FMT_DTS, - AUDIO_FMT_AVS, - AUDIO_FMT_MLP, - AUDIO_FMT_WMA, - AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback - AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP + AUDIO_FMT_AUTO = 0, + AUDIO_FMT_MPEG, + AUDIO_FMT_MP3, + AUDIO_FMT_DOLBY_DIGITAL, + AUDIO_FMT_BASIC = AUDIO_FMT_DOLBY_DIGITAL, + AUDIO_FMT_AAC, + AUDIO_FMT_AAC_PLUS, + AUDIO_FMT_DD_PLUS, + AUDIO_FMT_DTS, + AUDIO_FMT_AVS, + AUDIO_FMT_MLP, + AUDIO_FMT_WMA, + AUDIO_FMT_MPG1, // TD only. For Movieplayer / cPlayback + AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP } AUDIO_FORMAT; class cAudio @@ -61,6 +61,7 @@ class cAudio int do_mute(bool enable, bool remember); void setBypassMode(bool disable); + public: /* construct & destruct */ cAudio(void *, void *, void *); diff --git a/raspi/cs_api.h b/raspi/cs_api.h deleted file mode 120000 index a794ffd..0000000 --- a/raspi/cs_api.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/cs_api.h \ No newline at end of file diff --git a/raspi/dmx.cpp b/raspi/dmx.cpp index e5fdf4f..0858a47 100644 --- a/raspi/dmx.cpp +++ b/raspi/dmx.cpp @@ -19,7 +19,6 @@ * along with this program. If not, see . */ - #include "config.h" #include #include @@ -27,16 +26,17 @@ #include #include #include +#include #include #include #include -#include -#include "dmx_lib.h" +#include +#include "dmx_hal.h" #include "lt_debug.h" -/* needed for getSTC :-( */ #include "video_lib.h" +/* needed for getSTC... */ extern cVideo *videoDecoder; #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_DEMUX, this, args) @@ -44,14 +44,8 @@ extern cVideo *videoDecoder; #define lt_info_c(args...) _lt_info(TRIPLE_DEBUG_DEMUX, NULL, args) #define dmx_err(_errfmt, _errstr, _revents) do { \ - uint16_t _pid = (uint16_t)-1; uint16_t _f = 0;\ - if (dmx_type == DMX_PSI_CHANNEL) { \ - _pid = s_flt.pid; _f = s_flt.filter.filter[0]; \ - } else { \ - _pid = p_flt.pid; \ - }; \ lt_info("%s " _errfmt " fd:%d, ev:0x%x %s pid:0x%04hx flt:0x%02hx\n", \ - __func__, _errstr, fd, _revents, DMX_T[dmx_type], _pid, _f); \ + __func__, _errstr, fd, _revents, DMX_T[dmx_type], pid, flt); \ } while(0); cDemux *videoDemux = NULL; @@ -90,9 +84,6 @@ cDemux::cDemux(int n) else num = n; fd = -1; - measure = false; - last_measure = 0; - last_data = 0; } cDemux::~cDemux() @@ -154,12 +145,11 @@ void cDemux::Close(void) lt_info("%s #%d: not open!\n", __FUNCTION__, num); return; } + pesfds.clear(); ioctl(fd, DMX_STOP); close(fd); fd = -1; - if (measure) - return; if (dmx_type == DMX_TP_CHANNEL) { dmx_tp_count--; @@ -251,17 +241,20 @@ int cDemux::Read(unsigned char *buff, int len, int timeout) return rc; } -bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filter, +bool cDemux::sectionFilter(unsigned short _pid, const unsigned char * const filter, const unsigned char * const mask, int len, int timeout, const unsigned char * const negmask) { + struct dmx_sct_filter_params s_flt; memset(&s_flt, 0, sizeof(s_flt)); + pid = _pid; if (len > DMX_FILTER_SIZE) { lt_info("%s #%d: len too long: %d, DMX_FILTER_SIZE %d\n", __func__, num, len, DMX_FILTER_SIZE); len = DMX_FILTER_SIZE; } + flt = filter[0]; s_flt.pid = pid; s_flt.timeout = timeout; memcpy(s_flt.filter.filter, filter, len); @@ -364,8 +357,11 @@ bool cDemux::sectionFilter(unsigned short pid, const unsigned char * const filte return true; } -bool cDemux::pesFilter(const unsigned short pid) +bool cDemux::pesFilter(const unsigned short _pid) { + struct dmx_pes_filter_params p_flt; + pid = _pid; + flt = 0; /* allow PID 0 for web streaming e.g. * this check originally is from tuxbox cvs but I'm not sure * what it is good for... @@ -382,20 +378,19 @@ bool cDemux::pesFilter(const unsigned short pid) p_flt.output = DMX_OUT_DECODER; p_flt.input = DMX_IN_FRONTEND; - /* for now, output to TS_TAP for live mode, - * test playback with "omxplayer /dev/dvb/adapter0/dvr0" */ switch (dmx_type) { case DMX_PCR_ONLY_CHANNEL: p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TS_TAP; + p_flt.output = DMX_OUT_TAP; + return true; break; case DMX_AUDIO_CHANNEL: p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TS_TAP; + p_flt.output = DMX_OUT_TSDEMUX_TAP; break; case DMX_VIDEO_CHANNEL: p_flt.pes_type = DMX_PES_OTHER; - p_flt.output = DMX_OUT_TS_TAP; + p_flt.output = DMX_OUT_TSDEMUX_TAP; break; case DMX_PES_CHANNEL: p_flt.pes_type = DMX_PES_OTHER; diff --git a/raspi/dmx_lib.h b/raspi/dmx_lib.h index 754511e..7a5e1a5 100644 --- a/raspi/dmx_lib.h +++ b/raspi/dmx_lib.h @@ -1,10 +1,9 @@ -#ifndef __DEMUX_TD_H -#define __DEMUX_TD_H +#ifndef __dmx_hal__ +#define __dmx_hal__ #include #include #include -#include #include #include "../common/cs_types.h" @@ -28,20 +27,13 @@ typedef struct unsigned short pid; } pes_pids; +class cRecord; +class cPlayback; class cDemux { - private: - int num; - int fd; - int buffersize; - bool measure; - uint64_t last_measure, last_data; - DMX_CHANNEL_TYPE dmx_type; - std::vector pesfds; - struct dmx_sct_filter_params s_flt; - struct dmx_pes_filter_params p_flt; + friend class cRecord; + friend class cPlayback; public: - bool Open(DMX_CHANNEL_TYPE pes_type, void * x = NULL, int y = 0); void Close(void); bool Start(bool record = false); @@ -58,13 +50,20 @@ class cDemux int getUnit(void); static bool SetSource(int unit, int source); static int GetSource(int unit); - // TD only functions int getFD(void) { return fd; }; /* needed by cPlayback class */ - void removePid(unsigned short Pid); /* needed by cRecord class */ - std::vector getPesPids(void) { return pesfds; }; - // cDemux(int num = 0); ~cDemux(); + + private: + void removePid(unsigned short Pid); /* needed by cRecord class */ + int num; + int fd; + int buffersize; + uint16_t pid; + uint8_t flt; + std::vector pesfds; + DMX_CHANNEL_TYPE dmx_type; + void *pdata; }; -#endif //__DEMUX_H +#endif //__dmx_hal__ diff --git a/raspi/init.cpp b/raspi/init.cpp index 4937194..6e6adfc 100644 --- a/raspi/init.cpp +++ b/raspi/init.cpp @@ -34,7 +34,7 @@ #include #include -#include "init_lib.h" +#include "init_td.h" #include "lt_debug.h" #include "glfb.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_INIT, NULL, args) diff --git a/raspi/init_lib.h b/raspi/init_lib.h deleted file mode 100644 index d9a6f09..0000000 --- a/raspi/init_lib.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef __INIT_TD_H -#define __INIT_TD_H -void init_td_api(); -void shutdown_td_api(); -#endif diff --git a/raspi/video_lib.h b/raspi/video_lib.h index 07718b1..5f325f8 100644 --- a/raspi/video_lib.h +++ b/raspi/video_lib.h @@ -1,10 +1,11 @@ -#ifndef _VIDEO_TD_H -#define _VIDEO_TD_H +#ifndef _VIDEO_LIB_H +#define _VIDEO_LIB_H #include #include -#include "../common/cs_types.h" -#include "dmx_lib.h" +#include "cs_types.h" +#include "dmx_hal.h" + extern "C" { #include } @@ -57,7 +58,7 @@ typedef enum { DISPLAY_AR_14_9, DISPLAY_AR_16_9, DISPLAY_AR_20_9, - DISPLAY_AR_RAW, + DISPLAY_AR_RAW } DISPLAY_AR; typedef enum { @@ -101,7 +102,7 @@ typedef enum { /* not used, for dummy functions */ typedef enum { - VIDEO_HDMI_CEC_MODE_OFF = 0, + VIDEO_HDMI_CEC_MODE_OFF = 0, VIDEO_HDMI_CEC_MODE_TUNER, VIDEO_HDMI_CEC_MODE_RECORDER } VIDEO_HDMI_CEC_MODE; From 320af2c9f520a5563ca19dd6352e0a580a147140 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 22 Mar 2018 21:20:06 +0100 Subject: [PATCH 28/38] all: clean up pwrmngr header file Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/efc797365ff6c2d3fceeab32adf92f32eae88dfc Author: max_10 Date: 2018-03-22 (Thu, 22 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- azbox/Makefile.am | 4 +- azbox/pwrmngr.cpp | 1 - azbox/pwrmngr.h | 1 - common/Makefile.am | 3 +- common/pwrmngr.cpp | 179 +++++++++++++++++++++++++++++++++++++++++ generic-pc/Makefile.am | 6 +- generic-pc/pwrmngr.cpp | 1 - generic-pc/pwrmngr.h | 1 - include/pwrmngr.h | 65 ++++++++++----- libarmbox/Makefile.am | 1 - libarmbox/pwrmngr.cpp | 32 -------- libarmbox/pwrmngr.h | 53 ------------ libduckbox/Makefile.am | 1 - libduckbox/pwrmngr.cpp | 1 - libduckbox/pwrmngr.h | 1 - libspark/Makefile.am | 2 - libspark/pwrmngr.cpp | 102 ----------------------- libspark/pwrmngr.h | 53 ------------ libtriple/pwrmngr.cpp | 87 -------------------- libtriple/pwrmngr.h | 53 ------------ raspi/pwrmngr.cpp | 1 - raspi/pwrmngr.h | 1 - 22 files changed, 231 insertions(+), 418 deletions(-) delete mode 120000 azbox/pwrmngr.cpp delete mode 120000 azbox/pwrmngr.h create mode 100644 common/pwrmngr.cpp delete mode 120000 generic-pc/pwrmngr.cpp delete mode 120000 generic-pc/pwrmngr.h delete mode 100644 libarmbox/pwrmngr.cpp delete mode 100644 libarmbox/pwrmngr.h delete mode 120000 libduckbox/pwrmngr.cpp delete mode 120000 libduckbox/pwrmngr.h delete mode 100644 libspark/pwrmngr.cpp delete mode 100644 libspark/pwrmngr.h delete mode 100644 libtriple/pwrmngr.cpp delete mode 100644 libtriple/pwrmngr.h delete mode 120000 raspi/pwrmngr.cpp delete mode 120000 raspi/pwrmngr.h diff --git a/azbox/Makefile.am b/azbox/Makefile.am index 0e6b74f..7e8b5a7 100644 --- a/azbox/Makefile.am +++ b/azbox/Makefile.am @@ -1,7 +1,8 @@ noinst_LTLIBRARIES = libazbox.la AM_CPPFLAGS = \ - -I$(top_srcdir)/common + -I$(top_srcdir)/common \ + -I$(top_srcdir)/include AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_LDFLAGS = -lpthread @@ -13,6 +14,5 @@ libazbox_la_SOURCES = \ audio.cpp \ init.cpp \ playback.cpp \ - pwrmngr.cpp \ record.cpp diff --git a/azbox/pwrmngr.cpp b/azbox/pwrmngr.cpp deleted file mode 120000 index cee9acb..0000000 --- a/azbox/pwrmngr.cpp +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.cpp \ No newline at end of file diff --git a/azbox/pwrmngr.h b/azbox/pwrmngr.h deleted file mode 120000 index e63e97b..0000000 --- a/azbox/pwrmngr.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.h \ No newline at end of file diff --git a/common/Makefile.am b/common/Makefile.am index 0fb4902..17395fc 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -32,4 +32,5 @@ endif libcommon_la_SOURCES += \ lt_debug.cpp \ - proc_tools.c + proc_tools.c \ + pwrmngr.cpp diff --git a/common/pwrmngr.cpp b/common/pwrmngr.cpp new file mode 100644 index 0000000..7aac8a3 --- /dev/null +++ b/common/pwrmngr.cpp @@ -0,0 +1,179 @@ +/* + * (C) 2010-2013 Stefan Seyfried + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ +#include + +#include "pwrmngr.h" +#include "lt_debug.h" + +#include +#include + +#include +#include +#include +#include +#include + +#if HAVE_TRIPLEDRAGON +#include +#include +#endif + +#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args) +#define lt_info(args...) _lt_info(TRIPLE_DEBUG_PWRMNGR, this, args) + +/* cpufreqmanager */ +void cCpuFreqManager::Up(void) +{ + lt_debug("%s\n", __func__); +} + +void cCpuFreqManager::Down(void) +{ + lt_debug("%s\n", __func__); +} + +void cCpuFreqManager::Reset(void) +{ + lt_debug("%s\n", __func__); +} + +/* those function dummies return true or "harmless" values */ +bool cCpuFreqManager::SetDelta(unsigned long) +{ + lt_debug("%s\n", __func__); + return true; +} + +unsigned long cCpuFreqManager::GetDelta(void) +{ + lt_debug("%s\n", __func__); + return 0; +} + +#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE +unsigned long cCpuFreqManager::GetCpuFreq(void) { + int freq = 0; + if (FILE *pll0 = fopen("/proc/cpu_frequ/pll0_ndiv_mdiv", "r")) { + char buffer[120]; + while(fgets(buffer, sizeof(buffer), pll0)) { + if (1 == sscanf(buffer, "SH4 = %d MHZ", &freq)) + break; + } + fclose(pll0); + return 1000 * 1000 * (unsigned long) freq; + } + return 0; +} +#else +unsigned long cCpuFreqManager::GetCpuFreq(void) +{ + lt_debug("%s\n", __func__); + return 0; +} +#endif + +bool cCpuFreqManager::SetCpuFreq(unsigned long f) +{ + lt_info("%s(%lu) => set standby = %s\n", __func__, f, f?"true":"false"); +#if HAVE_TRIPLEDRAGON + /* actually SetCpuFreq is used to determine if the system is in standby + this is an "elegant" hack, because: + * during a recording, cpu freq is kept "high", even if the box is sent to standby + * the "SetStandby" call is made even if a recording is running + On the TD, setting standby disables the frontend, so we must not do it + if a recording is running. + For now, the values in neutrino are hardcoded: + * f == 0 => max => not standby + * f == 50000000 => min => standby + */ + int fd = open("/dev/stb/tdsystem", O_RDONLY); + if (fd < 0) + { + perror("open tdsystem"); + return false; + } + if (f) + { + ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ + ioctl(fd, IOC_AVS_STANDBY_ENTER); + if (getenv("TRIPLE_LCDBACKLIGHT")) + { + lt_info("%s: TRIPLE_LCDBACKLIGHT is set: keeping LCD backlight on\n", __func__); + close(fd); + fd = open("/dev/stb/tdlcd", O_RDONLY); + if (fd < 0) + lt_info("%s: open tdlcd error: %m\n", __func__); + else + ioctl(fd, IOC_LCD_BACKLIGHT_ON); + } + } + else + { + ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ + ioctl(fd, IOC_AVS_STANDBY_LEAVE); + /* unmute will be done by cAudio::do_mute(). Ugly, but prevents pops */ + // ioctl(fd, IOC_AVS_SET_VOLUME, 0); /* max gain */ + } + + close(fd); +#elif HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE + if (f) { + FILE *pll0 = fopen ("/proc/cpu_frequ/pll0_ndiv_mdiv", "w"); + if (pll0) { + f /= 1000000; + fprintf(pll0, "%lu\n", (f/10 << 8) | 3); + fclose (pll0); + return false; + } + } +#endif + return true; +} + +cCpuFreqManager::cCpuFreqManager(void) +{ + lt_debug("%s\n", __func__); +} + +/* powermanager */ +bool cPowerManager::Open(void) +{ + lt_debug("%s\n", __func__); + return true; +} + +void cPowerManager::Close(void) +{ + lt_debug("%s\n", __func__); +} + +bool cPowerManager::SetStandby(bool Active, bool Passive) +{ + lt_debug("%s(%d, %d)\n", __func__, Active, Passive); + return true; +} + +cPowerManager::cPowerManager(void) +{ + lt_debug("%s\n", __func__); +} + +cPowerManager::~cPowerManager() +{ + lt_debug("%s\n", __func__); +} diff --git a/generic-pc/Makefile.am b/generic-pc/Makefile.am index fdab1bf..baf15da 100644 --- a/generic-pc/Makefile.am +++ b/generic-pc/Makefile.am @@ -1,6 +1,7 @@ noinst_LTLIBRARIES = libgeneric.la -AM_CPPFLAGS = \ +AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS +AM_CPPFLAGS += \ -I$(top_srcdir)/common \ -I$(top_srcdir)/include @@ -21,7 +22,6 @@ libgeneric_la_SOURCES = \ audio.cpp \ glfb.cpp \ init.cpp \ - pwrmngr.cpp \ record.cpp if ENABLE_GSTREAMER_01 @@ -43,5 +43,3 @@ libgeneric_la_SOURCES += \ playback.cpp endif endif - -AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/generic-pc/pwrmngr.cpp b/generic-pc/pwrmngr.cpp deleted file mode 120000 index cee9acb..0000000 --- a/generic-pc/pwrmngr.cpp +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.cpp \ No newline at end of file diff --git a/generic-pc/pwrmngr.h b/generic-pc/pwrmngr.h deleted file mode 120000 index e63e97b..0000000 --- a/generic-pc/pwrmngr.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.h \ No newline at end of file diff --git a/include/pwrmngr.h b/include/pwrmngr.h index 74fc806..167929a 100644 --- a/include/pwrmngr.h +++ b/include/pwrmngr.h @@ -1,20 +1,47 @@ -#include -#if HAVE_TRIPLEDRAGON -#include "../libtriple/pwrmngr.h" -#elif HAVE_DUCKBOX_HARDWARE -#include "../libduckbox/pwrmngr.h" -#elif HAVE_SPARK_HARDWARE -#include "../libspark/pwrmngr.h" -#elif HAVE_ARM_HARDWARE -#include "../libarmbox/pwrmngr.h" -#elif HAVE_AZBOX_HARDWARE -#include "../azbox/pwrmngr.h" -#elif HAVE_GENERIC_HARDWARE -#if BOXMODEL_RASPI -#include "../raspi/pwrmngr.h" -#else -#include "../generic-pc/pwrmngr.h" -#endif -#else -#error neither HAVE_TRIPLEDRAGON nor HAVE_SPARK_HARDWARE defined +/* + * (C) 2010-2013 Stefan Seyfried + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef __pwrmngr_hal__ +#define __pwrmngr_hal__ + +class cCpuFreqManager +{ +public: + cCpuFreqManager(void); + void Up(void); + void Down(void); + void Reset(void); + + bool SetCpuFreq(unsigned long CpuFreq); + bool SetDelta(unsigned long Delta); + unsigned long GetCpuFreq(void); + unsigned long GetDelta(void); +}; + +class cPowerManager +{ +public: + cPowerManager(void); + virtual ~cPowerManager(); + + bool Open(void); + void Close(void); + + bool SetStandby(bool Active, bool Passive); +}; + #endif diff --git a/libarmbox/Makefile.am b/libarmbox/Makefile.am index 227f506..4d5c162 100644 --- a/libarmbox/Makefile.am +++ b/libarmbox/Makefile.am @@ -20,7 +20,6 @@ libarmbox_la_SOURCES = \ video.cpp \ audio.cpp \ init.cpp \ - pwrmngr.cpp \ record.cpp if ENABLE_GSTREAMER_10 diff --git a/libarmbox/pwrmngr.cpp b/libarmbox/pwrmngr.cpp deleted file mode 100644 index f4eff66..0000000 --- a/libarmbox/pwrmngr.cpp +++ /dev/null @@ -1,32 +0,0 @@ -#include - -#include "pwrmngr.h" -#include "lt_debug.h" -#include -#include -#include -#include -#include - -#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args) -void cCpuFreqManager::Up(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Down(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Reset(void) { lt_debug("%s\n", __FUNCTION__); } -/* those function dummies return true or "harmless" values */ -bool cCpuFreqManager::SetDelta(unsigned long) { lt_debug("%s\n", __FUNCTION__); return true; } -unsigned long cCpuFreqManager::GetCpuFreq(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -unsigned long cCpuFreqManager::GetDelta(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -// -cCpuFreqManager::cCpuFreqManager(void) { lt_debug("%s\n", __FUNCTION__); } - -bool cPowerManager::SetState(PWR_STATE) { lt_debug("%s\n", __FUNCTION__); return true; } - -bool cPowerManager::Open(void) { lt_debug("%s\n", __FUNCTION__); return true; } -void cPowerManager::Close(void) { lt_debug("%s\n", __FUNCTION__); } -// -bool cPowerManager::SetStandby(bool Active, bool Passive) { lt_debug("%s(%d, %d)\n", __FUNCTION__, Active, Passive); return true; } -bool cCpuFreqManager::SetCpuFreq(unsigned long f) { lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false"); return true; } -// -cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); } -cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); } - diff --git a/libarmbox/pwrmngr.h b/libarmbox/pwrmngr.h deleted file mode 100644 index 55dc984..0000000 --- a/libarmbox/pwrmngr.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __PWRMNGR_H__ -#define __PWRMNGR_H__ - -// -- cCpuFreqManager ---------------------------------------------------------- - -class cCpuFreqManager { -private: - unsigned long startCpuFreq; - unsigned long delta; -public: - void Up(void); - void Down(void); - void Reset(void); - // - bool SetCpuFreq(unsigned long CpuFreq); - bool SetDelta(unsigned long Delta); - unsigned long GetCpuFreq(void); - unsigned long GetDelta(void); - // - cCpuFreqManager(void); - -}; - -// -- cPowerManageger ---------------------------------------------------------- - -typedef enum -{ - PWR_INIT = 1, - PWR_FULL_ACTIVE, /* all devices/clocks up */ - PWR_ACTIVE_STANDBY, - PWR_PASSIVE_STANDBY, - PWR_INVALID -} PWR_STATE; - -class cPowerManager { -private: - bool init; - bool opened; - PWR_STATE powerState; - // - static void ApplicationCallback(void *, void *, signed long, void *, void *) {} - bool SetState(PWR_STATE PowerState); -public: - bool Open(void); - void Close(void); - // - bool SetStandby(bool Active, bool Passive); - // - cPowerManager(void); - virtual ~cPowerManager(); -}; - -#endif // __PWRMNGR_H__ diff --git a/libduckbox/Makefile.am b/libduckbox/Makefile.am index 2568f0b..5b47cab 100644 --- a/libduckbox/Makefile.am +++ b/libduckbox/Makefile.am @@ -22,7 +22,6 @@ libduckbox_la_SOURCES = \ audio_mixer.cpp \ init.cpp \ playback_libeplayer3.cpp \ - pwrmngr.cpp \ record.cpp AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/libduckbox/pwrmngr.cpp b/libduckbox/pwrmngr.cpp deleted file mode 120000 index cee9acb..0000000 --- a/libduckbox/pwrmngr.cpp +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.cpp \ No newline at end of file diff --git a/libduckbox/pwrmngr.h b/libduckbox/pwrmngr.h deleted file mode 120000 index e63e97b..0000000 --- a/libduckbox/pwrmngr.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.h \ No newline at end of file diff --git a/libspark/Makefile.am b/libspark/Makefile.am index 4864195..74f9837 100644 --- a/libspark/Makefile.am +++ b/libspark/Makefile.am @@ -6,7 +6,6 @@ AM_CPPFLAGS = \ -I$(top_srcdir)/libeplayer3/include AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing - AM_LDFLAGS = \ -lOpenThreads \ @AVFORMAT_LIBS@ \ @@ -23,7 +22,6 @@ libspark_la_SOURCES = \ audio_mixer.cpp \ init.cpp \ playback_libeplayer3.cpp \ - pwrmngr.cpp \ record.cpp AM_CPPFLAGS += -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS diff --git a/libspark/pwrmngr.cpp b/libspark/pwrmngr.cpp deleted file mode 100644 index b5ab30a..0000000 --- a/libspark/pwrmngr.cpp +++ /dev/null @@ -1,102 +0,0 @@ -#include - -#include "pwrmngr.h" -#include "lt_debug.h" -#include -#include -#include -#include -#include - -#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args) -void cCpuFreqManager::Up(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Down(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Reset(void) { lt_debug("%s\n", __FUNCTION__); } -/* those function dummies return true or "harmless" values */ -bool cCpuFreqManager::SetDelta(unsigned long) { lt_debug("%s\n", __FUNCTION__); return true; } -#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE -unsigned long cCpuFreqManager::GetCpuFreq(void) { - int freq = 0; - if (FILE *pll0 = fopen("/proc/cpu_frequ/pll0_ndiv_mdiv", "r")) { - char buffer[120]; - while(fgets(buffer, sizeof(buffer), pll0)) { - if (1 == sscanf(buffer, "SH4 = %d MHZ", &freq)) - break; - } - fclose(pll0); - return 1000 * 1000 * (unsigned long) freq; - } - return 0; -} -#else -unsigned long cCpuFreqManager::GetCpuFreq(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -#endif -unsigned long cCpuFreqManager::GetDelta(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -// -cCpuFreqManager::cCpuFreqManager(void) { lt_debug("%s\n", __FUNCTION__); } - -bool cPowerManager::SetState(PWR_STATE) { lt_debug("%s\n", __FUNCTION__); return true; } - -bool cPowerManager::Open(void) { lt_debug("%s\n", __FUNCTION__); return true; } -void cPowerManager::Close(void) { lt_debug("%s\n", __FUNCTION__); } -// -bool cPowerManager::SetStandby(bool Active, bool Passive) -{ - lt_debug("%s(%d, %d)\n", __FUNCTION__, Active, Passive); - return true; -} - -bool cCpuFreqManager::SetCpuFreq(unsigned long f) -{ -#if HAVE_SPARK_HARDWARE || HAVE_DUCKBOX_HARDWARE - if (f) { - FILE *pll0 = fopen ("/proc/cpu_frequ/pll0_ndiv_mdiv", "w"); - if (pll0) { - f /= 1000000; - fprintf(pll0, "%lu\n", (f/10 << 8) | 3); - fclose (pll0); - return false; - } - } -#else - /* actually SetCpuFreq is used to determine if the system is in standby - this is an "elegant" hack, because: - * during a recording, cpu freq is kept "high", even if the box is sent to standby - * the "SetStandby" call is made even if a recording is running - On the TD, setting standby disables the frontend, so we must not do it - if a recording is running. - For now, the values in neutrino are hardcoded: - * f == 0 => max => not standby - * f == 50000000 => min => standby - */ - lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false"); -#if 0 - int fd = open("/dev/stb/tdsystem", O_RDONLY); - if (fd < 0) - { - perror("open tdsystem"); - return false; - } - if (f) - { - ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ - ioctl(fd, IOC_AVS_STANDBY_ENTER); - } - else - { - ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ - ioctl(fd, IOC_AVS_STANDBY_LEAVE); - /* unmute will be done by cAudio::do_mute(). Ugly, but prevents pops */ - // ioctl(fd, IOC_AVS_SET_VOLUME, 0); /* max gain */ - } - - close(fd); -#endif -#endif - return true; -} - -// -cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); } -cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); } - diff --git a/libspark/pwrmngr.h b/libspark/pwrmngr.h deleted file mode 100644 index 55dc984..0000000 --- a/libspark/pwrmngr.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __PWRMNGR_H__ -#define __PWRMNGR_H__ - -// -- cCpuFreqManager ---------------------------------------------------------- - -class cCpuFreqManager { -private: - unsigned long startCpuFreq; - unsigned long delta; -public: - void Up(void); - void Down(void); - void Reset(void); - // - bool SetCpuFreq(unsigned long CpuFreq); - bool SetDelta(unsigned long Delta); - unsigned long GetCpuFreq(void); - unsigned long GetDelta(void); - // - cCpuFreqManager(void); - -}; - -// -- cPowerManageger ---------------------------------------------------------- - -typedef enum -{ - PWR_INIT = 1, - PWR_FULL_ACTIVE, /* all devices/clocks up */ - PWR_ACTIVE_STANDBY, - PWR_PASSIVE_STANDBY, - PWR_INVALID -} PWR_STATE; - -class cPowerManager { -private: - bool init; - bool opened; - PWR_STATE powerState; - // - static void ApplicationCallback(void *, void *, signed long, void *, void *) {} - bool SetState(PWR_STATE PowerState); -public: - bool Open(void); - void Close(void); - // - bool SetStandby(bool Active, bool Passive); - // - cPowerManager(void); - virtual ~cPowerManager(); -}; - -#endif // __PWRMNGR_H__ diff --git a/libtriple/pwrmngr.cpp b/libtriple/pwrmngr.cpp deleted file mode 100644 index e526246..0000000 --- a/libtriple/pwrmngr.cpp +++ /dev/null @@ -1,87 +0,0 @@ -#include -#include - -#include "pwrmngr.h" -#include "lt_debug.h" -#include -#include -#include -#include -#include - -#include -#include - -#define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_PWRMNGR, this, args) -#define lt_info(args...) _lt_info(TRIPLE_DEBUG_PWRMNGR, this, args) -void cCpuFreqManager::Up(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Down(void) { lt_debug("%s\n", __FUNCTION__); } -void cCpuFreqManager::Reset(void) { lt_debug("%s\n", __FUNCTION__); } -/* those function dummies return true or "harmless" values */ -bool cCpuFreqManager::SetDelta(unsigned long) { lt_debug("%s\n", __FUNCTION__); return true; } -unsigned long cCpuFreqManager::GetCpuFreq(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -unsigned long cCpuFreqManager::GetDelta(void) { lt_debug("%s\n", __FUNCTION__); return 0; } -// -cCpuFreqManager::cCpuFreqManager(void) { lt_debug("%s\n", __FUNCTION__); } - -bool cPowerManager::SetState(PWR_STATE) { lt_debug("%s\n", __FUNCTION__); return true; } - -bool cPowerManager::Open(void) { lt_debug("%s\n", __FUNCTION__); return true; } -void cPowerManager::Close(void) { lt_debug("%s\n", __FUNCTION__); } -// -bool cPowerManager::SetStandby(bool Active, bool Passive) -{ - lt_debug("%s(%d, %d)\n", __FUNCTION__, Active, Passive); - return true; -} - -bool cCpuFreqManager::SetCpuFreq(unsigned long f) -{ - /* actually SetCpuFreq is used to determine if the system is in standby - this is an "elegant" hack, because: - * during a recording, cpu freq is kept "high", even if the box is sent to standby - * the "SetStandby" call is made even if a recording is running - On the TD, setting standby disables the frontend, so we must not do it - if a recording is running. - For now, the values in neutrino are hardcoded: - * f == 0 => max => not standby - * f == 50000000 => min => standby - */ - lt_debug("%s(%lu) => set standby = %s\n", __FUNCTION__, f, f?"true":"false"); - int fd = open("/dev/stb/tdsystem", O_RDONLY); - if (fd < 0) - { - perror("open tdsystem"); - return false; - } - if (f) - { - ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ - ioctl(fd, IOC_AVS_STANDBY_ENTER); - if (getenv("TRIPLE_LCDBACKLIGHT")) - { - lt_info("%s: TRIPLE_LCDBACKLIGHT is set: keeping LCD backlight on\n", __func__); - close(fd); - fd = open("/dev/stb/tdlcd", O_RDONLY); - if (fd < 0) - lt_info("%s: open tdlcd error: %m\n", __func__); - else - ioctl(fd, IOC_LCD_BACKLIGHT_ON); - } - } - else - { - ioctl(fd, IOC_AVS_SET_VOLUME, 31); /* mute AVS to avoid ugly noise */ - ioctl(fd, IOC_AVS_STANDBY_LEAVE); - /* unmute will be done by cAudio::do_mute(). Ugly, but prevents pops */ - // ioctl(fd, IOC_AVS_SET_VOLUME, 0); /* max gain */ - } - - close(fd); - return true; -} - -// -cPowerManager::cPowerManager(void) { lt_debug("%s\n", __FUNCTION__); } -cPowerManager::~cPowerManager() { lt_debug("%s\n", __FUNCTION__); } - diff --git a/libtriple/pwrmngr.h b/libtriple/pwrmngr.h deleted file mode 100644 index 55dc984..0000000 --- a/libtriple/pwrmngr.h +++ /dev/null @@ -1,53 +0,0 @@ -#ifndef __PWRMNGR_H__ -#define __PWRMNGR_H__ - -// -- cCpuFreqManager ---------------------------------------------------------- - -class cCpuFreqManager { -private: - unsigned long startCpuFreq; - unsigned long delta; -public: - void Up(void); - void Down(void); - void Reset(void); - // - bool SetCpuFreq(unsigned long CpuFreq); - bool SetDelta(unsigned long Delta); - unsigned long GetCpuFreq(void); - unsigned long GetDelta(void); - // - cCpuFreqManager(void); - -}; - -// -- cPowerManageger ---------------------------------------------------------- - -typedef enum -{ - PWR_INIT = 1, - PWR_FULL_ACTIVE, /* all devices/clocks up */ - PWR_ACTIVE_STANDBY, - PWR_PASSIVE_STANDBY, - PWR_INVALID -} PWR_STATE; - -class cPowerManager { -private: - bool init; - bool opened; - PWR_STATE powerState; - // - static void ApplicationCallback(void *, void *, signed long, void *, void *) {} - bool SetState(PWR_STATE PowerState); -public: - bool Open(void); - void Close(void); - // - bool SetStandby(bool Active, bool Passive); - // - cPowerManager(void); - virtual ~cPowerManager(); -}; - -#endif // __PWRMNGR_H__ diff --git a/raspi/pwrmngr.cpp b/raspi/pwrmngr.cpp deleted file mode 120000 index cee9acb..0000000 --- a/raspi/pwrmngr.cpp +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.cpp \ No newline at end of file diff --git a/raspi/pwrmngr.h b/raspi/pwrmngr.h deleted file mode 120000 index e63e97b..0000000 --- a/raspi/pwrmngr.h +++ /dev/null @@ -1 +0,0 @@ -../libspark/pwrmngr.h \ No newline at end of file From 313ecf2f3f5abb0f504bddeb189f61f017ca424f Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Mon, 26 Feb 2018 18:10:20 +0100 Subject: [PATCH 29/38] add screenshot for hd51 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/9b30bc7d8185c1ed947193a7774be05483079be4 Author: Jacek Jendrzej Date: 2018-02-26 (Mon, 26 Feb 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 254 +++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 250 insertions(+), 4 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 360b58c..901d620 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -45,6 +45,7 @@ extern "C" #include #include #include +#include } #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args) @@ -842,11 +843,256 @@ void cVideo::SetColorFormat(COLOR_FORMAT color_format) { proc_put("/proc/stb/video/hdmi_colorspace", p, strlen(p)); } -/* TODO: aspect ratio correction and PIP */ -bool cVideo::GetScreenImage(unsigned char * &video, int &xres, int &yres, bool get_video, bool get_osd, bool scale_to_video) +bool getvideo2(unsigned char *video, int xres, int yres) { - lt_info("%s: video 0x%p xres %d yres %d vid %d osd %d scale %d\n", - __func__, video, xres, yres, get_video, get_osd, scale_to_video); + if(video == NULL) + return false; + char videosnapshot[] = "/dev/dvb/adapter0/video0"; + int fd_video = open(videosnapshot, O_RDONLY); + if (fd_video < 0) { + perror(videosnapshot); + return false; + } + ssize_t r = read(fd_video, video, xres * yres * 3); + close(fd_video); + return true; +} +static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh, AVPixelFormat sfmt) +{ + bool ret = false; + int len = 0; + struct SwsContext *scale = NULL; + scale = sws_getCachedContext(scale, sw, sh, sfmt, dw, dh, AV_PIX_FMT_RGB32, SWS_BICUBIC, 0, 0, 0); + if (!scale) { + lt_info_c("%s: ERROR setting up SWS context\n", __func__); + return ret; + } + AVFrame *sframe = av_frame_alloc(); + AVFrame *dframe = av_frame_alloc(); + if (sframe && dframe) { + len = av_image_fill_arrays(sframe->data, sframe->linesize, &(src)[0], sfmt, sw, sh, 1); + if(len>-1) + ret = true; + + if(ret && (len = av_image_fill_arrays(dframe->data, dframe->linesize, &(dst)[0], AV_PIX_FMT_RGB32, dw, dh, 1)<0)) + ret = false; + + if(ret && (len = sws_scale(scale, sframe->data, sframe->linesize, 0, sh, dframe->data, dframe->linesize)<0)) + ret = false; + else + ret = true; + }else{ + lt_info_c("%s: could not alloc sframe (%p) or dframe (%p)\n", __func__, sframe, dframe); + ret = false; + } + + if(sframe){ + av_frame_free(&sframe); + sframe = NULL; + } + if(dframe){ + av_frame_free(&dframe); + dframe = NULL; + } + if(scale){ + sws_freeContext(scale); + scale = NULL; + } + lt_info_c("%s: %s scale %ix%i to %ix%i ,len %i\n",ret?" ":"ERROR",__func__, sw, sh, dw, dh,len); + + return ret; +} + +// grabing the osd picture +void get_osd_size(int &xres, int &yres, int &bits_per_pixel) +{ + int fb=open("/dev/fb/0", O_RDWR); + if (fb == -1) + { + fprintf(stderr, "Framebuffer failed\n"); + return; + } + + struct fb_var_screeninfo var_screeninfo; + if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) + { + fprintf(stderr, "Framebuffer: \n"); + close(fb); + return; + } + close(fb); + + bits_per_pixel = var_screeninfo.bits_per_pixel; + xres=var_screeninfo.xres; + yres=var_screeninfo.yres; + fprintf(stderr, "... Framebuffer-Size: %d x %d\n",xres,yres); + +} +void get_osd_buf(unsigned char *osd_data) +{ + unsigned char *lfb = NULL; + struct fb_fix_screeninfo fix_screeninfo; + struct fb_var_screeninfo var_screeninfo; + + int fb=open("/dev/fb/0", O_RDWR); + if (fb == -1) + { + fprintf(stderr, "Framebuffer failed\n"); + return; + } + + if(ioctl(fb, FBIOGET_FSCREENINFO, &fix_screeninfo) == -1) + { + fprintf(stderr, "Framebuffer: \n"); + close(fb); + return; + } + + if(ioctl(fb, FBIOGET_VSCREENINFO, &var_screeninfo) == -1) + { + fprintf(stderr, "Framebuffer: \n"); + close(fb); + return; + } + + if(!(lfb = (unsigned char*)mmap(0, fix_screeninfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0))) + { + fprintf(stderr, "Framebuffer: \n"); + close(fb); + return; + } + + if ( var_screeninfo.bits_per_pixel == 32 ) + { + fprintf(stderr, "Grabbing 32bit Framebuffer ...\n"); + // get 32bit framebuffer + memcpy(osd_data,lfb,fix_screeninfo.line_length*var_screeninfo.yres); + } + close(fb); +} + +inline void rgb24torgb32(unsigned char *src, unsigned char *dest,int picsize) { + for (int i = 0; i < picsize; i++) { + *dest++ = *src++; + *dest++ = *src++; + *dest++ = *src++; + *dest++ = 255; + } +} + +/* TODO: aspect ratio correction and PIP */ +bool cVideo::GetScreenImage(unsigned char * &out_data, int &xres, int &yres, bool get_video, bool get_osd, bool scale_to_video) +{ +#define VDEC_PIXFMT AV_PIX_FMT_BGR24 + + lt_info("%s: out_data 0x%p xres %d yres %d vid %d osd %d scale %d\n", + __func__, out_data, xres, yres, get_video, get_osd, scale_to_video); + int aspect = 0; + getPictureInfo(xres, yres, aspect); /* aspect is dummy here */ + aspect = getAspectRatio(); + if(xres < 1 || yres < 1 ) + get_video = false; + + + if(!get_video && !get_osd) + return false; + + int osd_w = 0; + int osd_h = 0; + int bits_per_pixel = 0; + if(get_osd){ + get_osd_size(osd_w, osd_h, bits_per_pixel); + if(osd_w < 1 || osd_h < 1 || bits_per_pixel != 32) + get_osd = false; + if(!scale_to_video && get_osd){ + xres = osd_w; + yres = osd_h; + } + } + unsigned char *osd_data = NULL; + out_data = (unsigned char *)malloc(xres * yres * 4);/* will be freed by caller */ + if (out_data == NULL) + return false; + + if (get_video) { + const int grab_w = 1920; const int grab_h = 1080; //hd51 video0 is always 1920x1080 + unsigned char *video_src = (unsigned char *)malloc(grab_w * grab_h * 3); + if (video_src == NULL) + return false; + if(getvideo2(video_src, grab_w,grab_h) == false){ + free(out_data); + free(video_src); + return false; + } + if (grab_w != xres || grab_h != yres){ /* scale video into data... */ + bool ret = swscale(video_src, out_data, grab_w, grab_h, xres, yres,VDEC_PIXFMT); + if(!ret){ + free(out_data); + free(video_src); + return false; + } + }else{ /* get_video and no fancy scaling needed */ + rgb24torgb32(video_src, out_data, grab_w * grab_h); + } + free(video_src); + } + + if(get_osd){ + osd_data = (unsigned char *)malloc(osd_w * osd_h * 4); + if(osd_data) + get_osd_buf(osd_data); + } + + if (get_osd && (osd_w != xres || osd_h != yres)) { + /* rescale osd */ + unsigned char *osd_src = (unsigned char *)malloc(xres * yres * 4); + if(osd_src){ + bool ret = swscale(osd_data, osd_src, osd_w, osd_h, xres, yres,AV_PIX_FMT_RGB32); + if(!ret){ + free(out_data); + free(osd_data); + free(osd_src); + return false; + } + free(osd_data); + osd_data = NULL; + osd_data = osd_src; + }else{ + free(out_data); + free(osd_data); + return false; + } + } + + if (get_video && get_osd) { + /* alpha blend osd onto out_data (video). TODO: maybe libavcodec can do this? */ + uint32_t *d = (uint32_t *)out_data; + uint32_t *pixpos = (uint32_t *) osd_data; + for (int count = 0; count < yres; count++) { + for (int count2 = 0; count2 < xres; count2++ ) { + uint32_t pix = *pixpos; + if ((pix & 0xff000000) == 0xff000000) + *d = pix; + else { + uint8_t *in = (uint8_t *)(pixpos); + uint8_t *out = (uint8_t *)d; + int a = in[3]; /* TODO: big/little endian? */ + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + in++; out++; + *out = (*out + ((*in - *out) * a) / 256); + } + d++; + pixpos++; + } + } + } + else if (get_osd) /* only get_osd, out_data is not yet populated */ + memcpy(out_data, osd_data, xres * yres * sizeof(uint32_t)); + + if(osd_data) + free(osd_data); return true; } From 75af85cb638dd6b633aa850c17f543c411395550 Mon Sep 17 00:00:00 2001 From: Thilo Graf Date: Tue, 13 Mar 2018 22:20:11 +0100 Subject: [PATCH 30/38] libarmbox/video.cpp: fix possible compile error error: unused variable 'r' [-Werror=unused-variable] Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e10b5fd6f2e53dd9302f788b88e645a5a704d858 Author: Thilo Graf Date: 2018-03-13 (Tue, 13 Mar 2018) ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 901d620..b582b29 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -853,7 +853,7 @@ bool getvideo2(unsigned char *video, int xres, int yres) perror(videosnapshot); return false; } - ssize_t r = read(fd_video, video, xres * yres * 3); + //ssize_t r = read(fd_video, video, xres * yres * 3); close(fd_video); return true; } From 161ba28427cfc4951d493685aac53b05d2bcc95a Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 22 Mar 2018 13:38:29 +0100 Subject: [PATCH 31/38] fix commit 6d8a853e823d46f8b8ebbfc15fab938a6fde5e75 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/d3201d6c49b2cc024610e38bf36c4be7fa98393d Author: Jacek Jendrzej Date: 2018-03-22 (Thu, 22 Mar 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index b582b29..a9f6bda 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -845,17 +845,21 @@ void cVideo::SetColorFormat(COLOR_FORMAT color_format) { bool getvideo2(unsigned char *video, int xres, int yres) { + bool ret = false; if(video == NULL) - return false; + return ret; char videosnapshot[] = "/dev/dvb/adapter0/video0"; int fd_video = open(videosnapshot, O_RDONLY); if (fd_video < 0) { perror(videosnapshot); - return false; + return ret; + } + ssize_t r = read(fd_video, video, xres * yres * 3); + if(r){ + ret = true; } - //ssize_t r = read(fd_video, video, xres * yres * 3); close(fd_video); - return true; + return ret; } static bool swscale(unsigned char *src, unsigned char *dst, int sw, int sh, int dw, int dh, AVPixelFormat sfmt) { From 494e3964fd4b4c1e67882650e481f1375e1f648a Mon Sep 17 00:00:00 2001 From: samsamsam Date: Fri, 30 Mar 2018 14:29:35 +0200 Subject: [PATCH 32/38] Do not wait in the FFMPEG thread. Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/dbeb0884cfd6bb404ce61148ef94a854ae9604b7 Author: samsamsam Date: 2018-03-30 (Fri, 30 Mar 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 27 +++++++++++++++----- libeplayer3-arm/container/flv2mpeg4_ffmpeg.c | 2 +- libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 2 +- libeplayer3-arm/main/exteplayer.c | 18 +++++++++++-- 4 files changed, 38 insertions(+), 11 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 5fec340..874e78f 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -182,7 +182,7 @@ static void releaseMutex(const char *filename __attribute__((unused)), const con typedef int32_t (* Write_FN)(Context_t *context, void *); -static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData) +static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData, int64_t pts __attribute__((unused))) { /* Because Write is blocking we will release mutex which protect * avformat structures, during write time @@ -485,6 +485,10 @@ static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) { pts = INVALID_PTS_VALUE; } + else + { + pts &= 0x01FFFFFFFF; // PES header can handle only 33 bit PTS + } return pts; } @@ -571,6 +575,14 @@ static void FFMPEGThread(Context_t *context) int8_t isWaitingForFinish = 0; while (context && context->playback && context->playback->isPlaying) { + /* When user press PAUSE we call pause on AUDIO and VIDEO decoders, + * we will not wait here because we can still fill + * DVB drivers buffers at PAUSE time + * + * In the future we can add buffering queue before injection in to + * AUDIO, VIDEO decoders, so we can not wait here + */ +#ifdef __sh__ //IF MOVIE IS PAUSED, WAIT if (context->playback->isPaused) { @@ -579,6 +591,7 @@ static void FFMPEGThread(Context_t *context) usleep(10000); continue; } +#endif if (context->playback->isSeeking) { ffmpeg_printf(10, "seeking\n"); @@ -835,7 +848,7 @@ static void FFMPEGThread(Context_t *context) { avOut.infoFlags = 1; // TS container } - if (Write(context->output->video->Write, context, &avOut) < 0) + if (Write(context->output->video->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to video device failed\n"); } @@ -903,7 +916,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (Write(context->output->audio->Write, context, &avOut) < 0) + if (Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("(raw pcm) writing data to audio device failed\n"); } @@ -1079,7 +1092,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to audio device failed\n"); } @@ -1100,7 +1113,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("(aac) writing data to audio device failed\n"); } @@ -1117,7 +1130,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; - if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut) < 0) + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to audio device failed\n"); } @@ -1146,7 +1159,7 @@ static void FFMPEGThread(Context_t *context) subOut.data = (uint8_t *)packet.data; subOut.pts = pts; subOut.durationMS = duration; - if (Write(context->output->subtitle->Write, context, &subOut) < 0) + if (Write(context->output->subtitle->Write, context, &subOut, pts) < 0) { ffmpeg_err("writing data to teletext fifo failed\n"); } diff --git a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c index a96e055..8f72216 100644 --- a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c +++ b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c @@ -34,7 +34,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p avOut.width = ctx->track->width; avOut.height = ctx->track->height; avOut.type = "video"; - if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut) < 0) + if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut, avOut.pts) < 0) { ffmpeg_err("writing data to video device failed\n"); } diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index f77ef73..74a5559 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -107,7 +107,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6 avOut.width = track->width; avOut.height = track->height; avOut.type = "video"; - if (Write(ctx->output->video->Write, ctx, &avOut) < 0) + if (Write(ctx->output->video->Write, ctx, &avOut, avOut.pts) < 0) { ffmpeg_err("writing data to video device failed\n"); } diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index d7c2c19..0589587 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -635,7 +635,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 39); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 40); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); @@ -922,7 +922,21 @@ int main(int argc, char *argv[]) commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); + int64_t lastPts = 0; + commandRetVal = 1; + if (g_player->container && g_player->container->selectedContainer) + { + commandRetVal = g_player->container->selectedContainer->Command((Context_t*)g_player->container, CONTAINER_LAST_PTS, &lastPts); + } + + if (0 == commandRetVal && lastPts != INVALID_PTS_VALUE) + { + fprintf(stderr, "{\"J\":{\"ms\":%lld,\"lms\":%lld}}\n", pts / 90, lastPts / 90); + } + else + { + fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); + } } break; } From 96ff564f451ee5bcdf9b033067546667a9ff59de Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sat, 31 Mar 2018 11:39:41 +0200 Subject: [PATCH 33/38] Add buffering for Linux DVB outputs Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/4202cff1c5706ae07470b73c1b003c824ebfa8cc Author: samsamsam Date: 2018-03-31 (Sat, 31 Mar 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/Makefile.am | 1 + libeplayer3-arm/include/output.h | 1 + libeplayer3-arm/include/writer.h | 1 + libeplayer3-arm/main/exteplayer.c | 16 +- libeplayer3-arm/output/linuxdvb_buffering.c | 389 +++++++++++++++++++ libeplayer3-arm/output/linuxdvb_mipsel.c | 380 +++++------------- libeplayer3-arm/output/output.c | 41 +- libeplayer3-arm/output/writer/mipsel/aac.c | 6 +- libeplayer3-arm/output/writer/mipsel/ac3.c | 2 +- libeplayer3-arm/output/writer/mipsel/amr.c | 2 +- libeplayer3-arm/output/writer/mipsel/divx3.c | 2 +- libeplayer3-arm/output/writer/mipsel/dts.c | 2 +- libeplayer3-arm/output/writer/mipsel/h263.c | 2 +- libeplayer3-arm/output/writer/mipsel/h264.c | 5 +- libeplayer3-arm/output/writer/mipsel/h265.c | 5 +- libeplayer3-arm/output/writer/mipsel/lpcm.c | 2 +- libeplayer3-arm/output/writer/mipsel/mp3.c | 2 +- libeplayer3-arm/output/writer/mipsel/mpeg2.c | 2 +- libeplayer3-arm/output/writer/mipsel/mpeg4.c | 2 +- libeplayer3-arm/output/writer/mipsel/pcm.c | 4 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 2 +- libeplayer3-arm/output/writer/mipsel/vp.c | 2 +- libeplayer3-arm/output/writer/mipsel/wma.c | 2 +- libeplayer3-arm/output/writer/mipsel/wmv.c | 2 +- libeplayer3-arm/playback/playback.c | 8 - 25 files changed, 563 insertions(+), 320 deletions(-) create mode 100644 libeplayer3-arm/output/linuxdvb_buffering.c diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index b1bdd32..1f7f51e 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -21,6 +21,7 @@ libeplayer3_arm_la_SOURCES = \ output/linuxdvb_mipsel.c \ output/output_subtitle.c \ output/output.c \ + output/linuxdvb_buffering.c \ output/writer/common/pes.c \ output/writer/common/misc.c \ output/writer/mipsel/writer.c \ diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index 5b0fedb..16a61f1 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -28,6 +28,7 @@ typedef enum OUTPUT_DISCONTINUITY_REVERSE, OUTPUT_GET_FRAME_COUNT, OUTPUT_GET_PROGRESSIVE, + OUTPUT_SET_BUFFER_SIZE, } OutputCmd_t; typedef struct diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index c027899..28c74d3 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -22,6 +22,7 @@ typedef struct unsigned int Height; unsigned char Version; unsigned int InfoFlags; + ssize_t (* WriteV) (int, const struct iovec *, size_t); } WriterAVCallData_t; typedef struct WriterCaps_s diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 0589587..a71e33b 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -480,14 +480,14 @@ static void UpdateVideoTrack() HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); } -static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx) +static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB) { int ret = 0; int c; //int digit_optind = 0; //int aopt = 0, bopt = 0; //char *copt = 0, *dopt = 0; - while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:")) != -1) + while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1) { switch (c) { @@ -597,6 +597,9 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int free(ffopt); break; } + case 'b': + *linuxDvbBufferSizeMB = 1024 * 1024 * atoi(optarg); + break; default: printf("?? getopt returned character code 0%o ??\n", c); ret = -1; @@ -631,14 +634,16 @@ int main(int argc, char *argv[]) memset(audioFile, '\0', sizeof(audioFile)); int audioTrackIdx = -1; int subtitleTrackIdx = -1; + uint32_t linuxDvbBufferSizeMB = 0; char argvBuff[256]; memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 40); - if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx)) + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 41); + if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); + printf("[-b size] Linux DVB output buffer size in MB\n"); printf("[-a 0|1|2|3] AAC software decoding - 1 bit - AAC ADTS, 2 - bit AAC LATM\n"); printf("[-e] EAC3 software decoding\n"); printf("[-3] AC3 software decoding\n"); @@ -707,6 +712,9 @@ int main(int argc, char *argv[]) g_player->output->Command(g_player, OUTPUT_ADD, "audio"); g_player->output->Command(g_player, OUTPUT_ADD, "video"); g_player->output->Command(g_player, OUTPUT_ADD, "subtitle"); + //Set LINUX DVB additional write buffer size + if (linuxDvbBufferSizeMB) + g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB); g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack); if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4)) { diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c new file mode 100644 index 0000000..c8f106e --- /dev/null +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -0,0 +1,389 @@ +/* + * RAM write buffering utilities + * samsamsam 2018 + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* ***************************** */ +/* Includes */ +/* ***************************** */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "misc.h" +#include "writer.h" + +/* ***************************** */ +/* Types */ +/* ***************************** */ +typedef enum OutputType_e{ + OUTPUT_UNK, + OUTPUT_AUDIO, + OUTPUT_VIDEO, +} OutputType_t; + +typedef struct BufferingNode_s { + uint32_t dataSize; + OutputType_t dataType; + struct BufferingNode_s *next; +} BufferingNode_t; + +/* ***************************** */ +/* Makros/Constants */ +/* ***************************** */ +#define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0 +#define cERR_LINUX_DVB_BUFFERING_ERROR -1 + +//#define SAM_WITH_DEBUG +#ifdef SAM_WITH_DEBUG +#define LINUX_DVB_BUFFERING_DEBUG +#else +#define LINUX_DVB_BUFFERING_SILENT +#endif + +#ifdef LINUX_DVB_BUFFERING_DEBUG + +static const uint16_t debug_level = 40; + +#define buff_printf(level, fmt, x...) do { \ +if (debug_level >= level) printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTION__, ## x); } while (0) +#else +#define buff_printf(level, fmt, x...) +#endif + +#ifndef LINUX_DVB_BUFFERING_SILENT +#define buff_err(fmt, x...) do { printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTION__, ## x); } while (0) +#else +#define buff_err(fmt, x...) +#endif + +/* ***************************** */ +/* Varaibles */ +/* ***************************** */ +static pthread_t bufferingThread; +static pthread_mutex_t bufferingMtx; +static pthread_cond_t bufferingExitCond; +static pthread_cond_t bufferingDataConsumedCond; +static pthread_cond_t bufferingdDataAddedCond; +static bool hasBufferingThreadStarted = false; +static BufferingNode_t *bufferingQueueHead = NULL; +static BufferingNode_t *bufferingQueueTail = NULL; + +static uint32_t maxBufferingDataSize = 0; +static uint32_t bufferingDataSize = 0; + +static int videofd = -1; +static int audiofd = -1; + +/* ***************************** */ +/* Prototypes */ +/* ***************************** */ + +/* ***************************** */ +/* MISC Functions */ +/* ***************************** */ + +/* **************************** */ +/* Worker Thread */ +/* **************************** */ +static void LinuxDvbBuffThread(Context_t *context) +{ + static BufferingNode_t *nodePtr = NULL; + buff_printf(20, "ENTER\n"); + while (0 == PlaybackDieNow(0)) + { + pthread_mutex_lock(&bufferingMtx); + if (nodePtr) + { + free(nodePtr); + nodePtr = NULL; + /* signal that we free some space in queue */ + pthread_cond_signal(&bufferingDataConsumedCond); + } + + if (!bufferingQueueHead) + { + assert(bufferingQueueTail == NULL); + + /* Queue is empty we need to wait for data to be added */ + pthread_cond_wait(&bufferingdDataAddedCond, &bufferingMtx); + pthread_mutex_unlock(&bufferingMtx); + continue; /* To check PlaybackDieNow(0) */ + } + else + { + nodePtr = bufferingQueueHead; + bufferingQueueHead = bufferingQueueHead->next; + if (bufferingQueueHead == NULL) + { + bufferingQueueTail = NULL; + } + + if (bufferingDataSize >= (nodePtr->dataSize + sizeof(BufferingNode_t))) + { + bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); + } + else + { + assert(bufferingDataSize == 0); + bufferingDataSize = 0; + } + } + pthread_mutex_unlock(&bufferingMtx); + + /* We will write data without mutex + * this have some disadvantage because we can + * write some portion of data after LinuxDvbBuffFlush, + * for example after seek, this will be fixed later + */ + if (nodePtr && !context->playback->isSeeking) + { + /* Write data to valid output */ + uint8_t *dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t); + int fd = nodePtr->dataType == OUTPUT_VIDEO ? videofd : audiofd; + if (0 != write_with_retry(fd, dataPtr, nodePtr->dataSize)) + { + printf("Something is WRONG\n"); + } + } + } + + pthread_mutex_lock(&bufferingMtx); + pthread_cond_signal(&bufferingExitCond); + pthread_mutex_unlock(&bufferingMtx); + + buff_printf(20, "EXIT\n"); + hasBufferingThreadStarted = false; +} + +int32_t WriteSetBufferingSize(const uint32_t bufferSize) +{ + maxBufferingDataSize = bufferSize; + return cERR_LINUX_DVB_BUFFERING_NO_ERROR; +} + +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) +{ + int32_t error = 0; + int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR; + + buff_printf(10, "\n"); + + if (!hasBufferingThreadStarted) + { + pthread_attr_t attr; + pthread_attr_init(&attr); + pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + + if((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) + { + buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error)); + + hasBufferingThreadStarted = false; + ret = cERR_LINUX_DVB_BUFFERING_ERROR; + } + else + { + buff_printf(10, "Created thread\n"); + hasBufferingThreadStarted = true; + + /* init synchronization prymitives */ + pthread_mutex_init(&bufferingMtx, NULL); + + pthread_cond_init(&bufferingExitCond, NULL); + pthread_cond_init(&bufferingDataConsumedCond, NULL); + pthread_cond_init(&bufferingdDataAddedCond, NULL); + } + } + + if (!ret) + { + if (!strcmp("video", type) && -1 == videofd) + { + videofd = outfd; + } + else if (!strcmp("audio", type) && -1 == audiofd) + { + audiofd = outfd; + } + else + { + ret = cERR_LINUX_DVB_BUFFERING_ERROR; + } + } + + buff_printf(10, "exiting with value %d\n", ret); + return ret; +} + +int32_t LinuxDvbBuffClose(Context_t *context) +{ + int32_t ret = 0; + + buff_printf(10, "\n"); + videofd = -1; + audiofd = -1; + + if (hasBufferingThreadStarted) + { + struct timespec max_wait = {0, 0}; + pthread_mutex_lock(&bufferingMtx); + /* wait for thread end */ + clock_gettime(CLOCK_REALTIME, &max_wait); + max_wait.tv_sec += 1; + pthread_cond_timedwait(&bufferingExitCond, &bufferingMtx, &max_wait); + pthread_mutex_unlock(&bufferingMtx); + + if (!hasBufferingThreadStarted) + { + /* destroy synchronization prymitives? + * for a moment, we'll exit linux process, + * so the system will do this for us + */ + /* + pthread_mutex_destroy(&bufferingMtx); + pthread_cond_destroy(&bufferingDataConsumedCond); + pthread_cond_destroy(&bufferingdDataAddedCond); + */ + } + } + + ret = hasBufferingThreadStarted ? cERR_LINUX_DVB_BUFFERING_ERROR : cERR_LINUX_DVB_BUFFERING_NO_ERROR; + + buff_printf(10, "exiting with value %d\n", ret); + return ret; +} + +int32_t LinuxDvbBuffFlush(Context_t *context) +{ + static BufferingNode_t *nodePtr = NULL; + buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead); + pthread_mutex_lock(&bufferingMtx); + while (bufferingQueueHead) + { + nodePtr = bufferingQueueHead; + bufferingQueueHead = nodePtr->next; + bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); + free(nodePtr); + } + bufferingQueueHead = NULL; + bufferingQueueTail = NULL; + buff_printf(40, "bufferingDataSize [%u]\n", bufferingDataSize); + assert(bufferingDataSize == 0); + bufferingDataSize = 0; + + /* signal that queue is empty */ + pthread_cond_signal(&bufferingDataConsumedCond); + pthread_mutex_unlock(&bufferingMtx); + buff_printf(40, "EXIT\n"); + return 0; +} + +ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) +{ + OutputType_t dataType = OUTPUT_UNK; + BufferingNode_t *nodePtr = NULL; + uint8_t *dataPtr = NULL; + uint32_t chunkSize = 0; + uint32_t i = 0; + + buff_printf(60, "ENTER\n"); + if (fd == videofd) + { + buff_printf(60, "VIDEO\n"); + dataType = OUTPUT_VIDEO; + } + else if (fd == audiofd) + { + buff_printf(60, "AUDIO\n"); + dataType = OUTPUT_AUDIO; + } + else + { + buff_err("Unknown output type\n"); + return cERR_LINUX_DVB_BUFFERING_ERROR; + } + + for (i=0; i= maxBufferingDataSize) + { + /* Buffering queue is full we need wait for space*/ + pthread_cond_wait(&bufferingDataConsumedCond, &bufferingMtx); + } + else + { + /* Add chunk to buffering queue */ + if (bufferingQueueHead == NULL) + { + bufferingQueueHead = nodePtr; + bufferingQueueTail = nodePtr; + } + else + { + bufferingQueueTail->next = nodePtr; + bufferingQueueTail = nodePtr; + } + + bufferingDataSize += chunkSize; + chunkSize -= sizeof(BufferingNode_t); + nodePtr->dataSize = chunkSize; + nodePtr->dataType = dataType; + nodePtr->next = NULL; + + /* signal that we added some data to queue */ + pthread_cond_signal(&bufferingdDataAddedCond); + break; + } + } + pthread_mutex_unlock(&bufferingMtx); + buff_printf(60, "EXIT\n"); + return chunkSize; +} diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 1699f7d..4ef70df 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -93,13 +94,18 @@ struct DVBApiVideoInfo_s static struct DVBApiVideoInfo_s videoInfo = {-1, -1, -1, -1, -1}; unsigned long long int sCURRENT_PTS = 0; +bool isBufferedOutput = false; pthread_mutex_t LinuxDVBmutex; /* ***************************** */ /* Prototypes */ /* ***************************** */ - +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); +int32_t LinuxDvbBuffClose(Context_t *context); +int32_t LinuxDvbBuffFlush(Context_t *context); +ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic); +int32_t WriteSetBufferingSize(const uint32_t bufferSize); int LinuxDvbStop(Context_t *context, char *type); /* ***************************** */ @@ -108,15 +114,12 @@ int LinuxDvbStop(Context_t *context, char *type); void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { - linuxdvb_printf(250, "requesting mutex\n"); pthread_mutex_lock(&LinuxDVBmutex); - linuxdvb_printf(250, "received mutex\n"); } void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { pthread_mutex_unlock(&LinuxDVBmutex); - linuxdvb_printf(250, "released mutex\n"); } static int LinuxDvbMapBypassMode(int bypass) @@ -130,66 +133,62 @@ static int LinuxDvbMapBypassMode(int bypass) int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) { - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); if (video && videofd < 0) { videofd = open(VIDEODEV, O_RDWR | O_CLOEXEC); if (videofd < 0) { - linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno); - linuxdvb_err("%s\n", strerror(errno)); + linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno)); return cERR_LINUXDVB_ERROR; } if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(videofd, VIDEO_FREEZE) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno)); } + if (isBufferedOutput) + LinuxDvbBuffOpen(context, type, videofd); } if (audio && audiofd < 0) { audiofd = open(AUDIODEV, O_RDWR | O_CLOEXEC); if (audiofd < 0) { - linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno); - linuxdvb_err("%s\n", strerror(errno)); + linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno)); return cERR_LINUXDVB_ERROR; } if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(audiofd, AUDIO_PAUSE) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno)); } + if (isBufferedOutput) + LinuxDvbBuffOpen(context, type, audiofd); } return cERR_LINUXDVB_NO_ERROR; } int LinuxDvbClose(Context_t *context, char *type) { - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); /* closing stand alone is not allowed, so prevent * user from closing and don't call stop. stop will @@ -207,6 +206,8 @@ int LinuxDvbClose(Context_t *context, char *type) close(audiofd); audiofd = -1; } + if (isBufferedOutput) + LinuxDvbBuffClose(context); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); return cERR_LINUXDVB_NO_ERROR; } @@ -215,8 +216,8 @@ int LinuxDvbPlay(Context_t *context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; Writer_t *writer; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); if (video && videofd != -1) { @@ -224,15 +225,6 @@ int LinuxDvbPlay(Context_t *context, char *type) context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); linuxdvb_printf(10, "V %s\n", Encoding); writer = getWriter(Encoding); - // SULGE VU 4K dont like this - /* - if (0 != ioctl(videofd, VIDEO_STOP)) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - */ if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -243,27 +235,23 @@ int LinuxDvbPlay(Context_t *context, char *type) linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) writer->caps->dvbStreamType) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } free(Encoding); if (0 != ioctl(videofd, VIDEO_PLAY)) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } if (ioctl(videofd, VIDEO_CONTINUE) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } } if (audio && audiofd != -1) @@ -272,15 +260,6 @@ int LinuxDvbPlay(Context_t *context, char *type) context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); linuxdvb_printf(20, "0 A %s\n", Encoding); writer = getWriter(Encoding); - // SULGE VU 4K dont like this - /* - if (0 != ioctl(audiofd, AUDIO_STOP)) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - */ if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -291,21 +270,18 @@ int LinuxDvbPlay(Context_t *context, char *type) linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) < 0) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } if (ioctl(audiofd, AUDIO_PLAY) < 0) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } if (ioctl(audiofd, AUDIO_CONTINUE) < 0) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } free(Encoding); @@ -326,13 +302,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(videofd, VIDEO_STOP) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } ioctl(videofd, VIDEO_SLOWMOTION, 0); @@ -343,21 +317,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) { if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } - /* set back to normal speed (end trickmodes) */ - /* - if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - } - */ if (ioctl(audiofd, AUDIO_STOP) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX); @@ -368,17 +332,16 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) { - int ret = cERR_LINUXDVB_NO_ERROR; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + int32_t ret = cERR_LINUXDVB_NO_ERROR; + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (video && videofd != -1) { if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -386,8 +349,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) { if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -397,9 +359,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) { - int ret = cERR_LINUXDVB_NO_ERROR; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + int32_t ret = cERR_LINUXDVB_NO_ERROR; + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); if (video && videofd != -1) { @@ -409,8 +371,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) } if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -418,8 +379,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) { if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -427,22 +387,6 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) return ret; } -int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int *surplus __attribute__((unused))) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - /* - int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; - linuxdvb_printf(50, "\n"); - if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); - } - linuxdvb_printf(50, "exiting\n"); - */ - return ret; -} - int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) { int ret = cERR_LINUXDVB_NO_ERROR; @@ -451,25 +395,17 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) { if (*flag == '1') { - //AUDIO_SET_MUTE has no effect with new player - //if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1) if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno)); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } else { - //AUDIO_SET_MUTE has no effect with new player - //if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1) if (ioctl(audiofd, AUDIO_PLAY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno)); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -480,52 +416,23 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { - /* - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); - linuxdvb_printf(10, "v%d a%d\n", video, audio); - if ((video && videofd != -1) || (audio && audiofd != -1)) - { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - if (video && videofd != -1) - { - if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); - } - } - if (audio && audiofd != -1) - { - if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); - } - } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - linuxdvb_printf(10, "exiting\n"); - */ return cERR_LINUXDVB_NO_ERROR; } -#ifndef use_set_speed_instead_ff int LinuxDvbFastForward(Context_t *context, char *type) { - int ret = cERR_LINUXDVB_NO_ERROR; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + int32_t ret = cERR_LINUXDVB_NO_ERROR; + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); if (audio) {} linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); if (video && videofd != -1) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - /* konfetti comment: speed is a value given in skipped frames */ + // konfetti comment: speed is a value given in skipped frames if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_FAST_FORWARD: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -533,69 +440,12 @@ int LinuxDvbFastForward(Context_t *context, char *type) linuxdvb_printf(10, "exiting with value %d\n", ret); return ret; } -#else - -static unsigned int SpeedList[] = -{ - 1000, 1100, 1200, 1300, 1500, - 2000, 3000, 4000, 5000, 8000, - 12000, 16000, - 125, 250, 500, 700, 800, 900 -}; - -int LinuxDvbFastForward(Context_t *context, char *type) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - int speedIndex; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); - linuxdvb_printf(10, "v%d a%d\n", video, audio); - if (video && videofd != -1) - { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); - linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - /* - if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - */ - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - if (audio && audiofd != -1) - { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); - linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - /* - if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - */ - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - } - linuxdvb_printf(10, "exiting with value %d\n", ret); - return ret; -} -#endif - -int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) -{ - int ret = cERR_LINUXDVB_NO_ERROR; - return ret; -} int LinuxDvbSlowMotion(Context_t *context, char *type) { - int ret = cERR_LINUXDVB_NO_ERROR; - unsigned char video = !strcmp("video", type); - unsigned char audio = !strcmp("audio", type); + int32_t ret = cERR_LINUXDVB_NO_ERROR; + uint8_t video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); if ((video && videofd != -1) || (audio && audiofd != -1)) { @@ -604,8 +454,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) { if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SLOWMOTION: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_SLOWMOTION: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -617,7 +466,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { - int ret = cERR_LINUXDVB_NO_ERROR; + int32_t ret = cERR_LINUXDVB_NO_ERROR; /* konfetti: this one is dedicated to audiofd so we * are ignoring what is given by type! I think we should * remove this param. Therefor we should add a variable @@ -629,8 +478,7 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -643,7 +491,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); - linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio); + linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio); if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -651,8 +499,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -660,8 +507,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) { if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -673,17 +519,16 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) { - int ret = cERR_LINUXDVB_ERROR; + int32_t ret = cERR_LINUXDVB_ERROR; linuxdvb_printf(50, "\n"); - // pts is a non writting requests and can be done in parallel to other requests - //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); + // GET_PTS is immutable call, so it can be done in parallel to other requests if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) { ret = cERR_LINUXDVB_NO_ERROR; } else { - linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno)); + linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); } if (ret != cERR_LINUXDVB_NO_ERROR) { @@ -693,7 +538,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i } else { - linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno)); + linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); } } if (ret != cERR_LINUXDVB_NO_ERROR) @@ -701,20 +546,18 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i sCURRENT_PTS = 0; } *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; - //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); return ret; } int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount __attribute__((unused))) { - int ret = cERR_LINUXDVB_NO_ERROR; - return ret; + return cERR_LINUXDVB_NO_ERROR; } int LinuxDvbSwitch(Context_t *context, char *type) { - unsigned char audio = !strcmp("audio", type); - unsigned char video = !strcmp("video", type); + uint8_t audio = !strcmp("audio", type); + uint8_t video = !strcmp("video", type); Writer_t *writer; linuxdvb_printf(10, "v%d a%d\n", video, audio); if ((video && videofd != -1) || (audio && audiofd != -1)) @@ -730,38 +573,27 @@ int LinuxDvbSwitch(Context_t *context, char *type) writer = getWriter(Encoding); if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - /* - if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) AUDIO_ENCODING_MP3) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); - } - */ } else { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); if (ioctl(audiofd, AUDIO_SET_BYPASS_MODE, (void *) LinuxDvbMapBypassMode(writer->caps->dvbStreamType)) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_BYPASS_MODE: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); } } if (ioctl(audiofd, AUDIO_PLAY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); + linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); } free(Encoding); } @@ -778,34 +610,24 @@ int LinuxDvbSwitch(Context_t *context, char *type) context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); if (ioctl(videofd, VIDEO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); } if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } linuxdvb_printf(10, "V %s\n", Encoding); writer = getWriter(Encoding); if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); - /* - if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) VIDEO_ENCODING_AUTO) == -1) - { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); - } - */ } else { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) writer->caps->dvbStreamType) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); } } if (ioctl(videofd, VIDEO_PLAY) == -1) @@ -813,8 +635,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) /* konfetti: fixme: think on this, I think we should * return an error here and stop the playback mode */ - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno)); + linuxdvb_err("VIDEO_PLAY:ERROR %d, %s\n", errno, strerror(errno)); } free(Encoding); } @@ -832,11 +653,11 @@ int LinuxDvbSwitch(Context_t *context, char *type) static int Write(Context_t *context, void *_out) { AudioVideoOut_t *out = (AudioVideoOut_t *) _out; - int ret = cERR_LINUXDVB_NO_ERROR; - int res = 0; - unsigned char video = 0; - unsigned char audio = 0; - Writer_t *writer; + int32_t ret = cERR_LINUXDVB_NO_ERROR; + int32_t res = 0; + uint8_t video = 0; + uint8_t audio = 0; + Writer_t *writer = NULL; WriterAVCallData_t call; if (out == NULL) { @@ -921,7 +742,8 @@ static int Write(Context_t *context, void *_out) call.Width = out->width; call.Height = out->height; call.InfoFlags = out->infoFlags; - call.Version = 0; // is unsingned char + call.Version = 0; + call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; if (writer->writeData) { res = writer->writeData(&call); @@ -963,7 +785,8 @@ static int Write(Context_t *context, void *_out) call.FrameRate = out->frameRate; call.FrameScale = out->timeScale; call.InfoFlags = out->infoFlags; - call.Version = 0; /* -1; unsigned char cannot be negative */ + call.Version = 0; + call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; if (writer->writeData) { res = writer->writeData(&call); @@ -1009,6 +832,8 @@ static int reset(Context_t *context) writer->reset(); } free(Encoding); + if (isBufferedOutput) + LinuxDvbBuffFlush(context); return ret; } @@ -1065,11 +890,6 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) return LinuxDvbFastForward(context, (char *)argument); break; } - case OUTPUT_REVERSE: - { - return LinuxDvbReverse(context, (char *)argument); - break; - } case OUTPUT_AVSYNC: { ret = LinuxDvbAVSync(context, (char *)argument); @@ -1104,11 +924,6 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) return LinuxDvbAudioMute(context, (char *)argument); break; } - case OUTPUT_DISCONTINUITY_REVERSE: - { - return LinuxDvbReverseDiscontinuity(context, (int *)argument); - break; - } case OUTPUT_GET_FRAME_COUNT: { unsigned long long int frameCount = 0; @@ -1122,6 +937,21 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) *((int *)argument) = videoInfo.progressive; break; } + case OUTPUT_SET_BUFFER_SIZE: + { + ret = cERR_LINUXDVB_ERROR; + if (!isBufferedOutput) + { + uint32_t bufferSize = *((uint32_t*)argument); + ret = cERR_LINUXDVB_NO_ERROR; + if (bufferSize > 0) + { + WriteSetBufferingSize(bufferSize); + isBufferedOutput = true; + } + } + break; + } default: linuxdvb_err("ContainerCmd %d not supported!\n", command); ret = cERR_LINUXDVB_ERROR; diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 168c203..8c1580f 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -522,21 +522,40 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) ret = cERR_OUTPUT_INTERNAL_ERROR; } break; - case OUTPUT_GET_PROGRESSIVE: + } + case OUTPUT_GET_PROGRESSIVE: + { + if (context && context->playback) { - if (context && context->playback) + if (context->playback->isVideo) { - if (context->playback->isVideo) - { - return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void *) argument); - } + return context->output->video->Command(context, OUTPUT_GET_PROGRESSIVE, (void *) argument); } - else - { - ret = cERR_OUTPUT_INTERNAL_ERROR; - } - break; } + else + { + ret = cERR_OUTPUT_INTERNAL_ERROR; + } + break; + } + case OUTPUT_SET_BUFFER_SIZE: + { + if (context && context->playback) + { + if (context->output->video) + { + return context->output->video->Command(context, OUTPUT_SET_BUFFER_SIZE, argument); + } + else if (context->output->audio) + { + return context->output->audio->Command(context, OUTPUT_SET_BUFFER_SIZE, argument); + } + } + else + { + ret = cERR_OUTPUT_INTERNAL_ERROR; + } + break; } default: output_err("%s::%s OutputCmd %d not supported!\n", __FILE__, __FUNCTION__, command); diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index 8e6d163..c1cec2d 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -195,7 +195,7 @@ static int _writeData(WriterAVCallData_t *call, int type) iov[0].iov_len = HeaderLength; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - return writev_with_retry(call->fd, iov, 2); + return call->WriteV(call->fd, iov, 2); } static int writeDataADTS(WriterAVCallData_t *call) @@ -253,7 +253,7 @@ static int writeDataADTS(WriterAVCallData_t *call) iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - return writev_with_retry(call->fd, iov, 2); + return call->WriteV(call->fd, iov, 2); } static int writeDataLATM(WriterAVCallData_t *call) @@ -309,7 +309,7 @@ static int writeDataLATM(WriterAVCallData_t *call) iov[1].iov_len = 3; iov[2].iov_base = pLATMCtx->buffer; iov[2].iov_len = pLATMCtx->len; - return writev_with_retry(call->fd, iov, 3); + return call->WriteV(call->fd, iov, 3); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index b71b089..37ee989 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -126,7 +126,7 @@ static int writeData(WriterAVCallData_t *call) iov[1].iov_base = call->data; iov[1].iov_len = call->len; ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len); - return writev_with_retry(call->fd, iov, 2); + return call->WriteV(call->fd, iov, 2); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/amr.c b/libeplayer3-arm/output/writer/mipsel/amr.c index cb843b5..d509ea5 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -145,7 +145,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = headerSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - int len = writev_with_retry(call->fd, iov, 2); + int len = call->WriteV(call->fd, iov, 2); amr_printf(10, "amr_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index 98f1f4a..de7ebab 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -169,7 +169,7 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = headerSize; iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; - int len = writev_with_retry(call->fd, iov, ic); + int len = call->WriteV(call->fd, iov, ic); divx_printf(10, "xvid_Write < len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index b56969b..beb8e28 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -150,7 +150,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = Data; iov[1].iov_len = Size; - int32_t len = writev_with_retry(call->fd, iov, 2); + int32_t len = call->WriteV(call->fd, iov, 2); dts_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/h263.c index 152b026..39c4ed2 100644 --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/h263.c @@ -125,7 +125,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = HeaderLength; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - len = writev_with_retry(call->fd, iov, 2); + len = call->WriteV(call->fd, iov, 2); h263_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 9855288..4dbf2b6 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -55,6 +55,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ +#define H264_SILENT //#define H264_DEBUG #ifdef H264_DEBUG @@ -348,7 +349,7 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = call->len; PacketLength += call->len; iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); - return writev_with_retry(call->fd, iov, ic); + return call->WriteV(call->fd, iov, ic); } else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0]) { @@ -418,7 +419,7 @@ static int writeData(WriterAVCallData_t *call) while ((pos + NalLengthBytes) < call->len); h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); - len = writev_with_retry(call->fd, iov, ic); + len = call->WriteV(call->fd, iov, ic); PacketLength += iov[0].iov_len; if (PacketLength != len) { diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index cb21d99..ad59853 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -55,6 +55,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ +#define H264_SILENT //#define H265_DEBUG #ifdef H265_DEBUG @@ -220,7 +221,7 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = call->len; PacketLength += call->len; iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); - return writev_with_retry(call->fd, iov, ic); + return call->WriteV(call->fd, iov, ic); } uint32_t PacketLength = 0; ic = 0; @@ -275,7 +276,7 @@ static int writeData(WriterAVCallData_t *call) while ((pos + NalLengthBytes) < call->len); h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); - len = writev_with_retry(call->fd, iov, ic); + len = call->WriteV(call->fd, iov, ic); PacketLength += iov[0].iov_len; if (PacketLength != len) { diff --git a/libeplayer3-arm/output/writer/mipsel/lpcm.c b/libeplayer3-arm/output/writer/mipsel/lpcm.c index aca119e..f03fc5d 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -238,7 +238,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = pes_header_size; iov[1].iov_base = frame; iov[1].iov_len = i_frame_size; - i_ret_size += writev_with_retry(call->fd, iov, 2); + i_ret_size += call->WriteV(call->fd, iov, 2); } memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2); i_buffer_used = i_leftover_samples; diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index 88c5a82..3271f98 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -123,7 +123,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = headerSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - int len = writev_with_retry(call->fd, iov, 2); + int len = call->WriteV(call->fd, iov, 2); mp3_printf(10, "mp3_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index daa9daf..2e53f70 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -125,7 +125,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0); iov[1].iov_base = call->data + Position; iov[1].iov_len = PacketLength; - ssize_t l = writev_with_retry(call->fd, iov, 2); + ssize_t l = call->WriteV(call->fd, iov, 2); if (l < 0) { len = l; diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 7abce59..23cb154 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -137,7 +137,7 @@ static int writeData(WriterAVCallData_t *call) } iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; - int len = writev_with_retry(call->fd, iov, ic); + int len = call->WriteV(call->fd, iov, ic); mpeg4_printf(10, "xvid_Write < len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index bc63b09..8246100 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -265,10 +265,10 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = headerSize; iov[1].iov_base = fixed_buffer; iov[1].iov_len = fixed_buffersize; - writev_with_retry(call->fd, iov, 2); + call->WriteV(call->fd, iov, 2); fixed_buffertimestamp += fixed_bufferduration; int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); - writev_with_retry(g_fd_dump, iov, 2); + call->WriteV(g_fd_dump, iov, 2); close(g_fd_dump); } return size; diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index f6997ab..d291e2a 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -175,7 +175,7 @@ static int writeData(WriterAVCallData_t *call) free(videocodecdata.data); videocodecdata.data = NULL; } - return writev_with_retry(call->fd, iov, ic); + return call->WriteV(call->fd, iov, ic); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index 2e31151..0c61c8c 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -138,7 +138,7 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) iov[0].iov_len = pes_header_len; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - return writev_with_retry(call->fd, iov, 2); + return call->WriteV(call->fd, iov, 2); } static int writeDataVP6(WriterAVCallData_t *call) diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 6500c7e..cea0459 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -158,7 +158,7 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = headerSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; - return writev_with_retry(call->fd, iov, 2); + return call->WriteV(call->fd, iov, 2); } /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 96db958..225697b 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -181,7 +181,7 @@ static int writeData(WriterAVCallData_t *call) free(videocodecdata.data); videocodecdata.data = NULL; } - return writev_with_retry(call->fd, iov, ic); + return call->WriteV(call->fd, iov, ic); } /* ***************************** */ diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index f9364e9..1cf422f 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -468,14 +468,6 @@ static int PlaybackFastBackward(Context_t *context, int *speed) playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); } context->output->Command(context, OUTPUT_CLEAR, NULL); - if (context->output->Command(context, OUTPUT_REVERSE, NULL) < 0) - { - playback_err("OUTPUT_REVERSE failed\n"); - context->playback->BackWard = 0; - context->playback->Speed = 1; - context->playback->isSeeking = 0; - ret = cERR_PLAYBACK_ERROR; - } } else { From 2db6662e04b0b0501b868ea7500c7617da3d8bba Mon Sep 17 00:00:00 2001 From: samsamsam Date: Mon, 2 Apr 2018 23:59:24 +0200 Subject: [PATCH 34/38] Linux DVB output for STBs based on Broadcom - replace active pooling by select (ready to write) Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/c972398b885f08f66c668f60f8d29324ed03f292 Author: samsamsam Date: 2018-04-02 (Mon, 02 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/include/playback.h | 4 ++ libeplayer3-arm/include/writer.h | 2 + libeplayer3-arm/main/exteplayer.c | 31 +++++---- libeplayer3-arm/output/linuxdvb_buffering.c | 54 ++++++++++++++-- libeplayer3-arm/output/writer/mipsel/writer.c | 64 +++++++++++++++++++ libeplayer3-arm/playback/playback.c | 45 ++++++++++++- 6 files changed, 178 insertions(+), 22 deletions(-) diff --git a/libeplayer3-arm/include/playback.h b/libeplayer3-arm/include/playback.h index e817e38..68a7fc8 100644 --- a/libeplayer3-arm/include/playback.h +++ b/libeplayer3-arm/include/playback.h @@ -2,6 +2,10 @@ #define PLAYBACK_H_ #include #include +#include + +typedef void( * PlaybackDieNowCallback )(); +bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback); typedef enum { PLAYBACK_OPEN, diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index 28c74d3..5f09166 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -4,6 +4,7 @@ #include #include #include +#include "common.h" typedef enum { eNone, eAudio, eVideo} eWriterType_t; @@ -87,5 +88,6 @@ Writer_t *getDefaultVideoWriter(); Writer_t *getDefaultAudioWriter(); ssize_t write_with_retry(int fd, const void *buf, size_t size); ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic); +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size); #endif diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index a71e33b..6ad047b 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -84,10 +84,15 @@ static void TerminateAllSockets(void) } } -static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread */ +static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread and kbhit */ static int isPlaybackStarted = 0; static pthread_mutex_t playbackStartMtx; +static void TerminateWakeUp() +{ + write(g_pfd[1], "x", 1); +} + static void *TermThreadFun(void *arg __attribute__((unused))) { const char *socket_path = "/tmp/iptvplayer_extplayer_term_fd"; @@ -126,13 +131,6 @@ static void *TermThreadFun(void *arg __attribute__((unused))) } if (FD_ISSET(fd, &readfds)) { - /* - if ((cl = accept(fd, NULL, NULL)) == -1) - { - perror("TermThreadFun accept error"); - goto finish; - } - */ pthread_mutex_lock(&playbackStartMtx); PlaybackDieNow(1); if (isPlaybackStarted) @@ -171,16 +169,17 @@ static void map_inter_file_path(char *filename) static int kbhit(void) { struct timeval tv; - fd_set read_fd; + fd_set readfds; tv.tv_sec = 1; tv.tv_usec = 0; - FD_ZERO(&read_fd); - FD_SET(0, &read_fd); - if (-1 == select(1, &read_fd, NULL, NULL, &tv)) + FD_ZERO(&readfds); + FD_SET(0,&readfds); + FD_SET(g_pfd[0], &readfds); + if(-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv)) { return 0; } - if (FD_ISSET(0, &read_fd)) + if (FD_ISSET(0, &readfds)) { return 1; } @@ -639,7 +638,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 41); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 42); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); @@ -745,6 +744,7 @@ int main(int argc, char *argv[]) fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal); if (g_player->playback->isPlaying) { + PlaybackDieNowRegisterCallback(TerminateWakeUp); HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al"); if (audioTrackIdx >= 0) @@ -763,7 +763,7 @@ int main(int argc, char *argv[]) } HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc"); } - while (g_player->playback->isPlaying) + while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0)) { /* we made fgets non blocking */ if (NULL == fgets(argvBuff, sizeof(argvBuff) - 1, stdin)) @@ -994,6 +994,5 @@ int main(int argc, char *argv[]) pthread_mutex_destroy(&playbackStartMtx); close(g_pfd[0]); close(g_pfd[1]); - //printOutputCapabilities(); exit(0); } diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index c8f106e..fb7adff 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -98,6 +99,7 @@ static uint32_t bufferingDataSize = 0; static int videofd = -1; static int audiofd = -1; +static int g_pfd[2] = {-1, -1}; /* ***************************** */ /* Prototypes */ @@ -106,14 +108,46 @@ static int audiofd = -1; /* ***************************** */ /* MISC Functions */ /* ***************************** */ +static void WriteWakeUp() +{ + write(g_pfd[1], "x", 1); +} /* **************************** */ /* Worker Thread */ /* **************************** */ static void LinuxDvbBuffThread(Context_t *context) { + int flags = 0; static BufferingNode_t *nodePtr = NULL; buff_printf(20, "ENTER\n"); + + if (pipe(g_pfd) == -1) + { + buff_err("critical error\n"); + } + /* Make read and write ends of pipe nonblocking */ + if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1) + { + buff_err("critical error\n"); + } + /* Make read end nonblocking */ + flags |= O_NONBLOCK; + if (fcntl(g_pfd[0], F_SETFL, flags) == -1) + { + buff_err("critical error\n"); + } + if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1) + { + buff_err("critical error\n"); + } + /* Make write end nonblocking */ + flags |= O_NONBLOCK; + if (fcntl(g_pfd[1], F_SETFL, flags) == -1) + { + buff_err("critical error\n"); + } + PlaybackDieNowRegisterCallback(WriteWakeUp); while (0 == PlaybackDieNow(0)) { pthread_mutex_lock(&bufferingMtx); @@ -165,9 +199,9 @@ static void LinuxDvbBuffThread(Context_t *context) /* Write data to valid output */ uint8_t *dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t); int fd = nodePtr->dataType == OUTPUT_VIDEO ? videofd : audiofd; - if (0 != write_with_retry(fd, dataPtr, nodePtr->dataSize)) + if (0 != WriteWithRetry(context, g_pfd[0], fd, dataPtr, nodePtr->dataSize)) { - printf("Something is WRONG\n"); + buff_err("Something is WRONG\n"); } } } @@ -178,6 +212,10 @@ static void LinuxDvbBuffThread(Context_t *context) buff_printf(20, "EXIT\n"); hasBufferingThreadStarted = false; + close(g_pfd[0]); + close(g_pfd[1]); + g_pfd[0] = -1; + g_pfd[1] = -1; } int32_t WriteSetBufferingSize(const uint32_t bufferSize) @@ -240,7 +278,7 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) return ret; } -int32_t LinuxDvbBuffClose(Context_t *context) +int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) { int32_t ret = 0; @@ -251,6 +289,10 @@ int32_t LinuxDvbBuffClose(Context_t *context) if (hasBufferingThreadStarted) { struct timespec max_wait = {0, 0}; + + /* WakeUp if we are waiting in the write */ + WriteWakeUp(); + pthread_mutex_lock(&bufferingMtx); /* wait for thread end */ clock_gettime(CLOCK_REALTIME, &max_wait); @@ -278,10 +320,14 @@ int32_t LinuxDvbBuffClose(Context_t *context) return ret; } -int32_t LinuxDvbBuffFlush(Context_t *context) +int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused))) { static BufferingNode_t *nodePtr = NULL; buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead); + + /* signal if we are waiting for write to DVB decoders */ + WriteWakeUp(); + pthread_mutex_lock(&bufferingMtx); while (bufferingQueueHead) { diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index 2d7f70a..594ee47 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -29,6 +29,7 @@ #include "misc.h" #include "writer.h" +#include "common.h" /* ***************************** */ /* Makros/Constants */ @@ -100,6 +101,69 @@ static Writer_t *AvailableWriter[] = /* Functions */ /* ***************************** */ +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size) +{ + fd_set rfds; + fd_set wfds; + + ssize_t ret; + int retval = -1; + int maxFd = pipefd > fd ? pipefd : fd; + + while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) + { + FD_ZERO(&rfds); + FD_ZERO(&wfds); + + FD_SET(pipefd, &rfds); + FD_SET(fd, &wfds); + + retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); + if (retval < 0) + { + break; + } + + if(FD_ISSET(pipefd, &rfds)) + { + char tmp; + /* flush pipefd pipe */ + while(1 == read(pipefd, &tmp, 1)); + break; + } + + if(FD_ISSET(fd, &wfds)) + { + ret = write(fd, buf, size); + if (ret < 0) + { + switch(errno) + { + case EINTR: + case EAGAIN: + continue; + default: + retval = -3; + break; + } + if (retval < 0) + { + break; + } + } + + if (ret < 0) + { + return ret; + } + + size -= ret; + buf += ret; + } + } + return 0; +} + ssize_t write_with_retry(int fd, const void *buf, size_t size) { ssize_t ret; diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 1cf422f..bac6adb 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -57,6 +57,8 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define cMaxSpeed_ff 128 /* fixme: revise */ #define cMaxSpeed_fr -320 /* fixme: revise */ +#define MAX_PLAYBACK_DIE_NOW_CALLBACKS 10 + /* ***************************** */ /* Varaibles */ /* ***************************** */ @@ -67,17 +69,30 @@ static int hasThreadStarted = 0; /* ***************************** */ /* Prototypes */ /* ***************************** */ + static int32_t PlaybackTerminate(Context_t *context); +static int8_t dieNow = 0; +static PlaybackDieNowCallback playbackDieNowCallbacks[MAX_PLAYBACK_DIE_NOW_CALLBACKS] = {NULL}; /* ***************************** */ /* MISC Functions */ /* ***************************** */ + int8_t PlaybackDieNow(int8_t val) { - static int8_t dieNow = 0; - if (val == 1) + if (val == 1 && dieNow == 0) { + uint32_t i = 0; dieNow = 1; + while (i < MAX_PLAYBACK_DIE_NOW_CALLBACKS) + { + if (playbackDieNowCallbacks[i] == NULL) + { + break; + } + playbackDieNowCallbacks[i](); + i += 1; + } } else if (val == 2) { @@ -86,6 +101,32 @@ int8_t PlaybackDieNow(int8_t val) return dieNow; } +bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback) +{ + bool ret = false; + if (callback) + { + uint32_t i = 0; + while (i < MAX_PLAYBACK_DIE_NOW_CALLBACKS) + { + if (playbackDieNowCallbacks[i] == callback) + { + ret = true; + break; + } + + if (playbackDieNowCallbacks[i] == NULL) + { + playbackDieNowCallbacks[i] = callback; + ret = true; + break; + } + i += 1; + } + } + return ret; +} + /* **************************** */ /* Supervisor Thread */ /* **************************** */ From b97420448f0e12cd69c7f7e655c3c8c93f437bfc Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 3 Apr 2018 00:00:54 +0200 Subject: [PATCH 35/38] Replace the AAC Main object type to the AAC LC in the ADTS header - workaround for no audio on some TS'streams Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e7da3a7d100bec7bde5808d84f0c5d7a89df364a Author: samsamsam Date: 2018-04-03 (Tue, 03 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/output/writer/mipsel/aac.c | 13 ++++++++++++- libeplayer3-arm/output/writer/sh4/aac.c | 8 ++++++++ 3 files changed, 21 insertions(+), 2 deletions(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 6ad047b..ed82df1 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -638,7 +638,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 42); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 43); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index c1cec2d..c382f16 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -177,6 +177,14 @@ static int _writeData(WriterAVCallData_t *call, int type) aac_err("parsing Data with missing syncword. ignoring...\n"); return 0; } + + // STB can handle only AAC LC profile + if (0 == (call->data[2] & 0xC0)) + { + // change profile AAC Main -> AAC LC (Low Complexity) + aac_printf(1, "change profile AAC Main -> AAC LC (Low Complexity) in the ADTS header"); + call->data[2] = (call->data[2] & 0x1F) | 0x40; + } } else // check LOAS header { @@ -217,8 +225,11 @@ static int writeDataADTS(WriterAVCallData_t *call) return 0; } if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || - HasADTSHeader(call->data, call->len)) + HasADTSHeader(call->data, call->len)) { + //(aacbuf[2] & 0x1F) | 0x40 + + //printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]); return _writeData(call, 0); } uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; diff --git a/libeplayer3-arm/output/writer/sh4/aac.c b/libeplayer3-arm/output/writer/sh4/aac.c index 6eeab11..e70336c 100644 --- a/libeplayer3-arm/output/writer/sh4/aac.c +++ b/libeplayer3-arm/output/writer/sh4/aac.c @@ -176,6 +176,14 @@ static int _writeData(void *_call, int type) aac_err("parsing Data with missing syncword. ignoring...\n"); return 0; } + + // STB can handle only AAC LC profile + if (0 == (call->data[2] & 0xC0)) + { + // change profile AAC Main -> AAC LC (Low Complexity) + aac_printf(1, "change profile AAC Main -> AAC LC (Low Complexity) in the ADTS header"); + call->data[2] = (call->data[2] & 0x1F) | 0x40; + } } else // check LOAS header { From 67c1a995370af75ed28275cc1f924c858980faec Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 3 Apr 2018 09:37:33 +0200 Subject: [PATCH 36/38] Linux DVB output - workaround for BUG? in the DVB drivers Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/262d5849e037f516146079324fc3b2b8bf4b5909 Author: samsamsam Date: 2018-04-03 (Tue, 03 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/output/linuxdvb_buffering.c | 7 +++ libeplayer3-arm/output/linuxdvb_mipsel.c | 4 ++ libeplayer3-arm/output/writer/mipsel/aac.c | 2 - libeplayer3-arm/output/writer/mipsel/writer.c | 46 +++++++++++++++---- 5 files changed, 50 insertions(+), 11 deletions(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index ed82df1..b333d9b 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -638,7 +638,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 43); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 44); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index fb7adff..f4c5db3 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -349,6 +349,13 @@ int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused))) return 0; } +int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused))) +{ + /* signal if we are waiting for write to DVB decoders */ + WriteWakeUp(); + return 0; +} + ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) { OutputType_t dataType = OUTPUT_UNK; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 4ef70df..d9f084d 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -104,6 +104,8 @@ pthread_mutex_t LinuxDVBmutex; int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); int32_t LinuxDvbBuffClose(Context_t *context); int32_t LinuxDvbBuffFlush(Context_t *context); +int32_t LinuxDvbBuffResume(Context_t *context); + ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic); int32_t WriteSetBufferingSize(const uint32_t bufferSize); int LinuxDvbStop(Context_t *context, char *type); @@ -383,6 +385,8 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + if (isBufferedOutput) + LinuxDvbBuffResume(context); linuxdvb_printf(10, "exiting\n"); return ret; } diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index c382f16..90b48c7 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -227,8 +227,6 @@ static int writeDataADTS(WriterAVCallData_t *call) if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { - //(aacbuf[2] & 0x1F) | 0x40 - //printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]); return _writeData(call, 0); } diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index 594ee47..829e4db 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -101,6 +101,12 @@ static Writer_t *AvailableWriter[] = /* Functions */ /* ***************************** */ +static void FlusPipe(int pipefd) +{ + char tmp; + while(1 == read(pipefd, &tmp, 1)); +} + ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size) { fd_set rfds; @@ -109,6 +115,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, ssize_t ret; int retval = -1; int maxFd = pipefd > fd ? pipefd : fd; + struct timeval tv; while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) { @@ -118,18 +125,34 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, FD_SET(pipefd, &rfds); FD_SET(fd, &wfds); - retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); + /* When we PAUSE LINUX DVB outputs buffers then audio/video buffers + * will be filled to full unfortunately, in such case after resume + * select never return with fd set - bug in DVB drivers? + * So, there will be to workarounds: + * 1. write to pipe pipe at resume to exit select immediately + * 2. even if fd is not set exit from select after 0,1s + * (it seems that second workaround is not needed) + */ + //tv.tv_sec = 0; + //tv.tv_usec = 100000; // 100ms + + retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv); if (retval < 0) { break; } + //if (retval == 0) + //{ + // //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n"); + // continue; + //} + if(FD_ISSET(pipefd, &rfds)) { - char tmp; - /* flush pipefd pipe */ - while(1 == read(pipefd, &tmp, 1)); - break; + FlusPipe(pipefd); + //printf("RETURN FROM SELECT DUE TO pipefd SET\n"); + continue; } if(FD_ISSET(fd, &wfds)) @@ -150,12 +173,19 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, { break; } - } - if (ret < 0) - { return ret; } + else if (ret == 0) + { + //printf("This should not happen. Select return fd ready to write, but write return 0, errno [%d]\n", errno); + tv.tv_sec = 0; + tv.tv_usec = 10000; // 10ms + retval = select(pipefd + 1, &rfds, NULL, NULL, &tv); + if (retval) + FlusPipe(pipefd); + continue; + } size -= ret; buf += ret; From d3d225ac35e5ff98cdd5e166d6389fbedf39e2da Mon Sep 17 00:00:00 2001 From: samsamsam Date: Thu, 5 Apr 2018 21:50:52 +0200 Subject: [PATCH 37/38] Improve STOP command in the buffering mode Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/68c06aaafa48ac24ace0d0e54c70d57bdce28251 Author: samsamsam Date: 2018-04-05 (Thu, 05 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 +- libeplayer3-arm/output/linuxdvb_buffering.c | 2 ++ libeplayer3-arm/output/linuxdvb_mipsel.c | 4 ++-- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index b333d9b..54526c8 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -638,7 +638,7 @@ int main(int argc, char *argv[]) memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 44); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 45); if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index f4c5db3..343296d 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -294,6 +294,8 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) WriteWakeUp(); pthread_mutex_lock(&bufferingMtx); + /* wake up if thread is waiting for data */ + pthread_cond_signal(&bufferingdDataAddedCond); /* wait for thread end */ clock_gettime(CLOCK_REALTIME, &max_wait); max_wait.tv_sec += 1; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index d9f084d..4335399 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -198,6 +198,8 @@ int LinuxDvbClose(Context_t *context, char *type) */ LinuxDvbStop(context, type); getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (isBufferedOutput) + LinuxDvbBuffClose(context); if (video && videofd != -1) { close(videofd); @@ -208,8 +210,6 @@ int LinuxDvbClose(Context_t *context, char *type) close(audiofd); audiofd = -1; } - if (isBufferedOutput) - LinuxDvbBuffClose(context); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); return cERR_LINUXDVB_NO_ERROR; } From 01d1fb6b28584387d5dc09ccacd85335fd687341 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 10 Apr 2018 11:31:57 +0200 Subject: [PATCH 38/38] libeplayer3-arm: insert original blank lines from exteplayer3.git, for better merge Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/65de063d1ea25251e68a5e800c36de9c2947a2ed Author: max_10 Date: 2018-04-10 (Tue, 10 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/Makefile.am | 2 +- libeplayer3-arm/container/buff_ffmpeg.c | 75 ++++- libeplayer3-arm/container/container.c | 12 + libeplayer3-arm/container/container_ffmpeg.c | 311 +++++++++++++++++- libeplayer3-arm/container/flv2mpeg4_ffmpeg.c | 13 + libeplayer3-arm/container/mpeg4p2_ffmpeg.c | 5 + libeplayer3-arm/container/wrapped_ffmpeg.c | 5 + libeplayer3-arm/external/ffmpeg/get_bits.h | 13 + libeplayer3-arm/external/ffmpeg/latmenc.h | 1 + libeplayer3-arm/external/ffmpeg/put_bits.h | 7 + .../external/ffmpeg/src/bitstream.c | 6 + libeplayer3-arm/external/ffmpeg/src/latmenc.c | 25 ++ .../external/ffmpeg/src/mpeg4audio.c | 16 + .../external/flv2mpeg4/src/bitreader.h | 9 + .../external/flv2mpeg4/src/bitwriter.h | 7 + .../external/flv2mpeg4/src/dcprediction.c | 12 + .../external/flv2mpeg4/src/dcprediction.h | 1 + libeplayer3-arm/external/flv2mpeg4/src/flv.h | 2 + .../external/flv2mpeg4/src/flv2mpeg4.c | 40 +++ .../external/flv2mpeg4/src/flvdecoder.c | 48 +++ libeplayer3-arm/external/flv2mpeg4/src/m4v.h | 2 + .../external/flv2mpeg4/src/m4vencode.c | 76 +++++ libeplayer3-arm/include/aac.h | 1 + libeplayer3-arm/include/bcm_ioctls.h | 7 + libeplayer3-arm/include/debug.h | 2 + libeplayer3-arm/include/manager.h | 2 + libeplayer3-arm/include/misc.h | 6 + libeplayer3-arm/include/output.h | 1 + libeplayer3-arm/include/pes.h | 2 + libeplayer3-arm/include/stm_ioctls.h | 4 + libeplayer3-arm/include/writer.h | 4 +- libeplayer3-arm/main/exteplayer.c | 84 ++++- libeplayer3-arm/manager/audio.c | 37 ++- libeplayer3-arm/manager/chapter.c | 3 +- libeplayer3-arm/manager/manager.c | 5 + libeplayer3-arm/manager/subtitle.c | 4 +- libeplayer3-arm/manager/video.c | 23 +- libeplayer3-arm/output/linuxdvb_buffering.c | 122 ++++--- libeplayer3-arm/output/linuxdvb_mipsel.c | 165 +++++++++- libeplayer3-arm/output/linuxdvb_sh4.c | 182 +++++++++- libeplayer3-arm/output/output.c | 11 +- libeplayer3-arm/output/output_subtitle.c | 31 +- libeplayer3-arm/output/writer/common/misc.c | 5 + libeplayer3-arm/output/writer/common/pes.c | 15 + libeplayer3-arm/output/writer/mipsel/aac.c | 31 +- libeplayer3-arm/output/writer/mipsel/ac3.c | 11 + libeplayer3-arm/output/writer/mipsel/amr.c | 11 + libeplayer3-arm/output/writer/mipsel/divx3.c | 16 +- libeplayer3-arm/output/writer/mipsel/dts.c | 10 + libeplayer3-arm/output/writer/mipsel/h263.c | 9 + libeplayer3-arm/output/writer/mipsel/h264.c | 51 +++ libeplayer3-arm/output/writer/mipsel/h265.c | 32 ++ libeplayer3-arm/output/writer/mipsel/lpcm.c | 21 +- libeplayer3-arm/output/writer/mipsel/mp3.c | 9 + libeplayer3-arm/output/writer/mipsel/mpeg2.c | 13 + libeplayer3-arm/output/writer/mipsel/mpeg4.c | 11 + libeplayer3-arm/output/writer/mipsel/pcm.c | 28 +- libeplayer3-arm/output/writer/mipsel/vc1.c | 15 + libeplayer3-arm/output/writer/mipsel/vp.c | 9 +- libeplayer3-arm/output/writer/mipsel/wma.c | 15 +- libeplayer3-arm/output/writer/mipsel/wmv.c | 15 + libeplayer3-arm/output/writer/mipsel/writer.c | 32 +- libeplayer3-arm/output/writer/sh4/aac.c | 32 ++ libeplayer3-arm/output/writer/sh4/ac3.c | 9 + libeplayer3-arm/output/writer/sh4/divx.c | 15 + libeplayer3-arm/output/writer/sh4/divx2.c | 19 ++ libeplayer3-arm/output/writer/sh4/dts.c | 11 + libeplayer3-arm/output/writer/sh4/h263.c | 13 + libeplayer3-arm/output/writer/sh4/h264.c | 69 ++++ libeplayer3-arm/output/writer/sh4/mp3.c | 9 + libeplayer3-arm/output/writer/sh4/mpeg2.c | 14 + libeplayer3-arm/output/writer/sh4/pcm.c | 26 ++ libeplayer3-arm/output/writer/sh4/pes.c | 14 + libeplayer3-arm/output/writer/sh4/vc1.c | 30 ++ libeplayer3-arm/output/writer/sh4/vorbis.c | 14 +- libeplayer3-arm/output/writer/sh4/wma.c | 15 +- libeplayer3-arm/output/writer/sh4/wmv.c | 31 ++ libeplayer3-arm/output/writer/sh4/writer.c | 9 + libeplayer3-arm/playback/playback.c | 114 ++++++- 79 files changed, 2070 insertions(+), 117 deletions(-) diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index 1f7f51e..b77dbf9 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -19,9 +19,9 @@ libeplayer3_arm_la_SOURCES = \ manager/subtitle.c \ manager/chapter.c \ output/linuxdvb_mipsel.c \ + output/linuxdvb_buffering.c \ output/output_subtitle.c \ output/output.c \ - output/linuxdvb_buffering.c \ output/writer/common/pes.c \ output/writer/common/misc.c \ output/writer/mipsel/writer.c \ diff --git a/libeplayer3-arm/container/buff_ffmpeg.c b/libeplayer3-arm/container/buff_ffmpeg.c index 61ac32d..3386b7f 100644 --- a/libeplayer3-arm/container/buff_ffmpeg.c +++ b/libeplayer3-arm/container/buff_ffmpeg.c @@ -95,15 +95,19 @@ static void update_finish_timeout() int64_t currPts = -1; int32_t ret = g_context->playback->Command(g_context, PLAYBACK_PTS, &currPts); finishTimeout += 1; + if (maxInjectedPts < 0 || maxInjectedPts == INVALID_PTS_VALUE) { maxInjectedPts = 0; } + //printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts); + /* On some STBs PTS readed from decoder is invalid after seek or at start * this is the reason for additional validation when we what to close immediately */ - if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts && ((currPts - maxInjectedPts) / 90000) < 2) + if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts && + ((currPts - maxInjectedPts) / 90000) < 2) { /* close immediately */ @@ -129,6 +133,7 @@ static int32_t ffmpeg_read_wrapper_base(void *opaque, uint8_t *buf, int32_t buf_ { break; } + int32_t partLen = ffmpeg_real_read_org(opaque, buf + len, buf_size - len); if (partLen > 0) { @@ -141,7 +146,9 @@ static int32_t ffmpeg_read_wrapper_base(void *opaque, uint8_t *buf, int32_t buf_ len = 0; break; } + update_finish_timeout(); + usleep(100000); continue; } @@ -163,25 +170,31 @@ static int32_t ffmpeg_read_wrapper(void *opaque, uint8_t *buf, int32_t buf_size) return ffmpeg_real_read_org(opaque, buf, buf_size); } } + #if 0 static int32_t ffmpeg_read_wrapper2(void *opaque, uint8_t *buf, int32_t buf_size) { return ffmpeg_read_wrapper_base(opaque, buf, buf_size, 1); } #endif + //for buffered io void getfillerMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); + pthread_mutex_lock(&fillermutex); + ffmpeg_printf(100, "::%d received mutex\n", line); } void releasefillerMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int line __attribute__((unused))) { pthread_mutex_unlock(&fillermutex); + ffmpeg_printf(100, "::%d released mutex\n", line); } + //for buffered io (end)encoding #if 0 static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time) @@ -190,6 +203,7 @@ static int32_t container_set_ffmpeg_buf_seek_time(int32_t *time) return cERR_CONTAINER_FFMPEG_NO_ERROR; } #endif + static int32_t container_set_ffmpeg_buf_size(int32_t *size) { if (ffmpeg_buf == NULL) @@ -203,6 +217,7 @@ static int32_t container_set_ffmpeg_buf_size(int32_t *size) ffmpeg_buf_size = (*size) + FILLBUFDIFF; } } + ffmpeg_printf(10, "size=%d, buffer size=%d\n", (*size), ffmpeg_buf_size); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -216,6 +231,7 @@ static int32_t container_get_ffmpeg_buf_size(int32_t *size) static int32_t container_get_fillbufstatus(int32_t *size) { int32_t rwdiff = 0; + if (ffmpeg_buf != NULL && ffmpeg_buf_read != NULL && ffmpeg_buf_write != NULL) { if (ffmpeg_buf_read < ffmpeg_buf_write) @@ -225,10 +241,13 @@ static int32_t container_get_fillbufstatus(int32_t *size) rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; rwdiff += ffmpeg_buf_write - ffmpeg_buf; } + *size = rwdiff; } + return cERR_CONTAINER_FFMPEG_NO_ERROR; } + #if 0 static int32_t container_stop_buffer() { @@ -236,6 +255,7 @@ static int32_t container_stop_buffer() return 0; } #endif + //flag 0: start direct //flag 1: from thread static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int32_t flag) @@ -243,11 +263,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 int32_t len = 0; int32_t rwdiff = ffmpeg_buf_size; uint8_t buf[FILLBUFPAKET]; + if (ffmpeg_read_org == NULL || ffmpeg_seek_org == NULL) { ffmpeg_err("ffmpeg_read_org or ffmpeg_seek_org is NULL\n"); return; } + while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) || (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF)) { @@ -255,11 +277,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 { break; } + if (flag == 0 && ffmpeg_buf_stop == 1) { ffmpeg_buf_stop = 0; break; } + getfillerMutex(__FILE__, __FUNCTION__, __LINE__); //do a seek if (ffmpeg_do_seek != 0) @@ -270,42 +294,53 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 ffmpeg_buf_write = ffmpeg_buf; ffmpeg_buf_read = ffmpeg_buf; } + ffmpeg_do_seek = 0; } + if (ffmpeg_buf_read == ffmpeg_buf_write) { ffmpeg_buf_valid_size = 0; rwdiff = ffmpeg_buf_size; } + if (ffmpeg_buf_read < ffmpeg_buf_write) { rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write; rwdiff += ffmpeg_buf_read - ffmpeg_buf; } + if (ffmpeg_buf_read > ffmpeg_buf_write) { rwdiff = ffmpeg_buf_read - ffmpeg_buf_write; } + int32_t size = FILLBUFPAKET; if (rwdiff - FILLBUFDIFF < size) { size = (rwdiff - FILLBUFDIFF); } + if (ffmpeg_buf_write + size > ffmpeg_buf + ffmpeg_buf_size) { size = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_write; } + if (ffmpeg_buf_write == ffmpeg_buf + ffmpeg_buf_size) { ffmpeg_buf_write = ffmpeg_buf; } + releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); + if (size > 0) { if (flag == 1 && hasfillerThreadStarted[id] == 2) break; len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size); if (flag == 1 && hasfillerThreadStarted[id] == 2) break; + ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len); + getfillerMutex(__FILE__, __FUNCTION__, __LINE__); if (len > 0) { @@ -333,11 +368,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 { int32_t buflen = 0; (*inpause) = 0; + getfillerMutex(__FILE__, __FUNCTION__, __LINE__); if (ffmpeg_buf_read < ffmpeg_buf_write) { buflen = ffmpeg_buf_write - ffmpeg_buf_read; } + if (ffmpeg_buf_read > ffmpeg_buf_write) { buflen = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; @@ -355,13 +392,17 @@ static void ffmpeg_fillerTHREAD(Context_t *context) { int32_t inpause = 0; int32_t id = hasfillerThreadStartedID; + ffmpeg_printf(10, "Running ID=%d!\n", id); + while (hasfillerThreadStarted[id] == 1) { ffmpeg_filler(context, id, &inpause, 1); usleep(10000); } + hasfillerThreadStarted[id] = 0; + ffmpeg_printf(10, "terminating ID=%d\n", id); } @@ -370,7 +411,9 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) int32_t error; int32_t ret = 0, i = 0; pthread_attr_t attr; + ffmpeg_printf(10, "\n"); + if (context && context->playback && context->playback->isPlaying) { ffmpeg_printf(10, "is Playing\n"); @@ -379,6 +422,7 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) { ffmpeg_printf(10, "is NOT Playing\n"); } + //get filler thread ID //if the thread hangs for long time, we use a new id for (i = 0; i < 10; i++) @@ -389,15 +433,18 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) break; } } + if (hasfillerThreadStarted[hasfillerThreadStartedID] == 0) { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + hasfillerThreadStarted[hasfillerThreadStartedID] = 1; if ((error = pthread_create(&fillerThread, &attr, (void *)&ffmpeg_fillerTHREAD, context)) != 0) { hasfillerThreadStarted[hasfillerThreadStartedID] = 0; ffmpeg_printf(10, "Error creating filler thread, error:%d:%s\n", error, strerror(error)); + ret = cERR_CONTAINER_FFMPEG_ERR; } else @@ -408,8 +455,10 @@ static int32_t ffmpeg_start_fillerTHREAD(Context_t *context) else { ffmpeg_printf(10, "All filler thread ID's in use!\n"); + ret = cERR_CONTAINER_FFMPEG_ERR; } + ffmpeg_printf(10, "exiting with value %d\n", ret); return ret; } @@ -418,9 +467,11 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b { int32_t len = buf_size; int32_t rwdiff = 0; + if (buf_size > 0) { getfillerMutex(__FILE__, __FUNCTION__, __LINE__); + if (ffmpeg_buf_read < ffmpeg_buf_write) rwdiff = ffmpeg_buf_write - ffmpeg_buf_read; if (ffmpeg_buf_read > ffmpeg_buf_write) @@ -429,18 +480,22 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b rwdiff += ffmpeg_buf_write - ffmpeg_buf; } rwdiff--; + if (len > rwdiff) { len = rwdiff; } + if (ffmpeg_buf_read + len > ffmpeg_buf + ffmpeg_buf_size) { len = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; } + if (len > 0) { memcpy(buf, ffmpeg_buf_read, len); ffmpeg_buf_read += len; + if (ffmpeg_buf_valid_size < FILLBUFDIFF) { if (ffmpeg_buf_valid_size + len > FILLBUFDIFF) @@ -452,6 +507,7 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b ffmpeg_buf_valid_size += len; } } + if (ffmpeg_buf_read == ffmpeg_buf + ffmpeg_buf_size) { ffmpeg_buf_read = ffmpeg_buf; @@ -463,6 +519,7 @@ static int32_t ffmpeg_read_real(void *opaque __attribute__((unused)), uint8_t *b } releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); } + return len; } @@ -471,6 +528,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size) int32_t sumlen = 0; int32_t len = 0; int32_t count = 2000; + while (sumlen < buf_size && (--count) > 0 && 0 == PlaybackDieNow(0)) { len = ffmpeg_read_real(opaque, buf, buf_size - sumlen); @@ -481,6 +539,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size) usleep(10000); } } + if (count == 0) { if (sumlen == 0) @@ -492,6 +551,7 @@ static int32_t ffmpeg_read(void *opaque, uint8_t *buf, int32_t buf_size) ffmpeg_err("Timeout, not all buffered data availabel (buf_size=%d sumlen=%d)!\n", buf_size, sumlen); } } + return sumlen; } @@ -500,10 +560,12 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, int64_t diff; int32_t rwdiff = 0; whence &= ~AVSEEK_FORCE; + if (whence != SEEK_CUR && whence != SEEK_SET) { return AVERROR(EINVAL); } + if (whence == SEEK_CUR) { diff = offset; @@ -512,20 +574,25 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, { diff = offset - avContextTab[0]->pb->pos; } + if (diff == 0) { return avContextTab[0]->pb->pos; } + getfillerMutex(__FILE__, __FUNCTION__, __LINE__); + if (ffmpeg_buf_read < ffmpeg_buf_write) { rwdiff = ffmpeg_buf_write - ffmpeg_buf_read; } + if (ffmpeg_buf_read > ffmpeg_buf_write) { rwdiff = (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read; rwdiff += ffmpeg_buf_write - ffmpeg_buf; } + if (diff > 0 && diff < rwdiff) { /* can do the seek inside the buffer */ @@ -557,29 +624,35 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, { releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); ffmpeg_printf(20, "real-seek diff=%lld\n", diff); + ffmpeg_do_seek_ret = 0; ffmpeg_do_seek = diff; while (ffmpeg_do_seek != 0) { usleep(100000); } + ffmpeg_do_seek = 0; if (ffmpeg_do_seek_ret < 0) { ffmpeg_err("seek not ok ret=%d\n", ffmpeg_do_seek_ret); return ffmpeg_do_seek_ret; } + //fill buffer int32_t count = ffmpeg_buf_seek_time * 10; int32_t size = 0; + container_get_fillbufstatus(&size); while (size < ffmpeg_buf_size - FILLBUFDIFF && (--count) > 0) { usleep(100000); container_get_fillbufstatus(&size); } + return avContextTab[0]->pb->pos + diff; } + releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); return avContextTab[0]->pb->pos + diff; } diff --git a/libeplayer3-arm/container/container.c b/libeplayer3-arm/container/container.c index 3f56f21..48ea13a 100644 --- a/libeplayer3-arm/container/container.c +++ b/libeplayer3-arm/container/container.c @@ -56,8 +56,10 @@ static void printContainerCapabilities() { int32_t i = 0; int32_t j = 0; + container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); container_printf(10, "Capabilities: "); + for (i = 0; AvailableContainer[i] != NULL; i++) { for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++) @@ -73,7 +75,9 @@ static int32_t selectContainer(Context_t *context, char *extension) int32_t i = 0; int32_t j = 0; int32_t ret = -1; + container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + for (i = 0; AvailableContainer[i] != NULL; i++) { for (j = 0; AvailableContainer[i]->Capabilities[j] != NULL; j++) @@ -81,26 +85,32 @@ static int32_t selectContainer(Context_t *context, char *extension) if (!strcasecmp(AvailableContainer[i]->Capabilities[j], extension)) { context->container->selectedContainer = AvailableContainer[i]; + container_printf(10, "Selected Container: %s\n", context->container->selectedContainer->Name); ret = 0; break; } } + if (ret == 0) { break; } } + if (ret != 0) { container_err("No Container found :-(\n"); } + return ret; } + static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused))) { int ret = 0; + container_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); switch (command) @@ -124,9 +134,11 @@ static int Command(Context_t *context, ContainerCmd_t command, void *argument __ container_err("%s::%s ContainerCmd %d not supported!\n", __FILE__, __FUNCTION__, command); break; } + return ret; } + ContainerHandler_t ContainerHandler = { "Output", diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 874e78f..f0f17c6 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -166,17 +166,21 @@ static void initMutex(void) static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { ffmpeg_printf(100, "::%d requesting mutex\n", line); + if (!mutexInitialized) { initMutex(); } + pthread_mutex_lock(&mutex); + ffmpeg_printf(100, "::%d received mutex\n", line); } static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line __attribute__((unused))) { pthread_mutex_unlock(&mutex); + ffmpeg_printf(100, "::%d released mutex\n", line); } @@ -194,6 +198,7 @@ static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData, i return ret; } + #include "buff_ffmpeg.c" #include "wrapped_ffmpeg.c" #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) @@ -430,10 +435,12 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra return pcm_resampling ? "A_IPCM" : "A_PCM"; case AV_CODEC_ID_AMR_NB: return "A_IPCM";//return "A_AMR"; + /* In exteplayer3 embedded text subtitle simple printed * to output like other data. Maybe worth to consider is to use * linux socket or pipe to put */ + /* subtitle */ case AV_CODEC_ID_SSA: #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100) @@ -477,10 +484,12 @@ static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) { pts = av_rescale(pts, (int64_t)stream->time_base.num * 90000, stream->time_base.den); } + if (avContextTab[avContextIdx]->start_time != AV_NOPTS_VALUE) { pts -= 90000 * avContextTab[avContextIdx]->start_time / AV_TIME_BASE; } + if (pts & 0x8000000000000000ull) { pts = INVALID_PTS_VALUE; @@ -489,6 +498,7 @@ static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) { pts &= 0x01FFFFFFFF; // PES header can handle only 33 bit PTS } + return pts; } @@ -504,6 +514,7 @@ static char *searchMeta(void *metadata, char *ourTag) AVDictionaryEntry *tag = NULL; #endif int i = 0; + while (metadata_map[i] != NULL) { if (strcmp(ourTag, metadata_map[i]) == 0) @@ -522,6 +533,7 @@ static char *searchMeta(void *metadata, char *ourTag) } i++; } + return NULL; } @@ -540,22 +552,27 @@ static void FFMPEGThread(Context_t *context) //int64_t lastPts = -1; int64_t currentVideoPts = -1; int64_t currentAudioPts = -1; + /* lastVideoDts and lastAudioDts * used in isTSLiveMode */ int64_t lastVideoDts = -1; int64_t lastAudioDts = -1; + int64_t showtime = 0; int64_t bofcount = 0; //int32_t err = 0; AudioVideoOut_t avOut; + g_context = context; + SwrContext *swr = NULL; AVFrame *decoded_frame = NULL; int32_t out_sample_rate = 44100; int32_t out_channels = 2; uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO; uint32_t cAVIdx = 0; + #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) Mpeg4P2Context mpeg4p2_context; memset(&mpeg4p2_context, 0, sizeof(Mpeg4P2Context)); @@ -572,16 +589,17 @@ static void FFMPEGThread(Context_t *context) usleep(1000); } ffmpeg_printf(10, "Running!\n"); + int8_t isWaitingForFinish = 0; while (context && context->playback && context->playback->isPlaying) { - /* When user press PAUSE we call pause on AUDIO and VIDEO decoders, - * we will not wait here because we can still fill - * DVB drivers buffers at PAUSE time - * - * In the future we can add buffering queue before injection in to - * AUDIO, VIDEO decoders, so we can not wait here - */ + /* When user press PAUSE we call pause on AUDIO and VIDEO decoders, + * we will not wait here because we can still fill + * DVB drivers buffers at PAUSE time + * + * In the future we can add buffering queue before injection in to + * AUDIO, VIDEO decoders, so we can not wait here + */ #ifdef __sh__ //IF MOVIE IS PAUSED, WAIT if (context->playback->isPaused) @@ -592,6 +610,7 @@ static void FFMPEGThread(Context_t *context) continue; } #endif + if (context->playback->isSeeking) { ffmpeg_printf(10, "seeking\n"); @@ -599,7 +618,9 @@ static void FFMPEGThread(Context_t *context) usleep(10000); continue; } + getMutex(__FILE__, __FUNCTION__, __LINE__); + if (!context->playback || !context->playback->isPlaying) { releaseMutex(__FILE__, __FUNCTION__, __LINE__); @@ -648,6 +669,7 @@ static void FFMPEGThread(Context_t *context) { bofcount = 0; } + if (do_seek_target_seconds || do_seek_target_bytes) { int res = -1; @@ -685,11 +707,13 @@ static void FFMPEGThread(Context_t *context) } do_seek_target_seconds = 0; do_seek_target_bytes = 0; + restart_audio_resampling = 1; currentVideoPts = -1; currentAudioPts = -1; latestPts = 0; seek_target_flag = 0; + // flush streams uint32_t i = 0; for (i = 0; i < IPTV_AV_CONTEXT_MAX_NUM; i += 1) @@ -718,6 +742,7 @@ static void FFMPEGThread(Context_t *context) flv2mpeg4_context_reset(&flv2mpeg4_context); #endif } + int ffmpegStatus = 0; if (!isWaitingForFinish) { @@ -736,6 +761,7 @@ static void FFMPEGThread(Context_t *context) cAVIdx = 0; } } + if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0) { int64_t pts = 0; @@ -743,7 +769,9 @@ static void FFMPEGThread(Context_t *context) Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; Track_t *subtitleTrack = NULL; + int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id; + reset_finish_timeout(); if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL) { @@ -751,10 +779,12 @@ static void FFMPEGThread(Context_t *context) { ffmpeg_err("error getting video track\n"); } + if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0) { ffmpeg_err("error getting audio track\n"); } + if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0) { ffmpeg_err("error getting subtitle track\n"); @@ -764,7 +794,9 @@ static void FFMPEGThread(Context_t *context) { ffmpeg_printf(1, "SKIP DISCARDED PACKET stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid); } + ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid); + if (videoTrack && (videoTrack->AVIdx == (int)cAVIdx) && (videoTrack->Id == pid)) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) @@ -799,11 +831,13 @@ static void FFMPEGThread(Context_t *context) uint8_t skipPacket = 0; currentVideoPts = videoTrack->pts = pts = calcPts(cAVIdx, videoTrack->stream, packet.pts); videoTrack->dts = dts = calcPts(cAVIdx, videoTrack->stream, packet.dts); + if ((currentVideoPts != INVALID_PTS_VALUE) && (currentVideoPts > latestPts)) { latestPts = currentVideoPts; update_max_injected_pts(latestPts); } + if (context->playback->isTSLiveMode) { if (dts != INVALID_PTS_VALUE) @@ -826,13 +860,16 @@ static void FFMPEGThread(Context_t *context) skipPacket = 1; } } + if (skipPacket) { wrapped_packet_unref(&packet); releaseMutex(__FILE__, __FUNCTION__, __LINE__); continue; } + ffmpeg_printf(200, "VideoTrack index = %d %lld\n", pid, currentVideoPts); + avOut.data = packet.data; avOut.len = packet.size; avOut.pts = pts; @@ -844,10 +881,12 @@ static void FFMPEGThread(Context_t *context) avOut.width = videoTrack->width; avOut.height = videoTrack->height; avOut.type = "video"; + if (avContextTab[cAVIdx]->iformat->flags & AVFMT_TS_DISCONT) { avOut.infoFlags = 1; // TS container } + if (Write(context->output->video->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to video device failed\n"); @@ -859,11 +898,13 @@ static void FFMPEGThread(Context_t *context) uint8_t skipPacket = 0; currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, packet.pts); dts = calcPts(cAVIdx, audioTrack->stream, packet.dts); + if ((currentAudioPts != INVALID_PTS_VALUE) && (currentAudioPts > latestPts) && (!videoTrack)) { latestPts = currentAudioPts; update_max_injected_pts(latestPts); } + if (context->playback->isTSLiveMode) { if (dts != INVALID_PTS_VALUE) @@ -886,12 +927,14 @@ static void FFMPEGThread(Context_t *context) skipPacket = 1; } } + if (skipPacket) { wrapped_packet_unref(&packet); releaseMutex(__FILE__, __FUNCTION__, __LINE__); continue; } + pcmPrivateData_t pcmExtradata; pcmExtradata.channels = get_codecpar(audioTrack->stream)->channels; pcmExtradata.bits_per_coded_sample = get_codecpar(audioTrack->stream)->bits_per_coded_sample; @@ -899,13 +942,16 @@ static void FFMPEGThread(Context_t *context) pcmExtradata.bit_rate = get_codecpar(audioTrack->stream)->bit_rate; pcmExtradata.ffmpeg_codec_id = get_codecpar(audioTrack->stream)->codec_id; pcmExtradata.bResampling = restart_audio_resampling; + uint8_t *pAudioExtradata = get_codecpar(audioTrack->stream)->extradata; uint32_t audioExtradataSize = get_codecpar(audioTrack->stream)->extradata_size; + ffmpeg_printf(200, "AudioTrack index = %d\n", pid); if (audioTrack->inject_raw_pcm == 1) { ffmpeg_printf(200, "write audio raw pcm\n"); restart_audio_resampling = 0; + avOut.data = packet.data; avOut.len = packet.size; avOut.pts = pts; @@ -916,6 +962,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; + if (Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("(raw pcm) writing data to audio device failed\n"); @@ -924,6 +971,7 @@ static void FFMPEGThread(Context_t *context) else if (audioTrack->inject_as_pcm == 1 && audioTrack->avCodecCtx) { AVCodecContext *c = audioTrack->avCodecCtx; + if (restart_audio_resampling) { restart_audio_resampling = 0; @@ -948,6 +996,7 @@ static void FFMPEGThread(Context_t *context) { break; } + if (!decoded_frame) { decoded_frame = wrapped_frame_alloc(); @@ -968,10 +1017,12 @@ static void FFMPEGThread(Context_t *context) restart_audio_resampling = 1; break; } + if (ret >= 0) { packet.size = 0; } + ret = avcodec_receive_frame(c, decoded_frame); if (ret < 0) { @@ -993,8 +1044,10 @@ static void FFMPEGThread(Context_t *context) ffmpeg_err("avcodec_decode_audio4: %d\n", len); break; } + packet.data += len; packet.size -= len; + if (!got_frame) { continue; @@ -1018,13 +1071,16 @@ static void FFMPEGThread(Context_t *context) } out_sample_rate = *rate ? *rate : 44100; } + swr = swr_alloc(); out_channels = c->channels; + if (c->channel_layout == 0) { c->channel_layout = av_get_default_channel_layout(c->channels); } out_channel_layout = c->channel_layout; + uint8_t downmix = stereo_software_decoder && out_channels > 2 ? 1 : 0; #ifdef __sh__ // player2 won't play mono @@ -1038,12 +1094,15 @@ static void FFMPEGThread(Context_t *context) out_channel_layout = AV_CH_LAYOUT_STEREO_DOWNMIX; out_channels = 2; } + av_opt_set_int(swr, "in_channel_layout", c->channel_layout, 0); av_opt_set_int(swr, "out_channel_layout", out_channel_layout, 0); av_opt_set_int(swr, "in_sample_rate", c->sample_rate, 0); av_opt_set_int(swr, "out_sample_rate", out_sample_rate, 0); av_opt_set_int(swr, "in_sample_fmt", c->sample_fmt, 0); av_opt_set_int(swr, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0); + + e = swr_init(swr); if (e < 0) { @@ -1053,6 +1112,7 @@ static void FFMPEGThread(Context_t *context) swr = NULL; } } + uint8_t *output[8] = {NULL}; int32_t in_samples = decoded_frame->nb_samples; int32_t out_samples = av_rescale_rnd(swr_get_delay(swr, c->sample_rate) + in_samples, out_sample_rate, c->sample_rate, AV_ROUND_UP); @@ -1068,8 +1128,10 @@ static void FFMPEGThread(Context_t *context) int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts), ((AVStream *) audioTrack->stream)->time_base.den, ((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate); + currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, next_out_pts); out_samples = swr_convert(swr, &output[0], out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples); + ////////////////////////////////////////////////////////////////////// // Update pcmExtradata according to decode parameters pcmExtradata.channels = av_get_channel_layout_nb_channels(out_channel_layout); @@ -1081,9 +1143,12 @@ static void FFMPEGThread(Context_t *context) #else pcmExtradata.ffmpeg_codec_id = AV_CODEC_ID_PCM_S16LE; #endif + ////////////////////////////////////////////////////////////////////// + avOut.data = output[0]; avOut.len = out_samples * sizeof(int16_t) * out_channels; + avOut.pts = pts; avOut.extradata = (unsigned char *) &pcmExtradata; avOut.extralen = sizeof(pcmExtradata); @@ -1092,6 +1157,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to audio device failed\n"); @@ -1103,6 +1169,7 @@ static void FFMPEGThread(Context_t *context) { ffmpeg_printf(200, "write audio aac\n"); ffmpeg_printf(200, ">>>>>>> %x %x %x %x %x %x %x\n", packet.data[0], packet.data[1], packet.data[2], packet.data[3], packet.data[4], packet.data[5], packet.data[6]); + avOut.data = packet.data; avOut.len = packet.size; avOut.pts = pts; @@ -1113,6 +1180,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("(aac) writing data to audio device failed\n"); @@ -1130,6 +1198,7 @@ static void FFMPEGThread(Context_t *context) avOut.width = 0; avOut.height = 0; avOut.type = "audio"; + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) { ffmpeg_err("writing data to audio device failed\n"); @@ -1141,6 +1210,7 @@ static void FFMPEGThread(Context_t *context) int64_t duration = -1; pts = calcPts(cAVIdx, subtitleTrack->stream, packet.pts); AVStream *stream = subtitleTrack->stream; + if (packet.duration != 0) { // duration in milliseconds @@ -1151,6 +1221,7 @@ static void FFMPEGThread(Context_t *context) // duration in milliseconds duration = (int64_t)av_rescale(get_packet_duration(&packet), (int64_t)stream->time_base.num * 1000, stream->time_base.den); } + if (duration > 0) { SubtitleOut_t subOut; @@ -1171,11 +1242,13 @@ static void FFMPEGThread(Context_t *context) if (0 != ffmpegStatus) { static char errbuf[256]; + if (0 == av_strerror(ffmpegStatus, errbuf, sizeof(errbuf))) { /* In this way we inform user about error within the core */ printf("{\"log\":\"Frame read error: '%s'\"}\n", errbuf); } + /* if(ffmpegStatus == AVERROR(EAGAIN)) { @@ -1184,6 +1257,7 @@ static void FFMPEGThread(Context_t *context) */ ffmpegStatus = 0; } + if (!is_finish_timeout() && !context->playback->isTSLiveMode) { isWaitingForFinish = 1; @@ -1224,6 +1298,7 @@ static void FFMPEGThread(Context_t *context) printf("{\"log\":\"Loop mode: jump to the start.\"}\n"); } } + // av_read_frame failed ffmpeg_err("no data ->end of file reached ? \n"); wrapped_packet_unref(&packet); @@ -1241,14 +1316,17 @@ static void FFMPEGThread(Context_t *context) wrapped_packet_unref(&packet); releaseMutex(__FILE__, __FUNCTION__, __LINE__); } /* while */ + if (swr) { swr_free(&swr); } + if (decoded_frame) { wrapped_frame_free(&decoded_frame); } + #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) mpeg4p2_context_reset(&mpeg4p2_context); if (NULL != mpeg4p2_bsf_context) @@ -1256,6 +1334,7 @@ static void FFMPEGThread(Context_t *context) av_bitstream_filter_close(mpeg4p2_bsf_context); } #endif + hasPlayThreadStarted = 0; context->playback->isPlaying = 0; PlaybackDieNow(1); @@ -1301,13 +1380,16 @@ AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_b { filename += 7; } + FILE *pFile = fopen(filename, "rb"); if (NULL == pFile) { return NULL; } + AVIOContext *avio_ctx = NULL; uint8_t *avio_ctx_buffer = NULL; + avio_ctx_buffer = av_malloc(avio_ctx_buffer_size); if (!avio_ctx_buffer) { @@ -1329,8 +1411,10 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int avContextTab[AVIdx] = avformat_alloc_context(); avContextTab[AVIdx]->interrupt_callback.callback = interrupt_cb; avContextTab[AVIdx]->interrupt_callback.opaque = context->playback; + #ifdef SAM_CUSTOM_IO - if (0 == strstr(filename, "://") || 0 == strncmp(filename, "file://", 7)) + if (0 == strstr(filename, "://") || + 0 == strncmp(filename, "file://", 7)) { AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096); if (avio_ctx) @@ -1344,6 +1428,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int } } #endif + AVDictionary **pavio_opts = NULL; eRTMPProtoImplType rtmpProtoImplType = RTMP_NONE; uint8_t numOfRTMPImpl = 0; @@ -1352,6 +1437,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int filename = filename + 2; rtmpProtoImplType = RTMP_NATIVE; } + if (1 == rtmp_proto_impl) { rtmpProtoImplType = RTMP_NATIVE; @@ -1360,6 +1446,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int { rtmpProtoImplType = RTMP_LIBRTMP; } + if (0 == strncmp(filename, "rtmp://", 7) || 0 == strncmp(filename, "rtmpe://", 8) || 0 == strncmp(filename, "rtmps://", 8) || @@ -1373,6 +1460,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int void *opaque = NULL; const char *protoName = NULL; uint8_t haveNativeProto = 0; + while ((protoName = avio_enum_protocols(&opaque, 1))) { if (0 == strcmp("rtmp", protoName)) @@ -1392,6 +1480,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int haveNativeProto = 1; } } + if (haveNativeProto > 0) { if (numOfRTMPImpl > 1) // we have both @@ -1402,7 +1491,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int * unless uri contain param wich can be understandable * only by librtmp */ - if (strstr(filename, " token=") || strstr(filename, " jtv=")) + if (strstr(filename, " token=") || + strstr(filename, " jtv=")) { rtmpProtoImplType = RTMP_LIBRTMP; } @@ -1421,10 +1511,12 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int { rtmpProtoImplType = RTMP_LIBRTMP; } + if (RTMP_NATIVE == rtmpProtoImplType) { char *baseUri = strdup(filename); char *token = NULL; + // check if uri have additional params if ((token = strtok(baseUri, " ")) != NULL) { @@ -1512,11 +1604,13 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int } token = NULL; } + if (conn[0] != '\0') { av_dict_set(&avio_opts, "rtmp_conn", conn, 0); } free(conn); + if (swfUrl[0] != '\0') { if (swfVfy[0] == '1' || !strncasecmp(swfVfy, "true", 4)) @@ -1531,6 +1625,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int free(swfUrl); free(swfVfy); } + if (2 == haveNativeProto) { filename = malloc(strlen(baseUri) + 2 + 1); @@ -1546,7 +1641,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int } } } - else if (0 == strncmp(filename, "http://", 7) || 0 == strncmp(filename, "https://", 8)) + else if (0 == strncmp(filename, "http://", 7) || + 0 == strncmp(filename, "https://", 8)) { av_dict_set(&avio_opts, "timeout", "20000000", 0); //20sec av_dict_set(&avio_opts, "reconnect", "1", 0); @@ -1557,7 +1653,9 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int av_dict_set(&avio_opts, "reconnect_streamed", "1", 0); } } + pavio_opts = &avio_opts; + if ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0) { if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN && @@ -1568,12 +1666,15 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int err = avformat_open_input(&avContextTab[AVIdx], filename + 2, fmt, pavio_opts); // filename2 - another memory leak, and also only once, so does not matter } + if (err != 0) { char error[512]; + ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename); av_strerror(err, error, 512); fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err); + if (avio_opts != NULL) { av_dict_free(&avio_opts); @@ -1582,22 +1683,29 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int return cERR_CONTAINER_FFMPEG_OPEN; } } + avContextTab[AVIdx]->iformat->flags |= AVFMT_SEEK_TO_PTS; avContextTab[AVIdx]->flags = AVFMT_FLAG_GENPTS; + printf("minimal Probe: %d\n", context->playback->noprobe); + if (context->playback->noprobe) { wrapped_set_max_analyze_duration(avContextTab[AVIdx], 1); } + ffmpeg_printf(20, "find_streaminfo\n"); + if (avformat_find_stream_info(avContextTab[AVIdx], NULL) < 0) { ffmpeg_err("Error avformat_find_stream_info\n"); } + //for buffered io if (avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL && !context->playback->isTSLiveMode) { ffmpeg_real_read_org = avContextTab[AVIdx]->pb->read_packet; + if (0 == AVIdx && strstr(filename, "://") != 0 && strncmp(filename, "file://", 7) != 0) { if (ffmpeg_buf_size > 0 && ffmpeg_buf_size > FILLBUFDIFF + FILLBUFPAKET) @@ -1605,15 +1713,18 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int if (avContextTab[AVIdx] != NULL && avContextTab[AVIdx]->pb != NULL) { ffmpeg_buf = av_malloc(ffmpeg_buf_size); + if (ffmpeg_buf != NULL) { ffmpeg_printf(10, "buffer size=%d\n", ffmpeg_buf_size); + ffmpeg_read_org = avContextTab[AVIdx]->pb->read_packet; avContextTab[AVIdx]->pb->read_packet = ffmpeg_read; ffmpeg_seek_org = avContextTab[AVIdx]->pb->seek; avContextTab[AVIdx]->pb->seek = ffmpeg_seek; ffmpeg_buf_read = ffmpeg_buf; ffmpeg_buf_write = ffmpeg_buf; + //fill buffer ffmpeg_filler(context, -1, NULL, 0); ffmpeg_start_fillerTHREAD(context); @@ -1627,28 +1738,34 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int } } //for buffered io (end) + return 0; } int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) { //int32_t err = 0; + ffmpeg_printf(10, ">\n"); + if (playFilesNames == NULL) { ffmpeg_err("playFilesNames NULL\n"); return cERR_CONTAINER_FFMPEG_NULL; } + if (playFilesNames->szFirstFile == NULL) { ffmpeg_err("playFilesNames->szFirstFile NULL\n"); return cERR_CONTAINER_FFMPEG_NULL; } + if (context == NULL) { ffmpeg_err("context NULL\n"); return cERR_CONTAINER_FFMPEG_NULL; } + ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile); if (playFilesNames->szSecondFile) { @@ -1658,24 +1775,29 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) avcodec_register_all(); av_register_all(); avformat_network_init(); + // SULGE DEBUG ENABLED // make ffmpeg silen // av_log_set_level(AV_LOG_DEBUG); av_log_set_callback(ffmpeg_silen_callback); + context->playback->abortRequested = 0; int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0); if (0 != res) { return res; } + if (playFilesNames->szSecondFile) { res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1); } + if (0 != res) { return res; } + terminating = 0; latestPts = 0; res = container_ffmpeg_update_tracks(context, playFilesNames->szFirstFile, 1); @@ -1687,35 +1809,45 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 Track_t *currAudioTrack = NULL; Track_t *currSubtitleTrack = NULL; uint32_t addedVideoTracksCount = 0; + if (terminating) { return cERR_CONTAINER_FFMPEG_NO_ERROR; } + getMutex(__FILE__, __FUNCTION__, __LINE__); + if (initial && context->manager->subtitle) { context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &currSubtitleTrack); } + if (context->manager->audio) { context->manager->audio->Command(context, MANAGER_GET_TRACK, &currAudioTrack); } + if (context->manager->video) { context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); } + if (context->manager->audio) { context->manager->audio->Command(context, MANAGER_INIT_UPDATE, NULL); } + #if 0 if (context->manager->subtitle) { context->manager->subtitle->Command(context, MANAGER_INIT_UPDATE, NULL); } #endif + ffmpeg_printf(20, "dump format\n"); av_dump_format(avContextTab[0], 0, filename, 0); + + uint32_t cAVIdx = 0; for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1) { @@ -1726,7 +1858,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 AVFormatContext *avContext = avContextTab[cAVIdx]; uint32_t *stream_index = NULL; uint32_t nb_stream_indexes = 0; + ffmpeg_printf(1, "cAVIdx[%d]: number of streams: %d\n", cAVIdx, avContext->nb_streams); + if (avContext->nb_programs > 0) { uint32_t n = 0; @@ -1764,6 +1898,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } } + uint32_t n = 0; for (n = 0; n < avContext->nb_streams; n++) { @@ -1771,6 +1906,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 AVStream *stream = avContext->streams[n]; int32_t version = 0; char *encoding = NULL; + if (nb_stream_indexes > 0 && stream_index != NULL) { uint32_t isStreamFromSelProg = 0; @@ -1783,6 +1919,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 break; } } + if (!isStreamFromSelProg) { stream->discard = AVDISCARD_ALL; @@ -1790,27 +1927,33 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 continue; // skip this stream } } + encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \ (uint8_t *)get_codecpar(stream)->extradata, \ (int)get_codecpar(stream)->extradata_size, \ (int)get_codecpar(stream)->profile, &version); + if (encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm) { encoding = "A_LPCM"; } + if (encoding != NULL) { ffmpeg_printf(1, "%d. encoding = %s - version %d\n", n, encoding, version); } + if (!stream->id) { stream->id = n; } + /* some values in track are unset and therefor copyTrack segfaults. * so set it by default to NULL! */ memset(&track, 0, sizeof(track)); track.AVIdx = cAVIdx; + switch (get_codecpar(stream)->codec_type) { case AVMEDIA_TYPE_VIDEO: @@ -1820,8 +1963,10 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { track.type = eTypeES; track.version = version; + track.width = get_codecpar(stream)->width; track.height = get_codecpar(stream)->height; + /* We will return here PAR (Pixel Aspect Ratio) client need to calculate DAR(Display Aspect Ratio) * example: PAR 64:45 DAR 16:9 * Resolution 720x576 @@ -1835,15 +1980,19 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num; track.aspect_ratio_den = get_codecpar(stream)->sample_aspect_ratio.den; } + track.extraData = get_codecpar(stream)->extradata; track.extraSize = get_codecpar(stream)->extradata_size; + track.aacbuf = 0; track.have_aacheader = -1; + AVRational rateRational = get_frame_rate(stream); if (rateRational.den != 0) { track.frame_rate = (uint32_t)(1000 * (int64_t)(rateRational.num) / (int64_t)(rateRational.den)); } + /* fixme: revise this */ if (track.frame_rate < 23970) { @@ -1853,6 +2002,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { track.TimeScale = 1000; } + ffmpeg_printf(10, "bit_rate [%lld]\n", get_codecpar(stream)->bit_rate); ffmpeg_printf(10, "time_base.den [%d]\n", stream->time_base.den); ffmpeg_printf(10, "time_base.num [%d]\n", stream->time_base.num); @@ -1860,19 +2010,24 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_printf(10, "height [%d]\n", get_codecpar(stream)->height); ffmpeg_printf(10, "frame_rate num [%d]\n", rateRational.num); ffmpeg_printf(10, "frame_rate den [%d]\n", rateRational.den); + ffmpeg_printf(10, "frame_rate [%u]\n", track.frame_rate); ffmpeg_printf(10, "TimeScale [%d]\n", track.TimeScale); + track.Name = "und"; track.Encoding = encoding; track.stream = stream; track.Id = ((AVStream *)(track.stream))->id; + track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den); if (stream->duration == AV_NOPTS_VALUE || 0 == strncmp(avContext->iformat->name, "dash", 4)) { ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); track.duration = (int64_t) avContext->duration / 1000; } + ffmpeg_printf(10, "duration [%lld]\n", track.duration); + if (context->manager->video) { if (get_codecpar(stream)->codec_id == AV_CODEC_ID_MPEG4) @@ -1907,20 +2062,26 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { AVDictionaryEntry *lang; track.type = eTypeES; + lang = av_dict_get(stream->metadata, "language", NULL, 0); + track.Name = lang ? lang->value : "und"; + ffmpeg_printf(10, "Language %s\n", track.Name); + track.Encoding = encoding; track.stream = stream; track.Id = ((AVStream *)(track.stream))->id; track.aacbuf = 0; track.have_aacheader = -1; + track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den); if (stream->duration == AV_NOPTS_VALUE) { ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); track.duration = (int64_t) avContext->duration / 1000; } + if (!strncmp(encoding, "A_IPCM", 6) || !strncmp(encoding, "A_LPCM", 6)) { track.inject_as_pcm = 1; @@ -1928,7 +2089,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 if (track.avCodecCtx) { ffmpeg_printf(10, " Handle inject_as_pcm = %d\n", track.inject_as_pcm); + AVCodec *codec = avcodec_find_decoder(get_codecpar(stream)->codec_id); + int errorCode = avcodec_open2(track.avCodecCtx, codec, NULL); if (codec != NULL && !errorCode) { @@ -1950,6 +2113,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 track.aacbuflen = sizeof(marker) / sizeof(char); track.aacbuf = malloc(track.aacbuflen); memcpy(track.aacbuf, marker, track.aacbuflen); + ffmpeg_printf(10, "AV_CODEC_ID_AAC_LATM no extradata ACC header should be available in each frame\n"); track.have_aacheader = 1; } @@ -1966,6 +2130,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 track.aacbuflen = sizeof(marker) / sizeof(char); track.aacbuf = malloc(track.aacbuflen); memcpy(track.aacbuf, marker, track.aacbuflen); + ffmpeg_printf(10, "AV_CODEC_ID_AAC no extradata ACC header should be available in each frame\n"); track.have_aacheader = 1; } @@ -1974,6 +2139,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_printf(10, "Create AAC ExtraData\n"); ffmpeg_printf(10, "get_codecpar(stream)->extradata_size %d\n", get_codecpar(stream)->extradata_size); //Hexdump(get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size); + /* extradata: 13 10 56 e5 9d 48 00 (anderen cops) object_type: 00010 2 = LC @@ -1988,12 +2154,14 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ps = 0 0000000 */ + int32_t object_type = 2; // LC int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate); int32_t chan_config = get_codecpar(stream)->channels - 1; ffmpeg_printf(1, "aac object_type %d\n", object_type); ffmpeg_printf(1, "aac sample_index %d\n", sample_index); ffmpeg_printf(1, "aac chan_config %d\n", chan_config); + if (get_codecpar(stream)->extradata_size >= 2) { MPEG4AudioConfig m4ac; @@ -2009,11 +2177,15 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 chan_config = m4ac.chan_config; } } + ffmpeg_printf(1, "aac object_type %d\n", object_type); ffmpeg_printf(1, "aac sample_index %d\n", sample_index); ffmpeg_printf(1, "aac chan_config %d\n", chan_config); + + // https://wiki.multimedia.cx/index.php/ADTS object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1 + track.aacbuflen = AAC_HEADER_LENGTH; track.aacbuf = malloc(8); track.aacbuf[0] = 0xFF; @@ -2025,6 +2197,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 track.aacbuf[4] = 0x00; track.aacbuf[5] = 0x1F; track.aacbuf[6] = 0xFC; + //printf("AAC_HEADER -> "); //Hexdump(track.aacbuf,7); track.have_aacheader = 1; @@ -2035,6 +2208,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_err("AV_CODEC_ID_AAC extradata not available\n"); } */ + } else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1 || get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2 || @@ -2049,6 +2223,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 uint16_t depth = get_codecpar(stream)->bits_per_coded_sample; uint32_t codec_data_size = get_codecpar(stream)->extradata_size; uint8_t *codec_data_pointer = get_codecpar(stream)->extradata; + // type_specific_data #define WMA_VERSION_1 0x160 #define WMA_VERSION_2_9 0x161 @@ -2076,40 +2251,58 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 track.aacbuflen = 104 + get_codecpar(stream)->extradata_size; track.aacbuf = malloc(track.aacbuflen); memset(track.aacbuf, 0, track.aacbuflen); + uint8_t ASF_Stream_Properties_Object[16] = {0x91, 0x07, 0xDC, 0xB7, 0xB7, 0xA9, 0xCF, 0x11, 0x8E, 0xE6, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65}; + memcpy(track.aacbuf + 0, ASF_Stream_Properties_Object, 16); // ASF_Stream_Properties_Object memcpy(track.aacbuf + 16, &track.aacbuflen, 4); //FrameDateLength + uint32_t sizehi = 0; memcpy(track.aacbuf + 20, &sizehi, 4); // sizehi (not used) + uint8_t ASF_Audio_Media[16] = {0x40, 0x9E, 0x69, 0xF8, 0x4D, 0x5B, 0xCF, 0x11, 0xA8, 0xFD, 0x00, 0x80, 0x5F, 0x5C, 0x44, 0x2B}; + memcpy(track.aacbuf + 24, ASF_Audio_Media, 16); //ASF_Audio_Media + uint8_t ASF_Audio_Spread[16] = {0x50, 0xCD, 0xC3, 0xBF, 0x8F, 0x61, 0xCF, 0x11, 0x8B, 0xB2, 0x00, 0xAA, 0x00, 0xB4, 0xE2, 0x20}; + memcpy(track.aacbuf + 40, ASF_Audio_Spread, 16); //ASF_Audio_Spread + memset(track.aacbuf + 56, 0, 4); // time_offset (not used) memset(track.aacbuf + 60, 0, 4); // time_offset_hi (not used) + uint8_t type_specific_data_length = 18 + get_codecpar(stream)->extradata_size; memcpy(track.aacbuf + 64, &type_specific_data_length, 4); //type_specific_data_length + uint8_t error_correction_data_length = 8; memcpy(track.aacbuf + 68, &error_correction_data_length, 4); //error_correction_data_length + uint16_t flags = 1; // stream_number memcpy(track.aacbuf + 72, &flags, 2); //flags + uint32_t reserved = 0; memcpy(track.aacbuf + 74, &reserved, 4); // reserved + memcpy(track.aacbuf + 78, &codec_id, 2); //codec_id + uint16_t number_of_channels = get_codecpar(stream)->channels; memcpy(track.aacbuf + 80, &number_of_channels, 2); //number_of_channels + uint32_t samples_per_second = get_codecpar(stream)->sample_rate; ffmpeg_printf(1, "samples_per_second = %d\n", samples_per_second); memcpy(track.aacbuf + 82, &samples_per_second, 4); //samples_per_second + uint32_t average_number_of_bytes_per_second = get_codecpar(stream)->bit_rate / 8; ffmpeg_printf(1, "average_number_of_bytes_per_second = %d\n", average_number_of_bytes_per_second); memcpy(track.aacbuf + 86, &average_number_of_bytes_per_second, 4); //average_number_of_bytes_per_second + uint16_t block_alignment = get_codecpar(stream)->block_align; ffmpeg_printf(1, "block_alignment = %d\n", block_alignment); memcpy(track.aacbuf + 90, &block_alignment, 2); //block_alignment + #if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32)) enum AVSampleFormat sample_fmt = get_codecpar(stream)->format; #else @@ -2118,12 +2311,15 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 uint16_t bits_per_sample = sample_fmt >= 0 ? (sample_fmt + 1) * 8 : 8; ffmpeg_printf(1, "bits_per_sample = %d (%d)\n", bits_per_sample, sample_fmt); memcpy(track.aacbuf + 92, &bits_per_sample, 2); //bits_per_sample + memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample + memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size); #else track.aacbuflen = 18 + get_codecpar(stream)->extradata_size; track.aacbuf = malloc(track.aacbuflen); memset(track.aacbuf, 0, track.aacbuflen); + uint8_t *data = track.aacbuf; /* codec tag */ *(data++) = codec_id & 0xff; @@ -2155,10 +2351,13 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 #endif ffmpeg_printf(1, "aacbuf:\n"); //Hexdump(track.aacbuf, track.aacbuflen); + //ffmpeg_printf(1, "priv_data:\n"); //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen); + track.have_aacheader = 1; } + if (context->manager->audio) { ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n"); @@ -2190,26 +2389,34 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { AVDictionaryEntry *lang = NULL; memset(&track, 0, sizeof(track)); + ffmpeg_printf(10, "CODEC_TYPE_SUBTITLE %d\n", get_codecpar(stream)->codec_type); + lang = av_dict_get(stream->metadata, "language", NULL, 0); track.Name = lang ? lang->value : "und"; ffmpeg_printf(10, "Language %s\n", track.Name); + track.Encoding = encoding; track.stream = stream; track.Id = ((AVStream *)(track.stream))->id; track.duration = (int64_t)av_rescale(stream->duration, (int64_t)stream->time_base.num * 1000, stream->time_base.den); + if (stream->duration == AV_NOPTS_VALUE) { ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); track.duration = (int64_t) avContext->duration / 1000; } + track.extraData = get_codecpar(stream)->extradata; track.extraSize = get_codecpar(stream)->extradata_size; + ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id); ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width); ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height); ffmpeg_printf(1, "subtitle stream %p\n", stream); + ffmpeg_printf(10, "FOUND SUBTITLE %s\n", track.Name); + if (context->manager->subtitle->Command(context, MANAGER_ADD, &track) < 0) { ffmpeg_err("failed to add subtitle track %d\n", n); @@ -2228,11 +2435,13 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } /* for */ } + if (context->manager->audio) { Track_t *Tracks = NULL; int32_t TrackCount = 0; int32_t selTrackIdx = -1; + context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); if (Tracks && TrackCount) @@ -2242,14 +2451,17 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { if (Tracks[i].pending || Tracks[i].Id < 0) continue; + if (selTrackIdx == -1) selTrackIdx = i; + if (currAudioTrack && currAudioTrack->Id == Tracks[i].Id) { selTrackIdx = i; break; } } + if (selTrackIdx > -1) { ((AVStream *)Tracks[selTrackIdx].stream)->discard = AVDISCARD_DEFAULT; @@ -2260,6 +2472,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } } } + releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2269,7 +2482,9 @@ static int32_t container_ffmpeg_play(Context_t *context) int32_t error = 0; int32_t ret = 0; pthread_attr_t attr; + ffmpeg_printf(10, "\n"); + if (context && context->playback && context->playback->isPlaying) { ffmpeg_printf(10, "is Playing\n"); @@ -2278,19 +2493,23 @@ static int32_t container_ffmpeg_play(Context_t *context) { ffmpeg_printf(10, "is NOT Playing\n"); } + if (hasPlayThreadStarted == 0) { pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if ((error = pthread_create(&PlayThread, &attr, (void *)&FFMPEGThread, context)) != 0) { ffmpeg_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error)); + hasPlayThreadStarted = 0; ret = cERR_CONTAINER_FFMPEG_ERR; } else { ffmpeg_printf(10, "Created thread\n"); + hasPlayThreadStarted = 1; } } @@ -2299,6 +2518,7 @@ static int32_t container_ffmpeg_play(Context_t *context) ffmpeg_printf(10, "A thread already exists!\n"); ret = cERR_CONTAINER_FFMPEG_ERR; } + ffmpeg_printf(10, "exiting with value %d\n", ret); return ret; } @@ -2311,16 +2531,20 @@ static int32_t container_ffmpeg_stop(Context_t *context) * in this case, ffmpeg thread will not be terminated * and causes in most cases a segfault */ + ffmpeg_printf(10, "\n"); + if (context->playback) { context->playback->isPlaying = 0; } + while ((hasPlayThreadStarted != 0) && (--wait_time) > 0) { ffmpeg_printf(10, "Waiting for ffmpeg thread to terminate itself, will try another %d times\n", wait_time); usleep(100000); } + if (wait_time == 0) { /* force close */ @@ -2331,10 +2555,14 @@ static int32_t container_ffmpeg_stop(Context_t *context) */ return ret; } + hasPlayThreadStarted = 0; terminating = 1; + getMutex(__FILE__, __FUNCTION__, __LINE__); + free_all_stored_avcodec_context(); + uint32_t i = 0; for (i = 0; i < IPTV_AV_CONTEXT_MAX_NUM; i += 1) { @@ -2360,13 +2588,17 @@ static int32_t container_ffmpeg_stop(Context_t *context) break; } } + if (avio_opts != NULL) { av_dict_free(&avio_opts); } + avformat_network_deinit(); ffmpeg_buf_free(); + releaseMutex(__FILE__, __FUNCTION__, __LINE__); + ffmpeg_printf(10, "ret %d\n", ret); return ret; } @@ -2375,19 +2607,25 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos) { int32_t flag = AVSEEK_FLAG_BYTE; off_t current_pos = avio_tell(avContextTab[0]->pb); + ffmpeg_printf(20, "seeking to position %lld (bytes)\n", pos); + if (current_pos > pos) { flag |= AVSEEK_FLAG_BACKWARD; } + if (avformat_seek_file(avContextTab[0], -1, INT64_MIN, pos, INT64_MAX, flag) < 0) { ffmpeg_err("Error seeking\n"); return cERR_CONTAINER_FFMPEG_ERR; } + ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb)); + return cERR_CONTAINER_FFMPEG_NO_ERROR; } + #if 0 //unused /* seeking relative to a given byteposition N seconds ->for reverse playback needed */ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec) @@ -2396,9 +2634,12 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t Track_t *audioTrack = NULL; Track_t *current = NULL; seek_target_flag = 0; + ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos); + context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if (videoTrack != NULL) { current = videoTrack; @@ -2407,23 +2648,28 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t { current = audioTrack; } + if (current == NULL) { ffmpeg_err("no track avaibale to seek\n"); return cERR_CONTAINER_FFMPEG_ERR; } + if (pos == -1) { pos = avio_tell(avContextTab[0]->pb); } + if (pts == -1) { pts = current->pts; } + if (sec < 0) { seek_target_flag |= AVSEEK_FLAG_BACKWARD; } + ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags); #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) @@ -2437,41 +2683,53 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t { sec *= 180000; } + pos += sec; + if (pos < 0) { ffmpeg_err("end of file reached\n"); releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_END_OF_FILE; } + ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec); + seek_target_bytes = pos; do_seek_target_bytes = 1; + return pos; } else #endif { sec += pts / 90000; + if (sec < 0) { sec = 0; } + ffmpeg_printf(10, "2. seeking to position %f sec ->time base %f %d\n", sec, av_q2d(((AVStream *) current->stream)->time_base), AV_TIME_BASE); + seek_target_seconds = sec * AV_TIME_BASE; do_seek_target_seconds = 1; } + releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } #endif + static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute) { Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; // Track_t *current = NULL; seek_target_flag = 0; + sec *= AV_TIME_BASE; + if (!absolute) { ffmpeg_printf(10, "seeking %lld sec\n", sec / AV_TIME_BASE); @@ -2497,9 +2755,12 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab sec = 0; } } + ffmpeg_printf(10, "goto %lld sec\n", sec / AV_TIME_BASE); + context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if (!videoTrack && !audioTrack) { ffmpeg_err("no track available to seek\n"); @@ -2526,11 +2787,13 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab { seek_target_flag |= AVSEEK_FLAG_BACKWARD; } + if (!context->playback || !context->playback->isPlaying) { releaseMutex(__FILE__, __FUNCTION__, __LINE__); return cERR_CONTAINER_FFMPEG_NO_ERROR; } + ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags); #if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) @@ -2541,10 +2804,13 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab * seeking per HTTP does still not work very good. forward seeks everytime * about 10 seconds, backward does not work. */ + getMutex(__FILE__, __FUNCTION__, __LINE__); off_t pos = avio_tell(avContextTab[0]->pb); releaseMutex(__FILE__, __FUNCTION__, __LINE__); + ffmpeg_printf(10, "pos %lld %lld\n", pos, avContextTab[0]->bit_rate); + if (avContextTab[0]->bit_rate) { sec *= avContextTab[0]->bit_rate / 8; @@ -2554,12 +2820,16 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab { sec *= 180000; } + pos = sec; + if (pos < 0) { pos = 0; } + ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE); + seek_target_bytes = pos / AV_TIME_BASE; do_seek_target_bytes = 1; } @@ -2569,6 +2839,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab seek_target_seconds = sec; do_seek_target_seconds = 1; } + return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2578,13 +2849,16 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; Track_t *current = NULL; + if (length == NULL) { ffmpeg_err("null pointer passed\n"); return cERR_CONTAINER_FFMPEG_ERR; } + context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if (videoTrack != NULL) { current = videoTrack; @@ -2593,7 +2867,9 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) { current = audioTrack; } + *length = 0; + if (current != NULL) { if (current->duration == 0) @@ -2617,6 +2893,7 @@ static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length) return cERR_CONTAINER_FFMPEG_ERR; } } + return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2628,6 +2905,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __ { Track_t *Tracks = NULL; int32_t TrackCount = 0; + context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); if (Tracks && TrackCount) @@ -2640,6 +2918,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __ } } releaseMutex(__FILE__, __FUNCTION__, __LINE__); + /* Hellmaster1024: nothing to do here! */ int64_t sec = -1; context->playback->Command(context, PLAYBACK_SEEK, (void *)&sec); @@ -2649,6 +2928,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __ static int32_t container_ffmpeg_switch_subtitle(Context_t *context, int32_t *arg __attribute__((unused))) { ffmpeg_printf(10, "track %d\n", *arg); + /* This is made to flush inside the buffer because * subtitles frame was already read and ignored * we seek to force ffmpeg to read once again the same data @@ -2672,7 +2952,9 @@ static int32_t container_ffmpeg_get_info(Context_t *context, char **infoString) Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; char *meta = NULL; + ffmpeg_printf(20, ">\n"); + if (avContextTab[0] != NULL) { if ((infoString == NULL) || (*infoString == NULL)) @@ -2680,9 +2962,12 @@ static int32_t container_ffmpeg_get_info(Context_t *context, char **infoString) ffmpeg_err("infostring NULL\n"); return cERR_CONTAINER_FFMPEG_ERR; } + ffmpeg_printf(20, "%s\n", *infoString); + context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + if ((meta = searchMeta(avContextTab[0]->metadata, *infoString)) == NULL) { if (audioTrack != NULL) @@ -2690,12 +2975,14 @@ static int32_t container_ffmpeg_get_info(Context_t *context, char **infoString) AVStream *stream = audioTrack->stream; meta = searchMeta(stream->metadata, *infoString); } + if ((meta == NULL) && (videoTrack != NULL)) { AVStream *stream = videoTrack->stream; meta = searchMeta(stream->metadata, *infoString); } } + if (meta != NULL) { *infoString = strdup(meta); @@ -2786,7 +3073,9 @@ static int container_ffmpeg_get_metadata(Context_t * context, char ***p) static int32_t Command(Context_t *context, ContainerCmd_t command, void *argument) { int ret = cERR_CONTAINER_FFMPEG_NO_ERROR; + ffmpeg_printf(50, "Command %d\n", command); + if (command != CONTAINER_SET_BUFFER_SEEK_TIME && command != CONTAINER_SET_BUFFER_SIZE && command != CONTAINER_GET_BUFFER_SIZE && @@ -2796,6 +3085,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen { return cERR_CONTAINER_FFMPEG_ERR; } + switch (command) { case CONTAINER_INIT: @@ -2878,6 +3168,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen ret = cERR_CONTAINER_FFMPEG_ERR; break; } + ffmpeg_printf(50, "exiting with value %d\n", ret); return ret; } diff --git a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c index 8f72216..cc00144 100644 --- a/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c +++ b/libeplayer3-arm/container/flv2mpeg4_ffmpeg.c @@ -5,6 +5,7 @@ #include "flv2mpeg4/flv2mpeg4.h" + typedef struct { flv2mpeg4_CTX *ctx; @@ -15,6 +16,7 @@ typedef struct Track_t *track; } Flv2Mpeg4Context; + static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int pts, const uint8_t *buf, int size) { Flv2Mpeg4Context *ctx = usr_data; @@ -22,6 +24,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p { return -1; } + AudioVideoOut_t avOut; avOut.data = (char *)buf; avOut.len = size; @@ -34,10 +37,12 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe, int p avOut.width = ctx->track->width; avOut.height = ctx->track->height; avOut.type = "video"; + if (Write(ctx->out_ctx->output->video->Write, ctx->out_ctx, &avOut, avOut.pts) < 0) { ffmpeg_err("writing data to video device failed\n"); } + return 0; } @@ -48,10 +53,12 @@ static int flv2mpeg4_context_write_extradata_cb(void *usr_data, int width, int h { return -1; } + free(ctx->extradata); ctx->extradata = malloc(extradatasize); memcpy(ctx->extradata, extradata, extradatasize); ctx->extradatasize = extradatasize; + return 0; } @@ -59,6 +66,7 @@ static void flv2mpeg4_context_reset(Flv2Mpeg4Context *context) { if (context == NULL || context->ctx == NULL) return; + flv2mpeg4_set_frame(context->ctx, 0, 0); } @@ -69,14 +77,19 @@ static int flv2mpeg4_write_packet(Context_t *out_ctx, Flv2Mpeg4Context *mpeg4p2_ mpeg4p2_ctx->ctx = flv2mpeg4_init_ctx(mpeg4p2_ctx, track->width, track->height, flv2mpeg4_context_write_packet_cb, flv2mpeg4_context_write_extradata_cb); flv2mpeg4_prepare_extra_data(mpeg4p2_ctx->ctx); } + *pts_current = track->pts = calcPts(cAVIdx, track->stream, pkt->pts); if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE)) { *pts_latest = *pts_current; } track->dts = calcPts(cAVIdx, track->stream, pkt->dts); + mpeg4p2_ctx->out_ctx = out_ctx; mpeg4p2_ctx->track = track; + uint32_t time_ms = (uint32_t)(track->pts / 90); + return flv2mpeg4_process_flv_packet(mpeg4p2_ctx->ctx, 0, pkt->data, pkt->size, time_ms); } + diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c index 74a5559..0565912 100644 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -14,6 +14,7 @@ typedef struct AVPacket *second_ip_frame; } Mpeg4P2Context; + static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src) { if (pkt_dest == NULL) @@ -82,6 +83,7 @@ static void mpeg4p2_context_reset(Mpeg4P2Context *context) av_free(context->second_ip_frame); } context->second_ip_frame = NULL; + context->b_frames_count = 0; context->first_ip_frame_written = 0; context->packet_duration = 0; @@ -95,6 +97,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6 *pts_latest = *pts_current; } track->dts = calcPts(avContextIdx, track->stream, pkt->dts); + AudioVideoOut_t avOut; avOut.data = pkt->data; avOut.len = pkt->size; @@ -107,6 +110,7 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6 avOut.width = track->width; avOut.height = track->height; avOut.type = "video"; + if (Write(ctx->output->video->Write, ctx, &avOut, avOut.pts) < 0) { ffmpeg_err("writing data to video device failed\n"); @@ -206,3 +210,4 @@ static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Tra } return 0; } + diff --git a/libeplayer3-arm/container/wrapped_ffmpeg.c b/libeplayer3-arm/container/wrapped_ffmpeg.c index 3ca4738..2bf6bb7 100644 --- a/libeplayer3-arm/container/wrapped_ffmpeg.c +++ b/libeplayer3-arm/container/wrapped_ffmpeg.c @@ -121,9 +121,11 @@ int store_avcodec_context(AVCodecContext *avCodecCtx __attribute__((unused)), ui { return -1; } + memset(ptr, 0x00, sizeof(CodecCtxStoreItem_t)); ptr->next = g_codecCtxStoreListHead; g_codecCtxStoreListHead = ptr; + return 0; } #else @@ -144,6 +146,7 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id); return NULL; } + if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0) { fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id); @@ -151,8 +154,10 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st return NULL; } av_codec_set_pkt_timebase(avCodecCtx, stream->time_base); + store_avcodec_context(avCodecCtx, cAVIdx, stream->id); } + return avCodecCtx; #else return stream->codec; diff --git a/libeplayer3-arm/external/ffmpeg/get_bits.h b/libeplayer3-arm/external/ffmpeg/get_bits.h index b0f49e3..e40e201 100644 --- a/libeplayer3-arm/external/ffmpeg/get_bits.h +++ b/libeplayer3-arm/external/ffmpeg/get_bits.h @@ -100,9 +100,11 @@ typedef struct GetBitContext unsigned int name ## _index = (gb)->index; \ unsigned int av_unused name ## _cache + #define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb) #define BITS_AVAILABLE(name, gb) 1 + #define CLOSE_READER(name, gb) (gb)->index = name ## _index # ifdef LONG_BITSTREAM_READER @@ -123,6 +125,7 @@ typedef struct GetBitContext #endif + #ifdef BITSTREAM_READER_LE # define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) @@ -139,6 +142,7 @@ typedef struct GetBitContext #define SKIP_COUNTER(name, gb, num) name ## _index += (num) + #define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index)) #define SKIP_BITS(name, gb, num) \ @@ -282,6 +286,7 @@ static inline unsigned int get_bits1(GetBitContext *s) #endif index++; s->index = index; + return result; } @@ -349,6 +354,7 @@ static inline int get_sbits_long(GetBitContext *s, int n) /* sign_extend(x, 0) is undefined */ if (!n) return 0; + return sign_extend(get_bits_long(s, n), n); } @@ -387,18 +393,22 @@ static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, { int buffer_size; int ret = 0; + if (bit_size >= INT_MAX - 7 || bit_size < 0 || !buffer) { bit_size = 0; buffer = NULL; ret = AVERROR_INVALIDDATA; } + buffer_size = (bit_size + 7) >> 3; + s->buffer = buffer; s->size_in_bits = bit_size; s->size_in_bits_plus8 = bit_size + 8; s->buffer_end = buffer + buffer_size; s->index = 0; + return ret; } @@ -500,6 +510,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) SKIP_BITS(name, gb, n); \ } while (0) + static inline int decode012(GetBitContext *gb) { int n; @@ -527,12 +538,14 @@ static inline int skip_1stop_8data_bits(GetBitContext *gb) { if (get_bits_left(gb) <= 0) return AVERROR_INVALIDDATA; + while (get_bits1(gb)) { skip_bits(gb, 8); if (get_bits_left(gb) <= 0) return AVERROR_INVALIDDATA; } + return 0; } diff --git a/libeplayer3-arm/external/ffmpeg/latmenc.h b/libeplayer3-arm/external/ffmpeg/latmenc.h index 8e6a847..e5d3345 100644 --- a/libeplayer3-arm/external/ffmpeg/latmenc.h +++ b/libeplayer3-arm/external/ffmpeg/latmenc.h @@ -42,3 +42,4 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size); int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *extradata, int extradata_size); #endif /* AVCODEC_LATMENC_H */ + diff --git a/libeplayer3-arm/external/ffmpeg/put_bits.h b/libeplayer3-arm/external/ffmpeg/put_bits.h index f99cfac..40cc722 100644 --- a/libeplayer3-arm/external/ffmpeg/put_bits.h +++ b/libeplayer3-arm/external/ffmpeg/put_bits.h @@ -54,6 +54,7 @@ static inline void init_put_bits(PutBitContext *s, uint8_t *buffer, buffer_size = 0; buffer = NULL; } + s->size_in_bits = 8 * buffer_size; s->buf = buffer; s->buf_end = s->buf + buffer_size; @@ -73,6 +74,7 @@ static inline void rebase_put_bits(PutBitContext *s, uint8_t *buffer, int buffer_size) { av_assert0(8 * buffer_size > s->size_in_bits); + s->buf_end = buffer + buffer_size; s->buf_ptr = buffer + (s->buf_ptr - s->buf); s->buf = buffer; @@ -154,9 +156,12 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) { unsigned int bit_buf; int bit_left; + av_assert2(n <= 31 && value < (1U << n)); + bit_buf = s->bit_buf; bit_left = s->bit_left; + /* XXX: optimize */ #ifdef BITSTREAM_WRITER_LE bit_buf |= value << (32 - bit_left); @@ -200,6 +205,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) bit_buf = value; } #endif + s->bit_buf = bit_buf; s->bit_left = bit_left; } @@ -207,6 +213,7 @@ static inline void put_bits(PutBitContext *s, int n, unsigned int value) static inline void put_sbits(PutBitContext *pb, int n, int32_t value) { av_assert2(n >= 0 && n <= 31); + put_bits(pb, n, av_mod_uintp2(value, n)); } diff --git a/libeplayer3-arm/external/ffmpeg/src/bitstream.c b/libeplayer3-arm/external/ffmpeg/src/bitstream.c index 8c0f795..c992273 100644 --- a/libeplayer3-arm/external/ffmpeg/src/bitstream.c +++ b/libeplayer3-arm/external/ffmpeg/src/bitstream.c @@ -31,6 +31,7 @@ #include #include + void avpriv_align_put_bits(PutBitContext *s) { put_bits(s, s->bit_left & 7, 0); @@ -52,9 +53,12 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) int words = length >> 4; int bits = length & 15; int i; + if (length == 0) return; + av_assert0(length <= put_bits_left(pb)); + if (words < 16 || put_bits_count(pb) & 7) { for (i = 0; i < words; i++) @@ -68,5 +72,7 @@ void avpriv_copy_bits(PutBitContext *pb, const uint8_t *src, int length) memcpy(put_bits_ptr(pb), src + i, 2 * words - i); skip_put_bytes(pb, 2 * words - i); } + put_bits(pb, bits, AV_RB16(src + 2 * words) >> (16 - bits)); } + diff --git a/libeplayer3-arm/external/ffmpeg/src/latmenc.c b/libeplayer3-arm/external/ffmpeg/src/latmenc.c index 86a11f4..9c13c32 100644 --- a/libeplayer3-arm/external/ffmpeg/src/latmenc.c +++ b/libeplayer3-arm/external/ffmpeg/src/latmenc.c @@ -38,9 +38,11 @@ #define latmenc_err(fmt, x...) #endif + int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) { MPEG4AudioConfig m4ac; + if (size > MAX_EXTRADATA_SIZE) { latmenc_err("Extradata is larger than currently supported.\n"); @@ -49,6 +51,7 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) ctx->off = avpriv_mpeg4audio_get_config(&m4ac, buf, size * 8, 1); if (ctx->off < 0) return ctx->off; + if (ctx->object_type == AOT_ALS && (ctx->off & 7)) { // as long as avpriv_mpeg4audio_get_config works correctly this is impossible @@ -56,6 +59,7 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) return AVERROR_INVALIDDATA; } /* FIXME: are any formats not allowed in LATM? */ + if (m4ac.object_type > AOT_SBR && m4ac.object_type != AOT_ALS) { latmenc_err("Muxing MPEG-4 AOT %d in LATM is not supported\n", m4ac.object_type); @@ -63,14 +67,17 @@ int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) } ctx->channel_conf = m4ac.chan_config; ctx->object_type = m4ac.object_type; + return 0; } static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int extradata_size, PutBitContext *bs) { int header_size; + /* AudioMuxElement */ put_bits(bs, 1, !!ctx->counter); + if (!ctx->counter) { /* StreamMuxConfig */ @@ -79,6 +86,7 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int put_bits(bs, 6, 0); /* numSubFrames */ put_bits(bs, 4, 0); /* numProgram */ put_bits(bs, 3, 0); /* numLayer */ + /* AudioSpecificConfig */ if (ctx->object_type == AOT_ALS) { @@ -90,6 +98,7 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int // + 3 assumes not scalable and dependsOnCoreCoder == 0, // see decode_ga_specific_config in libavcodec/aacdec.c avpriv_copy_bits(bs, extradata, ctx->off + 3); + if (!ctx->channel_conf) { GetBitContext gb; @@ -99,11 +108,14 @@ static void latmenc_write_frame_header(LATMContext *ctx, uint8_t *extradata, int avpriv_copy_pce_data(bs, &gb); } } + put_bits(bs, 3, 0); /* frameLengthType */ put_bits(bs, 8, 0xff); /* latmBufferFullness */ + put_bits(bs, 1, 0); /* otherDataPresent */ put_bits(bs, 1, 0); /* crcCheckPresent */ } + ctx->counter++; ctx->counter %= ctx->mod; } @@ -112,15 +124,22 @@ int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *ext { PutBitContext bs; int i, len; + if (size > 0x1fff) goto too_large; + init_put_bits(&bs, ctx->buffer, size + 1024 + MAX_EXTRADATA_SIZE); + latmenc_write_frame_header(ctx, extradata, extradata_size, &bs); + /* PayloadLengthInfo() */ for (i = 0; i <= size - 255; i += 255) put_bits(&bs, 8, 255); + put_bits(&bs, 8, size - i); + /* The LATM payload is written unaligned */ + /* PayloadMux() */ if (size && (data[0] & 0xe1) == 0x81) { @@ -137,17 +156,23 @@ int latmenc_write_packet(LATMContext *ctx, uint8_t *data, int size, uint8_t *ext } else avpriv_copy_bits(&bs, data, 8 * size); + avpriv_align_put_bits(&bs); flush_put_bits(&bs); + len = put_bits_count(&bs) >> 3; + if (len > 0x1fff) goto too_large; + memcpy(ctx->loas_header, "\x56\xe0\x00", 3); ctx->loas_header[1] |= (len >> 8) & 0x1f; ctx->loas_header[2] |= len & 0xff; ctx->len = len; return 0; + too_large: latmenc_err("LATM packet size larger than maximum size 0x1fff\n"); return AVERROR_INVALIDDATA; } + diff --git a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c index f43a568..934dc18 100644 --- a/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c +++ b/libeplayer3-arm/external/ffmpeg/src/mpeg4audio.c @@ -34,16 +34,21 @@ static int parse_config_ALS(GetBitContext *gb, MPEG4AudioConfig *c) { if (get_bits_left(gb) < 112) return -1; + if (get_bits_long(gb, 32) != MKBETAG('A', 'L', 'S', '\0')) return -1; + // override AudioSpecificConfig channel configuration and sample rate // which are buggy in old ALS conformance files c->sample_rate = get_bits_long(gb, 32); + // skip number of samples skip_bits_long(gb, 32); + // read number of channels c->chan_config = 0; c->channels = get_bits(gb, 16) + 1; + return 0; } @@ -79,11 +84,14 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, { GetBitContext gb; int specific_config_bitindex, ret; + if (bit_size <= 0) return AVERROR_INVALIDDATA; + ret = init_get_bits(&gb, buf, bit_size); if (ret < 0) return ret; + c->object_type = get_object_type(&gb); c->sample_rate = get_sample_rate(&gb, &c->sampling_index); c->chan_config = get_bits(&gb, 4); @@ -110,15 +118,19 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, c->ext_sample_rate = 0; } specific_config_bitindex = get_bits_count(&gb); + if (c->object_type == AOT_ALS) { skip_bits(&gb, 5); if (show_bits_long(&gb, 24) != MKBETAG('\0', 'A', 'L', 'S')) skip_bits_long(&gb, 24); + specific_config_bitindex = get_bits_count(&gb); + if (parse_config_ALS(&gb, c)) return -1; } + if (c->ext_object_type != AOT_SBR && sync_extension) { while (get_bits_left(&gb) > 15) @@ -141,12 +153,14 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, get_bits1(&gb); // skip 1 bit } } + //PS requires SBR if (!c->sbr) c->ps = 0; //Limit implicit PS to the HE-AACv2 Profile if ((c->ps == -1 && c->object_type != AOT_AAC_LC) || c->channels & ~0x01) c->ps = 0; + return specific_config_bitindex; } @@ -163,6 +177,7 @@ int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb) { int five_bit_ch, four_bit_ch, comment_size, bits; int offset = put_bits_count(pb); + copy_bits(pb, gb, 10); //Tag, Object Type, Frequency five_bit_ch = copy_bits(pb, gb, 4); //Front five_bit_ch += copy_bits(pb, gb, 4); //Side @@ -185,5 +200,6 @@ int avpriv_copy_pce_data(PutBitContext *pb, GetBitContext *gb) comment_size = copy_bits(pb, gb, 8); for (; comment_size > 0; comment_size--) copy_bits(pb, gb, 8); + return put_bits_count(pb) - offset; } diff --git a/libeplayer3-arm/external/flv2mpeg4/src/bitreader.h b/libeplayer3-arm/external/flv2mpeg4/src/bitreader.h index 4b3d2c9..d375839 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/bitreader.h +++ b/libeplayer3-arm/external/flv2mpeg4/src/bitreader.h @@ -56,6 +56,7 @@ static uint32 get_u24(BR *p) uint32 a = get_u8(p); uint32 b = get_u8(p); uint32 c = get_u8(p); + return (a << 16) | (b << 8) | c; } @@ -65,6 +66,7 @@ static uint32 get_u32(BR *p) uint32 b = get_u8(p); uint32 c = get_u8(p); uint32 d = get_u8(p); + return (a << 24) | (b << 16) | (c << 8) | d; } @@ -82,10 +84,12 @@ static uint32 show_bits(BR *p, uint32 bits) { const uint8 *pp; uint32 tmp; + pp = p->buf + p->read; tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]); tmp <<= p->bitoffset; tmp >>= 32 - bits; + return tmp; } @@ -93,10 +97,12 @@ static int32 show_sbits(BR *p, uint32 bits) { const uint8 *pp; int32 tmp; + pp = p->buf + p->read; tmp = (pp[0] << 24) | (pp[1] << 16) | (pp[2] << 8) | (pp[3]); tmp <<= p->bitoffset; tmp >>= 32 - bits; + return tmp; } @@ -150,14 +156,17 @@ static int __inline get_vlc(BR *br, const VLCtab *table, int bits, int max_depth index = show_bits(br, bits); code = table[index].code; n = table[index].n; + if (max_depth > 1 && n < 0) { flash_bits(br, bits); nb_bits = -n; + index = show_bits(br, nb_bits) + code; code = table[index].code; n = table[index].n; } + flash_bits(br, n); return code; } diff --git a/libeplayer3-arm/external/flv2mpeg4/src/bitwriter.h b/libeplayer3-arm/external/flv2mpeg4/src/bitwriter.h index 3e76f36..ead9639 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/bitwriter.h +++ b/libeplayer3-arm/external/flv2mpeg4/src/bitwriter.h @@ -57,12 +57,14 @@ static void __inline init_bw(BW *p, uint8 *buf, uint32 size) static void __inline forword_bits(BW *p, uint32 bits) { p->bitoffset += bits; + if (p->bitoffset >= 32) { p->buf[p->pos++] = (p->tmp >> 24) & 0xff; p->buf[p->pos++] = (p->tmp >> 16) & 0xff; p->buf[p->pos++] = (p->tmp >> 8) & 0xff; p->buf[p->pos++] = (p->tmp >> 0) & 0xff; + p->tmp = 0; p->bitoffset -= 32; } @@ -71,6 +73,7 @@ static void __inline forword_bits(BW *p, uint32 bits) static void __inline put_bits(BW *p, uint32 bits, uint32 value) { uint32 shift = 32 - p->bitoffset - bits; + if (shift <= 32) { p->tmp |= value << shift; @@ -81,6 +84,7 @@ static void __inline put_bits(BW *p, uint32 bits, uint32 value) shift = bits - (32 - p->bitoffset); p->tmp |= value >> shift; forword_bits(p, bits - shift); + p->tmp |= value << (32 - shift); forword_bits(p, shift); } @@ -98,6 +102,7 @@ static void __inline pad_to_boundary(BW *p) static void __inline flash_bw(BW *p) { pad_to_boundary(p); + switch (p->bitoffset) { case 0: // nothing to do @@ -118,6 +123,7 @@ static void __inline flash_bw(BW *p) // fprintf(stderr, "flash_bw error!(%d)\n", p->bitoffset); break; } + p->tmp = 0; p->bitoffset = 0; } @@ -136,6 +142,7 @@ static void __inline put_vlcdec(BW *bw, VLCDEC *vlcdec) static void __inline m4v_stuffing(BW *p) { int length; + put_bits(p, 1, 0); length = (- p->bitoffset) & 7; if (length) put_bits(p, length, (1 << length) - 1); diff --git a/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.c b/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.c index 90e350f..dfe2261 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.c +++ b/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.c @@ -25,6 +25,7 @@ #include "dcprediction.h" + // M4V ADDED static const uint8 mpeg4_y_dc_scale_table[32] = { @@ -43,10 +44,12 @@ static int __inline get_pred(int *dc_cur, int stride, int scale) { /* B C A X */ + int A = dc_cur[-1]; int B = dc_cur[-1 - stride]; int C = dc_cur[-stride]; int pred; + if (abs(A - B) < abs(B - C)) { pred = C; @@ -55,6 +58,7 @@ static int __inline get_pred(int *dc_cur, int stride, int scale) { pred = A; } + return (pred + (scale >> 1)) / scale; } @@ -68,6 +72,7 @@ static void __inline set_dc_to_dc_cur(int *dc_cur, int level, int scale) else level = 2047; } + dc_cur[0] = level; } @@ -118,6 +123,7 @@ int dcpred_for_enc(M4V_DCPRED *p, int n, int level) int *dc_cur = p->dc_cur[n]; int scale = get_scale(p, n); int pred = get_pred(dc_cur, p->stride[n], scale); + set_dc_to_dc_cur(dc_cur, level, scale); return level - pred; } @@ -127,6 +133,7 @@ int dcpred_for_dec(M4V_DCPRED *p, int n, int level) int *dc_cur = p->dc_cur[n]; int scale = get_scale(p, n); int pred = get_pred(dc_cur, p->stride[n], scale); + level += pred; set_dc_to_dc_cur(dc_cur, level, scale); return level; @@ -137,6 +144,7 @@ static void init_plane(M4V_DCPRED *pred, int n) { int x, len = pred->stride[n] * pred->height[n]; int *p = pred->_dc[n]; + for (x = 0; x < len; x++) { p[x] = 1024; @@ -156,16 +164,20 @@ void alloc_dcpred(M4V_DCPRED *pred, int mb_width, int mb_height) const int h2 = mb_height * 2 + 1; const int w = mb_width + 1; const int h = mb_height + 1; + pred->_dc[0] = pred->_dc[1] = pred->_dc[2] = pred->_dc[3] = (int *)malloc(sizeof(int) * w2 * h2); pred->_dc[4] = (int *)malloc(sizeof(int) * w * h); pred->_dc[5] = (int *)malloc(sizeof(int) * w * h); + pred->dc[0] = pred->dc[1] = pred->dc[2] = pred->dc[3] = pred->_dc[0] + w2 + 1; pred->dc[4] = pred->_dc[4] + w + 1; pred->dc[5] = pred->_dc[5] + w + 1; + pred->stride[0] = pred->stride[1] = pred->stride[2] = pred->stride[3] = w2; pred->height[0] = pred->height[1] = pred->height[2] = pred->height[3] = h2; pred->stride[4] = pred->stride[5] = w; pred->height[4] = pred->height[5] = h; + pred->block_offset[0] = 0; pred->block_offset[1] = 1; pred->block_offset[2] = w2; diff --git a/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.h b/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.h index 456a685..936b741 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.h +++ b/libeplayer3-arm/external/flv2mpeg4/src/dcprediction.h @@ -40,6 +40,7 @@ typedef struct _M4V_DCPRED int y_dc_scale; int c_dc_scale; + } M4V_DCPRED; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libeplayer3-arm/external/flv2mpeg4/src/flv.h b/libeplayer3-arm/external/flv2mpeg4/src/flv.h index 22874b3..e2f08ce 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/flv.h +++ b/libeplayer3-arm/external/flv2mpeg4/src/flv.h @@ -65,6 +65,7 @@ typedef struct _PICTURE int width; int height; + #define FLV_I_TYPE 0 #define FLV_P_TYPE 1 @@ -156,4 +157,5 @@ static const int8 rl_inter_run[102] = static const int rl_inter_n = 102; static const int rl_inter_last = 58; + #endif // FLV_H diff --git a/libeplayer3-arm/external/flv2mpeg4/src/flv2mpeg4.c b/libeplayer3-arm/external/flv2mpeg4/src/flv2mpeg4.c index 3e22d98..36049dd 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/flv2mpeg4.c +++ b/libeplayer3-arm/external/flv2mpeg4/src/flv2mpeg4.c @@ -41,6 +41,7 @@ typedef struct _CONVCTX M4V_VOL vol; } CONVCTX; + typedef struct { uint8 *out_buf; @@ -64,6 +65,7 @@ static const uint8 ff_mpeg4_c_dc_scale_table[32] = 0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }; + static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol) { vol->width = flv_pic->width; @@ -74,9 +76,11 @@ static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol) static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c) { vop->qscale = flv_pic->qscale; + vop->time = c->frame % 30; vop->icount = (c->icounter + 29) / 30; vop->intra_dc_threshold = 99; + if (flv_pic->picture_type == FLV_I_TYPE) { vop->picture_type = M4V_I_TYPE; @@ -91,13 +95,16 @@ static void copy_vop(PICTURE *flv_pic, M4V_VOP *vop, CONVCTX *c) static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb) { int i; + m4v_mb->dquant = flv_mb->dquant; memcpy(m4v_mb->block, flv_mb->block, sizeof(m4v_mb->block)); // !!!!!!! m4v_mb->intra = flv_mb->intra; m4v_mb->skip = flv_mb->skip; m4v_mb->mv_type = flv_mb->mv_type; + memcpy(m4v_mb->mv_x, flv_mb->mv_x, sizeof(m4v_mb->mv_x)); // !!!!!! memcpy(m4v_mb->mv_y, flv_mb->mv_y, sizeof(m4v_mb->mv_y)); // !!!!!! + // dc rescale if (m4v_mb->intra) { @@ -106,6 +113,7 @@ static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb) m4v_mb->block[i].block[0] *= 8; m4v_mb->block[i].block[0] /= ff_mpeg4_y_dc_scale_table[m4v_mb->qscale]; } + for (i = 4; i < 6; i++) { m4v_mb->block[i].block[0] *= 8; @@ -126,7 +134,9 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw vop.icount = (c->icounter + 29) / 30; m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 1); m4v_stuffing(bw); + flash_bw(bw); + // write frame if (pub_ctx->write_packet_cb(pub_ctx->usr_data, 0, @@ -136,10 +146,13 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw { return -1; } + clear_bw(bw); + c->frame++; c->icounter++; } + return 0; } @@ -151,9 +164,12 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B int x, y; int mb_width = (flvpic->width + 15) / 16; int mb_height = (flvpic->height + 15) / 16; + memset(&vop, 0, sizeof(vop)); + copy_vop(flvpic, &vop, c); m4v_encode_vop_header(bw, &vop, VOL_TIME_BITS, 0); + // transcode flv to mpeg4 for (y = 0; y < mb_height; y++) { @@ -161,6 +177,7 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B { memset(&mb, 0, sizeof(mb)); memset(&m4v_mb, 0, sizeof(m4v_mb)); + if (vop.picture_type == M4V_I_TYPE) { mb.intra = 1; @@ -180,8 +197,10 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B } } } + m4v_stuffing(bw); flash_bw(bw); + // write frame if (pub_ctx->write_packet_cb(pub_ctx->usr_data, vop.picture_type == M4V_I_TYPE, @@ -191,19 +210,25 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B { return -1; } + c->frame++; c->icounter++; + return 0; } static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, uint32 time) { PICTURE picture; + memset(&picture, 0, sizeof(picture)); init_dcpred(&c->vol.dcpred); + if (decode_picture_header(br, &picture) < 0) return -1; if (c->width != picture.width || c->height != picture.height) return -1; //size changed.. + copy_vol(&picture, &c->vol); + if (picture.picture_type == FLV_I_TYPE) { c->icounter = 0; @@ -212,10 +237,12 @@ static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, u { if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) return -1; } + if (write_m4v_picture_frame(pub_ctx, c, br, bw, &picture, time) < 0) { return -1; } + return 0; } @@ -235,16 +262,23 @@ int flv2mpeg4_prepare_extra_data(flv2mpeg4_CTX *ctx) CTX *p = ctx->priv; BW bw; CONVCTX *c = &(p->conv); + M4V_VOP vop; memset(&vop, 0, sizeof(vop)); + init_bw(&bw, p->out_buf, PACKETBUFFER_SIZE); + c->vol.width = c->width; c->vol.height = c->height; c->vol.time_bits = VOL_TIME_BITS; // 0-31 + m4v_encode_m4v_header(&bw, &c->vol, 0); + m4v_stuffing(&bw); flash_bw(&bw); + alloc_dcpred(&c->vol.dcpred, (c->width + 15) / 16, (c->height + 15) / 16); + return ctx->write_extradata_cb(ctx->usr_data, c->width, c->height, 200 * 1000, bw.buf, bw.pos); } @@ -265,20 +299,26 @@ flv2mpeg4_CTX *flv2mpeg4_init_ctx(void *priv_data, int width, int height, flv2mp pub_ctx->priv = malloc(sizeof(CTX)); memset(pub_ctx->priv, 0x0, sizeof(CTX)); CTX *ctx = pub_ctx->priv; + ctx->conv.width = width; ctx->conv.height = height; ctx->out_buf = malloc(PACKETBUFFER_SIZE); memset(ctx->out_buf, 0x0, PACKETBUFFER_SIZE); memset(&(ctx->vol), 0x0, sizeof(ctx->vol)); + return pub_ctx; } void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx) { CTX *ctx = (*pub_ctx)->priv; + free_dcpred(&ctx->conv.vol.dcpred); free(ctx->out_buf); free(ctx); free(*pub_ctx); *pub_ctx = NULL; } + + + diff --git a/libeplayer3-arm/external/flv2mpeg4/src/flvdecoder.c b/libeplayer3-arm/external/flv2mpeg4/src/flvdecoder.c index edfba70..9d84a31 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/flvdecoder.c +++ b/libeplayer3-arm/external/flv2mpeg4/src/flvdecoder.c @@ -38,6 +38,7 @@ static const uint8 zig_zag_scan[64] = 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; + static const VLCtab vlc_table_intra_MCBPC[] = //: table_size=72 table_allocated=128 bits=6 { {64, -3}, @@ -127,6 +128,7 @@ static const VLCtab vlc_table_rl_inter[] = //: table_size=554 table_allocated=10 {100, 3}, {101, 3}, {8, 1}, {7, 1} }; + static const VLCtab vlc_table_mv[] = //mv_vlc: table_size=538 table_allocated=1024 bits=9 { {512, -3}, {520, -2}, {524, -1}, {526, -1}, {528, -1}, {530, -1}, {532, -1}, {534, -1}, {536, -1}, {10, 9}, @@ -181,6 +183,7 @@ static int __inline decode_DC(BR *p) return -1; } if (level == 255) level = 128; + // printf("DC: %d\n", level); return level; } @@ -188,6 +191,7 @@ static int __inline decode_DC(BR *p) static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i) { int code, run, level, last, sign; + while (1) { code = get_vlc(p, vlc_table_rl_inter, 9, 2); @@ -196,12 +200,14 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i) printf("invalid Huffman code in getblock()\n"); return -1; } + if (code == rl_inter_n) { //escape if (escape_type == 1) { int is11bit = get_bits(p, 1); + last = get_bits(p, 1); run = get_bits(p, 6); if (is11bit) @@ -227,9 +233,11 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i) run = rl_inter_run[code]; level = rl_inter_level[code]; last = code >= rl_inter_last; + sign = get_bits(p, 1); if (sign) level = -level; } + i += run; if (i >= 64) { @@ -240,6 +248,7 @@ static int __inline decode_AC(BR *p, BLOCK *block, int escape_type, int i) if (last) break; i++; } + block->last_index = i; return 0; } @@ -252,12 +261,15 @@ static int __inline decode_intra_block(BR *p, BLOCK *block, int escape_type, int printf("dc error.\n"); return -1; } + block->block[0] = level; block->last_index = 0; + if (!coded) { return 0; } + if (decode_AC(p, block, escape_type, 1) < 0) return -1; return 0; } @@ -265,10 +277,12 @@ static int __inline decode_intra_block(BR *p, BLOCK *block, int escape_type, int static int __inline decode_inter_block(BR *p, BLOCK *block, int escape_type, int coded) { block->last_index = -1; + if (!coded) { return 0; } + if (decode_AC(p, block, escape_type, 0) < 0) return -1; return 0; } @@ -298,6 +312,7 @@ static int __inline get_inter_MCBPC(BR *br) if (cbpc < 0) return -1; } while (cbpc == 20); + return cbpc; } @@ -316,11 +331,14 @@ static int __inline decode_motion(BR *br, VLCDEC *vlcdec) { int tmp; int code = get_vlcdec(br, vlc_table_mv, 9, 2, vlcdec); + vlcdec->bits_ex = 0; + if (code == 0) return 0; if (code < 0) return -1; + tmp = get_bits(br, 1); /* vlcdec->value |= (tmp << vlcdec->bits); @@ -331,6 +349,7 @@ static int __inline decode_motion(BR *br, VLCDEC *vlcdec) */ vlcdec->bits_ex = 1; vlcdec->value_ex = tmp; + return 0; } @@ -338,23 +357,28 @@ static int __inline decode_intra_mb_internal(BR *p, MICROBLOCK *mb, int escape_t { int cbpy, cbp; int i; + cbpy = get_cbpy(p); if (cbpy < 0) { printf("cbpy error\n"); return -1; } + cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { mb->dquant = decode_dquant(p); qscale += mb->dquant; } + for (i = 0; i < 6; i++) { if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; cbp += cbp; } + return 0; } @@ -362,19 +386,23 @@ static int __inline decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_t { int cbpy, cbp; int i; + cbpy = get_cbpy(p); if (cbpy < 0) { printf("cbpy error\n"); return -1; } + cbpy ^= 0xF; cbp = (cbpc & 3) | (cbpy << 2); + if (dquant) { mb->dquant = decode_dquant(p); qscale += mb->dquant; } + if ((cbpc & 16) == 0) { // 16x16 motion prediction @@ -392,11 +420,13 @@ static int __inline decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_t } mb->mv_type = MV_TYPE_8X8; } + for (i = 0; i < 6; i++) { if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; cbp += cbp; } + return 0; } @@ -410,18 +440,22 @@ int decode_I_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale) printf("intra_MCBPC error\n"); return -1; } + dquant = cbpc & 4; decode_intra_mb_internal(p, mb, escape_type, qscale, cbpc, dquant); + if (show_bits(p, 16) == 0) { // printf("slice end???\n"); } + return 0; } int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale) { int cbpc = get_inter_MCBPC(p); + if (cbpc == -1) { printf("inter_MCBPC error\n"); @@ -435,6 +469,7 @@ int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale) { int dquant = cbpc & 8; mb->skip = 0; + if ((cbpc & 4) != 0) { mb->intra = 1; @@ -446,31 +481,38 @@ int decode_P_mb(BR *p, MICROBLOCK *mb, int escape_type, int qscale) decode_inter_mb_internal(p, mb, escape_type, qscale, cbpc, dquant); } } + if (show_bits(p, 16) == 0) { // printf("slice end???\n"); } + return 0; } int decode_picture_header(BR *p, PICTURE *picture) { int tmp, width = 0, height = 0; + if (get_bits(p, 17) != 1) { fprintf(stderr, "start code error\n"); return -1; } + tmp = get_bits(p, 5); if (tmp != 0 && tmp != 1) { fprintf(stderr, "picture format error\n"); return -1; } + picture->escape_type = tmp; picture->frame_number = get_bits(p, 8); + // printf("picture_format: %d\n", tmp); // printf("picture_number: %d\n", get_bits(p, 8)); + tmp = get_bits(p, 3); switch (tmp) { @@ -501,21 +543,27 @@ int decode_picture_header(BR *p, PICTURE *picture) fprintf(stderr, "size error\n"); return -1; } + picture->width = width; picture->height = height; // printf("width: %d height: %d\n", width, height); + picture->picture_type = get_bits(p, 2); // printf("picture_type: %d\n", tmp); + tmp = get_bits(p, 1); // printf("deblocking flag: %d\n", tmp); + tmp = get_bits(p, 5); picture->qscale = tmp; // printf("qscale: %d\n", tmp); + // PEI while (get_bits(p, 1) != 0) { flash_bits(p, 8); } + // dump_marker(0, "dd header end"); return 0; } diff --git a/libeplayer3-arm/external/flv2mpeg4/src/m4v.h b/libeplayer3-arm/external/flv2mpeg4/src/m4v.h index eddb7dd..df5fd2e 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/m4v.h +++ b/libeplayer3-arm/external/flv2mpeg4/src/m4v.h @@ -134,4 +134,6 @@ static const uint8 alternate_vertical_scan[64] = 38, 46, 54, 62, 39, 47, 55, 63, }; + #endif // M4V_H + diff --git a/libeplayer3-arm/external/flv2mpeg4/src/m4vencode.c b/libeplayer3-arm/external/flv2mpeg4/src/m4vencode.c index 7860d83..139a91b 100644 --- a/libeplayer3-arm/external/flv2mpeg4/src/m4vencode.c +++ b/libeplayer3-arm/external/flv2mpeg4/src/m4vencode.c @@ -63,6 +63,7 @@ static const uint32 vlce_inter_MCBPC_bits[28] = static void __inline encode_DC(BW *p, int level, int n) { if (level < -255 || level > 255) printf("dc overflow\n"); + #if 1 level += 256; if (n < 4) @@ -74,6 +75,7 @@ static void __inline encode_DC(BW *p, int level, int n) put_bits(p, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); } #else + int size, v; /* find number of bits */ size = 0; @@ -83,6 +85,7 @@ static void __inline encode_DC(BW *p, int level, int n) v >>= 1; size++; } + if (n < 4) { /* luminance */ @@ -93,6 +96,7 @@ static void __inline encode_DC(BW *p, int level, int n) /* chrominance */ put_bits(p, DCtab_chrom[size][1], DCtab_chrom[size][0]); } + /* encode remaining bits */ if (size > 0) { @@ -102,7 +106,9 @@ static void __inline encode_DC(BW *p, int level, int n) if (size > 8) put_bits(p, 1, 1); } + #endif + } static void __inline encode_escape_3(BW *p, int last, int run, int level) @@ -129,10 +135,13 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) int i = intra; int last_index = block->last_index; int last_non_zero = i - 1; + const uint8 *scan_table = zig_zag_scan; // !!! + #if 1 const uint8 *len_tab; const uint32 *bits_tab; + if (intra) { len_tab = uni_mpeg4_intra_rl_len; @@ -143,6 +152,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) len_tab = uni_mpeg4_inter_rl_len; bits_tab = uni_mpeg4_inter_rl_bits; } + for (; i < last_index; i++) { int level = block->block[scan_table[i]]; @@ -159,9 +169,11 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) { encode_escape_3(p, 0, run, level); } + last_non_zero = i; } } + { int level = block->block[scan_table[i]]; int run = i - last_non_zero - 1; @@ -179,6 +191,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) #else const RL *rl; int last, sign, code; + if (intra) { rl = &rl_intra; @@ -187,6 +200,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) { rl = &rl_inter; } + for (; i <= last_index; i++) { const int slevel = block->block[scan_table[i]]; @@ -202,6 +216,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) sign = 1; level = -level; } + code = get_rl_index(rl, last, run, level); put_bits(p, rl->table_vlc[code][1], rl->table_vlc[code][0]); if (code == rl->n) @@ -210,6 +225,7 @@ static void __inline encode_AC(BW *p, M4V_BLOCK *block, int intra) level1 = level - rl->max_level[run][last]; if (level1 < 1) goto esc2; + code = get_rl_index(rl, last, run, level1); if (code == rl->n) { @@ -255,7 +271,10 @@ esc3: last_non_zero = i; } } + #endif + + } static void __inline encode_intra_block(BW *bw, M4V_BLOCK *block, int n) @@ -293,6 +312,7 @@ static void __inline encode_inter_8x8_MCBPC(BW *bw, int cbpc) put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 16], vlce_inter_MCBPC_code[cbpc + 16]); } + // same as H.263 static void __inline encode_cbpy(BW *bw, int cbpy) { @@ -320,6 +340,7 @@ static void __inline encode_motion(BW *bw, VLCDEC *mv_x, VLCDEC *mv_y) { put_bits(bw, mv_x->bits_ex - 1, mv_x->value_ex >> 1); } + } put_vlcdec(bw, mv_y); if (mv_y->bits_ex) @@ -337,6 +358,7 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb) { int cbp = 0, cbpc, cbpy; int i; + for (i = 0; i < 6; i++) { if (mb->block[i].last_index >= 0) @@ -344,10 +366,13 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb) cbp |= 1 << (5 - i); } } + cbpc = cbp & 3; cbpy = cbp >> 2; cbpy ^= 0xF; + if (mb->dquant) cbpc += 8; + switch (mb->mv_type) { case MV_TYPE_16X16: @@ -366,6 +391,7 @@ static void __inline encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb) } break; } + for (i = 0; i < 6; i++) { encode_inter_block(bw, &mb->block[i]); @@ -376,6 +402,7 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if { int cbp = 0, cbpc, cbpy; int i; + for (i = 0; i < 6; i++) { if (mb->block[i].last_index >= 1) @@ -383,6 +410,7 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if cbp |= 1 << (5 - i); } } + cbpc = cbp & 3; if (iframe) { @@ -394,10 +422,15 @@ static void __inline encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int if if (mb->dquant) cbpc += 8; encode_intra_P_MCBPC(bw, cbpc); } + put_bits(bw, 1, 0); // AC Prediction = no + cbpy = cbp >> 2; + encode_cbpy(bw, cbpy); encode_dquant(bw, mb->dquant); + + for (i = 0; i < 6; i++) { encode_intra_block(bw, &mb->block[i], i); @@ -409,15 +442,20 @@ static int __inline encode_vo_header(BW *p) { put_bits(p, 16, 0); put_bits(p, 16, VOS_STARTCODE); + put_bits(p, 8, 1); // *** profile_and_level_indidation + put_bits(p, 16, 0); put_bits(p, 16, VISUAL_OBJECT_STARTCODE); + put_bits(p, 1, 1); put_bits(p, 4, 1); // vo_vel_id put_bits(p, 3, 1); // priority put_bits(p, 4, 1); // visual_object_type = video object put_bits(p, 1, 0); // video signal type = no clue + m4v_stuffing(p); + return 0; } @@ -425,19 +463,28 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol) { const int vo_number = 0; const int vol_number = 0; + put_bits(p, 16, 0); put_bits(p, 16, 0x100 + vo_number); + put_bits(p, 16, 0); put_bits(p, 16, 0x120 + vol_number); + put_bits(p, 1, 0); // random_accessible_vol put_bits(p, 8, 1); // video_object_type_indication = Simple Object Type + put_bits(p, 1, 0); //is_object_layer_identifier + put_bits(p, 4, 1); // *** aspect_ratio_info = 1(1:1) + put_bits(p, 1, 0); //vol_control_parameters + put_bits(p, 2, 0); // shape_type put_bits(p, 1, 1); // marker + if (vol->time_bits != 5) return -1; // for vop_time_increment_resolution = 30 put_bits(p, 16, 30); // *** vop_time_increment_resolution = 30 + put_bits(p, 1, 1); // marker put_bits(p, 1, 0); // fixed vop rate = no put_bits(p, 1, 1); // marker @@ -450,10 +497,12 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol) put_bits(p, 1, 0); // sprite = disable put_bits(p, 1, 0); // not8bit = false put_bits(p, 1, 0); // quant type = H.263 + put_bits(p, 1, 1); // complexity estimaition disable = true put_bits(p, 1, 1); // resync marker disable = true put_bits(p, 1, 0); // data pertitioning = false put_bits(p, 1, 0); // scalability = false + m4v_stuffing(p); return 0; } @@ -461,14 +510,21 @@ static int __inline encode_vol_header(BW *p, M4V_VOL *vol) static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vop_not_coded) { // static int time_old = 0; + int time_incr = vop->icount; if (vop->time != 0) time_incr = 0; + put_bits(p, 16, 0); put_bits(p, 16, VOP_STARTCODE); + put_bits(p, 2, vop->picture_type); + + // printf("not_code:%d vop_time: %d\n", vop_not_coded, vop->time); + // printf("pic:%d icount:%d vop_time: %d\n", vop->picture_type, time_incr, vop->time); + /* if (time_old > vop->time) { put_bits(p, 1, 1); @@ -476,54 +532,70 @@ static int __inline encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vo time_old = vop->time; */ + // !!!!! while (time_incr--) put_bits(p, 1, 1); put_bits(p, 1, 0); + put_bits(p, 1, 1); // marker put_bits(p, time_bits, vop->time); // time_increment put_bits(p, 1, 1); // marker + if (vop_not_coded) { put_bits(p, 1, 0); // vop coded return 0; } + put_bits(p, 1, 1); // vop coded + if (vop->picture_type == M4V_P_TYPE) { put_bits(p, 1, vop->rounding_type); // rounding type } + put_bits(p, 3, 0); // intra dc VLC threashold + put_bits(p, 5, vop->qscale); // qscale + if (vop->picture_type != M4V_I_TYPE) { put_bits(p, 3, vop->f_code); } + if (vop->picture_type == M4V_B_TYPE) { put_bits(p, 3, vop->b_code); } + return 0; } static __inline int encode_gop_header(BW *bw, uint32 time_ms) { int sec, min, hour; + sec = time_ms / 1000; min = sec / 60; sec %= 60; hour = min / 60; min %= 60; hour %= 24; + put_bits(bw, 16, 0); put_bits(bw, 16, GOP_STARTCODE); + put_bits(bw, 5, hour); put_bits(bw, 6, min); put_bits(bw, 1, 1); put_bits(bw, 6, sec); + put_bits(bw, 1, 0); // closed_gop == NO put_bits(bw, 1, 0); // broken link == NO + printf("GOP %02d:%02d:%02d\n", hour, min, sec); + m4v_stuffing(bw); return 0; } @@ -532,6 +604,7 @@ static int __inline encode_user_header(BW *p) { put_bits(p, 16, 0); put_bits(p, 16, USERDATA_STARTCODE); + put_bits(p, 8, 'v'); put_bits(p, 8, 'i'); put_bits(p, 8, 'x'); @@ -540,6 +613,7 @@ static int __inline encode_user_header(BW *p) put_bits(p, 8, 'n'); put_bits(p, 8, 'e'); put_bits(p, 8, 't'); + m4v_stuffing(p); return 0; } @@ -575,6 +649,7 @@ void m4v_encode_P_mb(BW *bw, M4V_MICROBLOCK *mb) { put_bits(bw, 1, 0); // coded } + if (mb->intra) { encode_mb_intra_internal(bw, mb, 0); @@ -592,6 +667,7 @@ int m4v_encode_I_dcpred(M4V_MICROBLOCK *mb, M4V_DCPRED *dcpred, int mb_x, int mb { dcpred_set_qscale(dcpred, mb->qscale); dcpred_set_pos(dcpred, mb_x, mb_y); + for (n = 0; n < 6; n ++) { int level = dcpred_for_enc(dcpred, n, mb->block[n].block[0]); diff --git a/libeplayer3-arm/include/aac.h b/libeplayer3-arm/include/aac.h index 4455043..33f32fd 100644 --- a/libeplayer3-arm/include/aac.h +++ b/libeplayer3-arm/include/aac.h @@ -29,6 +29,7 @@ static inline int HasADTSHeader(uint8_t *data, int size) { return 1; } + return 0; } diff --git a/libeplayer3-arm/include/bcm_ioctls.h b/libeplayer3-arm/include/bcm_ioctls.h index ef118e5..d52f298 100644 --- a/libeplayer3-arm/include/bcm_ioctls.h +++ b/libeplayer3-arm/include/bcm_ioctls.h @@ -35,6 +35,7 @@ typedef enum CT_VP9 } video_codec_type_t; + typedef enum { STREAMTYPE_UNKNOWN = -1, @@ -56,6 +57,8 @@ typedef enum STREAMTYPE_SPARK = 21, } video_stream_type_t; + + typedef enum { AUDIOTYPE_UNKNOWN = -1, @@ -75,4 +78,8 @@ typedef enum AUDIOTYPE_RAW = 0xf } audio_stream_type_t; + + + #endif /* H_DVB_BCM_H */ + diff --git a/libeplayer3-arm/include/debug.h b/libeplayer3-arm/include/debug.h index 9149895..1740868 100644 --- a/libeplayer3-arm/include/debug.h +++ b/libeplayer3-arm/include/debug.h @@ -6,6 +6,7 @@ static inline void Hexdump(unsigned char *Data, int length) { + int k; for (k = 0; k < length; k++) { @@ -14,6 +15,7 @@ static inline void Hexdump(unsigned char *Data, int length) printf("\n"); } printf("\n"); + } #endif diff --git a/libeplayer3-arm/include/manager.h b/libeplayer3-arm/include/manager.h index 81515bc..baed788 100644 --- a/libeplayer3-arm/include/manager.h +++ b/libeplayer3-arm/include/manager.h @@ -94,6 +94,7 @@ typedef struct TrackDescription_s int32_t aspect_ratio_num; int32_t aspect_ratio_den; int progressive; + } TrackDescription_t; struct Context_s; @@ -104,6 +105,7 @@ typedef struct Manager_s char *Name; int (* Command)(Context_t *, ManagerCmd_t, void *); char **Capabilities; + } Manager_t; typedef struct ManagerHandler_s diff --git a/libeplayer3-arm/include/misc.h b/libeplayer3-arm/include/misc.h index 4934180..f1114b4 100644 --- a/libeplayer3-arm/include/misc.h +++ b/libeplayer3-arm/include/misc.h @@ -56,14 +56,17 @@ static inline char *basename(char *name) { int i = 0; int pos = 0; + while (name[i] != 0) { if (name[i] == '/') pos = i; i++; } + if (name[pos] == '/') pos++; + return name + pos; } @@ -73,6 +76,7 @@ static inline char *dirname(char *name) static char path[100]; uint32_t i = 0; int32_t pos = 0; + while ((name[i] != 0) && (i < sizeof(path))) { if (name[i] == '/') @@ -82,8 +86,10 @@ static inline char *dirname(char *name) path[i] = name[i]; i++; } + path[i] = 0; path[pos] = 0; + return path; } diff --git a/libeplayer3-arm/include/output.h b/libeplayer3-arm/include/output.h index 16a61f1..533e60a 100644 --- a/libeplayer3-arm/include/output.h +++ b/libeplayer3-arm/include/output.h @@ -74,6 +74,7 @@ typedef struct Output_s int32_t (* Command)(Context_t *, OutputCmd_t, void *); int32_t (* Write)(Context_t *, void *); char **Capabilities; + } Output_t; extern Output_t LinuxDvbOutput; diff --git a/libeplayer3-arm/include/pes.h b/libeplayer3-arm/include/pes.h index 2026d4f..1b2d019 100644 --- a/libeplayer3-arm/include/pes.h +++ b/libeplayer3-arm/include/pes.h @@ -12,8 +12,10 @@ #define PES_START_CODE_RESERVED_4 0xfd #define PES_VERSION_FAKE_START_CODE 0x31 + #define MAX_PES_PACKET_SIZE (65535) + /* start codes */ #define PCM_PES_START_CODE 0xbd #define PRIVATE_STREAM_1_PES_START_CODE 0xbd diff --git a/libeplayer3-arm/include/stm_ioctls.h b/libeplayer3-arm/include/stm_ioctls.h index bdcd8dc..fcb19ee 100644 --- a/libeplayer3-arm/include/stm_ioctls.h +++ b/libeplayer3-arm/include/stm_ioctls.h @@ -92,6 +92,7 @@ typedef enum VIDEO_ENCODING_PRIVATE } video_encoding_t; + /* * List of possible audio encodings - used to select frame parser and codec. */ @@ -198,6 +199,7 @@ typedef struct dvb_play_info_s typedef dvb_play_info_t video_play_info_t; typedef dvb_play_info_t audio_play_info_t; + typedef enum { #define DVB_OPTION_VALUE_DISABLE 0 @@ -283,6 +285,7 @@ typedef enum // Legacy typo correction #define DVP_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING DVB_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING + typedef dvb_option_t video_option_t; /* Decoder commands */ @@ -293,6 +296,7 @@ typedef dvb_option_t video_option_t; #define VIDEO_CMD_SET_OPTION (4) #define VIDEO_CMD_GET_OPTION (5) + /* Flags for VIDEO_CMD_FREEZE */ #define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0) diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index 5f09166..b72636a 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -26,6 +26,8 @@ typedef struct ssize_t (* WriteV) (int, const struct iovec *, size_t); } WriterAVCallData_t; + + typedef struct WriterCaps_s { char *name; @@ -88,6 +90,6 @@ Writer_t *getDefaultVideoWriter(); Writer_t *getDefaultAudioWriter(); ssize_t write_with_retry(int fd, const void *buf, size_t size); ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic); -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size); +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, size_t size); #endif diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 54526c8..a6e0aea 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -101,34 +101,42 @@ static void *TermThreadFun(void *arg __attribute__((unused))) int cl = -1; int nfds = 1; fd_set readfds; + unlink(socket_path); if ((fd = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) { perror("TermThreadFun socket error"); goto finish; } + memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) == -1) { perror("TermThreadFun bind error"); goto finish; } + if (listen(fd, 1) == -1) { perror("TermThreadFun listen error"); goto finish; } + FD_ZERO(&readfds); FD_SET(g_pfd[0], &readfds); FD_SET(fd, &readfds); + nfds = fd > g_pfd[0] ? fd + 1 : g_pfd[0] + 1; + while (select(nfds, &readfds, NULL, NULL, NULL) == -1 && errno == EINTR) { /* Restart if interrupted by signal */ continue; } + if (FD_ISSET(fd, &readfds)) { pthread_mutex_lock(&playbackStartMtx); @@ -139,10 +147,12 @@ static void *TermThreadFun(void *arg __attribute__((unused))) kill(getpid(), SIGINT); pthread_mutex_unlock(&playbackStartMtx); } + finish: close(cl); close(fd); pthread_exit(NULL); + } static void map_inter_file_path(char *filename) @@ -170,19 +180,24 @@ static int kbhit(void) { struct timeval tv; fd_set readfds; + tv.tv_sec = 1; tv.tv_usec = 0; + FD_ZERO(&readfds); - FD_SET(0,&readfds); + FD_SET(0, &readfds); FD_SET(g_pfd[0], &readfds); - if(-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv)) + + if (-1 == select(g_pfd[0] + 1, &readfds, NULL, NULL, &tv)) { return 0; } + if (FD_ISSET(0, &readfds)) { return 1; } + return 0; } @@ -194,6 +209,7 @@ static void SetBuffering() { printf("SetBuffering: failed to change the buffer of stderr\n"); } + // make fgets not blocking int flags = fcntl(stdin->_fileno, F_GETFL, 0); fcntl(stdin->_fileno, F_SETFL, flags | O_NONBLOCK); @@ -203,6 +219,7 @@ static void SetNice(int prio) { #if 0 setpriority(PRIO_PROCESS, 0, -8); + int prio = sched_get_priority_max(SCHED_RR) / 2; struct sched_param param = { @@ -221,10 +238,12 @@ static void SetNice(int prio) static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff) { int commandRetVal = 0; + if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2)) { return -1; } + switch (argvBuff[1]) { case 'l': @@ -340,6 +359,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac { ok = sscanf(argvBuff + 1, "%d", &id); } + if (id >= 0 || (1 == ok && id == -1)) { commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); @@ -349,8 +369,10 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac break; } } + return commandRetVal; } + #if 0 static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff) { @@ -391,6 +413,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac } case 'c': { + TrackDescription_t *track = NULL; ptrManager->Command(g_player, MANAGER_GET_TRACK_DESC, &track); if (NULL != track) @@ -461,6 +484,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac { ok = sscanf(argvBuff + 1, "%d", &id); } + if (id >= 0 || (1 == ok && id == -1)) { commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); @@ -470,6 +494,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac break; } } + return commandRetVal; } #endif @@ -486,7 +511,7 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int //int digit_optind = 0; //int aopt = 0, bopt = 0; //char *copt = 0, *dopt = 0; - while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1) + while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1) { switch (c) { @@ -604,9 +629,11 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int ret = -1; } } + if (0 == ret && optind < argc) { ret = 0; + if (NULL == strstr(argv[optind], "://")) { strcpy(file, "file://"); @@ -629,16 +656,21 @@ int main(int argc, char *argv[]) int isTermThreadStarted = 0; char file[IPTV_MAX_FILE_PATH]; memset(file, '\0', sizeof(file)); + char audioFile[IPTV_MAX_FILE_PATH]; memset(audioFile, '\0', sizeof(audioFile)); + int audioTrackIdx = -1; int subtitleTrackIdx = -1; - uint32_t linuxDvbBufferSizeMB = 0; + + uint32_t linuxDvbBufferSizeMB = 0; + char argvBuff[256]; memset(argvBuff, '\0', sizeof(argvBuff)); int commandRetVal = -1; /* inform client that we can handle additional commands */ fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 45); + if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) { printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n"); @@ -671,59 +703,76 @@ int main(int argc, char *argv[]) printf("[-f ffopt=ffval] any other ffmpeg option\n"); exit(1); } + g_player = malloc(sizeof(Context_t)); if (NULL == g_player) { printf("g_player allocate error\n"); exit(1); } + pthread_mutex_init(&playbackStartMtx, NULL); do { int flags = 0; + if (pipe(g_pfd) == -1) break; + /* Make read and write ends of pipe nonblocking */ if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1) break; + /* Make read end nonblocking */ flags |= O_NONBLOCK; if (fcntl(g_pfd[0], F_SETFL, flags) == -1) break; + if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1) break; + /* Make write end nonblocking */ flags |= O_NONBLOCK; if (fcntl(g_pfd[1], F_SETFL, flags) == -1) break; + if (0 == pthread_create(&termThread, NULL, TermThreadFun, NULL)) isTermThreadStarted = 1; } while (0); + g_player->playback = &PlaybackHandler; g_player->output = &OutputHandler; g_player->container = &ContainerHandler; g_player->manager = &ManagerHandler; + // make sure to kill myself when parent dies prctl(PR_SET_PDEATHSIG, SIGKILL); + SetBuffering(); + //Registrating output devices g_player->output->Command(g_player, OUTPUT_ADD, "audio"); g_player->output->Command(g_player, OUTPUT_ADD, "video"); g_player->output->Command(g_player, OUTPUT_ADD, "subtitle"); - //Set LINUX DVB additional write buffer size + + //Set LINUX DVB additional write buffer size if (linuxDvbBufferSizeMB) g_player->output->Command(g_player, OUTPUT_SET_BUFFER_SIZE, &linuxDvbBufferSizeMB); + + g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack); if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4)) { g_player->playback->noprobe = 1; } + PlayFiles_t playbackFiles = {file, NULL}; if ('\0' != audioFile[0]) { playbackFiles.szSecondFile = audioFile; } + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles); fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal); if (commandRetVal < 0) @@ -734,17 +783,21 @@ int main(int argc, char *argv[]) } return 10; } + { pthread_mutex_lock(&playbackStartMtx); isPlaybackStarted = 1; pthread_mutex_unlock(&playbackStartMtx); + commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL); fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL); fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal); + if (g_player->playback->isPlaying) { PlaybackDieNowRegisterCallback(TerminateWakeUp); + HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al"); if (audioTrackIdx >= 0) @@ -754,6 +807,7 @@ int main(int argc, char *argv[]) commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd); } HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "ac"); + HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sl"); if (subtitleTrackIdx >= 0) { @@ -763,6 +817,7 @@ int main(int argc, char *argv[]) } HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc"); } + while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0)) { /* we made fgets non blocking */ @@ -772,10 +827,12 @@ int main(int argc, char *argv[]) kbhit(); continue; } + if (0 == argvBuff[0]) { continue; } + switch (argvBuff[0]) { case 'v': @@ -815,6 +872,7 @@ int main(int argc, char *argv[]) { int speed = 0; sscanf(argvBuff + 1, "%d", &speed); + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed); fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; @@ -833,6 +891,7 @@ int main(int argc, char *argv[]) { int speed = 0; sscanf(argvBuff + 1, "%d", &speed); + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed); fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; @@ -841,6 +900,7 @@ int main(int argc, char *argv[]) { int speed = 0; sscanf(argvBuff + 1, "%d", &speed); + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed); fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; @@ -852,11 +912,13 @@ int main(int argc, char *argv[]) int32_t lengthInt = 0; int64_t sec = 0; int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check + sscanf(argvBuff + 2, "%d", &gotoPos); if (0 <= gotoPos || force) { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); + lengthInt = (int32_t)length; if (10 <= lengthInt || force) { @@ -865,6 +927,7 @@ int main(int argc, char *argv[]) { sec = lengthInt - 10; } + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void *)&sec); fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal); } @@ -880,7 +943,9 @@ int main(int argc, char *argv[]) int64_t pts = 0; int32_t CurrentSec = 0; int8_t force = ('f' == argvBuff[1]) ? 1 : 0; // f - force, c - check + sscanf(argvBuff + 2, "%d", &seek); + commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); CurrentSec = (int32_t)(pts / 90000); if (0 == commandRetVal) @@ -891,6 +956,7 @@ int main(int argc, char *argv[]) { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); + lengthInt = (int32_t)length; if (10 <= lengthInt || force) { @@ -959,6 +1025,7 @@ int main(int argc, char *argv[]) fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \ DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested)); } + break; } case 'n': @@ -975,24 +1042,31 @@ int main(int argc, char *argv[]) } break; } + default: { break; } } } + g_player->output->Command(g_player, OUTPUT_CLOSE, NULL); } + if (NULL != g_player) { free(g_player); } + if (isTermThreadStarted && 1 == write(g_pfd[1], "x", 1)) { pthread_join(termThread, NULL); } + pthread_mutex_destroy(&playbackStartMtx); + close(g_pfd[0]); close(g_pfd[1]); + exit(0); } diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index 6e5abde..6543f51 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -84,6 +84,7 @@ static int CurrentTrack = 0; //TRACK[0] as default. static int ManagerAdd(Context_t *context, Track_t track) { audio_mgr_printf(10, "%s::%s name=\"%s\" encoding=\"%s\" id=%d\n", __FILE__, __FUNCTION__, track.Name, track.Encoding, track.Id); + if (Tracks == NULL) { Tracks = malloc(sizeof(Track_t) * TRACKWRAP); @@ -93,11 +94,13 @@ static int ManagerAdd(Context_t *context, Track_t track) Tracks[i].Id = -1; } } + if (Tracks == NULL) { audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); return cERR_AUDIO_MGR_ERROR; } + int i = 0; for (i = 0; i < TRACKWRAP; i++) { @@ -107,6 +110,7 @@ static int ManagerAdd(Context_t *context, Track_t track) return cERR_AUDIO_MGR_NO_ERROR; } } + if (TrackCount < TRACKWRAP) { copyTrack(&Tracks[TrackCount], &track); @@ -117,10 +121,12 @@ static int ManagerAdd(Context_t *context, Track_t track) audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); return cERR_AUDIO_MGR_ERROR; } + if (TrackCount > 0) { context->playback->isAudio = 1; } + audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); return cERR_AUDIO_MGR_NO_ERROR; } @@ -129,28 +135,36 @@ static char **ManagerList(Context_t *context __attribute__((unused))) { int i = 0, j = 0; char **tracklist = NULL; + audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); if (Tracks != NULL) { tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1)); + if (tracklist == NULL) { audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } + for (i = 0, j = 0; i < TrackCount; i++, j += 2) { if (Tracks[i].pending) + { continue; + } + size_t len = strlen(Tracks[i].Name) + 20; char tmp[len]; snprintf(tmp, len, "%d %s", Tracks[i].Id, Tracks[i].Name); tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(Tracks[i].Encoding); } + tracklist[j] = NULL; } audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); + return tracklist; } @@ -159,15 +173,18 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused { int i = 0; TrackDescription_t *tracklist = NULL; + audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); if (Tracks != NULL) { tracklist = malloc(sizeof(TrackDescription_t) * ((TrackCount) + 1)); + if (tracklist == NULL) { audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } + int j = 0; for (i = 0; i < TrackCount; ++i) { @@ -175,14 +192,17 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused { continue; } + tracklist[j].Id = Tracks[i].Id; tracklist[j].Name = strdup(Tracks[i].Name); tracklist[j].Encoding = strdup(Tracks[i].Encoding); ++j; } + tracklist[j].Id = -1; } //audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); + return tracklist; } #endif @@ -190,13 +210,16 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused static int ManagerDel(Context_t *context) { int i = 0; + audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (Tracks != NULL) { for (i = 0; i < TrackCount; i++) { freeTrack(&Tracks[i]); } + free(Tracks); Tracks = NULL; } @@ -205,17 +228,22 @@ static int ManagerDel(Context_t *context) audio_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); return cERR_AUDIO_MGR_ERROR; } + TrackCount = 0; CurrentTrack = 0; context->playback->isAudio = 0; + audio_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__); + return cERR_AUDIO_MGR_NO_ERROR; } static int Command(Context_t *context, ManagerCmd_t command, void *argument) { int ret = cERR_AUDIO_MGR_NO_ERROR; + audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + switch (command) { case MANAGER_ADD: @@ -244,6 +272,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_GET: { audio_mgr_printf(20, "%s::%s MANAGER_GET\n", __FILE__, __FUNCTION__); + if ((TrackCount > 0) && (CurrentTrack >= 0)) { *((int *)argument) = (int)Tracks[CurrentTrack].Id; @@ -277,9 +306,10 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_GET_TRACK: { audio_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); + if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; } else { @@ -315,6 +345,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) { int i; audio_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument)); + for (i = 0; i < TrackCount; i++) { if (Tracks[i].Id == *((int *)argument)) @@ -323,6 +354,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } } + if (i == TrackCount) { audio_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument)); @@ -349,10 +381,13 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) ret = cERR_AUDIO_MGR_ERROR; break; } + audio_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); + return ret; } + struct Manager_s AudioManager = { "Audio", diff --git a/libeplayer3-arm/manager/chapter.c b/libeplayer3-arm/manager/chapter.c index 14167a9..4a6fc11 100644 --- a/libeplayer3-arm/manager/chapter.c +++ b/libeplayer3-arm/manager/chapter.c @@ -181,8 +181,7 @@ static int ManagerDel(Context_t *context __attribute__((unused))) TrackCount = 0; CurrentTrack = 0; - chapter_mgr_printf(10, "%s::%s return no error\n", FILENAME, - __FUNCTION__); + chapter_mgr_printf(10, "%s::%s return no error\n", FILENAME, __FUNCTION__); return cERR_CHAPTER_MGR_NO_ERROR; } diff --git a/libeplayer3-arm/manager/manager.c b/libeplayer3-arm/manager/manager.c index 7ad53e8..c2b5c23 100644 --- a/libeplayer3-arm/manager/manager.c +++ b/libeplayer3-arm/manager/manager.c @@ -72,6 +72,7 @@ void copyTrack(Track_t *to, Track_t *from) { to->Name = strdup("Unknown"); } + if (from->Encoding != NULL) { to->Encoding = strdup(from->Encoding); @@ -80,6 +81,7 @@ void copyTrack(Track_t *to, Track_t *from) { to->Encoding = strdup("Unknown"); } + if (from->language != NULL) { to->language = strdup(from->language); @@ -100,16 +102,19 @@ void freeTrack(Track_t *track) free(track->Name); track->Name = NULL; } + if (track->Encoding != NULL) { free(track->Encoding); track->Encoding = NULL; } + if (track->language != NULL) { free(track->language); track->language = NULL; } + if (track->aacbuf != NULL) { free(track->aacbuf); diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index 4cff07c..144cb5c 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -33,12 +33,14 @@ #define TRACKWRAP 20 +//#define SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG #define SUBTITLE_MGR_DEBUG #else #define SUBTITLE_MGR_SILENT #endif + #ifdef SUBTITLE_MGR_DEBUG static short debug_level = 20; @@ -256,7 +258,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) { if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; } else { diff --git a/libeplayer3-arm/manager/video.c b/libeplayer3-arm/manager/video.c index adaa841..8a94d4a 100644 --- a/libeplayer3-arm/manager/video.c +++ b/libeplayer3-arm/manager/video.c @@ -84,6 +84,7 @@ static void (* updatedTrackInfoFnc)(void) = NULL; static int ManagerAdd(Context_t *context, Track_t track) { video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (Tracks == NULL) { Tracks = malloc(sizeof(Track_t) * TRACKWRAP); @@ -93,11 +94,13 @@ static int ManagerAdd(Context_t *context, Track_t track) Tracks[i].Id = -1; } } + if (Tracks == NULL) { video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); return cERR_VIDEO_MGR_ERROR; } + int i; for (i = 0; i < TRACKWRAP; i++) { @@ -107,6 +110,7 @@ static int ManagerAdd(Context_t *context, Track_t track) return cERR_VIDEO_MGR_NO_ERROR; } } + if (TrackCount < TRACKWRAP) { copyTrack(&Tracks[TrackCount], &track); @@ -117,10 +121,12 @@ static int ManagerAdd(Context_t *context, Track_t track) video_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); return cERR_VIDEO_MGR_ERROR; } + if (TrackCount > 0) { context->playback->isVideo = 1; } + video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); return cERR_VIDEO_MGR_NO_ERROR; } @@ -129,15 +135,19 @@ static char **ManagerList(Context_t *context __attribute__((unused))) { int i = 0, j = 0; char **tracklist = NULL; + video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (Tracks != NULL) { tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1)); + if (tracklist == NULL) { video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } + for (i = 0, j = 0; i < TrackCount; i++, j += 2) { if (Tracks[i].pending) @@ -152,6 +162,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) } tracklist[j] = NULL; } + video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); return tracklist; } @@ -159,7 +170,9 @@ static char **ManagerList(Context_t *context __attribute__((unused))) static int ManagerDel(Context_t *context) { int i = 0; + video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (Tracks != NULL) { for (i = 0; i < TrackCount; i++) @@ -174,9 +187,11 @@ static int ManagerDel(Context_t *context) video_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); return cERR_VIDEO_MGR_ERROR; } + TrackCount = 0; CurrentTrack = 0; context->playback->isVideo = 0; + video_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__); return cERR_VIDEO_MGR_NO_ERROR; } @@ -184,7 +199,9 @@ static int ManagerDel(Context_t *context) static int Command(Context_t *context, ManagerCmd_t command, void *argument) { int ret = cERR_VIDEO_MGR_NO_ERROR; + video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + switch (command) { case MANAGER_ADD: @@ -240,9 +257,10 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_GET_TRACK: { video_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", __FILE__, __FUNCTION__); + if ((TrackCount > 0) && (CurrentTrack >= 0)) { - *((Track_t **)argument) = (Track_t *) & Tracks[CurrentTrack]; + *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; } else { @@ -285,6 +303,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } } + if (i == TrackCount) { video_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument)); @@ -322,10 +341,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) ret = cERR_VIDEO_MGR_ERROR; break; } + video_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); return ret; } + struct Manager_s VideoManager = { "Video", diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index 343296d..2fc472f 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -41,13 +41,15 @@ /* ***************************** */ /* Types */ /* ***************************** */ -typedef enum OutputType_e{ +typedef enum OutputType_e +{ OUTPUT_UNK, OUTPUT_AUDIO, OUTPUT_VIDEO, } OutputType_t; -typedef struct BufferingNode_s { +typedef struct BufferingNode_s +{ uint32_t dataSize; OutputType_t dataType; struct BufferingNode_s *next; @@ -56,8 +58,8 @@ typedef struct BufferingNode_s { /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0 -#define cERR_LINUX_DVB_BUFFERING_ERROR -1 +#define cERR_LINUX_DVB_BUFFERING_NO_ERROR 0 +#define cERR_LINUX_DVB_BUFFERING_ERROR -1 //#define SAM_WITH_DEBUG #ifdef SAM_WITH_DEBUG @@ -83,8 +85,9 @@ if (debug_level >= level) printf("[%s:%d:%s] " fmt, __FILE__, __LINE__, __FUNCTI #endif /* ***************************** */ -/* Varaibles */ +/* Variables */ /* ***************************** */ + static pthread_t bufferingThread; static pthread_mutex_t bufferingMtx; static pthread_cond_t bufferingExitCond; @@ -108,46 +111,54 @@ static int g_pfd[2] = {-1, -1}; /* ***************************** */ /* MISC Functions */ /* ***************************** */ + static void WriteWakeUp() { write(g_pfd[1], "x", 1); } -/* **************************** */ -/* Worker Thread */ -/* **************************** */ -static void LinuxDvbBuffThread(Context_t *context) +/* ***************************** */ +/* Worker Thread */ +/* ***************************** */ + +static void LinuxDvbBuffThread(Context_t *context) { int flags = 0; static BufferingNode_t *nodePtr = NULL; buff_printf(20, "ENTER\n"); - + if (pipe(g_pfd) == -1) { buff_err("critical error\n"); } + /* Make read and write ends of pipe nonblocking */ if ((flags = fcntl(g_pfd[0], F_GETFL)) == -1) { buff_err("critical error\n"); } + /* Make read end nonblocking */ flags |= O_NONBLOCK; if (fcntl(g_pfd[0], F_SETFL, flags) == -1) { buff_err("critical error\n"); } + if ((flags = fcntl(g_pfd[1], F_GETFL)) == -1) { buff_err("critical error\n"); } + /* Make write end nonblocking */ flags |= O_NONBLOCK; if (fcntl(g_pfd[1], F_SETFL, flags) == -1) { buff_err("critical error\n"); } + PlaybackDieNowRegisterCallback(WriteWakeUp); + while (0 == PlaybackDieNow(0)) { pthread_mutex_lock(&bufferingMtx); @@ -158,11 +169,11 @@ static void LinuxDvbBuffThread(Context_t *context) /* signal that we free some space in queue */ pthread_cond_signal(&bufferingDataConsumedCond); } - + if (!bufferingQueueHead) { assert(bufferingQueueTail == NULL); - + /* Queue is empty we need to wait for data to be added */ pthread_cond_wait(&bufferingdDataAddedCond, &bufferingMtx); pthread_mutex_unlock(&bufferingMtx); @@ -176,7 +187,7 @@ static void LinuxDvbBuffThread(Context_t *context) { bufferingQueueTail = NULL; } - + if (bufferingDataSize >= (nodePtr->dataSize + sizeof(BufferingNode_t))) { bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); @@ -188,12 +199,12 @@ static void LinuxDvbBuffThread(Context_t *context) } } pthread_mutex_unlock(&bufferingMtx); - + /* We will write data without mutex - * this have some disadvantage because we can - * write some portion of data after LinuxDvbBuffFlush, - * for example after seek, this will be fixed later - */ + * this have some disadvantage because we can + * write some portion of data after LinuxDvbBuffFlush, + * for example after seek, this will be fixed later + */ if (nodePtr && !context->playback->isSeeking) { /* Write data to valid output */ @@ -205,11 +216,11 @@ static void LinuxDvbBuffThread(Context_t *context) } } } - + pthread_mutex_lock(&bufferingMtx); pthread_cond_signal(&bufferingExitCond); pthread_mutex_unlock(&bufferingMtx); - + buff_printf(20, "EXIT\n"); hasBufferingThreadStarted = false; close(g_pfd[0]); @@ -228,36 +239,36 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) { int32_t error = 0; int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR; - + buff_printf(10, "\n"); - if (!hasBufferingThreadStarted) + if (!hasBufferingThreadStarted) { pthread_attr_t attr; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) + if ((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) { buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error)); hasBufferingThreadStarted = false; ret = cERR_LINUX_DVB_BUFFERING_ERROR; } - else + else { buff_printf(10, "Created thread\n"); hasBufferingThreadStarted = true; /* init synchronization prymitives */ pthread_mutex_init(&bufferingMtx, NULL); - + pthread_cond_init(&bufferingExitCond, NULL); pthread_cond_init(&bufferingDataConsumedCond, NULL); pthread_cond_init(&bufferingdDataAddedCond, NULL); } } - + if (!ret) { if (!strcmp("video", type) && -1 == videofd) @@ -281,21 +292,22 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) { int32_t ret = 0; - + buff_printf(10, "\n"); videofd = -1; audiofd = -1; - - if (hasBufferingThreadStarted) + + if (hasBufferingThreadStarted) { struct timespec max_wait = {0, 0}; - - /* WakeUp if we are waiting in the write */ + + /* WakeUp if we are waiting in the write */ WriteWakeUp(); - + pthread_mutex_lock(&bufferingMtx); - /* wake up if thread is waiting for data */ + /* wake up if thread is waiting for data */ pthread_cond_signal(&bufferingdDataAddedCond); + /* wait for thread end */ clock_gettime(CLOCK_REALTIME, &max_wait); max_wait.tv_sec += 1; @@ -305,9 +317,9 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) if (!hasBufferingThreadStarted) { /* destroy synchronization prymitives? - * for a moment, we'll exit linux process, - * so the system will do this for us - */ + * for a moment, we'll exit linux process, + * so the system will do this for us + */ /* pthread_mutex_destroy(&bufferingMtx); pthread_cond_destroy(&bufferingDataConsumedCond); @@ -315,7 +327,7 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) */ } } - + ret = hasBufferingThreadStarted ? cERR_LINUX_DVB_BUFFERING_ERROR : cERR_LINUX_DVB_BUFFERING_NO_ERROR; buff_printf(10, "exiting with value %d\n", ret); @@ -326,46 +338,50 @@ int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused))) { static BufferingNode_t *nodePtr = NULL; buff_printf(40, "ENTER bufferingQueueHead[%p]\n", bufferingQueueHead); - + /* signal if we are waiting for write to DVB decoders */ WriteWakeUp(); pthread_mutex_lock(&bufferingMtx); while (bufferingQueueHead) { - nodePtr = bufferingQueueHead; - bufferingQueueHead = nodePtr->next; - bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); - free(nodePtr); + nodePtr = bufferingQueueHead; + bufferingQueueHead = nodePtr->next; + bufferingDataSize -= (nodePtr->dataSize + sizeof(BufferingNode_t)); + free(nodePtr); } bufferingQueueHead = NULL; bufferingQueueTail = NULL; buff_printf(40, "bufferingDataSize [%u]\n", bufferingDataSize); assert(bufferingDataSize == 0); bufferingDataSize = 0; - + /* signal that queue is empty */ pthread_cond_signal(&bufferingDataConsumedCond); pthread_mutex_unlock(&bufferingMtx); buff_printf(40, "EXIT\n"); + return 0; } int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused))) { - /* signal if we are waiting for write to DVB decoders */ + /* signal if we are waiting for write to DVB decoders + * + */ WriteWakeUp(); + return 0; } -ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) +ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) { OutputType_t dataType = OUTPUT_UNK; BufferingNode_t *nodePtr = NULL; uint8_t *dataPtr = NULL; uint32_t chunkSize = 0; uint32_t i = 0; - + buff_printf(60, "ENTER\n"); if (fd == videofd) { @@ -382,13 +398,13 @@ ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic) buff_err("Unknown output type\n"); return cERR_LINUX_DVB_BUFFERING_ERROR; } - - for (i=0; inext = nodePtr; bufferingQueueTail = nodePtr; } - + bufferingDataSize += chunkSize; chunkSize -= sizeof(BufferingNode_t); nodePtr->dataSize = chunkSize; nodePtr->dataType = dataType; nodePtr->next = NULL; - + /* signal that we added some data to queue */ pthread_cond_signal(&bufferingdDataAddedCond); break; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 4335399..f4acac6 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -50,9 +50,7 @@ /* Makros/Constants */ /* ***************************** */ -// SULGE DEBUG //#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define LINUXDVB_DEBUG static unsigned short debug_level = 20; @@ -64,15 +62,15 @@ static const char FILENAME[] = __FILE__; #ifdef LINUXDVB_DEBUG #define linuxdvb_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); } while (0) +if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) #else -#define linuxdvb_printf(level, fmt, x...) +#define linuxdvb_printf(x...) #endif #ifndef LINUXDVB_SILENT #define linuxdvb_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) #else -#define linuxdvb_err(fmt, x...) +#define linuxdvb_err(x...) #endif #define cERR_LINUXDVB_NO_ERROR 0 @@ -108,10 +106,11 @@ int32_t LinuxDvbBuffResume(Context_t *context); ssize_t BufferingWriteV(int fd, const struct iovec *iov, size_t ic); int32_t WriteSetBufferingSize(const uint32_t bufferSize); + int LinuxDvbStop(Context_t *context, char *type); /* ***************************** */ -/* Functions */ +/* MISC Functions */ /* ***************************** */ void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) @@ -137,53 +136,67 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) { uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd < 0) { videofd = open(VIDEODEV, O_RDWR | O_CLOEXEC); + if (videofd < 0) { linuxdvb_err("failed to open %s - errno %d, %s\n", VIDEODEV, errno, strerror(errno)); + linuxdvb_err("%s\n",); return cERR_LINUXDVB_ERROR; } + if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1) { linuxdvb_err("VIDEO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(videofd, VIDEO_FREEZE) == -1) { linuxdvb_err("VIDEO_FREEZE: ERROR %d, %s\n", errno, strerror(errno)); } + if (isBufferedOutput) LinuxDvbBuffOpen(context, type, videofd); } if (audio && audiofd < 0) { audiofd = open(AUDIODEV, O_RDWR | O_CLOEXEC); + if (audiofd < 0) { linuxdvb_err("failed to open %s - errno %d, %s\n", AUDIODEV, errno, strerror(errno)); return cERR_LINUXDVB_ERROR; } + if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY) == -1) { linuxdvb_err("AUDIO_SELECT_SOURCE: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(audiofd, AUDIO_PAUSE) == -1) { linuxdvb_err("AUDIO_PAUSE: ERROR %d, %s\n", errno, strerror(errno)); } + if (isBufferedOutput) LinuxDvbBuffOpen(context, type, audiofd); } + return cERR_LINUXDVB_NO_ERROR; } @@ -191,15 +204,20 @@ int LinuxDvbClose(Context_t *context, char *type) { uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + /* closing stand alone is not allowed, so prevent * user from closing and don't call stop. stop will * set default values for us (speed and so on). */ LinuxDvbStop(context, type); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (isBufferedOutput) LinuxDvbBuffClose(context); + if (video && videofd != -1) { close(videofd); @@ -210,6 +228,7 @@ int LinuxDvbClose(Context_t *context, char *type) close(audiofd); audiofd = -1; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); return cERR_LINUXDVB_NO_ERROR; } @@ -218,14 +237,19 @@ int LinuxDvbPlay(Context_t *context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; Writer_t *writer; + uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd != -1) { char *Encoding = NULL; context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(10, "V %s\n", Encoding); + writer = getWriter(Encoding); if (writer == NULL) { @@ -242,15 +266,18 @@ int LinuxDvbPlay(Context_t *context, char *type) } } free(Encoding); + if (0 != ioctl(videofd, VIDEO_PLAY)) { linuxdvb_err("VIDEO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + if (ioctl(videofd, VIDEO_CONTINUE) == -1) { linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); @@ -260,8 +287,11 @@ int LinuxDvbPlay(Context_t *context, char *type) { char *Encoding = NULL; context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "0 A %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -276,11 +306,13 @@ int LinuxDvbPlay(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } } + if (ioctl(audiofd, AUDIO_PLAY) < 0) { linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + if (ioctl(audiofd, AUDIO_CONTINUE) < 0) { linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); @@ -288,6 +320,7 @@ int LinuxDvbPlay(Context_t *context, char *type) } free(Encoding); } + ret = cERR_LINUXDVB_NO_ERROR; return ret; //return 0; @@ -298,19 +331,24 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(videofd, VIDEO_STOP) == -1) { linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + ioctl(videofd, VIDEO_SLOWMOTION, 0); ioctl(videofd, VIDEO_FAST_FORWARD, 0); ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX); @@ -321,6 +359,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) { linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(audiofd, AUDIO_STOP) == -1) { linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); @@ -328,7 +367,9 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) } ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX); } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + return ret; } @@ -337,8 +378,11 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) @@ -347,6 +391,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + if (audio && audiofd != -1) { if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1) @@ -355,7 +400,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + return ret; } @@ -364,19 +411,23 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd != -1) { if (context->playback->isForwarding == 0) { ioctl(videofd, VIDEO_FAST_FORWARD, 0); } + if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) { linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } + if (audio && audiofd != -1) { if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1) @@ -385,16 +436,21 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + if (isBufferedOutput) LinuxDvbBuffResume(context); + linuxdvb_printf(10, "exiting\n"); + return ret; } int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) { int ret = cERR_LINUXDVB_NO_ERROR; + linuxdvb_printf(10, "\n"); + if (audiofd != -1) { if (*flag == '1') @@ -414,7 +470,9 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) } } } + linuxdvb_printf(10, "exiting\n"); + return ret; } @@ -428,8 +486,11 @@ int LinuxDvbFastForward(Context_t *context, char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + if (audio) {} + linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); + if (video && videofd != -1) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -441,6 +502,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting with value %d\n", ret); return ret; } @@ -448,12 +510,16 @@ int LinuxDvbFastForward(Context_t *context, char *type) int LinuxDvbSlowMotion(Context_t *context, char *type) { int32_t ret = cERR_LINUXDVB_NO_ERROR; + uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1) @@ -462,9 +528,12 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -480,13 +549,16 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr if (audiofd != -1) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1) { linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + return ret; } @@ -495,10 +567,13 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, "LinuxDvbClear v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) @@ -515,16 +590,21 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting\n"); + return ret; } int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) { int32_t ret = cERR_LINUXDVB_ERROR; + linuxdvb_printf(50, "\n"); + // GET_PTS is immutable call, so it can be done in parallel to other requests if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) { @@ -534,6 +614,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i { linuxdvb_err("VIDEO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); } + if (ret != cERR_LINUXDVB_NO_ERROR) { if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS)) @@ -545,10 +626,12 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i linuxdvb_err("AUDIO_GET_PTS: ERROR %d, %s\n", errno, strerror(errno)); } } + if (ret != cERR_LINUXDVB_NO_ERROR) { sCURRENT_PTS = 0; } + *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; return ret; } @@ -563,26 +646,34 @@ int LinuxDvbSwitch(Context_t *context, char *type) uint8_t audio = !strcmp("audio", type); uint8_t video = !strcmp("video", type); Writer_t *writer; + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (audio && audiofd != -1) { char *Encoding = NULL; if (context && context->manager && context->manager->audio) { context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(10, "A %s\n", Encoding); + writer = getWriter(Encoding); + if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { linuxdvb_err("AUDIO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -595,6 +686,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); } } + if (ioctl(audiofd, AUDIO_PLAY) == -1) { linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); @@ -606,22 +698,28 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_printf(20, "no context for Audio\n"); } } + if (video && videofd != -1) { char *Encoding = NULL; if (context && context->manager && context->manager->video) { context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + if (ioctl(videofd, VIDEO_STOP, NULL) == -1) { linuxdvb_err("VIDEO_STOP: ERROR %d, %s\n", errno, strerror(errno)); } + if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("VIDEO_CLEAR_BUFFER: ERROR %d, %s\n", errno, strerror(errno)); } + linuxdvb_printf(10, "V %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -634,6 +732,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); } } + if (ioctl(videofd, VIDEO_PLAY) == -1) { /* konfetti: fixme: think on this, I think we should @@ -648,42 +747,54 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_printf(20, "no context for Video\n"); } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + } + linuxdvb_printf(10, "exiting\n"); + return cERR_LINUXDVB_NO_ERROR; } static int Write(Context_t *context, void *_out) { AudioVideoOut_t *out = (AudioVideoOut_t *) _out; - int32_t ret = cERR_LINUXDVB_NO_ERROR; - int32_t res = 0; - uint8_t video = 0; - uint8_t audio = 0; - Writer_t *writer = NULL; + int32_t ret = cERR_LINUXDVB_NO_ERROR; + int32_t res = 0; + uint8_t video = 0; + uint8_t audio = 0; + Writer_t *writer = NULL; WriterAVCallData_t call; + if (out == NULL) { linuxdvb_err("null pointer passed\n"); return cERR_LINUXDVB_ERROR; } + video = !strcmp("video", out->type); audio = !strcmp("audio", out->type); + linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); + if (video) { char *Encoding = NULL; context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "Encoding = %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); writer = getDefaultVideoWriter(); } + if (writer == NULL) { linuxdvb_err("unknown video codec and no default writer %s\n", Encoding); @@ -734,6 +845,7 @@ static int Write(Context_t *context, void *_out) } } } + call.fd = videofd; call.data = out->data; call.len = out->len; @@ -747,11 +859,13 @@ static int Write(Context_t *context, void *_out) call.Height = out->height; call.InfoFlags = out->infoFlags; call.Version = 0; - call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; + call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; + if (writer->writeData) { res = writer->writeData(&call); } + if (res < 0) { linuxdvb_err("failed to write data %d - %d\n", res, errno); @@ -759,19 +873,24 @@ static int Write(Context_t *context, void *_out) ret = cERR_LINUXDVB_ERROR; } } + free(Encoding); } else if (audio) { char *Encoding = NULL; context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); writer = getDefaultAudioWriter(); } + if (writer == NULL) { linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding); @@ -790,11 +909,13 @@ static int Write(Context_t *context, void *_out) call.FrameScale = out->timeScale; call.InfoFlags = out->infoFlags; call.Version = 0; - call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; + call.WriteV = isBufferedOutput ? BufferingWriteV : writev_with_retry; + if (writer->writeData) { res = writer->writeData(&call); } + if (res < 0) { linuxdvb_err("failed to write data %d - %d\n", res, errno); @@ -802,8 +923,10 @@ static int Write(Context_t *context, void *_out) ret = cERR_LINUXDVB_ERROR; } } + free(Encoding); } + return ret; } @@ -812,8 +935,11 @@ static int reset(Context_t *context) int ret = cERR_LINUXDVB_NO_ERROR; Writer_t *writer; char *Encoding = NULL; + context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("unknown video codec %s\n", Encoding); @@ -823,9 +949,13 @@ static int reset(Context_t *context) { writer->reset(); } + free(Encoding); + context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("unknown video codec %s\n", Encoding); @@ -835,16 +965,21 @@ static int reset(Context_t *context) { writer->reset(); } + free(Encoding); + if (isBufferedOutput) LinuxDvbBuffFlush(context); + return ret; } static int Command(Context_t *context, OutputCmd_t command, void *argument) { int ret = cERR_LINUXDVB_NO_ERROR; + linuxdvb_printf(50, "Command %d\n", command); + switch (command) { case OUTPUT_OPEN: @@ -946,7 +1081,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) ret = cERR_LINUXDVB_ERROR; if (!isBufferedOutput) { - uint32_t bufferSize = *((uint32_t*)argument); + uint32_t bufferSize = *((uint32_t *)argument); ret = cERR_LINUXDVB_NO_ERROR; if (bufferSize > 0) { @@ -961,7 +1096,9 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) ret = cERR_LINUXDVB_ERROR; break; } + linuxdvb_printf(50, "exiting with value %d\n", ret); + return ret; } diff --git a/libeplayer3-arm/output/linuxdvb_sh4.c b/libeplayer3-arm/output/linuxdvb_sh4.c index efbc39c..1eb6d23 100644 --- a/libeplayer3-arm/output/linuxdvb_sh4.c +++ b/libeplayer3-arm/output/linuxdvb_sh4.c @@ -70,6 +70,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define linuxdvb_err(x...) #endif + #define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_ERROR -1 @@ -99,84 +100,103 @@ pthread_mutex_t LinuxDVBmutex; int LinuxDvbStop(Context_t *context, char *type); /* ***************************** */ -/* Functions */ +/* MISC Functions */ /* ***************************** */ void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { + linuxdvb_printf(250, "requesting mutex\n"); + pthread_mutex_lock(&LinuxDVBmutex); + linuxdvb_printf(250, "received mutex\n"); } void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) { pthread_mutex_unlock(&LinuxDVBmutex); + linuxdvb_printf(250, "released mutex\n"); + } int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) { unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd < 0) { videofd = open(VIDEODEV, O_RDWR); + if (videofd < 0) { linuxdvb_err("failed to open %s - errno %d\n", VIDEODEV, errno); linuxdvb_err("%s\n", strerror(errno)); return cERR_LINUXDVB_ERROR; } + if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); } + if (ioctl(videofd, VIDEO_SELECT_SOURCE, (void *)VIDEO_SOURCE_MEMORY) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno)); } + if (ioctl(videofd, VIDEO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); } + if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); } + } if (audio && audiofd < 0) { audiofd = open(AUDIODEV, O_RDWR); + if (audiofd < 0) { linuxdvb_err("failed to open %s - errno %d\n", AUDIODEV, errno); linuxdvb_err("%s\n", strerror(errno)); + if (videofd < 0) close(videofd); return cERR_LINUXDVB_ERROR; } + if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); } + if (ioctl(audiofd, AUDIO_SELECT_SOURCE, (void *)AUDIO_SOURCE_MEMORY) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno)); } + if (ioctl(audiofd, AUDIO_SET_STREAMTYPE, (void *)STREAM_TYPE_PROGRAM) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno)); } } + return cERR_LINUXDVB_NO_ERROR; } @@ -184,13 +204,17 @@ int LinuxDvbClose(Context_t *context, char *type) { unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + /* closing stand alone is not allowed, so prevent * user from closing and dont call stop. stop will * set default values for us (speed and so on). */ LinuxDvbStop(context, type); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { close(videofd); @@ -201,6 +225,7 @@ int LinuxDvbClose(Context_t *context, char *type) close(audiofd); audiofd = -1; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); return cERR_LINUXDVB_NO_ERROR; } @@ -209,15 +234,21 @@ int LinuxDvbPlay(Context_t *context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; Writer_t *writer; + unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd != -1) { char *Encoding = NULL; context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(10, "V %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -238,6 +269,7 @@ int LinuxDvbPlay(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } } + if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); @@ -250,8 +282,11 @@ int LinuxDvbPlay(Context_t *context, char *type) { char *Encoding = NULL; context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "0 A %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -272,6 +307,7 @@ int LinuxDvbPlay(Context_t *context, char *type) ret = -1; } } + if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); @@ -280,6 +316,7 @@ int LinuxDvbPlay(Context_t *context, char *type) } free(Encoding); } + return ret; } @@ -288,8 +325,11 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) @@ -297,6 +337,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); } + /* set back to normal speed (end trickmodes) */ if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { @@ -317,6 +358,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); } + /* set back to normal speed (end trickmodes) */ if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { @@ -330,7 +372,9 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + return ret; } @@ -339,8 +383,11 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) @@ -359,7 +406,9 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + return ret; } @@ -368,7 +417,9 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) int ret = cERR_LINUXDVB_NO_ERROR; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) @@ -387,7 +438,10 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + linuxdvb_printf(10, "exiting\n"); + + return ret; } @@ -395,20 +449,26 @@ int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int { int ret = cERR_LINUXDVB_NO_ERROR; int dis_type = VIDEO_DISCONTINUITY_CONTINUOUS_REVERSE | *surplus; + linuxdvb_printf(50, "\n"); + if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); } + linuxdvb_printf(50, "exiting\n"); + return ret; } int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) { int ret = cERR_LINUXDVB_NO_ERROR; + linuxdvb_printf(10, "\n"); + if (audiofd != -1) { if (*flag == '1') @@ -436,18 +496,24 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) } } } + linuxdvb_printf(10, "exiting\n"); + return ret; } + int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) { unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) @@ -456,6 +522,7 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); } } + if (audio && audiofd != -1) { if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) @@ -464,9 +531,12 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting\n"); + return cERR_LINUXDVB_NO_ERROR; } @@ -474,22 +544,31 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) int LinuxDvbFastForward(Context_t *context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; + unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d speed %d\n", video, audio, context->playback->Speed); + if (video && videofd != -1) { + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + /* konfetti comment: speed is a value given in skipped frames */ + if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting with value %d\n", ret); + return ret; } #else @@ -508,38 +587,54 @@ int LinuxDvbFastForward(Context_t *context, char *type) int speedIndex; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if (video && videofd != -1) { + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); + linuxdvb_printf(1, "speedIndex %d\n", speedIndex); + if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + if (audio && audiofd != -1) { + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); + linuxdvb_printf(1, "speedIndex %d\n", speedIndex); + if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting with value %d\n", ret); + return ret; } #endif + int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; @@ -549,12 +644,16 @@ int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __att int LinuxDvbSlowMotion(Context_t *context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; + unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion) == -1) @@ -564,9 +663,12 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -582,14 +684,17 @@ int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused))) if (audiofd != -1) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (ioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + return ret; } @@ -598,10 +703,13 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) int32_t ret = cERR_LINUXDVB_NO_ERROR; uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); + linuxdvb_printf(10, ">>>>>>>>>>LinuxDvbClear v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (video && videofd != -1) { if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) @@ -620,18 +728,24 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } + linuxdvb_printf(10, "exiting\n"); + return ret; } int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) { int ret = cERR_LINUXDVB_ERROR; + linuxdvb_printf(50, "\n"); + // pts is a non writting requests and can be done in parallel to other requests //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); + if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) { ret = cERR_LINUXDVB_NO_ERROR; @@ -640,6 +754,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i { linuxdvb_err("VIDEO_GET_PTS: %d (%s)\n", errno, strerror(errno)); } + if (ret != cERR_LINUXDVB_NO_ERROR) { if (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *)&sCURRENT_PTS)) @@ -651,12 +766,16 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i linuxdvb_err("AUDIO_GET_PTS: %d (%s)\n", errno, strerror(errno)); } } + if (ret != cERR_LINUXDVB_NO_ERROR) { sCURRENT_PTS = 0; } + *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; + //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); + return ret; } @@ -664,8 +783,11 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l { int ret = cERR_LINUXDVB_NO_ERROR; dvb_play_info_t playInfo; + linuxdvb_printf(50, "\n"); + getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (videofd != -1) { if (ioctl(videofd, VIDEO_GET_PLAY_INFO, (void *)&playInfo) == -1) @@ -690,9 +812,12 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l { ret = cERR_LINUXDVB_ERROR; } + if (ret == cERR_LINUXDVB_NO_ERROR) *((unsigned long long int *)frameCount) = playInfo.frame_count; + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + return ret; } @@ -701,28 +826,38 @@ int LinuxDvbSwitch(Context_t *context, char *type) unsigned char audio = !strcmp("audio", type); unsigned char video = !strcmp("video", type); Writer_t *writer; + linuxdvb_printf(10, "v%d a%d\n", video, audio); + if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + if (audio && audiofd != -1) { char *Encoding = NULL; if (context && context->manager && context->manager->audio) { context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(10, "A %s\n", Encoding); + writer = getWriter(Encoding); + if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + } + if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + } + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -741,6 +876,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); } } + if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); @@ -753,24 +889,30 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_printf(20, "no context for Audio\n"); } } + if (video && videofd != -1) { char *Encoding = NULL; if (context && context->manager && context->manager->video) { context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + if (ioctl(videofd, VIDEO_STOP, NULL) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); } + if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); } + linuxdvb_printf(10, "V %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("cannot found writer for encoding %s using default\n", Encoding); @@ -789,6 +931,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); } } + if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) { /* konfetti: fixme: think on this, I think we should @@ -804,9 +947,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) linuxdvb_printf(20, "no context for Video\n"); } } + releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + } + linuxdvb_printf(10, "exiting\n"); + return cERR_LINUXDVB_NO_ERROR; } @@ -820,27 +967,35 @@ static int Write(void *_context, void *_out) unsigned char audio = 0; Writer_t *writer; WriterAVCallData_t call; + if (out == NULL) { linuxdvb_err("null pointer passed\n"); return cERR_LINUXDVB_ERROR; } + video = !strcmp("video", out->type); audio = !strcmp("audio", out->type); + linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); + if (video) { char *Encoding = NULL; context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "Encoding = %s\n", Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); writer = getDefaultVideoWriter(); } + if (writer == NULL) { linuxdvb_err("unknown video codec and no default writer %s\n", Encoding); @@ -891,6 +1046,7 @@ static int Write(void *_context, void *_out) } } } + call.fd = videofd; call.data = out->data; call.len = out->len; @@ -904,10 +1060,12 @@ static int Write(void *_context, void *_out) call.Height = out->height; call.InfoFlags = out->infoFlags; call.Version = 0; // is unsingned char + if (writer->writeData) { res = writer->writeData(&call); } + if (res < 0) { linuxdvb_err("failed to write data %d - %d\n", res, errno); @@ -915,19 +1073,24 @@ static int Write(void *_context, void *_out) ret = cERR_LINUXDVB_ERROR; } } + free(Encoding); } else if (audio) { char *Encoding = NULL; context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_printf(20, "searching default writer ... %s\n", Encoding); writer = getDefaultAudioWriter(); } + if (writer == NULL) { linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding); @@ -946,10 +1109,12 @@ static int Write(void *_context, void *_out) call.FrameScale = out->timeScale; call.InfoFlags = out->infoFlags; call.Version = 0; /* -1; unsigned char cannot be negative */ + if (writer->writeData) { res = writer->writeData(&call); } + if (res < 0) { linuxdvb_err("failed to write data %d - %d\n", res, errno); @@ -957,8 +1122,10 @@ static int Write(void *_context, void *_out) ret = cERR_LINUXDVB_ERROR; } } + free(Encoding); } + return ret; } @@ -967,8 +1134,11 @@ static int reset(Context_t *context) int ret = cERR_LINUXDVB_NO_ERROR; Writer_t *writer; char *Encoding = NULL; + context->manager->video->Command(context, MANAGER_GETENCODING, &Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("unknown video codec %s\n", Encoding); @@ -978,9 +1148,13 @@ static int reset(Context_t *context) { writer->reset(); } + free(Encoding); + context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); + writer = getWriter(Encoding); + if (writer == NULL) { linuxdvb_err("unknown video codec %s\n", Encoding); @@ -990,7 +1164,9 @@ static int reset(Context_t *context) { writer->reset(); } + free(Encoding); + return ret; } @@ -998,7 +1174,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) { Context_t *context = (Context_t *) _context; int ret = cERR_LINUXDVB_NO_ERROR; + linuxdvb_printf(50, "Command %d\n", command); + switch (command) { case OUTPUT_OPEN: @@ -1110,7 +1288,9 @@ static int Command(void *_context, OutputCmd_t command, void *argument) ret = cERR_LINUXDVB_ERROR; break; } + linuxdvb_printf(50, "exiting with value %d\n", ret); + return ret; } diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 8c1580f..d63f30c 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -77,14 +77,16 @@ static Output_t *AvailableOutput[] = /* ***************************** */ /* ***************************** */ -/* Functions */ +/* MISC Functions */ /* ***************************** */ static void printOutputCapabilities() { int i, j; + output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); output_printf(10, "Capabilities:\n"); + for (i = 0; AvailableOutput[i] != NULL; i++) { output_printf(10, "\t%s : ", AvailableOutput[i]->Name); @@ -103,7 +105,9 @@ static void printOutputCapabilities() static void OutputAdd(Context_t *context, char *port) { int i, j; + output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + for (i = 0; AvailableOutput[i] != NULL; i++) { for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++) @@ -133,6 +137,7 @@ static void OutputAdd(Context_t *context, char *port) static void OutputDel(Context_t *context, char *port) { output_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (!strcmp("audio", port)) { context->output->audio = NULL; @@ -150,7 +155,9 @@ static void OutputDel(Context_t *context, char *port) static int Command(Context_t *context, OutputCmd_t command, void *argument) { int ret = cERR_OUTPUT_NO_ERROR; + output_printf(10, "%s::%s Command %d\n", __FILE__, __FUNCTION__, command); + switch (command) { case OUTPUT_OPEN: @@ -562,7 +569,9 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) ret = cERR_OUTPUT_INTERNAL_ERROR; break; } + output_printf(10, "%s::%s exiting with value %d\n", __FILE__, __FUNCTION__, ret); + return ret; } diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index 726d230..16fc2bb 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -82,6 +82,7 @@ Number, Style, Name,, MarginL, MarginR, MarginV, Effect,, Text /* Types */ /* ***************************** */ + /* ***************************** */ /* Variables */ /* ***************************** */ @@ -94,19 +95,22 @@ static int isSubtitleOpened = 0; /* ***************************** */ /* ***************************** */ -/* Functions */ +/* MISC Functions */ /* ***************************** */ static void getMutex(int line __attribute__((unused))) { subtitle_printf(100, "%d requesting mutex\n", line); + pthread_mutex_lock(&mutex); + subtitle_printf(100, "%d received mutex\n", line); } static void releaseMutex(int line __attribute__((unused))) { pthread_mutex_unlock(&mutex); + subtitle_printf(100, "%d released mutex\n", line); } @@ -176,6 +180,7 @@ static char *json_string_escape(char *str) *ptr1++ = *ptr2; break; } + ++ptr2; } *ptr1 = '\0'; @@ -193,25 +198,32 @@ static int Write(Context_t *context, void *data) char *Encoding = NULL; SubtitleOut_t *out = NULL; int32_t curtrackid = -1; + subtitle_printf(10, "\n"); + if (data == NULL) { subtitle_err("null pointer passed\n"); return cERR_SUBTITLE_ERROR; } + out = (SubtitleOut_t *) data; + context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); if (curtrackid != (int32_t)out->trackId) { Flush(); } context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding); + if (Encoding == NULL) { subtitle_err("encoding unknown\n"); return cERR_SUBTITLE_ERROR; } + subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char *) out->data, out->len); + if (!strncmp("S_TEXT/SUBRIP", Encoding, 13)) { fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data)); @@ -225,6 +237,7 @@ static int Write(Context_t *context, void *data) subtitle_err("unknown encoding %s\n", Encoding); return cERR_SUBTITLE_ERROR; } + subtitle_printf(10, "<\n"); return cERR_SUBTITLE_NO_ERROR; } @@ -232,15 +245,21 @@ static int Write(Context_t *context, void *data) static int32_t subtitle_Open(Context_t *context __attribute__((unused))) { //uint32_t i = 0 ; + subtitle_printf(10, "\n"); + if (isSubtitleOpened == 1) { subtitle_err("already opened! ignoring\n"); return cERR_SUBTITLE_ERROR; } + getMutex(__LINE__); + isSubtitleOpened = 1; + releaseMutex(__LINE__); + subtitle_printf(10, "<\n"); return cERR_SUBTITLE_NO_ERROR; } @@ -248,18 +267,26 @@ static int32_t subtitle_Open(Context_t *context __attribute__((unused))) static int32_t subtitle_Close(Context_t *context __attribute__((unused))) { //uint32_t i = 0 ; + subtitle_printf(10, "\n"); + getMutex(__LINE__); + isSubtitleOpened = 0; + releaseMutex(__LINE__); + subtitle_printf(10, "<\n"); + return cERR_SUBTITLE_NO_ERROR; } static int Command(Context_t *context, OutputCmd_t command, void *argument __attribute__((unused))) { int ret = cERR_SUBTITLE_NO_ERROR; + subtitle_printf(50, "%d\n", command); + switch (command) { case OUTPUT_OPEN: @@ -312,10 +339,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument __att ret = cERR_SUBTITLE_ERROR; break; } + subtitle_printf(50, "exiting with value %d\n", ret); return ret; } + static char *SubtitleCapabilitis[] = { "subtitle", NULL }; Output_t SubtitleOutput = diff --git a/libeplayer3-arm/output/writer/common/misc.c b/libeplayer3-arm/output/writer/common/misc.c index c9c18af..71c5ec1 100644 --- a/libeplayer3-arm/output/writer/common/misc.c +++ b/libeplayer3-arm/output/writer/common/misc.c @@ -69,12 +69,15 @@ void PutBits(BitPacker_t *ld, unsigned int code, unsigned int length) { unsigned int bit_buf; unsigned int bit_left; + bit_buf = ld->BitBuffer; bit_left = ld->Remaining; + #ifdef DEBUG_PUTBITS if (ld->debug) dprintf("code = %d, length = %d, bit_buf = 0x%x, bit_left = %d\n", code, length, bit_buf, bit_left); #endif /* DEBUG_PUTBITS */ + if (length < bit_left) { /* fits into current buffer */ @@ -96,10 +99,12 @@ void PutBits(BitPacker_t *ld, unsigned int code, unsigned int length) bit_left = 32 - length; bit_buf = code; } + #ifdef DEBUG_PUTBITS if (ld->debug) dprintf("bit_left = %d, bit_buf = 0x%x\n", bit_left, bit_buf); #endif /* DEBUG_PUTBITS */ + /* writeback */ ld->BitBuffer = bit_buf; ld->Remaining = bit_left; diff --git a/libeplayer3-arm/output/writer/common/pes.c b/libeplayer3-arm/output/writer/common/pes.c index fea8dc3..e4788c5 100644 --- a/libeplayer3-arm/output/writer/common/pes.c +++ b/libeplayer3-arm/output/writer/common/pes.c @@ -57,6 +57,7 @@ /* Types */ /* ***************************** */ + /* ***************************** */ /* Varaibles */ /* ***************************** */ @@ -73,25 +74,32 @@ int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size) { BitPacker_t ld2 = {data, 0, 32}; int32_t i = 0; + PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8); PutBits(&ld2, payload_size & 0xff, 8); PutBits(&ld2, (payload_size >> 8) & 0xff, 8); PutBits(&ld2, (payload_size >> 16) & 0xff, 8); + for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++) { PutBits(&ld2, 0, 8); } + FlushBits(&ld2); + return PES_PRIVATE_DATA_LENGTH + 1; + } int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code) { BitPacker_t ld2 = {data, 0, 32}; + if (size > (MAX_PES_PACKET_SIZE - 13)) { size = -1; // unbounded } + PutBits(&ld2, 0x0, 8); PutBits(&ld2, 0x0, 8); PutBits(&ld2, 0x1, 8); // Start Code @@ -113,6 +121,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t PutBits(&ld2, 0x0, 1); // Copyright PutBits(&ld2, 0x0, 1); // Original or Copy //7 = 6+1 + if (pts != INVALID_PTS_VALUE) { PutBits(&ld2, 0x2, 2); @@ -121,6 +130,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t { PutBits(&ld2, 0x0, 2); // PTS_DTS flag } + PutBits(&ld2, 0x0, 1); // ESCR_flag PutBits(&ld2, 0x0, 1); // ES_rate_flag PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag @@ -128,6 +138,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t PutBits(&ld2, 0x0, 1); // PES_CRC_flag PutBits(&ld2, 0x0, 1); // PES_extension_flag //8 = 7+1 + if (pts != INVALID_PTS_VALUE) { PutBits(&ld2, 0x5, 8); @@ -137,6 +148,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t PutBits(&ld2, 0x0, 8); // PES_header_data_length } //9 = 8+1 + if (pts != INVALID_PTS_VALUE) { PutBits(&ld2, 0x2, 4); @@ -148,6 +160,7 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t PutBits(&ld2, 0x1, 1); } //14 = 9+5 + if (pic_start_code) { PutBits(&ld2, 0x0, 8); @@ -157,6 +170,8 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code) //14 + 4 = 18 } + FlushBits(&ld2); + return (ld2.Ptr - data); } diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index 90b48c7..4ec234b 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -143,7 +143,7 @@ LATMContext *pLATMCtx = NULL; /* ***************************** */ /* ***************************** */ -/* Functions */ +/* MISC Functions */ /* ***************************** */ static int reset() @@ -159,16 +159,19 @@ static int reset() static int _writeData(WriterAVCallData_t *call, int type) { aac_printf(10, "\n _writeData type[%d]\n", type); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len < 8)) { aac_err("parsing Data with missing AAC header. ignoring...\n"); return 0; } + /* simple validation */ if (0 == type) // check ADTS header { @@ -195,9 +198,13 @@ static int _writeData(WriterAVCallData_t *call, int type) return 0; } } + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + aac_printf(10, "AudioPts %lld\n", call->Pts); + unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; @@ -209,31 +216,37 @@ static int _writeData(WriterAVCallData_t *call, int type) static int writeDataADTS(WriterAVCallData_t *call) { aac_printf(10, "\n"); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { aac_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { aac_err("file pointer < 0. ignoring ...\n"); return 0; } + if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { //printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]); return _writeData(call, 0); } + uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint8_t *pExtraData = &PesHeader[headerSize]; + aac_printf(10, "AudioPts %lld\n", call->Pts); if (call->private_data == NULL) { @@ -244,6 +257,7 @@ static int writeDataADTS(WriterAVCallData_t *call) { memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); } + pExtraData[3] &= 0xC0; /* frame size over last 2 bits */ pExtraData[3] |= (PacketLength & 0x1800) >> 11; @@ -256,33 +270,41 @@ static int writeDataADTS(WriterAVCallData_t *call) /* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for * number of raw data blocks */ pExtraData[6] = 0xFC; + //PesHeader[6] = 0x81; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; iov[1].iov_base = call->data; iov[1].iov_len = call->len; + return call->WriteV(call->fd, iov, 2); } static int writeDataLATM(WriterAVCallData_t *call) { aac_printf(10, "\n"); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { aac_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->private_data && 0 == strncmp("LATM", (const char *)call->private_data, call->private_size)) { return _writeData(call, 1); } + aac_printf(10, "AudioPts %lld\n", call->Pts); + if (!pLATMCtx) { pLATMCtx = malloc(sizeof(LATMContext)); @@ -290,11 +312,13 @@ static int writeDataLATM(WriterAVCallData_t *call) pLATMCtx->mod = 14; pLATMCtx->counter = 0; } + if (!pLATMCtx) { aac_err("parsing NULL pLATMCtx. ignoring...\n"); return 0; } + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size); if (ret) @@ -310,14 +334,19 @@ static int writeDataLATM(WriterAVCallData_t *call) aac_err("latm_write_packet failed. ignoring...\n"); return 0; } + unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); + struct iovec iov[3]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; + iov[1].iov_base = pLATMCtx->loas_header; iov[1].iov_len = 3; + iov[2].iov_base = pLATMCtx->buffer; iov[2].iov_len = pLATMCtx->len; + return call->WriteV(call->fd, iov, 3); } diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index 37ee989..12ade9a 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -98,34 +98,45 @@ static int reset() static int writeData(WriterAVCallData_t *call) { ac3_printf(10, "\n"); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + if (call == NULL) { ac3_err("call data is NULL...\n"); return 0; } + ac3_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { ac3_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { ac3_err("file pointer < 0. ignoring ...\n"); return 0; } + struct iovec iov[3]; + iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); //+ sizeof(AC3_SYNC_HEADER) + //PesHeader[6] = 0x81; //PesHeader[7] = 0x80; //PesHeader[8] = 0x09; + //iov[1].iov_base = AC3_SYNC_HEADER; //iov[1].iov_len = sizeof(AC3_SYNC_HEADER); iov[1].iov_base = call->data; iov[1].iov_len = call->len; + ac3_printf(40, "PES HEADER LEN %d\n", iov[0].iov_len); + return call->WriteV(call->fd, iov, 2); } diff --git a/libeplayer3-arm/output/writer/mipsel/amr.c b/libeplayer3-arm/output/writer/mipsel/amr.c index d509ea5..98cc1a4 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -99,23 +99,29 @@ static int reset() static int writeData(WriterAVCallData_t *call) { unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; + amr_printf(10, "\n"); + if (call == NULL) { amr_err("call data is NULL...\n"); return 0; } + amr_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { amr_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { amr_err("file pointer < 0. ignoring ...\n"); return 0; } + uint8_t hasCodecData = 1; if (NULL != call->private_data && call->private_size >= 17) { @@ -128,11 +134,13 @@ static int writeData(WriterAVCallData_t *call) payload_len += 9; } payload_len += 4; + uint32_t headerSize = InsertPesHeader(PesHeader, payload_len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); PesHeader[headerSize++] = (payload_len >> 24) & 0xff; PesHeader[headerSize++] = (payload_len >> 16) & 0xff; PesHeader[headerSize++] = (payload_len >> 8) & 0xff; PesHeader[headerSize++] = payload_len & 0xff; + if (hasCodecData) { uint8_t tmp[] = {0x45, 0x4d, 0x50, 0x20, 0x00, 0x00, 0x80, 0x00, 0x01}; @@ -140,12 +148,15 @@ static int writeData(WriterAVCallData_t *call) //memcpy(&PesHeader[headerSize], call->private_data + 8, 9); //memset(&PesHeader[headerSize], 0, 9); } + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = headerSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; + int len = call->WriteV(call->fd, iov, 2); + amr_printf(10, "amr_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index de7ebab..d4de31f 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -118,25 +118,32 @@ static int writeData(WriterAVCallData_t *call) unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; // unsigned char Version = 5; // unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; + divx_printf(10, "\n"); + if (call == NULL) { divx_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { divx_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { divx_err("file pointer < 0. ignoring ...\n"); return 0; } + divx_printf(10, "AudioPts %lld\n", call->Pts); + struct iovec iov[8]; int ic = 0; + if (initialHeader) { initialHeader = 0; @@ -151,11 +158,14 @@ static int writeData(WriterAVCallData_t *call) data[2] = B_GET_BITS(height, 9, 2); data[3] = B_SET_BITS("height [1.0]", B_GET_BITS(height, 1, 0), 7, 6) | B_SET_BITS("'100000'", 0x20, 5, 0); + iov[ic].iov_base = brcm_divx311_sequence_header; iov[ic++].iov_len = sizeof(brcm_divx311_sequence_header); } + iov[ic].iov_base = PesHeader; uint32_t headerSize = 0; + if (memcmp(call->data, "\x00\x00\x01\xb6", 4)) { headerSize = InsertPesHeader(PesHeader, call->len + 4, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); @@ -167,10 +177,14 @@ static int writeData(WriterAVCallData_t *call) headerSize = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); } iov[ic++].iov_len = headerSize; + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; - int len = call->WriteV(call->fd, iov, ic); + + int len = call->WriteV(call->fd, iov, ic); + divx_printf(10, "xvid_Write < len=%d\n", len); + return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index beb8e28..34548ba 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -103,25 +103,32 @@ static int32_t reset() static int writeData(WriterAVCallData_t *call) { uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; + dts_printf(10, "\n"); + if (call == NULL) { dts_err("call data is NULL...\n"); return 0; } + dts_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { dts_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { dts_err("file pointer < 0. ignoring ...\n"); return 0; } + uint8_t *Data = call->data; int32_t Size = call->len; + #ifdef CHECK_FOR_DTS_HD int32_t pos = 0; while ((pos + 4) <= Size) @@ -135,6 +142,7 @@ static int writeData(WriterAVCallData_t *call) ++pos; } #endif + // #define DO_BYTESWAP #ifdef DO_BYTESWAP /* 16-bit byte swap all data before injecting it */ @@ -145,11 +153,13 @@ static int writeData(WriterAVCallData_t *call) Data[i + 1] = Tmp; } #endif + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = Data; iov[1].iov_len = Size; + int32_t len = call->WriteV(call->fd, iov, 2); dts_printf(10, "< len %d\n", len); return len; diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/h263.c index 39c4ed2..1d8b0e5 100644 --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/h263.c @@ -95,37 +95,46 @@ static int writeData(WriterAVCallData_t *call) { uint8_t PesHeader[PES_MAX_HEADER_SIZE]; int32_t len = 0; + h263_printf(10, "\n"); + if (call == NULL) { h263_err("call data is NULL...\n"); return 0; } + h263_printf(10, "VideoPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { h263_err("NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { h263_err("file pointer < 0. ignoring ...\n"); return 0; } + int32_t HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); int32_t PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len); int32_t PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; HeaderLength += PrivateHeaderLength; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; iov[1].iov_base = call->data; iov[1].iov_len = call->len; len = call->WriteV(call->fd, iov, 2); + h263_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 4dbf2b6..8fe4be9 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -103,34 +103,45 @@ static int sps_pps_in_stream = 0; static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize) { uint8_t *aExtraData = *ppExtraData; + if (aExtraData[0] != 1 || !pData) { // Not AVCC or nothing to update with. return -1; } + int32_t nalsize = (aExtraData[4] & 3) + 1; + uint8_t sps[256]; uint8_t spsIdx = 0; + uint8_t numSps = 0; + uint8_t pps[256]; uint8_t ppsIdx = 0; + uint8_t numPps = 0; + if (nalsize != 4) { return -1; } + // Find SPS and PPS NALUs in AVCC data uint8_t *d = pData; while (d + 4 < pData + dataSize) { uint32_t nalLen = ReadUint32(d); + uint8_t nalType = d[4] & 0x1f; if (nalType == 7) { /* SPS */ + // 16 bits size sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); sps[spsIdx++] = (uint8_t)(0xFF & nalLen); + if (spsIdx + nalLen >= sizeof(sps)) { h264_err("SPS no free space to copy...\n"); @@ -138,15 +149,19 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, } memcpy(&(sps[spsIdx]), d + 4, nalLen); spsIdx += nalLen; + numSps += 1; + h264_printf(10, "SPS len[%u]...\n", nalLen); } else if (nalType == 8) { /* PPS */ + // 16 bits size pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); pps[ppsIdx++] = (uint8_t)(0xFF & nalLen); + if (ppsIdx + nalLen >= sizeof(sps)) { h264_err("PPS not free space to copy...\n"); @@ -154,7 +169,9 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, } memcpy(&(pps[ppsIdx]), d + 4, nalLen); ppsIdx += nalLen; + numPps += 1; + h264_printf(10, "PPS len[%u]...\n", nalLen); } d += 4 + nalLen; @@ -167,18 +184,21 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, aExtraData[idx++] = sps[4]; // profile compat aExtraData[idx++] = sps[5]; // level aExtraData[idx++] = 0xff; // nal size - 1 + aExtraData[idx++] = 0xe0 | numSps; if (numSps) { memcpy(&(aExtraData[idx]), sps, spsIdx); idx += spsIdx; } + aExtraData[idx++] = numPps; if (numPps) { memcpy(&(aExtraData[idx]), pps, ppsIdx); idx += ppsIdx; } + h264_printf(10, "aExtraData len[%u]...\n", idx); *pExtraDataSize = idx; return 0; @@ -192,6 +212,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { unsigned char tmp[2048]; unsigned int tmp_len = 0; + unsigned int cd_pos = 0; h264_printf(10, "H264 have codec data..!\n"); if (cd_len > 7 && data[0] == 1) @@ -238,9 +259,11 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne tmp_len += 4; memcpy(tmp + tmp_len, data + cd_pos, len); tmp_len += len; + CodecData = malloc(tmp_len); memcpy(CodecData, tmp, tmp_len); CodecDataLen = tmp_len; + *NalLength = (data[4] & 0x03) + 1; ret = 0; } @@ -297,28 +320,34 @@ static int writeData(WriterAVCallData_t *call) int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); + if (call == NULL) { h264_err("call data is NULL...\n"); return 0; } + TimeDelta = call->FrameRate; TimeScale = call->FrameScale; /* avoid compiler warnings */ if (TimeDelta) {} if (TimeScale) {} VideoPts = call->Pts; + h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); + if ((call->data == NULL) || (call->len <= 0)) { h264_err("NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { h264_err("file pointer < 0. ignoring ...\n"); return 0; } + /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || @@ -329,6 +358,7 @@ static int writeData(WriterAVCallData_t *call) uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; iov[ic++].iov_base = PesHeader; + while (InsertPrivData && i < 36 && (call->len - i) > 5) { if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68))) @@ -338,6 +368,7 @@ static int writeData(WriterAVCallData_t *call) } i += 1; } + if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime { initialHeader = 0; @@ -345,10 +376,13 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = call->private_size; PacketLength += call->private_size; } + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; + iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); + return call->WriteV(call->fd, iov, ic); } else if (!call->private_data || call->private_size < 7 || 1 != call->private_data[0]) @@ -356,9 +390,12 @@ static int writeData(WriterAVCallData_t *call) h264_err("No valid private data available! [%d]\n", (int)call->private_size); return 0; } + uint32_t PacketLength = 0; + ic = 0; iov[ic++].iov_base = PesHeader; + //if (initialHeader) { if (CodecData) @@ -366,19 +403,23 @@ static int writeData(WriterAVCallData_t *call) free(CodecData); CodecData = NULL; } + uint8_t *private_data = call->private_data; uint32_t private_size = call->private_size; + if (PreparCodecData(private_data, private_size, &NalLengthBytes)) { UpdateExtraData(&private_data, &private_size, call->data, call->len); PreparCodecData(private_data, private_size, &NalLengthBytes); } + if (private_data != call->private_data) { avc3 = 1; free(private_data); private_data = NULL; } + if (CodecData != NULL) { iov[ic].iov_base = CodecData; @@ -387,6 +428,7 @@ static int writeData(WriterAVCallData_t *call) initialHeader = 0; } } + if (CodecData != NULL) { uint32_t pos = 0; @@ -397,6 +439,7 @@ static int writeData(WriterAVCallData_t *call) h264_err(">> Drop data due to ic overflow\n"); break; } + uint32_t pack_len = 0; uint32_t i = 0; for (i = 0; i < NalLengthBytes; i++, pos++) @@ -404,21 +447,28 @@ static int writeData(WriterAVCallData_t *call) pack_len <<= 8; pack_len += call->data[pos]; } + if ((pos + pack_len) > call->len) { pack_len = call->len - pos; } + iov[ic].iov_base = Head; iov[ic++].iov_len = sizeof(Head); PacketLength += sizeof(Head); + iov[ic].iov_base = call->data + pos; iov[ic++].iov_len = pack_len; PacketLength += pack_len; + pos += pack_len; + } while ((pos + NalLengthBytes) < call->len); + h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); + len = call->WriteV(call->fd, iov, ic); PacketLength += iov[0].iov_len; if (PacketLength != len) @@ -426,6 +476,7 @@ static int writeData(WriterAVCallData_t *call) h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength); } } + h264_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index ad59853..1e61411 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -105,7 +105,9 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { unsigned char tmp[2048]; unsigned int tmp_len = 0; + h264_printf(10, "H265 have codec data..!"); + if (cd_len > 3 && (data[0] || data[1] || data[2] > 1)) { if (cd_len > 22) @@ -115,6 +117,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { h264_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]); } + *NalLength = (data[21] & 3) + 1; int num_param_sets = data[22]; uint32_t pos = 23; @@ -150,6 +153,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne pos += nal_size; } } + CodecData = malloc(tmp_len); memcpy(CodecData, tmp, tmp_len); CodecDataLen = tmp_len; @@ -160,6 +164,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { *NalLength = 0; } + return ret; } @@ -179,33 +184,40 @@ static int writeData(WriterAVCallData_t *call) int ic = 0; struct iovec iov[IOVEC_SIZE]; h264_printf(20, "\n"); + if (call == NULL) { h264_err("call data is NULL...\n"); return 0; } + TimeDelta = call->FrameRate; TimeScale = call->FrameScale; /* avoid compiler warnings */ if (TimeDelta) {} if (TimeScale) {} VideoPts = call->Pts; + h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); + if ((call->data == NULL) || (call->len <= 0)) { h264_err("NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { h264_err("file pointer < 0. ignoring ...\n"); return 0; } + if (call->InfoFlags & 0x1) // TS container { h264_printf(10, "H265 simple inject method!\n"); uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; + iov[ic++].iov_base = PesHeader; initialHeader = 0; if (initialHeader) @@ -215,17 +227,24 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = call->private_size; PacketLength += call->private_size; } + iov[ic].iov_base = ""; iov[ic++].iov_len = 1; + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; + iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); + return call->WriteV(call->fd, iov, ic); } + uint32_t PacketLength = 0; + ic = 0; iov[ic++].iov_base = PesHeader; + if (initialHeader) { if (CodecData) @@ -233,9 +252,12 @@ static int writeData(WriterAVCallData_t *call) free(CodecData); CodecData = NULL; } + uint8_t *private_data = call->private_data; uint32_t private_size = call->private_size; + PreparCodecData(private_data, private_size, &NalLengthBytes); + if (CodecData != NULL) { iov[ic].iov_base = CodecData; @@ -244,6 +266,7 @@ static int writeData(WriterAVCallData_t *call) initialHeader = 0; } } + if (CodecData != NULL) { uint32_t pos = 0; @@ -254,6 +277,7 @@ static int writeData(WriterAVCallData_t *call) h264_err(">> Drop data due to ic overflow\n"); break; } + uint32_t pack_len = 0; uint32_t i = 0; for (i = 0; i < NalLengthBytes; i++, pos++) @@ -261,21 +285,28 @@ static int writeData(WriterAVCallData_t *call) pack_len <<= 8; pack_len += call->data[pos]; } + if ((pos + pack_len) > call->len) { pack_len = call->len - pos; } + iov[ic].iov_base = Head; iov[ic++].iov_len = sizeof(Head); PacketLength += sizeof(Head); + iov[ic].iov_base = call->data + pos; iov[ic++].iov_len = pack_len; PacketLength += pack_len; + pos += pack_len; + } while ((pos + NalLengthBytes) < call->len); + h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); + len = call->WriteV(call->fd, iov, ic); PacketLength += iov[0].iov_len; if (PacketLength != len) @@ -283,6 +314,7 @@ static int writeData(WriterAVCallData_t *call) h264_err("<<<< not all data have been written [%d/%d]\n", len, PacketLength); } } + h264_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/lpcm.c b/libeplayer3-arm/output/writer/mipsel/lpcm.c index f03fc5d..cf099a2 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -59,7 +59,6 @@ /* ***************************** */ //#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define LPCM_DEBUG #else @@ -135,23 +134,29 @@ static int32_t reset() static int writeData(WriterAVCallData_t *call) { lpcm_printf(10, "\n"); + if (!call) { lpcm_err("call data is NULL...\n"); return 0; } + lpcm_printf(10, "AudioPts %lld\n", call->Pts); + if (!call->data || (call->len <= 0)) { lpcm_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { lpcm_err("file pointer < 0. ignoring ...\n"); return 0; } + pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; + int32_t i_rate = (int32_t)pcmPrivateData->sample_rate; int32_t i_channels = (int32_t)pcmPrivateData->channels; int32_t i_nb_samples = call->len / (i_channels * 2); @@ -161,6 +166,7 @@ static int writeData(WriterAVCallData_t *call) lpcm_err("Error DVD LPCM supports a maximum of eight channels i_channels[%d]\n", i_channels); return 0; } + if (pcmPrivateData->bResampling || NULL == p_buffer) { lpcm_printf(1, "i_rate: [%d]\n", i_rate); @@ -183,6 +189,7 @@ static int writeData(WriterAVCallData_t *call) lpcm_err("Error DVD LPCM sample_rate not supported [%d]\n", i_rate); return 0; } + /* In DVD LCPM, a frame is always 150 PTS ticks. */ i_frame_samples = i_rate * 150 / 90000; i_frame_size = i_frame_samples * i_channels * 2 + LLPCM_VOB_HEADER_LEN; @@ -191,6 +198,7 @@ static int writeData(WriterAVCallData_t *call) free(p_buffer); } p_buffer = malloc(i_frame_samples * i_channels * 16); + if (NULL != p_frame_buffer) { free(p_frame_buffer); @@ -200,9 +208,11 @@ static int writeData(WriterAVCallData_t *call) i_frame_num = 0; i_bitspersample = 16; } + const int i_num_frames = (i_buffer_used + i_nb_samples) / i_frame_samples; const int i_leftover_samples = (i_buffer_used + i_nb_samples) % i_frame_samples; const int i_start_offset = -i_buffer_used; + int32_t i_bytes_consumed = 0; int32_t i = 0; for (i = 0; i < i_num_frames; ++i) @@ -214,9 +224,11 @@ static int writeData(WriterAVCallData_t *call) frame[3] = (i_frame_num + i) & 0x1f; /* no emphasis, no mute */ frame[4] = (i_freq_code << 4) | (i_channels - 1); frame[5] = 0x80; /* neutral dynamic range */ + const int i_consume_samples = i_frame_samples - i_buffer_used; const int i_kept_bytes = i_buffer_used * i_channels * 2; const int i_consume_bytes = i_consume_samples * i_channels * 2; + #ifdef WORDS_BIGENDIAN memcpy(frame + 6, p_buffer, i_kept_bytes); memcpy(frame + 6 + i_kept_bytes, call->data + i_bytes_consumed, i_consume_bytes); @@ -224,15 +236,20 @@ static int writeData(WriterAVCallData_t *call) swab(p_buffer, frame + 6, i_kept_bytes); swab(call->data + i_bytes_consumed, frame + 6 + i_kept_bytes, i_consume_bytes); #endif + i_frame_num++; i_buffer_used = 0; i_bytes_consumed += i_consume_bytes; + /* We need to find i_length by means of next_pts due to possible roundoff errors. */ uint64_t this_pts = call->Pts + (i * i_frame_samples + i_start_offset) * 90000 / i_rate; + uint32_t pes_header_size = 0; pes_header_size = InsertPesHeader(PesHeader, i_frame_size + 1, MPEG_AUDIO_PES_START_CODE, this_pts, 0); + PesHeader[pes_header_size] = 0xa0; pes_header_size += 1; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = pes_header_size; @@ -240,8 +257,10 @@ static int writeData(WriterAVCallData_t *call) iov[1].iov_len = i_frame_size; i_ret_size += call->WriteV(call->fd, iov, 2); } + memcpy(p_buffer, call->data + i_bytes_consumed, i_leftover_samples * i_channels * 2); i_buffer_used = i_leftover_samples; + return i_ret_size; } diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index 3271f98..9eb9f5c 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -94,24 +94,31 @@ static int reset() static int writeData(WriterAVCallData_t *call) { unsigned char PesHeader[PES_MAX_HEADER_SIZE + 22]; + mp3_printf(10, "\n"); + if (call == NULL) { mp3_err("call data is NULL...\n"); return 0; } + mp3_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { mp3_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { mp3_err("file pointer < 0. ignoring ...\n"); return 0; } + call->private_size = 0; + uint32_t headerSize = InsertPesHeader(PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); if (call->private_size > 0) { @@ -123,7 +130,9 @@ static int writeData(WriterAVCallData_t *call) iov[0].iov_len = headerSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; + int len = call->WriteV(call->fd, iov, 2); + mp3_printf(10, "mp3_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index 2e53f70..aecc701 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -95,36 +95,47 @@ static int reset() static int writeData(WriterAVCallData_t *call) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + int len = 0; unsigned int Position = 0; + mpeg2_printf(10, "\n"); + if (call == NULL) { mpeg2_err("call data is NULL...\n"); return 0; } + mpeg2_printf(10, "VideoPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { mpeg2_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { mpeg2_err("file pointer < 0. ignoring ...\n"); return 0; } + while (Position < call->len) { int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? (call->len - Position) : MAX_PES_PACKET_SIZE; + int Remaining = call->len - Position - PacketLength; + mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position); + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0); iov[1].iov_base = call->data + Position; iov[1].iov_len = PacketLength; + ssize_t l = call->WriteV(call->fd, iov, 2); if (l < 0) { @@ -132,9 +143,11 @@ static int writeData(WriterAVCallData_t *call) break; } len += l; + Position += PacketLength; call->Pts = INVALID_PTS_VALUE; } + mpeg2_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 23cb154..0086992 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -103,32 +103,40 @@ static int reset() static int writeData(WriterAVCallData_t *call) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + mpeg4_printf(10, "\n"); + if (call == NULL) { mpeg4_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { mpeg4_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { mpeg4_err("file pointer < 0. ignoring ...\n"); return 0; } + mpeg4_printf(10, "VideoPts %lld\n", call->Pts); + unsigned int PacketLength = call->len; if (initialHeader && call->private_size && call->private_data != NULL) { PacketLength += call->private_size; } + struct iovec iov[3]; int ic = 0; iov[ic].iov_base = PesHeader; iov[ic++].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + if (initialHeader && call->private_size && call->private_data != NULL) { initialHeader = 0; @@ -137,8 +145,11 @@ static int writeData(WriterAVCallData_t *call) } iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; + int len = call->WriteV(call->fd, iov, ic); + mpeg4_printf(10, "xvid_Write < len=%d\n", len); + return len; } diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index 8246100..f50ab64 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -56,8 +56,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define PCM_DEBUG #else @@ -113,26 +111,32 @@ static int32_t reset() static int writeData(WriterAVCallData_t *call) { pcm_printf(10, "\n"); + if (!call) { pcm_err("call data is NULL...\n"); return 0; } + pcm_printf(10, "AudioPts %lld\n", call->Pts); + if (!call->data || (call->len <= 0)) { pcm_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { pcm_err("file pointer < 0. ignoring ...\n"); return 0; } + static uint8_t PesHeader[PES_MAX_HEADER_SIZE + 22]; pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; uint8_t *buffer = call->data; uint32_t size = call->len; + if (pcmPrivateData->bResampling || NULL == fixed_buffer) { if (0) @@ -143,14 +147,18 @@ static int writeData(WriterAVCallData_t *call) printf("ioctl %d", ioctl(call->fd, AUDIO_PLAY)); printf("ioctl %d", ioctl(call->fd, AUDIO_CONTINUE)); } + int32_t format = 0x01; + int32_t width = 0; int32_t depth = 0; int32_t rate = (uint64_t)pcmPrivateData->sample_rate; int32_t channels = (uint8_t) pcmPrivateData->channels; int32_t block_align = 0; int32_t byterate = 0; + uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; + //uint8_t dataPrecision = 0; uint8_t LE = 0; switch (codecID) @@ -183,7 +191,9 @@ static int writeData(WriterAVCallData_t *call) default: break; } + uint8_t *data = codec_data; + byterate = channels * rate * width / 8; block_align = channels * width / 8; memset(data, 0, sizeof(codec_data)); @@ -209,10 +219,12 @@ static int writeData(WriterAVCallData_t *call) /* word size */ *(data++) = depth & 0xff; *(data++) = (depth >> 8) & 0xff; + uint32_t nfixed_buffersize = rate * 30 / 1000; nfixed_buffersize *= channels * depth / 8; fixed_buffertimestamp = call->Pts; fixed_bufferduration = 90000 * nfixed_buffersize / byterate; + if (fixed_buffersize != nfixed_buffersize || NULL == fixed_buffer) { fixed_buffersize = nfixed_buffersize; @@ -227,6 +239,7 @@ static int writeData(WriterAVCallData_t *call) if (LE) {} //printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE"); } + while (size > 0) { uint32_t cpSize = (fixed_buffersize - fixed_bufferfilled); @@ -236,10 +249,12 @@ static int writeData(WriterAVCallData_t *call) fixed_bufferfilled += size; return size; } + memcpy(fixed_buffer + fixed_bufferfilled, buffer, cpSize); fixed_bufferfilled = 0; buffer += cpSize; size -= cpSize; + uint32_t addHeaderSize = 0; if (IsDreambox()) { @@ -253,13 +268,17 @@ static int writeData(WriterAVCallData_t *call) PesHeader[headerSize++] = 0x4D; // M PesHeader[headerSize++] = 0x41; // A } + PesHeader[headerSize++] = (fixed_buffersize >> 24) & 0xff; PesHeader[headerSize++] = (fixed_buffersize >> 16) & 0xff; PesHeader[headerSize++] = (fixed_buffersize >> 8) & 0xff; PesHeader[headerSize++] = fixed_buffersize & 0xff; + memcpy(PesHeader + headerSize, codec_data, sizeof(codec_data)); headerSize += sizeof(codec_data); + PesHeader[6] |= 1; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = headerSize; @@ -267,10 +286,13 @@ static int writeData(WriterAVCallData_t *call) iov[1].iov_len = fixed_buffersize; call->WriteV(call->fd, iov, 2); fixed_buffertimestamp += fixed_bufferduration; - int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT | O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); + + int g_fd_dump = open("/hdd/lpcm/ffmpeg.pes", O_CREAT | + O_RDWR | O_APPEND, S_IRUSR | S_IWUSR); call->WriteV(g_fd_dump, iov, 2); close(g_fd_dump); } + return size; } diff --git a/libeplayer3-arm/output/writer/mipsel/vc1.c b/libeplayer3-arm/output/writer/mipsel/vc1.c index d291e2a..0cdb63b 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -79,6 +79,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define vc1_err(fmt, x...) #endif + /* ***************************** */ /* Types */ /* ***************************** */ @@ -110,28 +111,35 @@ static int reset() static int writeData(WriterAVCallData_t *call) { //int len = 0; + vc1_printf(10, "\n"); + if (call == NULL) { vc1_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { vc1_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { vc1_err("file pointer < 0. ignoring ...\n"); return 0; } + vc1_printf(10, "VideoPts %lld\n", call->Pts); vc1_printf(10, "Got Private Size %d\n", call->private_size); + unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)]; int32_t ic = 0; struct iovec iov[5]; unsigned int PacketLength = 0; + iov[ic++].iov_base = PesHeader; if (initialHeader) { @@ -152,6 +160,7 @@ static int writeData(WriterAVCallData_t *call) PacketLength += videocodecdata.length; } } + uint8_t needFrameStartCode = 0; if (sizeof(Vc1FrameStartCode) >= call->len || memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) @@ -159,22 +168,28 @@ static int writeData(WriterAVCallData_t *call) needFrameStartCode = 1; PacketLength += sizeof(Vc1FrameStartCode); } + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; + iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + /* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */ PesHeader[6] |= 1; + if (needFrameStartCode) { memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); iov[0].iov_len += sizeof(Vc1FrameStartCode); } + if (videocodecdata.data) { free(videocodecdata.data); videocodecdata.data = NULL; } + return call->WriteV(call->fd, iov, ic); } diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index 0c61c8c..a9f75aa 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -54,7 +54,6 @@ /* ***************************** */ //#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define VP_DEBUG #else @@ -77,6 +76,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define vp_err(fmt, x...) #endif + /* ***************************** */ /* Types */ /* ***************************** */ @@ -101,25 +101,31 @@ static int reset() static int writeData(WriterAVCallData_t *call, int is_vp6) { vp_printf(10, "\n"); + if (call == NULL) { vp_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { vp_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { vp_err("file pointer < 0. ignoring ...\n"); return 0; } + vp_printf(10, "VideoPts %lld\n", call->Pts); vp_printf(10, "Got Private Size %d\n", call->private_size); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; struct iovec iov[2]; + iov[0].iov_base = PesHeader; uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); uint32_t len = call->len + 4 + 6; @@ -138,6 +144,7 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) iov[0].iov_len = pes_header_len; iov[1].iov_base = call->data; iov[1].iov_len = call->len; + return call->WriteV(call->fd, iov, 2); } diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index cea0459..15d6b2d 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -53,8 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define WMA_DEBUG #else @@ -106,28 +104,36 @@ static int reset() static int writeData(WriterAVCallData_t *call) { //int len = 0; + wma_printf(10, "\n"); + if (call == NULL) { wma_err("call data is NULL...\n"); return 0; } + wma_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { wma_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { wma_err("file pointer < 0. ignoring ...\n"); return 0; } + uint32_t packetLength = 4 + call->private_size + call->len; + if (IsDreambox()) { packetLength += 4; } + if ((packetLength + PES_MAX_HEADER_SIZE) > MaxPesHeader) { if (PesHeader) @@ -137,6 +143,7 @@ static int writeData(WriterAVCallData_t *call) MaxPesHeader = packetLength + PES_MAX_HEADER_SIZE; PesHeader = malloc(MaxPesHeader); } + uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); if (IsDreambox()) { @@ -145,14 +152,18 @@ static int writeData(WriterAVCallData_t *call) PesHeader[headerSize++] = 0x4D; // M PesHeader[headerSize++] = 0x41; // A } + size_t payload_len = call->len; PesHeader[headerSize++] = (payload_len >> 24) & 0xff; PesHeader[headerSize++] = (payload_len >> 16) & 0xff; PesHeader[headerSize++] = (payload_len >> 8) & 0xff; PesHeader[headerSize++] = payload_len & 0xff; + memcpy(PesHeader + headerSize, call->private_data, call->private_size); headerSize += call->private_size; + PesHeader[6] |= 1; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = headerSize; diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 225697b..13934c7 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -108,27 +108,33 @@ static int reset() static int writeData(WriterAVCallData_t *call) { wmv_printf(10, "\n"); + if (call == NULL) { wmv_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { wmv_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { wmv_err("file pointer < 0. ignoring ...\n"); return 0; } + wmv_printf(10, "VideoPts %lld\n", call->Pts); wmv_printf(10, "Got Private Size %d\n", call->private_size); + unsigned char PesHeader[PES_MAX_HEADER_SIZE + sizeof(Vc1FrameStartCode)]; int32_t ic = 0; struct iovec iov[5]; unsigned int PacketLength = 0; + iov[ic++].iov_base = PesHeader; if (initialHeader) { @@ -138,8 +144,10 @@ static int writeData(WriterAVCallData_t *call) free(videocodecdata.data); videocodecdata.data = NULL; } + unsigned int codec_size = call->private_size; if (codec_size > 4) codec_size = 4; + videocodecdata.length = 33; uint8_t *data = videocodecdata.data = malloc(videocodecdata.length); memset(videocodecdata.data, 0, videocodecdata.length); @@ -158,6 +166,7 @@ static int writeData(WriterAVCallData_t *call) PacketLength += videocodecdata.length; } } + uint8_t needFrameStartCode = 0; if (sizeof(Vc1FrameStartCode) >= call->len || memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) @@ -165,22 +174,28 @@ static int writeData(WriterAVCallData_t *call) needFrameStartCode = 1; PacketLength += sizeof(Vc1FrameStartCode); } + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; + iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + /* some mipsel receiver(s) like et4x00 needs to have Copy(0)/Original(1) flag set to Original */ PesHeader[6] |= 1; + if (needFrameStartCode) { memcpy(PesHeader + iov[0].iov_len, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); iov[0].iov_len += sizeof(Vc1FrameStartCode); } + if (videocodecdata.data) { free(videocodecdata.data); videocodecdata.data = NULL; } + return call->WriteV(call->fd, iov, ic); } diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index 829e4db..209c75c 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -111,7 +111,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, { fd_set rfds; fd_set wfds; - + ssize_t ret; int retval = -1; int maxFd = pipefd > fd ? pipefd : fd; @@ -125,36 +125,36 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, FD_SET(pipefd, &rfds); FD_SET(fd, &wfds); - /* When we PAUSE LINUX DVB outputs buffers then audio/video buffers - * will be filled to full unfortunately, in such case after resume + /* When we PAUSE LINUX DVB outputs buffers then audio/video buffers + * will be filled to full unfortunately, in such case after resume * select never return with fd set - bug in DVB drivers? * So, there will be to workarounds: * 1. write to pipe pipe at resume to exit select immediately - * 2. even if fd is not set exit from select after 0,1s + * 2. even if fd is not set exit from select after 0,1s * (it seems that second workaround is not needed) */ //tv.tv_sec = 0; //tv.tv_usec = 100000; // 100ms - + retval = select(maxFd + 1, &rfds, &wfds, NULL, NULL); //&tv); if (retval < 0) { break; } - + //if (retval == 0) //{ // //printf("RETURN FROM SELECT DUE TO TIMEOUT TIMEOUT\n"); // continue; //} - + if(FD_ISSET(pipefd, &rfds)) { FlusPipe(pipefd); //printf("RETURN FROM SELECT DUE TO pipefd SET\n"); continue; } - + if(FD_ISSET(fd, &wfds)) { ret = write(fd, buf, size); @@ -173,7 +173,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, { break; } - + return ret; } else if (ret == 0) @@ -186,7 +186,7 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, FlusPipe(pipefd); continue; } - + size -= ret; buf += ret; } @@ -219,12 +219,15 @@ ssize_t write_with_retry(int fd, const void *buf, size_t size) break; } } + if (ret < 0) { return ret; } + size -= ret; buf += ret; + if (size > 0) { if (usleep(1000)) @@ -255,6 +258,7 @@ ssize_t writev_with_retry(int fd, const struct iovec *iov, size_t ic) Writer_t *getWriter(char *encoding) { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0) @@ -263,13 +267,16 @@ Writer_t *getWriter(char *encoding) return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding); + return NULL; } Writer_t *getDefaultVideoWriter() { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0) @@ -278,13 +285,16 @@ Writer_t *getDefaultVideoWriter() return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found\n", __func__); + return NULL; } Writer_t *getDefaultAudioWriter() { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0) @@ -293,6 +303,8 @@ Writer_t *getDefaultAudioWriter() return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found\n", __func__); + return NULL; } diff --git a/libeplayer3-arm/output/writer/sh4/aac.c b/libeplayer3-arm/output/writer/sh4/aac.c index e70336c..28b06b8 100644 --- a/libeplayer3-arm/output/writer/sh4/aac.c +++ b/libeplayer3-arm/output/writer/sh4/aac.c @@ -43,6 +43,7 @@ #include #include "ffmpeg/latmenc.h" + #include "common.h" #include "output.h" #include "debug.h" @@ -157,17 +158,21 @@ static int reset() static int _writeData(void *_call, int type) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + aac_printf(10, "\n _writeData type[%d]\n", type); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len < 8)) { aac_err("parsing Data with missing AAC header. ignoring...\n"); return 0; } + /* simple validation */ if (0 == type) // check ADTS header { @@ -194,9 +199,13 @@ static int _writeData(void *_call, int type) return 0; } } + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + aac_printf(10, "AudioPts %lld\n", call->Pts); + unsigned int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; @@ -208,31 +217,38 @@ static int _writeData(void *_call, int type) static int writeDataADTS(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + aac_printf(10, "\n"); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { aac_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { aac_err("file pointer < 0. ignoring ...\n"); return 0; } + if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) || HasADTSHeader(call->data, call->len)) { return _writeData(_call, 0); } + uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint8_t *pExtraData = &PesHeader[headerSize]; + aac_printf(10, "AudioPts %lld\n", call->Pts); if (call->private_data == NULL) { @@ -243,6 +259,7 @@ static int writeDataADTS(void *_call) { memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); } + pExtraData[3] &= 0xC0; /* frame size over last 2 bits */ pExtraData[3] |= (PacketLength & 0x1800) >> 11; @@ -255,33 +272,41 @@ static int writeDataADTS(void *_call) /* buffer fullness(0x7FF for VBR) continued over 6 first bits + 2 zeros for * number of raw data blocks */ pExtraData[6] = 0xFC; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; iov[1].iov_base = call->data; iov[1].iov_len = call->len; + return writev(call->fd, iov, 2); } static int writeDataLATM(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + aac_printf(10, "\n"); + if (call == NULL) { aac_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { aac_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->private_data && 0 == strncmp("LATM", call->private_data, call->private_size)) { return _writeData(_call, 1); } + aac_printf(10, "AudioPts %lld\n", call->Pts); + if (!pLATMCtx) { pLATMCtx = malloc(sizeof(LATMContext)); @@ -289,11 +314,13 @@ static int writeDataLATM(void *_call) pLATMCtx->mod = 14; pLATMCtx->counter = 0; } + if (!pLATMCtx) { aac_err("parsing NULL pLATMCtx. ignoring...\n"); return 0; } + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; int ret = latmenc_decode_extradata(pLATMCtx, call->private_data, call->private_size); if (ret) @@ -309,14 +336,19 @@ static int writeDataLATM(void *_call) aac_err("latm_write_packet failed. ignoring...\n"); return 0; } + unsigned int HeaderLength = InsertPesHeader(PesHeader, pLATMCtx->len + 3, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); + struct iovec iov[3]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; + iov[1].iov_base = pLATMCtx->loas_header; iov[1].iov_len = 3; + iov[2].iov_base = pLATMCtx->buffer; iov[2].iov_len = pLATMCtx->len; + return writev(call->fd, iov, 3); } diff --git a/libeplayer3-arm/output/writer/sh4/ac3.c b/libeplayer3-arm/output/writer/sh4/ac3.c index cf50f6b..3ff3df0 100644 --- a/libeplayer3-arm/output/writer/sh4/ac3.c +++ b/libeplayer3-arm/output/writer/sh4/ac3.c @@ -98,29 +98,38 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + ac3_printf(10, "\n"); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + if (call == NULL) { ac3_err("call data is NULL...\n"); return 0; } + ac3_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { ac3_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { ac3_err("file pointer < 0. ignoring ...\n"); return 0; } + struct iovec iov[2]; + iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->len, PRIVATE_STREAM_1_PES_START_CODE, call->Pts, 0); iov[1].iov_base = call->data; iov[1].iov_len = call->len; + return writev(call->fd, iov, 2); } diff --git a/libeplayer3-arm/output/writer/sh4/divx.c b/libeplayer3-arm/output/writer/sh4/divx.c index 904b7af..e18538d 100644 --- a/libeplayer3-arm/output/writer/sh4/divx.c +++ b/libeplayer3-arm/output/writer/sh4/divx.c @@ -101,6 +101,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) { static uint8_t *oldData = NULL; static int32_t oldSize = 0; + uint8_t update = 0; if (data != NULL && size > 0) { @@ -121,6 +122,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) } } } + if (update) { if (oldData != NULL) @@ -131,43 +133,56 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) memcpy(oldData, data, size); oldSize = size; } + return update; } static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + divx_printf(10, "\n"); + if (call == NULL) { divx_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { divx_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { divx_err("file pointer < 0. ignoring ...\n"); return 0; } + divx_printf(10, "VideoPts %lld\n", call->Pts); + struct iovec iov[4]; int ic = 0; iov[ic].iov_base = PesHeader; iov[ic++].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + if (updateCodecData(call->private_data, call->private_size)) { iov[ic].iov_base = call->private_data; iov[ic++].iov_len = call->private_size; } + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; + int len = writev(call->fd, iov, ic); + divx_printf(10, "xvid_Write < len=%d\n", len); + return len; } diff --git a/libeplayer3-arm/output/writer/sh4/divx2.c b/libeplayer3-arm/output/writer/sh4/divx2.c index a658416..c7b8654 100644 --- a/libeplayer3-arm/output/writer/sh4/divx2.c +++ b/libeplayer3-arm/output/writer/sh4/divx2.c @@ -101,6 +101,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) { static uint8_t *oldData = NULL; static int32_t oldSize = 0; + uint8_t update = 0; if (data != NULL && size > 0) { @@ -121,6 +122,7 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) } } } + if (update) { if (oldData != NULL) @@ -131,12 +133,14 @@ static uint8_t updateCodecData(uint8_t *data, int32_t size) memcpy(oldData, data, size); oldSize = size; } + return update; } static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers unsigned int FakeHeaderLength; @@ -144,26 +148,34 @@ static int writeData(void *_call) unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */ BitPacker_t ld = {FakeHeaders, 0, 32}; + divx_printf(10, "\n"); + if (call == NULL) { divx_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { divx_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { divx_err("file pointer < 0. ignoring ...\n"); return 0; } + divx_printf(10, "AudioPts %lld\n", call->Pts); + usecPerFrame = 1000000000 / call->FrameRate; divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame); + memset(FakeHeaders, 0, sizeof(FakeHeaders)); + /* Create info record for frame parser */ /* divx4 & 5 VOS @@ -177,23 +189,30 @@ static int writeData(void *_call) PutBits(&ld, usecPerFrame, 32); // microseconds per frame FlushBits(&ld); + FakeHeaderLength = (ld.Ptr - (FakeHeaders)); + struct iovec iov[4]; int ic = 0; iov[ic].iov_base = PesHeader; iov[ic++].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, FakeStartCode); iov[ic].iov_base = FakeHeaders; iov[ic++].iov_len = FakeHeaderLength; + if (initialHeader) { iov[ic].iov_base = call->private_data; iov[ic++].iov_len = call->private_size; initialHeader = 0; } + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; + int len = writev(call->fd, iov, ic); + divx_printf(10, "xvid_Write < len=%d\n", len); + return len; } diff --git a/libeplayer3-arm/output/writer/sh4/dts.c b/libeplayer3-arm/output/writer/sh4/dts.c index 25bd117..fb2a21f 100644 --- a/libeplayer3-arm/output/writer/sh4/dts.c +++ b/libeplayer3-arm/output/writer/sh4/dts.c @@ -102,26 +102,34 @@ static int reset() static int32_t writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; + dts_printf(10, "\n"); + if (call == NULL) { dts_err("call data is NULL...\n"); return 0; } + dts_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { dts_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { dts_err("file pointer < 0. ignoring ...\n"); return 0; } + uint8_t *Data = call->data; int32_t Size = call->len; + #ifdef CHECK_FOR_DTS_HD int32_t pos = 0; while ((pos + 4) <= Size) @@ -135,6 +143,7 @@ static int32_t writeData(void *_call) ++pos; } #endif + // #define DO_BYTESWAP #ifdef DO_BYTESWAP /* 16-bit byte swap all data before injecting it */ @@ -145,11 +154,13 @@ static int32_t writeData(void *_call) Data[i + 1] = Tmp; } #endif + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, Size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = Data; iov[1].iov_len = Size; + int32_t len = writev(call->fd, iov, 2); dts_printf(10, "< len %d\n", len); return len; diff --git a/libeplayer3-arm/output/writer/sh4/h263.c b/libeplayer3-arm/output/writer/sh4/h263.c index 86430df..466d720 100644 --- a/libeplayer3-arm/output/writer/sh4/h263.c +++ b/libeplayer3-arm/output/writer/sh4/h263.c @@ -97,39 +97,52 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; int len = 0; + h263_printf(10, "\n"); + if (call == NULL) { h263_err("call data is NULL...\n"); return 0; } + h263_printf(10, "VideoPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { h263_err("NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { h263_err("file pointer < 0. ignoring ...\n"); return 0; } + int HeaderLength = InsertPesHeader(PesHeader, call->len, H263_VIDEO_PES_START_CODE, call->Pts, 0); + int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len); + int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; + HeaderLength += PrivateHeaderLength; + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; iov[1].iov_base = call->data; iov[1].iov_len = call->len; len = writev(call->fd, iov, 2); + h263_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/h264.c b/libeplayer3-arm/output/writer/sh4/h264.c index 482b219..39a6afa 100644 --- a/libeplayer3-arm/output/writer/sh4/h264.c +++ b/libeplayer3-arm/output/writer/sh4/h264.c @@ -113,34 +113,45 @@ static int avc3 = 0; static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, uint8_t *pData, uint32_t dataSize) { uint8_t *aExtraData = *ppExtraData; + if (aExtraData[0] != 1 || !pData) { // Not AVCC or nothing to update with. return -1; } + int32_t nalsize = (aExtraData[4] & 3) + 1; + uint8_t sps[256]; uint8_t spsIdx = 0; + uint8_t numSps = 0; + uint8_t pps[256]; uint8_t ppsIdx = 0; + uint8_t numPps = 0; + if (nalsize != 4) { return -1; } + // Find SPS and PPS NALUs in AVCC data uint8_t *d = pData; while (d + 4 < pData + dataSize) { uint32_t nalLen = ReadUint32(d); + uint8_t nalType = d[4] & 0x1f; if (nalType == 7) { /* SPS */ + // 16 bits size sps[spsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); sps[spsIdx++] = (uint8_t)(0xFF & nalLen); + if (spsIdx + nalLen >= sizeof(sps)) { h264_err("SPS no free space to copy...\n"); @@ -148,15 +159,19 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, } memcpy(&(sps[spsIdx]), d + 4, nalLen); spsIdx += nalLen; + numSps += 1; + h264_printf(10, "SPS len[%u]...\n", nalLen); } else if (nalType == 8) { /* PPS */ + // 16 bits size pps[ppsIdx++] = (uint8_t)(0xFF & (nalLen >> 8)); pps[ppsIdx++] = (uint8_t)(0xFF & nalLen); + if (ppsIdx + nalLen >= sizeof(sps)) { h264_err("PPS not free space to copy...\n"); @@ -164,7 +179,9 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, } memcpy(&(pps[ppsIdx]), d + 4, nalLen); ppsIdx += nalLen; + numPps += 1; + h264_printf(10, "PPS len[%u]...\n", nalLen); } d += 4 + nalLen; @@ -177,18 +194,21 @@ static int32_t UpdateExtraData(uint8_t **ppExtraData, uint32_t *pExtraDataSize, aExtraData[idx++] = sps[4]; // profile compat aExtraData[idx++] = sps[5]; // level aExtraData[idx++] = 0xff; // nal size - 1 + aExtraData[idx++] = 0xe0 | numSps; if (numSps) { memcpy(&(aExtraData[idx]), sps, spsIdx); idx += spsIdx; } + aExtraData[idx++] = numPps; if (numPps) { memcpy(&(aExtraData[idx]), pps, ppsIdx); idx += ppsIdx; } + h264_printf(10, "aExtraData len[%u]...\n", idx); *pExtraDataSize = idx; return 0; @@ -204,6 +224,7 @@ static int32_t reset() static int32_t writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + uint8_t PesHeader[PES_MAX_HEADER_SIZE]; uint64_t VideoPts; uint32_t TimeDelta; @@ -212,25 +233,31 @@ static int32_t writeData(void *_call) int32_t ic = 0; struct iovec iov[128]; h264_printf(10, "\n"); + if (call == NULL) { h264_err("call data is NULL...\n"); return 0; } + TimeDelta = call->FrameRate; TimeScale = call->FrameScale; VideoPts = call->Pts; + h264_printf(10, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); + if ((call->data == NULL) || (call->len <= 0)) { h264_err("NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { h264_err("file pointer < 0. ignoring ...\n"); return 0; } + /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || @@ -238,6 +265,7 @@ static int32_t writeData(void *_call) { uint32_t PacketLength = 0; uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE; + iov[ic++].iov_base = PesHeader; initialHeader = 0; if (initialHeader) @@ -247,16 +275,20 @@ static int32_t writeData(void *_call) iov[ic++].iov_len = call->private_size; PacketLength += call->private_size; } + iov[ic].iov_base = ""; iov[ic++].iov_len = 1; + iov[ic].iov_base = call->data; iov[ic++].iov_len = call->len; PacketLength += call->len; + /*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than data is available. The content of this byte does not matter. It will be ignored by the player */ iov[ic].iov_base = "\0"; iov[ic++].iov_len = 1; + iov[0].iov_len = InsertPesHeader(PesHeader, -1, MPEG_VIDEO_PES_START_CODE, VideoPts, FakeStartCode); int ret = writev(call->fd, iov, ic); return ret; @@ -266,6 +298,7 @@ static int32_t writeData(void *_call) h264_err("No valid private data available!\n"); return 0; } + if (initialHeader) { uint8_t *private_data = call->private_data; @@ -276,8 +309,11 @@ static int32_t writeData(void *_call) unsigned int ParamOffset; unsigned int InitialHeaderLength = 0; unsigned int ParametersLength; + ParametersLength = 0; + unsigned char HeaderData[19]; + if (private_size <= sizeof(avcC_t)) { UpdateExtraData(&private_data, &private_size, call->data, call->len); @@ -287,6 +323,7 @@ static int32_t writeData(void *_call) avcCHeader = (avcC_t *)private_data; } } + HeaderData[ParametersLength++] = 0x00; // Start code HeaderData[ParametersLength++] = 0x00; HeaderData[ParametersLength++] = 0x01; @@ -294,14 +331,17 @@ static int32_t writeData(void *_call) // Container message version - changes when/if we vary the format of the message HeaderData[ParametersLength++] = CONTAINER_PARAMETERS_VERSION; HeaderData[ParametersLength++] = 0xff; // Field separator + if (TimeDelta == 0xffffffff) TimeDelta = (TimeScale > 1000) ? 1001 : 1; + HeaderData[ParametersLength++] = (TimeScale >> 24) & 0xff; // Output the timescale HeaderData[ParametersLength++] = (TimeScale >> 16) & 0xff; HeaderData[ParametersLength++] = 0xff; HeaderData[ParametersLength++] = (TimeScale >> 8) & 0xff; HeaderData[ParametersLength++] = TimeScale & 0xff; HeaderData[ParametersLength++] = 0xff; + HeaderData[ParametersLength++] = (TimeDelta >> 24) & 0xff; // Output frame period HeaderData[ParametersLength++] = (TimeDelta >> 16) & 0xff; HeaderData[ParametersLength++] = 0xff; @@ -309,7 +349,9 @@ static int32_t writeData(void *_call) HeaderData[ParametersLength++] = TimeDelta & 0xff; HeaderData[ParametersLength++] = 0xff; HeaderData[ParametersLength++] = 0x80; // Rsbp trailing bits + assert(ParametersLength <= sizeof(HeaderData)); + ic = 0; iov[ic].iov_base = PesHeader; iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); @@ -320,8 +362,10 @@ static int32_t writeData(void *_call) { return len; } + NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1; ParamSets = avcCHeader->NumParamSets & 0x1f; + h264_printf(20, "avcC contents:\n"); h264_printf(20, " version: %d\n", avcCHeader->Version); h264_printf(20, " profile: %d\n", avcCHeader->Profile); @@ -329,13 +373,16 @@ static int32_t writeData(void *_call) h264_printf(20, " level: %d\n", avcCHeader->Level); h264_printf(20, " nal length bytes: %d\n", NalLengthBytes); h264_printf(20, " number of sequence param sets: %d\n", ParamSets); + ParamOffset = 0; ic = 0; iov[ic++].iov_base = PesHeader; for (i = 0; i < ParamSets; i++) { unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1]; + h264_printf(20, " sps %d has length %d\n", i, PsLength); + iov[ic].iov_base = (char *)Head; iov[ic++].iov_len = sizeof(Head); InitialHeaderLength += sizeof(Head); @@ -344,13 +391,18 @@ static int32_t writeData(void *_call) InitialHeaderLength += PsLength; ParamOffset += PsLength + 2; } + ParamSets = avcCHeader->Params[ParamOffset]; + h264_printf(20, " number of picture param sets: %d\n", ParamSets); + ParamOffset++; for (i = 0; i < ParamSets; i++) { unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1]; + h264_printf(20, " pps %d has length %d\n", i, PsLength); + iov[ic].iov_base = (char *) Head; iov[ic++].iov_len = sizeof(Head); InitialHeaderLength += sizeof(Head); @@ -359,27 +411,34 @@ static int32_t writeData(void *_call) InitialHeaderLength += PsLength; ParamOffset += PsLength + 2; } + iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); ssize_t l = writev(call->fd, iov, ic); + if (private_data != call->private_data) { free(private_data); } + if (l < 0) { return l; } + len += l; initialHeader = 0; } + unsigned int SampleSize = call->len; unsigned int NalStart = 0; unsigned int VideoPosition = 0; + do { unsigned int NalLength; unsigned char NalData[4]; int NalPresent = 1; + memcpy(NalData, call->data + VideoPosition, NalLengthBytes); VideoPosition += NalLengthBytes; NalStart += NalLengthBytes; @@ -398,11 +457,14 @@ static int32_t writeData(void *_call) NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); break; } + h264_printf(20, "NalStart = %u + NalLength = %u > SampleSize = %u\n", NalStart, NalLength, SampleSize); + if (NalStart + NalLength > SampleSize) { h264_printf(20, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart); + NalStart = SampleSize; } else @@ -410,30 +472,37 @@ static int32_t writeData(void *_call) NalStart += NalLength; ic = 0; iov[ic++].iov_base = PesHeader; + if (NalPresent) { NalPresent = 0; iov[ic].iov_base = (char *)Head; iov[ic++].iov_len = sizeof(Head); } + iov[ic].iov_base = call->data + VideoPosition; iov[ic++].iov_len = NalLength; VideoPosition += NalLength; + h264_printf(20, " pts=%llu\n", VideoPts); + iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); ssize_t l = writev(call->fd, iov, ic); if (l < 0) return l; len += l; + VideoPts = INVALID_PTS_VALUE; } } while (NalStart < SampleSize); + if (len < 0) { h264_err("error writing data errno = %d\n", errno); h264_err("%s\n", strerror(errno)); } + h264_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/mp3.c b/libeplayer3-arm/output/writer/sh4/mp3.c index f66bb41..7ed7d02 100644 --- a/libeplayer3-arm/output/writer/sh4/mp3.c +++ b/libeplayer3-arm/output/writer/sh4/mp3.c @@ -97,30 +97,39 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + mp3_printf(10, "\n"); + if (call == NULL) { mp3_err("call data is NULL...\n"); return 0; } + mp3_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { mp3_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { mp3_err("file pointer < 0. ignoring ...\n"); return 0; } + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = call->data; iov[1].iov_len = call->len; + int len = writev(call->fd, iov, 2); + mp3_printf(10, "mp3_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/mpeg2.c b/libeplayer3-arm/output/writer/sh4/mpeg2.c index 2fd8ad6..cb1f928 100644 --- a/libeplayer3-arm/output/writer/sh4/mpeg2.c +++ b/libeplayer3-arm/output/writer/sh4/mpeg2.c @@ -97,37 +97,49 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + int len = 0; unsigned int Position = 0; + mpeg2_printf(10, "\n"); + if (call == NULL) { mpeg2_err("call data is NULL...\n"); return 0; } + mpeg2_printf(10, "VideoPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { mpeg2_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { mpeg2_err("file pointer < 0. ignoring ...\n"); return 0; } + while (Position < call->len) { int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? (call->len - Position) : MAX_PES_PACKET_SIZE; + int32_t Remaining = call->len - Position - PacketLength; + mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position); + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0); iov[1].iov_base = call->data + Position; iov[1].iov_len = PacketLength; + ssize_t l = writev(call->fd, iov, 2); if (l < 0) { @@ -135,9 +147,11 @@ static int writeData(void *_call) break; } len += l; + Position += PacketLength; call->Pts = INVALID_PTS_VALUE; } + mpeg2_printf(10, "< len %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/pcm.c b/libeplayer3-arm/output/writer/sh4/pcm.c index 5b752dd..4a7103f 100644 --- a/libeplayer3-arm/output/writer/sh4/pcm.c +++ b/libeplayer3-arm/output/writer/sh4/pcm.c @@ -124,10 +124,13 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32 uBitsPerSample/*Format->wBitsPerSample*/, (uBitsPerSample/*Format->wBitsPerSample*/ / 8) ); + SubFrameLen = 0; SubFramesPerPES = 0; breakBufferFillSize = 0; + memcpy(lpcm_prv, clpcm_prv, sizeof(lpcm_prv)); + //figure out size of subframe //and set up sample rate switch (uSampleRate) @@ -158,14 +161,18 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32 default: break; } + SubFrameLen *= uNoOfChannels; SubFrameLen *= (uBitsPerSample / 8); + //rewrite PES size to have as many complete subframes per PES as we can // FIXME: PES header size was hardcoded to 18 in previous code. Actual size returned by InsertPesHeader is 14. SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen; SubFrameLen *= SubFramesPerPES; + //set number of channels lpcm_prv[10] = uNoOfChannels - 1; + switch (uBitsPerSample) { case 24: @@ -176,6 +183,7 @@ static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32 printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample); return 1; } + return 0; } @@ -188,25 +196,33 @@ static int32_t reset() static int32_t writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + pcm_printf(10, "\n"); + if (!call) { pcm_err("call data is NULL...\n"); return 0; } + pcm_printf(10, "AudioPts %lld\n", call->Pts); + if (!call->data || (call->len <= 0)) { pcm_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { pcm_err("file pointer < 0. ignoring ...\n"); return 0; } + pcmPrivateData_t *pcmPrivateData = (pcmPrivateData_t *)call->private_data; + if (initialHeader) { uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; @@ -240,11 +256,14 @@ static int32_t writeData(void *_call) initialHeader = 0; prepareClipPlay(pcmPrivateData->channels, pcmPrivateData->sample_rate, pcmPrivateData->bits_per_coded_sample, LE); } + uint8_t *buffer = call->data; uint32_t size = call->len; + uint32_t n; uint8_t *injectBuffer = malloc(SubFrameLen); uint32_t pos; + for (pos = 0; pos < size;) { //printf("PCM %s - Position=%d\n", __FUNCTION__, pos); @@ -255,6 +274,7 @@ static int32_t writeData(void *_call) //printf("PCM %s - Unplayed=%d\n", __FUNCTION__, breakBufferFillSize); break; } + //get first PES's worth if (breakBufferFillSize > 0) { @@ -268,12 +288,15 @@ static int32_t writeData(void *_call) memcpy(injectBuffer, &buffer[pos], sizeof(uint8_t)*SubFrameLen); pos += SubFrameLen; } + struct iovec iov[3]; iov[0].iov_base = PesHeader; iov[1].iov_base = lpcm_prv; iov[1].iov_len = sizeof(lpcm_prv); + iov[2].iov_base = injectBuffer; iov[2].iov_len = SubFrameLen; + //write the PCM data if (16 == pcmPrivateData->bits_per_coded_sample) { @@ -305,8 +328,10 @@ static int32_t writeData(void *_call) p[ 8] = t; } } + //increment err... subframe count? lpcm_prv[1] = ((lpcm_prv[1] + SubFramesPerPES) & 0x1F); + iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len + iov[2].iov_len, PCM_PES_START_CODE, call->Pts, 0); int32_t len = writev(call->fd, iov, 3); if (len < 0) @@ -315,6 +340,7 @@ static int32_t writeData(void *_call) } } free(injectBuffer); + return size; } diff --git a/libeplayer3-arm/output/writer/sh4/pes.c b/libeplayer3-arm/output/writer/sh4/pes.c index 8df20a8..12a7bd6 100644 --- a/libeplayer3-arm/output/writer/sh4/pes.c +++ b/libeplayer3-arm/output/writer/sh4/pes.c @@ -70,23 +70,30 @@ int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size) { BitPacker_t ld2 = {data, 0, 32}; int i; + PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8); PutBits(&ld2, payload_size & 0xff, 8); PutBits(&ld2, (payload_size >> 8) & 0xff, 8); PutBits(&ld2, (payload_size >> 16) & 0xff, 8); + for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++) PutBits(&ld2, 0, 8); + FlushBits(&ld2); + return PES_PRIVATE_DATA_LENGTH + 1; + } int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsigned long long int pts, int pic_start_code) { BitPacker_t ld2 = {data, 0, 32}; + if (size > (MAX_PES_PACKET_SIZE - 13)) { size = -1; // unbounded } + PutBits(&ld2, 0x0, 8); PutBits(&ld2, 0x0, 8); PutBits(&ld2, 0x1, 8); // Start Code @@ -108,6 +115,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi PutBits(&ld2, 0x0, 1); // Copyright PutBits(&ld2, 0x0, 1); // Original or Copy //7 = 6+1 + if (pts != INVALID_PTS_VALUE) { PutBits(&ld2, 0x2, 2); @@ -116,6 +124,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi { PutBits(&ld2, 0x0, 2); // PTS_DTS flag } + PutBits(&ld2, 0x0, 1); // ESCR_flag PutBits(&ld2, 0x0, 1); // ES_rate_flag PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag @@ -123,11 +132,13 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi PutBits(&ld2, 0x0, 1); // PES_CRC_flag PutBits(&ld2, 0x0, 1); // PES_extension_flag //8 = 7+1 + if (pts != INVALID_PTS_VALUE) PutBits(&ld2, 0x5, 8); else PutBits(&ld2, 0x0, 8); // PES_header_data_length //9 = 8+1 + if (pts != INVALID_PTS_VALUE) { PutBits(&ld2, 0x2, 4); @@ -139,6 +150,7 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi PutBits(&ld2, 0x1, 1); } //14 = 9+5 + if (pic_start_code) { PutBits(&ld2, 0x0, 8); @@ -148,6 +160,8 @@ int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, unsi PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code) //14 + 4 = 18 } + FlushBits(&ld2); + return (ld2.Ptr - data); } diff --git a/libeplayer3-arm/output/writer/sh4/vc1.c b/libeplayer3-arm/output/writer/sh4/vc1.c index baa8129..4865e9f 100644 --- a/libeplayer3-arm/output/writer/sh4/vc1.c +++ b/libeplayer3-arm/output/writer/sh4/vc1.c @@ -127,25 +127,31 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + int len = 0; vc1_printf(10, "\n"); + if (call == NULL) { vc1_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { vc1_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { vc1_err("file pointer < 0. ignoring ...\n"); return 0; } + vc1_printf(10, "VideoPts %lld\n", call->Pts); vc1_printf(10, "Got Private Size %d\n", call->private_size); + if (initialHeader) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; @@ -153,18 +159,25 @@ static int writeData(void *_call) unsigned char *PesPtr; unsigned int crazyFramerate = 0; struct iovec iov[2]; + vc1_printf(10, "Framerate: %u\n", call->FrameRate); vc1_printf(10, "biWidth: %d\n", call->Width); vc1_printf(10, "biHeight: %d\n", call->Height); + crazyFramerate = ((10000000.0 / call->FrameRate) * 1000.0); vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate); + memset(PesPayload, 0, sizeof(PesPayload)); + PesPtr = PesPayload; + memcpy(PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode)); PesPtr += sizeof(SequenceLayerStartCode); + memcpy(PesPtr, Metadata, sizeof(Metadata)); PesPtr += METADATA_STRUCT_C_START; PesPtr += WMV3_PRIVATE_DATA_LENGTH; + /* Metadata Header Struct A */ *PesPtr++ = (call->Height >> 0) & 0xff; *PesPtr++ = (call->Height >> 8) & 0xff; @@ -174,43 +187,56 @@ static int writeData(void *_call) *PesPtr++ = (call->Width >> 8) & 0xff; *PesPtr++ = (call->Width >> 16) & 0xff; *PesPtr++ = call->Width >> 24; + PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ + *PesPtr++ = (crazyFramerate >> 0) & 0xff; *PesPtr++ = (crazyFramerate >> 8) & 0xff; *PesPtr++ = (crazyFramerate >> 16) & 0xff; *PesPtr++ = crazyFramerate >> 24; + iov[0].iov_base = PesHeader; iov[1].iov_base = PesPayload; iov[1].iov_len = PesPtr - PesPayload; iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); len = writev(call->fd, iov, 2); + /* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */ iov[0].iov_base = PesHeader; iov[1].iov_base = call->private_data; iov[1].iov_len = call->private_size; iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); len = writev(call->fd, iov, 2); + initialHeader = 0; } + if (call->len > 0 && call->data) { uint32_t Position = 0; uint8_t insertSampleHeader = 1; + while (Position < call->len) { int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? (call->len - Position) : MAX_PES_PACKET_SIZE; + int32_t Remaining = call->len - Position - PacketLength; + vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position); + uint8_t PesHeader[PES_MAX_HEADER_SIZE]; int32_t HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0); + if (insertSampleHeader) { const uint8_t Vc1FrameStartCode[] = {0, 0, 1, VC1_FRAME_START_CODE}; + if (!FrameHeaderSeen && (call->len > 3) && (memcmp(call->data, Vc1FrameStartCode, 4) == 0)) { FrameHeaderSeen = 1; } + if (!FrameHeaderSeen) { memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); @@ -218,11 +244,13 @@ static int writeData(void *_call) } insertSampleHeader = 0; } + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; iov[1].iov_base = call->data + Position; iov[1].iov_len = PacketLength; + ssize_t l = writev(call->fd, iov, 2); if (l < 0) { @@ -230,10 +258,12 @@ static int writeData(void *_call) break; } len += l; + Position += PacketLength; call->Pts = INVALID_PTS_VALUE; } } + vc1_printf(10, "< %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/vorbis.c b/libeplayer3-arm/output/writer/sh4/vorbis.c index 0b09940..3ed1cb2 100644 --- a/libeplayer3-arm/output/writer/sh4/vorbis.c +++ b/libeplayer3-arm/output/writer/sh4/vorbis.c @@ -50,8 +50,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define VORBIS_DEBUG #else @@ -98,30 +96,42 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + vorbis_printf(10, "\n"); + if (call == NULL) { vorbis_err("call data is NULL...\n"); return 0; } + vorbis_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { vorbis_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { vorbis_err("file pointer < 0. ignoring ...\n"); return 0; } + int HeaderLength = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); + unsigned char *PacketStart = malloc(call->len + HeaderLength); + memcpy(PacketStart, PesHeader, HeaderLength); memcpy(PacketStart + HeaderLength, call->data, call->len); + int len = write(call->fd, PacketStart, call->len + HeaderLength); + free(PacketStart); + vorbis_printf(10, "vorbis_Write-< len=%d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/wma.c b/libeplayer3-arm/output/writer/sh4/wma.c index 39a42a9..4b92ac5 100644 --- a/libeplayer3-arm/output/writer/sh4/wma.c +++ b/libeplayer3-arm/output/writer/sh4/wma.c @@ -51,8 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - #ifdef SAM_WITH_DEBUG #define WMA_DEBUG #else @@ -102,32 +100,41 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + int len = 0; + wma_printf(10, "\n"); + if (call == NULL) { wma_err("call data is NULL...\n"); return 0; } + wma_printf(10, "AudioPts %lld\n", call->Pts); + if ((call->data == NULL) || (call->len <= 0)) { wma_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { wma_err("file pointer < 0. ignoring ...\n"); return 0; } + if (initialHeader) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + if ((call->private_size <= 0) || (call->private_data == NULL)) { wma_err("private NULL.\n"); return -1; } + struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = InsertPesHeader(PesHeader, call->private_size, MPEG_AUDIO_PES_START_CODE, 0, 0); @@ -136,6 +143,7 @@ static int writeData(void *_call) len = writev(call->fd, iov, 2); initialHeader = 0; } + if (len > -1 && call->len > 0 && call->data) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; @@ -144,10 +152,13 @@ static int writeData(void *_call) iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); iov[1].iov_base = call->data; iov[1].iov_len = call->len; + ssize_t l = writev(call->fd, iov, 2); len = (l > -1) ? len + l : l; } + wma_printf(10, "wma < %d\n", len); + return len; } diff --git a/libeplayer3-arm/output/writer/sh4/wmv.c b/libeplayer3-arm/output/writer/sh4/wmv.c index cc61134..9a644d9 100644 --- a/libeplayer3-arm/output/writer/sh4/wmv.c +++ b/libeplayer3-arm/output/writer/sh4/wmv.c @@ -128,31 +128,40 @@ static int reset() static int writeData(void *_call) { WriterAVCallData_t *call = (WriterAVCallData_t *) _call; + awmv_t private_data; int len = 0; + wmv_printf(10, "\n"); + if (call == NULL) { wmv_err("call data is NULL...\n"); return 0; } + if ((call->data == NULL) || (call->len <= 0)) { wmv_err("parsing NULL Data. ignoring...\n"); return 0; } + if (call->fd < 0) { wmv_err("file pointer < 0. ignoring ...\n"); return 0; } + wmv_printf(10, "VideoPts %lld\n", call->Pts); wmv_printf(10, "Got Private Size %d\n", call->private_size); + memcpy(private_data.privateData, call->private_data, call->private_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->private_size); + private_data.width = call->Width; private_data.height = call->Height; private_data.framerate = call->FrameRate; + #define PES_MIN_HEADER_SIZE 9 if (initialHeader) { @@ -160,16 +169,22 @@ static int writeData(void *_call) unsigned char *PesPtr; unsigned int MetadataLength; unsigned int crazyFramerate = 0; + wmv_printf(10, "Framerate: %u\n", private_data.framerate); wmv_printf(10, "biWidth: %d\n", private_data.width); wmv_printf(10, "biHeight: %d\n", private_data.height); + crazyFramerate = ((10000000.0 / private_data.framerate) * 1000.0); wmv_printf(10, "crazyFramerate: %u\n", crazyFramerate); + PesPtr = &PesPacket[PES_MIN_HEADER_SIZE]; + memcpy(PesPtr, Metadata, sizeof(Metadata)); PesPtr += METADATA_STRUCT_C_START; + memcpy(PesPtr, private_data.privateData, WMV3_PRIVATE_DATA_LENGTH); PesPtr += WMV3_PRIVATE_DATA_LENGTH; + /* Metadata Header Struct A */ *PesPtr++ = (private_data.height >> 0) & 0xff; *PesPtr++ = (private_data.height >> 8) & 0xff; @@ -179,16 +194,23 @@ static int writeData(void *_call) *PesPtr++ = (private_data.width >> 8) & 0xff; *PesPtr++ = (private_data.width >> 16) & 0xff; *PesPtr++ = private_data.width >> 24; + PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ + *PesPtr++ = (crazyFramerate >> 0) & 0xff; *PesPtr++ = (crazyFramerate >> 8) & 0xff; *PesPtr++ = (crazyFramerate >> 16) & 0xff; *PesPtr++ = crazyFramerate >> 24; + MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE]; + int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + len = write(call->fd, PesPacket, HeaderLength + MetadataLength); + initialHeader = 0; } + if (call->len > 0 && call->data) { unsigned int Position = 0; @@ -197,12 +219,16 @@ static int writeData(void *_call) { int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? (call->len - Position) : MAX_PES_PACKET_SIZE; + int Remaining = call->len - Position - PacketLength; + wmv_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", PacketLength, Remaining, Position); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; memset(PesHeader, '0', PES_MAX_HEADER_SIZE); int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, call->Pts, 0); unsigned char *PacketStart; + if (insertSampleHeader) { unsigned int PesLength; @@ -215,18 +241,23 @@ static int writeData(void *_call) PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; + HeaderLength += PrivateHeaderLength; insertSampleHeader = 0; } + PacketStart = malloc(call->len + HeaderLength); memcpy(PacketStart, PesHeader, HeaderLength); memcpy(PacketStart + HeaderLength, call->data + Position, PacketLength); + len = write(call->fd, PacketStart, PacketLength + HeaderLength); free(PacketStart); + Position += PacketLength; call->Pts = INVALID_PTS_VALUE; } } + wmv_printf(10, "< %d\n", len); return len; } diff --git a/libeplayer3-arm/output/writer/sh4/writer.c b/libeplayer3-arm/output/writer/sh4/writer.c index a9d8548..1ac9cf2 100644 --- a/libeplayer3-arm/output/writer/sh4/writer.c +++ b/libeplayer3-arm/output/writer/sh4/writer.c @@ -100,6 +100,7 @@ static Writer_t *AvailableWriter[] = Writer_t *getWriter(char *encoding) { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0) @@ -108,13 +109,16 @@ Writer_t *getWriter(char *encoding) return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, encoding); + return NULL; } Writer_t *getDefaultVideoWriter() { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0) @@ -123,13 +127,16 @@ Writer_t *getDefaultVideoWriter() return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found\n", __func__); + return NULL; } Writer_t *getDefaultAudioWriter() { int i; + for (i = 0; AvailableWriter[i] != NULL; i++) { if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0) @@ -138,6 +145,8 @@ Writer_t *getDefaultAudioWriter() return AvailableWriter[i]; } } + writer_printf(1, "%s: no writer found\n", __func__); + return NULL; } diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index bac6adb..6ed983e 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -114,7 +114,7 @@ bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback) ret = true; break; } - + if (playbackDieNowCallbacks[i] == NULL) { playbackDieNowCallbacks[i] = callback; @@ -135,6 +135,7 @@ static void SupervisorThread(Context_t *context) { hasThreadStarted = 1; playback_printf(10, ">\n"); + while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) { usleep(100000); @@ -158,19 +159,26 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) { PlaybackStop(context); } + char *uri = pFiles->szFirstFile; + playback_printf(10, "URI=%s\n", uri); + if (context->playback->isPlaying) { // shouldn't happen playback_err("playback already running\n"); return cERR_PLAYBACK_ERROR; } + char *extension = NULL; + context->playback->uri = strdup(uri); + context->playback->isFile = 0; context->playback->isHttp = 0; context->playback->noprobe = 0; + if (!strncmp("file://", uri, 7) || !strncmp("myts://", uri, 7)) { context->playback->isFile = 1; @@ -183,6 +191,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) { context->playback->noprobe = 0; } + extension = getExtension(context->playback->uri + 7); if (!extension) { @@ -207,6 +216,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) free(context->playback->uri); context->playback->uri = tUri; } + if (strstr(uri, ":10000") || strstr(uri, ":31339/id=")) { context->playback->noprobe = 1; @@ -217,6 +227,7 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) playback_err("Unknown stream (%s)\n", uri); return cERR_PLAYBACK_ERROR; } + pFiles->szFirstFile = context->playback->uri; if ((context->container->Command(context, CONTAINER_ADD, extension) < 0) || (!context->container->selectedContainer) || @@ -225,20 +236,26 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) playback_err("CONTAINER_ADD failed\n"); return cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value 0\n"); + return cERR_PLAYBACK_NO_ERROR; } static int PlaybackClose(Context_t *context) { int ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + if (context->container->Command(context, CONTAINER_DEL, NULL) < 0) { playback_err("container delete failed\n"); } + context->manager->audio->Command(context, MANAGER_DEL, NULL); context->manager->video->Command(context, MANAGER_DEL, NULL); + context->playback->isPaused = 0; context->playback->isPlaying = 0; context->playback->isForwarding = 0; @@ -250,8 +267,10 @@ static int PlaybackClose(Context_t *context) free(context->playback->uri); context->playback->uri = NULL; } + PlaybackDieNow(2); playback_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -259,13 +278,17 @@ static int PlaybackPlay(Context_t *context) { pthread_attr_t attr; int ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + if (!context->playback->isPlaying) { context->playback->AVSync = 1; context->output->Command(context, OUTPUT_AVSYNC, NULL); + context->playback->isCreationPhase = 1; // allows the created thread to go into wait mode ret = context->output->Command(context, OUTPUT_PLAY, NULL); + if (ret != 0) { playback_err("OUTPUT_PLAY failed!\n"); @@ -287,6 +310,7 @@ static int PlaybackPlay(Context_t *context) context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 1; + if (hasThreadStarted == 0) { int error; @@ -302,13 +326,17 @@ static int PlaybackPlay(Context_t *context) playback_printf(10, "Created thread\n"); } } + playback_printf(10, "clearing isCreationPhase!\n"); + context->playback->isCreationPhase = 0; // allow thread to go into next state + ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL); if (ret != 0) { playback_err("CONTAINER_PLAY failed!\n"); } + } } else @@ -316,19 +344,25 @@ static int PlaybackPlay(Context_t *context) playback_err("playback already running\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int PlaybackPause(Context_t *context) { int ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + if (context->playback->isPlaying && !context->playback->isPaused) { if (context->playback->SlowMotion) context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output->Command(context, OUTPUT_PAUSE, NULL); + context->playback->isPaused = 1; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; @@ -341,6 +375,7 @@ static int PlaybackPause(Context_t *context) playback_err("playback not playing or already in pause mode\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); return ret; } @@ -348,15 +383,19 @@ static int PlaybackPause(Context_t *context) static int32_t PlaybackContinue(Context_t *context) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + if (context->playback->isPlaying && (context->playback->isPaused || context->playback->isForwarding || context->playback->BackWard || context->playback->SlowMotion)) { if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard) context->output->Command(context, OUTPUT_CLEAR, NULL); + if (context->playback->BackWard) context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); + context->playback->isPaused = 0; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; @@ -370,6 +409,7 @@ static int32_t PlaybackContinue(Context_t *context) playback_err("continue not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); return ret; } @@ -378,34 +418,43 @@ static int32_t PlaybackStop(Context_t *context) { int32_t ret = cERR_PLAYBACK_NO_ERROR; int wait_time = 20; + playback_printf(10, "\n"); + PlaybackDieNow(1); + if (context && context->playback && context->playback->isPlaying) { + context->playback->isPaused = 0; context->playback->isPlaying = 0; context->playback->isForwarding = 0; context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 0; + context->output->Command(context, OUTPUT_STOP, NULL); context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); + } else { playback_err("stop not possible\n"); ret = cERR_PLAYBACK_ERROR; } + while ((hasThreadStarted == 1) && (--wait_time) > 0) { playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); usleep(100000); } + if (wait_time == 0) { playback_err("Timeout waiting for thread!\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); return ret; } @@ -413,16 +462,22 @@ static int32_t PlaybackStop(Context_t *context) static int32_t PlaybackTerminate(Context_t *context) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + int wait_time = 20; + playback_printf(20, "\n"); + PlaybackDieNow(1); + if (context && context->playback && context->playback->isPlaying) { //First Flush and than delete container, else e2 cant read length of file anymore + if (context->output->Command(context, OUTPUT_FLUSH, NULL) < 0) { playback_err("failed to flush output.\n"); } + context->playback->isPaused = 0; context->playback->isPlaying = 0; context->playback->isForwarding = 0; @@ -435,21 +490,25 @@ static int32_t PlaybackTerminate(Context_t *context) else { playback_err("%p %p %d\n", context, context->playback, context->playback->isPlaying); + /* fixme: konfetti: we should return an error here but this seems to be a condition which * can happen and is not a real error, which leads to a dead neutrino. should investigate * here later. */ } + while ((hasThreadStarted == 1) && (--wait_time) > 0) { playback_printf(10, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); usleep(100000); } + if (wait_time == 0) { playback_err("Timeout waiting for thread!\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(20, "exiting with value %d\n", ret); return ret; } @@ -457,7 +516,9 @@ static int32_t PlaybackTerminate(Context_t *context) static int PlaybackFastForward(Context_t *context, int *speed) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "speed %d\n", *speed); + /* Audio only forwarding not supported */ if (context->playback->isVideo && !context->playback->isHttp && !context->playback->BackWard && (!context->playback->isPaused || context->playback->isPlaying)) { @@ -477,14 +538,18 @@ static int PlaybackFastForward(Context_t *context, int *speed) playback_err("fast forward not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int PlaybackFastBackward(Context_t *context, int *speed) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "speed = %d\n", *speed); + /* Audio only reverse play not supported */ if (context->playback->isVideo && !context->playback->isForwarding && (!context->playback->isPaused || context->playback->isPlaying)) @@ -508,6 +573,7 @@ static int PlaybackFastBackward(Context_t *context, int *speed) context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); } + context->output->Command(context, OUTPUT_CLEAR, NULL); } else @@ -515,15 +581,19 @@ static int PlaybackFastBackward(Context_t *context, int *speed) playback_err("fast backward not possible\n"); ret = cERR_PLAYBACK_ERROR; } + context->playback->isSeeking = 0; playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackSlowMotion(Context_t *context, int *speed) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + //Audio only forwarding not supported if (context->playback->isVideo && !context->playback->isHttp && context->playback->isPlaying) { @@ -549,14 +619,18 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed) playback_err("slowmotion not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "pos: %lldd\n", *pos); + if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused) { context->playback->isSeeking = 1; @@ -576,15 +650,20 @@ static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute) playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackPts(Context_t *context, int64_t *pts) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(20, "\n"); + *pts = 0; + if (context->playback->isPlaying) { ret = context->output->Command(context, OUTPUT_PTS, pts); @@ -594,15 +673,20 @@ static int32_t PlaybackPts(Context_t *context, int64_t *pts) playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(20, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount) { int ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(20, "\n"); + *frameCount = 0; + if (context->playback->isPlaying) { ret = context->output->Command(context, OUTPUT_GET_FRAME_COUNT, frameCount); @@ -612,15 +696,20 @@ static int32_t PlaybackGetFrameCount(Context_t *context, uint64_t *frameCount) playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(20, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackLength(Context_t *context, int64_t *length) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(20, "\n"); + *length = -1; + if (context->playback->isPlaying) { if (context->container && context->container->selectedContainer) @@ -633,6 +722,7 @@ static int32_t PlaybackLength(Context_t *context, int64_t *length) playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(20, "exiting with value %d\n", ret); return ret; } @@ -642,7 +732,9 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track) int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t curtrackid = 0; int32_t nextrackid = 0; + playback_printf(10, "\n"); + if (context && context->playback && context->playback->isPlaying) { if (context->manager && context->manager->audio) @@ -656,13 +748,16 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track) playback_err("switch audio not possible\n"); ret = cERR_PLAYBACK_ERROR; } + if (nextrackid != curtrackid) { + //PlaybackPause(context); if (context->output && context->output->audio) { context->output->audio->Command(context, OUTPUT_SWITCH, (void *)"audio"); } + if (context->container && context->container->selectedContainer) { context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, &nextrackid); @@ -675,6 +770,7 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track) playback_err("switch audio not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); return ret; } @@ -684,7 +780,9 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track) int32_t ret = cERR_PLAYBACK_NO_ERROR; int32_t curtrackid = -1; int32_t nextrackid = -1; + playback_printf(10, "Track: %d\n", *track); + if (context && context->playback && context->playback->isPlaying) { if (context->manager && context->manager->subtitle) @@ -692,12 +790,14 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track) context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); context->manager->subtitle->Command(context, MANAGER_SET, track); context->manager->subtitle->Command(context, MANAGER_GET, &nextrackid); + if (curtrackid != nextrackid && nextrackid > -1) { if (context->output && context->output->subtitle) { context->output->subtitle->Command(context, OUTPUT_SWITCH, (void *)"subtitle"); } + if (context->container && context->container->selectedContainer) { context->container->selectedContainer->Command(context, CONTAINER_SWITCH_SUBTITLE, &nextrackid); @@ -715,14 +815,18 @@ static int32_t PlaybackSwitchSubtitle(Context_t *context, int32_t *track) playback_err("not possible\n"); ret = cERR_PLAYBACK_ERROR; } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackInfo(Context_t *context, char **infoString) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(10, "\n"); + /* konfetti comment: * removed if clause here (playback running) because its * not necessary for all container. e.g. in case of ffmpeg @@ -732,7 +836,9 @@ static int32_t PlaybackInfo(Context_t *context, char **infoString) { context->container->selectedContainer->Command(context, CONTAINER_INFO, infoString); } + playback_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -742,13 +848,17 @@ static int PlaybackMetadata(Context_t *context, char ***metadata) if (context->container && context->container->selectedContainer) context->container->selectedContainer->Command(context, CONTAINER_GET_METADATA, metadata); + return ret; } static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + playback_printf(20, "Command %d\n", command); + + switch (command) { case PLAYBACK_OPEN: @@ -851,7 +961,9 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument ret = cERR_PLAYBACK_ERROR; break; } + playback_printf(20, "exiting with value %d\n", ret); + return ret; }