From b952546a3a8dcf7978ca95bfc8ba5eea385a1c93 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 8 Feb 2018 20:42:15 +0100 Subject: [PATCH 01/72] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/9a7b46f8a39baa0d84eb41af7d9e05ab3ee31199 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 5951cbef51e43d12012b010fbdff0719afb62a5b Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:34:01 +0100 Subject: [PATCH 02/72] fix OUTPUT_PLAY error handling Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/0a2767edd29c7f8e496bd1764a37c0ae221c119f 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 a357d08b456f25e6fa5bc0ddfee8fcfdca350e79 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 10 Feb 2018 20:41:24 +0100 Subject: [PATCH 03/72] 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/c1cbb167142abf096507bb886b830f1f58d23498 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 0b3bcc162899c65612423e544c73048bc626a5da Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sun, 11 Feb 2018 12:01:19 +0100 Subject: [PATCH 04/72] supplement to 4bd66ae15da86b413d6de64c51b3471dd8bc801a, fix segfault with only audio stream Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e93920680b66ddc356ebf8c97d86df660f167616 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 e6c5999d1d6347e86828c62f387854f6d46520db Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 6 Mar 2018 19:08:31 +0100 Subject: [PATCH 05/72] libeplayer3-arm: reduce compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/1f4b3a3bb44c6acee0773d14c3e521b2e49e240e 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 59b0eeba27535a97a38f1cd7df7a511fc54250e2 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 7 Mar 2018 23:59:23 +0100 Subject: [PATCH 06/72] libeplayer3-arm: cleanup types, use Context_t in commands Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/98823b7457003bbda66da42dba234aee4b14eedd 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 c10bbaba6be5f68973d955e6e2ded1575d73f743 Mon Sep 17 00:00:00 2001 From: BPanther Date: Sat, 10 Mar 2018 23:20:23 +0100 Subject: [PATCH 07/72] missing brightness added for ufs922, hdbox, octagon1008, mini2, av7500 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/73375302f4f43d5f49bb4cdb1cb9d3d517e7bed3 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 31544a2bf0478b34549542702f5d8774b554695b Mon Sep 17 00:00:00 2001 From: vanhofen Date: Sun, 11 Mar 2018 22:41:07 +0100 Subject: [PATCH 08/72] introduce caps.has_button_timer Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/8cd107e8e003a3455f664b7dfd275383135d83f7 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 791e906695986a3b8203b627d577ab0ea0fb0968 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 13 Mar 2018 12:03:28 +0100 Subject: [PATCH 09/72] 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/c9c90ad6d68392d2405bfd16b65e6ff4260e188b 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 f19c639e948ddd0a5de586b21d44ff87e64f984b Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 13 Mar 2018 12:55:59 +0100 Subject: [PATCH 10/72] h264 writer - Revert not intended test change Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b5a0c5016be29d0bea1a483f16996f7b81ff7fbb 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 b2aae77f0b29d6f1c5e0f5d196cc4a92a667e9ad Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sun, 18 Mar 2018 01:16:08 +0100 Subject: [PATCH 11/72] 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/9434ba80d0a8251522ae8da0d08ddd02f3a48e39 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 f1fa42979d25ff2fe6b33887f91f627083093245 Mon Sep 17 00:00:00 2001 From: max_10 Date: Sun, 18 Mar 2018 01:21:50 +0100 Subject: [PATCH 12/72] container_ffmpeg: fix Write from incompatible pointer type Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e3dd0e2b1c46e52d0915cf55e459d1e24da411a3 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 6120fcb478f042b272f2182ce1563d9e4cad28a8 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 20 Mar 2018 11:42:39 +0100 Subject: [PATCH 13/72] armbox: fix video policy again Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/46a8c49f8732be1fd3b4073b4f0d8a5916cf2210 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 ef8bc55..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", "bestfit", "letterbox", "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 ecb8ec42ee2f9ae6316dd4350df94694aa4f9f7f Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 21 Mar 2018 01:53:22 +0100 Subject: [PATCH 14/72] all: clean up cDemux headers Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/1dd4f504523642e194ab98718feedd04724b9026 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 3ca8baf0466cd3a921b0c132bda092a65c99578e Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 22 Mar 2018 21:20:06 +0100 Subject: [PATCH 15/72] all: clean up pwrmngr header file Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/bbeed3bed02d82090381720239e201385afbff6d 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 fa47e0a8358ca6948b491ac70c8d57533abf315a Mon Sep 17 00:00:00 2001 From: TangoCash Date: Mon, 2 Apr 2018 16:04:13 +0200 Subject: [PATCH 16/72] fix generic compile Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e52fc4fe86508cc589f2cb7f90614d1b2d449f86 Author: TangoCash Date: 2018-04-02 (Mon, 02 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- generic-pc/playback_gst_10.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/generic-pc/playback_gst_10.cpp b/generic-pc/playback_gst_10.cpp index 08bc508..063027d 100644 --- a/generic-pc/playback_gst_10.cpp +++ b/generic-pc/playback_gst_10.cpp @@ -30,7 +30,6 @@ #include #include -#include "dmx_lib.h" #include "audio_lib.h" #include "video_lib.h" #include "glfb.h" From 717224d5b910809de28db5fc7f319c2090e71746 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Fri, 30 Mar 2018 14:29:35 +0200 Subject: [PATCH 17/72] 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/ed672424a95bc683e48ab1f36806417b0603cff4 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 e43ab45859b691444997ab4d9a1a162cc0b9b4a3 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sat, 31 Mar 2018 11:39:41 +0200 Subject: [PATCH 18/72] 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/d31e113cda6cd52c2cd7cbf075907581c5a23573 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 793c6d5a2641c88e4e637351ac044b41eb30e276 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Mon, 2 Apr 2018 23:59:24 +0200 Subject: [PATCH 19/72] 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/c03d29098e528c1b041b2d2d836a472d78a3ce5f 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 e6c1b4625532f2a0e2f78aeec0b96d05d62eec53 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 3 Apr 2018 00:00:54 +0200 Subject: [PATCH 20/72] 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/b470289e55ea36d810afb60d6532e3ee69352fab 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 b8088c6330a890d978d3d9e80711a536ab3e7efc Mon Sep 17 00:00:00 2001 From: samsamsam Date: Tue, 3 Apr 2018 09:37:33 +0200 Subject: [PATCH 21/72] 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/9b7e34ef16baa8a6b675bbfe54599f7bf9d72b3d 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 07d618980a2a4f2e8fef058589057d4c119b8fa8 Mon Sep 17 00:00:00 2001 From: samsamsam Date: Thu, 5 Apr 2018 21:50:52 +0200 Subject: [PATCH 22/72] 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/7899747ceaca55ab66f7aec758b63723d037164b 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 02cab4374494aafdd12a9bdf238b809a4fc2e3c5 Mon Sep 17 00:00:00 2001 From: max_10 Date: Tue, 10 Apr 2018 11:31:57 +0200 Subject: [PATCH 23/72] 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/d444bee65af61ac6312a0463002fc56fa9411f1a 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; } From fcf1e93bfa3d437223b2d65ed7a74560fb73b2ae Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sat, 7 Apr 2018 12:47:45 +0200 Subject: [PATCH 24/72] Add possibility to provide moov atom data as separate file. This will allow playback of MP4 files which are under download and moov atom is located at the end of file. Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b08408fc9f99b7c5eb7b3438d2ea2faebe9c929e Author: samsamsam Date: 2018-04-07 (Sat, 07 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 155 ++++++++++++++++--- libeplayer3-arm/include/common.h | 8 +- libeplayer3-arm/main/exteplayer.c | 63 +++++--- libeplayer3-arm/output/writer/mipsel/h264.c | 2 +- libeplayer3-arm/output/writer/sh4/h264.c | 23 ++- 5 files changed, 198 insertions(+), 53 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index f0f17c6..a8b4f46 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -1353,40 +1353,142 @@ static int32_t interrupt_cb(void *ctx) } #ifdef SAM_CUSTOM_IO +typedef struct CustomIOCtx_t +{ + FILE *pFile; + FILE *pMoovFile; + int64_t iOffset; + + char *szFile; + uint64_t iFileSize; + char *szMoovAtomFile; + uint64_t iMoovAtomOffset; +} CustomIOCtx_t; + +CustomIOCtx_t *custom_io_tab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL}; + int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize) { - size_t ret = fread((void *) buffer, (size_t) 1, (size_t) lSize, (FILE *)ptr); - return (int)ret; + CustomIOCtx_t *io = (CustomIOCtx_t *)ptr; + int ret = 0; + + if (!io->pMoovFile) + { + ret = (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pFile); + } + else + { + if (io->iOffset < io->iMoovAtomOffset) + { + ret = (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pFile); + buffer += ret; + lSize -= ret; + } + + if (io->iOffset + ret >= io->iMoovAtomOffset) + { + if (ret) + { + if (fseeko(io->pMoovFile, io->iOffset + ret - io->iMoovAtomOffset, SEEK_SET)) + { + // something goes wrong + ffmpeg_err("fseeko on moov atom file fail \n"); + lSize = 0; + } + } + + ret += (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pMoovFile); + } + + io->iOffset += ret; + } + return ret; } // whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence) { - if (AVSEEK_SIZE == whence) + CustomIOCtx_t *io = (CustomIOCtx_t *)ptr; + int64_t ret = -1; + if (!io->pMoovFile) { - return -1; + if (AVSEEK_SIZE != whence) + { + ret = (int64_t)fseeko(io->pFile, (off_t)pos, whence); + if (0 == ret) + { + ret = (int64_t)ftello(io->pFile); + } + } } - int ret = fseeko((FILE *)ptr, (off_t)pos, whence); - if (0 == ret) + else { - return (off_t)ftello((FILE *)ptr); + switch (whence) + { + case SEEK_SET: + ret = pos; + break; + case SEEK_CUR: + ret += pos; + break; + case SEEK_END: + ret = io->iFileSize + pos; + break; + case AVSEEK_SIZE: + return io->iFileSize; + default: + return -1; + } + + if (ret >= 0 && ret <= io->iFileSize) + { + if (ret < io->iMoovAtomOffset) + { + if (!fseeko(io->pFile, (off_t)ret, SEEK_SET)) + io->iOffset = ret; + else + ret = -1; + } + else + { + if (!fseeko(io->pMoovFile, (off_t)(ret - io->iMoovAtomOffset), SEEK_SET)) + io->iOffset = ret; + else + ret = -1; + } + } + else + { + ret = -1; + } } return ret; } -AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_buffer_size) +AVIOContext *container_ffmpeg_get_avio_context(CustomIOCtx_t *custom_io, size_t avio_ctx_buffer_size) { - if (strstr(filename, "file://") == filename) - { - filename += 7; - } + if (strstr(custom_io->szFile, "file://") == custom_io->szFile) + custom_io->szFile += 7; - FILE *pFile = fopen(filename, "rb"); - if (NULL == pFile) + custom_io->pFile = fopen(custom_io->szFile, "rb"); + if (NULL == custom_io->pFile) { return NULL; } + if (custom_io->szMoovAtomFile && custom_io->szMoovAtomFile[0] != '\0') + { + if (strstr(custom_io->szMoovAtomFile, "file://") == custom_io->szMoovAtomFile) + custom_io->szMoovAtomFile += 7; + + custom_io->pMoovFile = fopen(custom_io->szMoovAtomFile, "rb"); + if (NULL == custom_io->pMoovFile) + { + fclose(custom_io->pFile); + return NULL; + } + } + AVIOContext *avio_ctx = NULL; uint8_t *avio_ctx_buffer = NULL; @@ -1395,7 +1497,7 @@ AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_b { return NULL; } - avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, pFile, &SAM_ReadFunc, NULL, &SAM_SeekFunc); + avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, custom_io, &SAM_ReadFunc, NULL, &SAM_SeekFunc); if (!avio_ctx) { return NULL; @@ -1404,7 +1506,7 @@ AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_b } #endif -int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int32_t AVIdx) +int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uint64_t fileSize, char *moovAtomFile, uint64_t moovAtomOffset, int32_t AVIdx) { int32_t err = 0; AVInputFormat *fmt = NULL; @@ -1416,7 +1518,16 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int if (0 == strstr(filename, "://") || 0 == strncmp(filename, "file://", 7)) { - AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096); + AVIOContext *avio_ctx = NULL; + custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t)); + sizeof(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t)); + + custom_io_tab[AVIdx]->szFile = filename; + custom_io_tab[AVIdx]->iFileSize = fileSize; + custom_io_tab[AVIdx]->szMoovAtomFile = moovAtomFile; + custom_io_tab[AVIdx]->iMoovAtomOffset = moovAtomOffset; + + avio_ctx = container_ffmpeg_get_avio_context(custom_io_tab[AVIdx], 4096); if (avio_ctx) { avContextTab[AVIdx]->pb = avio_ctx; @@ -1424,6 +1535,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int } else { + free(custom_io_tab[AVIdx]); + custom_io_tab[AVIdx] = NULL; return cERR_CONTAINER_FFMPEG_OPEN; } } @@ -1782,15 +1895,17 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) av_log_set_callback(ffmpeg_silen_callback); context->playback->abortRequested = 0; - int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0); + int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ + playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); if (0 != res) { return res; } - if (playFilesNames->szSecondFile) + if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0') { - res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1); + res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \ + playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); } if (0 != res) diff --git a/libeplayer3-arm/include/common.h b/libeplayer3-arm/include/common.h index ae0f4d9..993f5b6 100644 --- a/libeplayer3-arm/include/common.h +++ b/libeplayer3-arm/include/common.h @@ -9,12 +9,16 @@ #include "playback.h" #include -typedef char PlayFilesTab_t[2]; - typedef struct PlayFiles_t { char *szFirstFile; char *szSecondFile; + char *szFirstMoovAtomFile; + char *szSecondMoovAtomFile; + uint64_t iFirstFileSize; + uint64_t iSecondFileSize; + uint64_t iFirstMoovAtomOffset; + uint64_t iSecondMoovAtomOffset; } PlayFiles_t; typedef struct Context_s diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index a6e0aea..85ab823 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -504,14 +504,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, uint32_t *linuxDvbBufferSizeMB) +static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, 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:b:")) != -1) + while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:F:S:O:")) != -1) { switch (c) { @@ -572,8 +572,13 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *subtitleTrackIdx = atoi(optarg); break; case 'x': - strncpy(audioFile, optarg, IPTV_MAX_FILE_PATH - 1); - map_inter_file_path(audioFile); + if (optarg[0] != '\0') + { + playbackFiles->szSecondFile = malloc(IPTV_MAX_FILE_PATH); + strncpy(playbackFiles->szSecondFile, optarg, IPTV_MAX_FILE_PATH - 1); + playbackFiles->szSecondFile[IPTV_MAX_FILE_PATH] = '\0'; + map_inter_file_path(playbackFiles->szSecondFile); + } break; case 'h': ffmpeg_av_dict_set("headers", optarg, 0); @@ -624,6 +629,21 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int case 'b': *linuxDvbBufferSizeMB = 1024 * 1024 * atoi(optarg); break; + case 'S': + playbackFiles->iFirstFileSize = (uint64_t) strtoull(optarg, (char **)NULL, 10); + break; + case 'O': + playbackFiles->iFirstMoovAtomOffset = (uint64_t) strtoull(optarg, (char **)NULL, 10); + break; + case 'F': + if (optarg[0] != '\0') + { + playbackFiles->szFirstMoovAtomFile = malloc(IPTV_MAX_FILE_PATH); + strncpy(playbackFiles->szFirstMoovAtomFile, optarg, IPTV_MAX_FILE_PATH - 1); + playbackFiles->szFirstMoovAtomFile[IPTV_MAX_FILE_PATH] = '\0'; + map_inter_file_path(playbackFiles->szFirstMoovAtomFile); + } + break; default: printf("?? getopt returned character code 0%o ??\n", c); ret = -1; @@ -633,14 +653,15 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int if (0 == ret && optind < argc) { ret = 0; - + playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH); if (NULL == strstr(argv[optind], "://")) { - strcpy(file, "file://"); + strcpy(playbackFiles->szFirstFile, "file://"); } - strcat(file, argv[optind]); - map_inter_file_path(file); - printf("file: [%s]\n", file); + strcat(playbackFiles->szFirstFile, argv[optind]); + playbackFiles->szFirstFile[IPTV_MAX_FILE_PATH] = '\0'; + map_inter_file_path(playbackFiles->szFirstFile); + printf("file: [%s]\n", playbackFiles->szFirstFile); ++optind; } else @@ -654,11 +675,6 @@ int main(int argc, char *argv[]) { pthread_t termThread; 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; @@ -669,9 +685,11 @@ 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", 45); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 46); - if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB)) + PlayFiles_t playbackFiles; + memset(&playbackFiles, 0x00, sizeof(playbackFiles)); + if (0 != ParseParams(argc, argv, &playbackFiles, &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"); @@ -701,6 +719,9 @@ int main(int argc, char *argv[]) printf("[-0 idx] video MPEG-DASH representation index\n"); printf("[-1 idx] audio MPEG-DASH representation index\n"); printf("[-f ffopt=ffval] any other ffmpeg option\n"); + printf("[-F path to additional file with moov atom data (used for mp4 playback in progressive download mode)\n"); + printf("[-O moov atom offset in the original file (used for mp4 playback in progressive download mode)\n"); + printf("[-S remote file size (used for mp4 playback in progressive download mode)\n"); exit(1); } @@ -762,19 +783,13 @@ int main(int argc, char *argv[]) g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack); - if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4)) + if (strncmp(playbackFiles.szFirstFile, "rtmp", 4) && strncmp(playbackFiles.szFirstFile, "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); + fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, playbackFiles.szFirstFile, commandRetVal); if (commandRetVal < 0) { if (NULL != g_player) diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index 8fe4be9..b5b37da 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -396,7 +396,7 @@ static int writeData(WriterAVCallData_t *call) ic = 0; iov[ic++].iov_base = PesHeader; - //if (initialHeader) + if (!avc3) { if (CodecData) { diff --git a/libeplayer3-arm/output/writer/sh4/h264.c b/libeplayer3-arm/output/writer/sh4/h264.c index 39a6afa..3172c5b 100644 --- a/libeplayer3-arm/output/writer/sh4/h264.c +++ b/libeplayer3-arm/output/writer/sh4/h264.c @@ -100,7 +100,7 @@ const uint8_t Head[] = {0, 0, 0, 1}; static int32_t initialHeader = 1; static uint32_t NalLengthBytes = 1; static int avc3 = 0; - +static int sps_pps_in_stream = 0; /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -263,12 +263,23 @@ static int32_t writeData(void *_call) (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 i = 0; + uint8_t InsertPrivData = !sps_pps_in_stream; uint32_t PacketLength = 0; - uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE; - + uint32_t FakeStartCode = PES_VERSION_FAKE_START_CODE; iov[ic++].iov_base = PesHeader; - initialHeader = 0; - if (initialHeader) + + 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))) + { + 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; @@ -299,7 +310,7 @@ static int32_t writeData(void *_call) return 0; } - if (initialHeader) + if (!avc3) { uint8_t *private_data = call->private_data; uint32_t private_size = call->private_size; From 4d2f9d3513216e26fecfac4efea24cafbd3dadbb Mon Sep 17 00:00:00 2001 From: samsamsam Date: Sat, 7 Apr 2018 17:48:05 +0200 Subject: [PATCH 25/72] Fix wrong playback file name Signed-off-by: max_10 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/45ca7f69b7acf4ac8e0beb1ce3327bf6acce5e38 Author: samsamsam Date: 2018-04-07 (Sat, 07 Apr 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 5 ++++- libeplayer3-arm/output/linuxdvb_buffering.c | 6 ++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 85ab823..b2065de 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -575,6 +575,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * if (optarg[0] != '\0') { playbackFiles->szSecondFile = malloc(IPTV_MAX_FILE_PATH); + playbackFiles->szSecondFile[0] = '\0'; strncpy(playbackFiles->szSecondFile, optarg, IPTV_MAX_FILE_PATH - 1); playbackFiles->szSecondFile[IPTV_MAX_FILE_PATH] = '\0'; map_inter_file_path(playbackFiles->szSecondFile); @@ -639,6 +640,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * if (optarg[0] != '\0') { playbackFiles->szFirstMoovAtomFile = malloc(IPTV_MAX_FILE_PATH); + playbackFiles->szFirstMoovAtomFile[0] = '\0'; strncpy(playbackFiles->szFirstMoovAtomFile, optarg, IPTV_MAX_FILE_PATH - 1); playbackFiles->szFirstMoovAtomFile[IPTV_MAX_FILE_PATH] = '\0'; map_inter_file_path(playbackFiles->szFirstMoovAtomFile); @@ -654,6 +656,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * { ret = 0; playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH); + playbackFiles->szFirstFile[0] = '\0'; if (NULL == strstr(argv[optind], "://")) { strcpy(playbackFiles->szFirstFile, "file://"); @@ -685,7 +688,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", 46); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 47); PlayFiles_t playbackFiles; memset(&playbackFiles, 0x00, sizeof(playbackFiles)); diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index 2fc472f..f66b471 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "common.h" #include "misc.h" @@ -309,8 +310,13 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) pthread_cond_signal(&bufferingdDataAddedCond); /* wait for thread end */ +#if 0 + /* This code couse symbol versioning of clock_gettime@GLIBC_2.17 */ clock_gettime(CLOCK_REALTIME, &max_wait); max_wait.tv_sec += 1; +#else + max_wait.tv_sec = time(NULL) + 2; +#endif pthread_cond_timedwait(&bufferingExitCond, &bufferingMtx, &max_wait); pthread_mutex_unlock(&bufferingMtx); From 6e9c5688f069590265e1b063d027c5912a3cd7b7 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 11 Apr 2018 23:02:02 +0200 Subject: [PATCH 26/72] bugfix-last-commits Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b2d616f3fc09b91da0e2ac9a5cdd234e1de5019c Author: max_10 Date: 2018-04-11 (Wed, 11 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/playback_libeplayer3.cpp | 2 +- libeplayer3-arm/container/container_ffmpeg.c | 21 ++++++++++++-------- 2 files changed, 14 insertions(+), 9 deletions(-) diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index c5acdba..83a75ae 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -117,7 +117,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in } else isHTTP = true; - PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL}; + PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0}; if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 0) { if (pm == PLAYMODE_TS) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index a8b4f46..7cb9fab 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -1378,14 +1378,14 @@ int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize) } else { - if (io->iOffset < io->iMoovAtomOffset) + if ((uint64_t)io->iOffset < io->iMoovAtomOffset) { ret = (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pFile); buffer += ret; lSize -= ret; } - if (io->iOffset + ret >= io->iMoovAtomOffset) + if ((uint64_t)io->iOffset + ret >= io->iMoovAtomOffset) { if (ret) { @@ -1440,12 +1440,12 @@ int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence) return -1; } - if (ret >= 0 && ret <= io->iFileSize) + if (ret >= 0 && (uint64_t)ret <= io->iFileSize) { - if (ret < io->iMoovAtomOffset) + if ((uint64_t)ret < io->iMoovAtomOffset) { if (!fseeko(io->pFile, (off_t)ret, SEEK_SET)) - io->iOffset = ret; + io->iOffset = (uint64_t)ret; else ret = -1; } @@ -1520,7 +1520,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin { AVIOContext *avio_ctx = NULL; custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t)); - sizeof(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t)); + memset(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t)); custom_io_tab[AVIdx]->szFile = filename; custom_io_tab[AVIdx]->iFileSize = fileSize; @@ -2690,7 +2690,12 @@ static int32_t container_ffmpeg_stop(Context_t *context) * avformat_close_input do not expect custom io, so it try * to release incorrectly */ - fclose(avContextTab[i]->pb->opaque); + CustomIOCtx_t *io = (CustomIOCtx_t *)avContextTab[i]->pb->opaque; + if (io->pFile) + fclose(io->pFile); + if (io->pMoovFile) + fclose(io->pMoovFile); + free(custom_io_tab[i]); av_freep(&(avContextTab[i]->pb->buffer)); av_freep(&(avContextTab[i]->pb)); use_custom_io[i] = 0; @@ -3295,4 +3300,4 @@ Container_t FFMPEGContainer = "FFMPEG", &Command, FFMPEG_Capabilities -}; \ No newline at end of file +}; From d0a539f602a32617694849dea34bc5c38d6085ad Mon Sep 17 00:00:00 2001 From: GetAway Date: Thu, 26 Apr 2018 09:09:24 +0200 Subject: [PATCH 27/72] fix HD51 mix-up letterbox<->panscan Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/4157945d6040b0702d963028a1dff634abfbc530 Author: GetAway Date: 2018-04-26 (Thu, 26 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video_lib.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libarmbox/video_lib.h b/libarmbox/video_lib.h index 1631cb4..7a914fe 100644 --- a/libarmbox/video_lib.h +++ b/libarmbox/video_lib.h @@ -73,8 +73,12 @@ typedef enum { } DISPLAY_AR; typedef enum { - DISPLAY_AR_MODE_PANSCAN = 0, - DISPLAY_AR_MODE_LETTERBOX, + /* FIX for HD51 mix-up of letterbox / panscan + Standard is 1. PANSCAN 2. LETTERBOX + If next drivers are correct please revert + this and pzapit.cpp */ + DISPLAY_AR_MODE_LETTERBOX = 0, + DISPLAY_AR_MODE_PANSCAN, DISPLAY_AR_MODE_NONE, DISPLAY_AR_MODE_PANSCAN2 } DISPLAY_AR_MODE; From 0c87d7b495251cc51f1c3696e1bad6392e6ea55a Mon Sep 17 00:00:00 2001 From: TangoCash Date: Fri, 27 Apr 2018 07:53:48 +0200 Subject: [PATCH 28/72] small fix Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/d0b8259baa435eef02ad082447009e09e6f537ed Author: TangoCash Date: 2018-04-27 (Fri, 27 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ 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 a9f6bda..b3e5f96 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -363,7 +363,7 @@ 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[] = { "letterbox", "panscan", "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 5c95f1f8f997a9275e4406617471623d31180058 Mon Sep 17 00:00:00 2001 From: GetAway Date: Thu, 26 Apr 2018 09:10:04 +0200 Subject: [PATCH 29/72] fix possible segfault Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/01240cf168c02a1394be4ab44ecc8db83422eb38 Author: GetAway Date: 2018-04-26 (Thu, 26 Apr 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- azbox/video.cpp | 8 +++++--- libarmbox/video.cpp | 8 +++++--- libspark/video.cpp | 8 +++++--- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/azbox/video.cpp b/azbox/video.cpp index bf08c65..8ce3817 100644 --- a/azbox/video.cpp +++ b/azbox/video.cpp @@ -158,7 +158,9 @@ int cVideo::setAspectRatio(int aspect, int mode) /* { "panscan", "letterbox", "fullscreen", "14:9", "(unset)" } */ static const char *m[] = { "1", "2", "0", "1", "(unset)" }; int n; - lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[(mode < 0||mode > 3) ? 4 : mode]); + + int mo = (mode < 0||mode > 3) ? 4 : mode; + lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[(mo]); if (aspect > 3 || aspect == 0) lt_info("%s: invalid aspect: %d\n", __func__, aspect); @@ -173,8 +175,8 @@ int cVideo::setAspectRatio(int aspect, int mode) if (mode == -1) return 0; - lt_debug("%s: /proc/scalingmode -> %s\n", __func__, m[mode]); - n = proc_put("/proc/scalingmode", m[mode], strlen(m[mode])); + lt_debug("%s: /proc/scalingmode -> %s\n", __func__, m[mo]); + n = proc_put("/proc/scalingmode", m[mo], strlen(m[mo])); if (n < 0) return 1; return 0; diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index b3e5f96..3b1f244 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -365,7 +365,9 @@ int cVideo::setAspectRatio(int aspect, int mode) // 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]); + + int mo = (mode < 0||mode > 3) ? 4 : mode; + lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[mo]); if (aspect > 3 || aspect == 0) lt_info("%s: invalid aspect: %d\n", __func__, aspect); @@ -380,8 +382,8 @@ int cVideo::setAspectRatio(int aspect, int mode) if (mode == -1) return 0; - lt_debug("%s: /proc/stb/video/policy -> %s\n", __func__, m[mode]); - n = proc_put("/proc/stb/video/policy", m[mode], strlen(m[mode])); + lt_debug("%s: /proc/stb/video/policy -> %s\n", __func__, m[mo]); + n = proc_put("/proc/stb/video/policy", m[mo], strlen(m[mo])); if (n < 0) return 1; return 0; diff --git a/libspark/video.cpp b/libspark/video.cpp index 3e331d9..a190ac8 100644 --- a/libspark/video.cpp +++ b/libspark/video.cpp @@ -361,7 +361,9 @@ 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)" }; int n; - lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[(mode < 0||mode > 3) ? 4 : mode]); + + int mo = (mode < 0||mode > 3) ? 4 : mode; + lt_debug("%s: a:%d m:%d %s\n", __func__, aspect, mode, m[mo]); if (aspect > 3 || aspect == 0) lt_info("%s: invalid aspect: %d\n", __func__, aspect); @@ -376,8 +378,8 @@ int cVideo::setAspectRatio(int aspect, int mode) if (mode == -1) return 0; - lt_debug("%s: /proc/stb/video/policy -> %s\n", __func__, m[mode]); - n = proc_put("/proc/stb/video/policy", m[mode], strlen(m[mode])); + lt_debug("%s: /proc/stb/video/policy -> %s\n", __func__, m[mo]); + n = proc_put("/proc/stb/video/policy", m[mo], strlen(m[mo])); if (n < 0) return 1; return 0; From 6ba24f5c89f04071be0bc644240fc83e0d058873 Mon Sep 17 00:00:00 2001 From: Frankenstone Date: Fri, 27 Apr 2018 23:33:05 +0200 Subject: [PATCH 30/72] Revert "fix HD51 mix-up letterbox<->panscan" This reverts commit f10ab4605634c1ed76973b098ad0c44d9225c4e6. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/0bd5b8751e74d85c95723daabbdec8c31f6fc805 Author: Frankenstone Date: 2018-04-27 (Fri, 27 Apr 2018) ------------------ This commit was generated by Migit --- libarmbox/video_lib.h | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/libarmbox/video_lib.h b/libarmbox/video_lib.h index 7a914fe..1631cb4 100644 --- a/libarmbox/video_lib.h +++ b/libarmbox/video_lib.h @@ -73,12 +73,8 @@ typedef enum { } DISPLAY_AR; typedef enum { - /* FIX for HD51 mix-up of letterbox / panscan - Standard is 1. PANSCAN 2. LETTERBOX - If next drivers are correct please revert - this and pzapit.cpp */ - DISPLAY_AR_MODE_LETTERBOX = 0, - DISPLAY_AR_MODE_PANSCAN, + DISPLAY_AR_MODE_PANSCAN = 0, + DISPLAY_AR_MODE_LETTERBOX, DISPLAY_AR_MODE_NONE, DISPLAY_AR_MODE_PANSCAN2 } DISPLAY_AR_MODE; From ce11b5cb774eb8ad43f27796aaecfdd70ca9c273 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Fri, 18 May 2018 12:50:12 +0200 Subject: [PATCH 31/72] use SetCECState in deepstandby Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/f5ecac70266348b2789869755300d76f325582c9 Author: Jacek Jendrzej Date: 2018-05-18 (Fri, 18 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 3b1f244..b7cf3c2 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -323,6 +323,9 @@ cVideo::cVideo(int, void *, void *, unsigned int unit) cVideo::~cVideo(void) { + if (standby_cec_activ && fd >= 0) + SetCECState(true); + closeDevice(); } From 92c71a8b6d36a1e7213e6eae60870f6bf5478c85 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 19 May 2018 18:34:26 +0200 Subject: [PATCH 32/72] add av input switch in deep/standby Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/9b5012d2ac6238f5f826a94a7adf69ae946adaf7 Author: Jacek Jendrzej Date: 2018-05-19 (Sat, 19 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index b7cf3c2..2af8e7b 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -301,6 +301,19 @@ int image_to_mpeg2(const char *image_name, int fd) return ret; } +void setAVInput(int val) +{ + if (val != 0 && val != 1) + return; + + int input_fd = open("/proc/stb/avs/0/input", O_WRONLY); + if(input_fd){ + const char *input[] = {"encoder", "aux"}; + write(input_fd, input[val], strlen(input[val])); + close(input_fd); + } +} + cVideo::cVideo(int, void *, void *, unsigned int unit) { lt_debug("%s unit %u\n", __func__, unit); @@ -323,6 +336,8 @@ cVideo::cVideo(int, void *, void *, unsigned int unit) cVideo::~cVideo(void) { + if(fd >= 0) + setAVInput(1); if (standby_cec_activ && fd >= 0) SetCECState(true); @@ -619,10 +634,14 @@ void cVideo::Standby(unsigned int bOn) if (bOn) { closeDevice(); + if(fd < 0) + setAVInput(1); } else { openDevice(); + if(fd >= 0) + setAVInput(0); } video_standby = bOn; SetCECState(video_standby); From 9d184ea2df8c6ca9aa1be7428399902ae4fc46b9 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 19 May 2018 19:21:22 +0200 Subject: [PATCH 33/72] use enum for setAVInput Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2748553a3bb4171b2837711b8a9e82b185832be9 Author: Jacek Jendrzej Date: 2018-05-19 (Sat, 19 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 13 ++++--------- 1 file changed, 4 insertions(+), 9 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 2af8e7b..12e542a 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -300,12 +300,9 @@ int image_to_mpeg2(const char *image_name, int fd) av_free(formatContext); return ret; } - +enum{ENCODER,AUX}; void setAVInput(int val) { - if (val != 0 && val != 1) - return; - int input_fd = open("/proc/stb/avs/0/input", O_WRONLY); if(input_fd){ const char *input[] = {"encoder", "aux"}; @@ -337,7 +334,7 @@ cVideo::cVideo(int, void *, void *, unsigned int unit) cVideo::~cVideo(void) { if(fd >= 0) - setAVInput(1); + setAVInput(AUX); if (standby_cec_activ && fd >= 0) SetCECState(true); @@ -634,14 +631,12 @@ void cVideo::Standby(unsigned int bOn) if (bOn) { closeDevice(); - if(fd < 0) - setAVInput(1); + setAVInput(AUX); } else { openDevice(); - if(fd >= 0) - setAVInput(0); + setAVInput(ENCODER); } video_standby = bOn; SetCECState(video_standby); From b3ca6591f401f362531b20c17180d8838076421b Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Fri, 25 May 2018 17:05:09 +0200 Subject: [PATCH 34/72] fix CEC TV ON after deepstandby Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/d63ecb3686765a4f68a11cd7cde05db6ef86bcd2 Author: Jacek Jendrzej Date: 2018-05-25 (Fri, 25 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 12e542a..6fb8495 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -1125,7 +1125,7 @@ bool cVideo::SetCECMode(VIDEO_HDMI_CEC_MODE _deviceType) physicalAddress[0] = 0x10; physicalAddress[1] = 0x00; logicalAddress = 1; - + if (_deviceType == VIDEO_HDMI_CEC_MODE_OFF) { if (hdmiFd >= 0) { @@ -1209,11 +1209,15 @@ bool cVideo::SetCECMode(VIDEO_HDMI_CEC_MODE _deviceType) if (ioctl(hdmiFd, CEC_S_MODE, &monitor) < 0) lt_info("%s: CEC monitor failed (%m)\n", __func__); + GetCECAddressInfo(); + + if(autoview_cec_activ) + SetCECState(false); + + return true; + } - - GetCECAddressInfo(); - - return true; + return false; } void cVideo::GetCECAddressInfo() From b5ff2c2138345efa8a2f06ead8217486ac690b87 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Tue, 29 May 2018 18:06:21 +0200 Subject: [PATCH 35/72] fix framerate for movieplayer Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/6ad87ad3c1db2107aaec1e462711192269b53fbf Author: Jacek Jendrzej Date: 2018-05-29 (Tue, 29 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 6fb8495..16e209b 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -730,7 +730,10 @@ void cVideo::getPictureInfo(int &width, int &height, int &rate) if (fd == -1) { /* in movieplayer mode, fd is not opened -> fall back to procfs */ - r = proc_get_hex(VMPEG_framerate[devnum]); + char buf[16]; + int n = proc_get(VMPEG_framerate[devnum], buf, 16); + if (n > 0) + sscanf(buf, "%i", &r); width = proc_get_hex(VMPEG_xres[devnum]); height = proc_get_hex(VMPEG_yres[devnum]); rate = rate2csapi(r); From 173d00231ba404944f0b7ab58bc78d9cbb24d477 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Tue, 29 May 2018 18:37:58 +0200 Subject: [PATCH 36/72] fix getAspectRatio for movieplayer Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/baddea3b221c2bf77d2dc367cb9d3961917bf023 Author: Jacek Jendrzej Date: 2018-05-29 (Tue, 29 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ 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 16e209b..3da7ada 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -411,7 +411,7 @@ int cVideo::getAspectRatio(void) { /* in movieplayer mode, fd is not opened -> fall back to procfs */ int n = proc_get_hex(VMPEG_aspect[devnum]); - return n * 2 + 1; + return n; } if (fop(ioctl, VIDEO_GET_SIZE, &s) < 0) { From 176110a0fcbd8f3d58eb5d4d7e60fb0dd89bad5b Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Tue, 29 May 2018 16:32:47 +0200 Subject: [PATCH 37/72] set av input on start Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/a1f1070da5a18e2dc75e145f0aec1ffe1bc6e274 Author: Jacek Jendrzej Date: 2018-05-29 (Tue, 29 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/video.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libarmbox/video.cpp b/libarmbox/video.cpp index 3da7ada..439eace 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -329,6 +329,7 @@ cVideo::cVideo(int, void *, void *, unsigned int unit) hdmiFd = -1; standby_cec_activ = autoview_cec_activ = false; openDevice(); + setAVInput(ENCODER); } cVideo::~cVideo(void) From 621f6afec8f3c99366d66d4ef5cb489703df5653 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 31 May 2018 13:55:54 +0200 Subject: [PATCH 38/72] fix framerate 29970 signalisatiom (by bazi98) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/e618c66606b0a5241bb81c2596e30cdbaaffc00c Author: Jacek Jendrzej Date: 2018-05-31 (Thu, 31 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ 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 0f8381d..1255b0c 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -708,7 +708,7 @@ static inline int rate2csapi(int rate) return 1; case 25000: return 2; - case 29976: + case 29970: return 3; case 30000: return 4; From 1fe9e9c15c8a0d2a1ee0c0aca3113fad8b9d45e3 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Wed, 30 May 2018 10:40:58 +0200 Subject: [PATCH 39/72] fix signalisation bitrate 599940 (by bazi98) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/4c43f7a12fa0a233ffe705f686168159912e3be7 Author: Jacek Jendrzej Date: 2018-05-30 (Wed, 30 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ 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 439eace..ea8d6b9 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -714,7 +714,7 @@ static inline int rate2csapi(int rate) return 4; case 50000: return 5; - case 50940: + case 59940: return 6; case 60000: return 7; From b06a32c7141099c307673b391c3f75e6559da5f8 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Thu, 31 May 2018 13:55:54 +0200 Subject: [PATCH 40/72] fix framerate 29970 signalisatiom (by bazi98) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/ceba5df622ce0a6b63f62c46c646a13989b8bed9 Author: Jacek Jendrzej Date: 2018-05-31 (Thu, 31 May 2018) ------------------ No further description and justification available within origin commit message! ------------------ 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 ea8d6b9..f9991d0 100644 --- a/libarmbox/video.cpp +++ b/libarmbox/video.cpp @@ -708,7 +708,7 @@ static inline int rate2csapi(int rate) return 1; case 25000: return 2; - case 29976: + case 29970: return 3; case 30000: return 4; From e78be631ba63d69080ae6ba46ad1861cbc257ba2 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 28 Jul 2018 14:24:12 +0200 Subject: [PATCH 41/72] fix possible segfault Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/5e04171a83982878b338bd7ea83bb503ebea9ac7 Author: Jacek Jendrzej Date: 2018-07-28 (Sat, 28 Jul 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/playback/playback.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 97e0c9a..098cc4d 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -300,7 +300,8 @@ static int PlaybackPlay(Context_t *context) context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 0; - context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); + if (context->container && context->container->selectedContainer) + context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); } else { @@ -330,8 +331,8 @@ static int PlaybackPlay(Context_t *context) 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 (context->container && context->container->selectedContainer) + ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL); if (ret != 0) { playback_err("CONTAINER_PLAY failed!\n"); From 5bca6b6844ee863c85a87b0c02ab9927c916897b Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 29 Aug 2018 12:13:43 +0200 Subject: [PATCH 42/72] [libarmbox] playback_libeplayer3.cpp code format Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/da6ffe04dcd85b94c499453ac17742929ccf9457 Author: max_10 Date: 2018-08-29 (Wed, 29 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/playback_libeplayer3.cpp | 104 ++++++++++++++++++++++------- 1 file changed, 81 insertions(+), 23 deletions(-) diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index 83a75ae..0a2f1ed 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -47,33 +47,41 @@ bool cPlayback::Open(playmode_t PlayMode) last_size = 0; nPlaybackSpeed = 0; init_jump = -1; + if (player) free(player); player = NULL; + player = (Context_t *) malloc(sizeof(Context_t)); + if (player) { player->playback = &PlaybackHandler; player->output = &OutputHandler; player->container = &ContainerHandler; player->manager = &ManagerHandler; + lt_info("%s - player output name: %s PlayMode: %s\n", __func__, player->output->Name, aPLAYMODE[PlayMode]); } + //Registration of output devices if (player && player->output) { player->output->Command(player, OUTPUT_ADD, (void *)"audio"); player->output->Command(player, OUTPUT_ADD, (void *)"video"); } + return 0; } void cPlayback::Close(void) { lt_info("%s\n", __func__); + //Dagobert: movieplayer does not call stop, it calls close ;) if(playing) Stop(); + if (decoders_closed) { audioDecoder->openDevice(); @@ -92,7 +100,9 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in bool ret = false; bool isHTTP = false; no_probe = false; + lt_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d\n", __func__, filename, vpid, vtype, apid, ac3); + init_jump = -1; //create playback path mAudioStream = 0; @@ -100,11 +110,14 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in mTeletextStream = -1; unlink("/tmp/.id3coverart"); std::string file; + if (*filename == '/') file = "file://"; file += filename; + if ((file.find(":31339/id=") != std::string::npos) || (file.find(":10000") != std::string::npos) || (file.find(":8001/") != std::string::npos)) // for LocalTV and Entertain-TV streaming no_probe = true; + if (file.substr(0, 7) == "file://") { if (file.substr(file.length() - 3) == ".ts") @@ -117,6 +130,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in } else isHTTP = true; + PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0}; if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 0) { @@ -140,15 +154,16 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in { printf("AudioTrack List\n"); int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) + for (i = 0; TrackList[i] != NULL; i += 2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]); free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } free(TrackList); } } + //SUB if (player && player->manager && player->manager->subtitle) { @@ -160,13 +175,14 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in int i = 0; for (i = 0; TrackList[i] != NULL; i+=2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]); free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } free(TrackList); } } + /* //Teletext if (player && player->manager && player->manager->teletext) @@ -177,15 +193,16 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in { printf("TeletextTrack List\n"); int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) + for (i = 0; TrackList[i] != NULL; i += 2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]); free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } free(TrackList); } } + */ //Chapters if (player && player->manager && player->manager->chapter) @@ -196,19 +213,21 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in { printf("Chapter List\n"); int i = 0; - for (i = 0; TrackList[i] != NULL; i+=2) + for (i = 0; TrackList[i] != NULL; i += 2) { - printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + printf("\t%s - %s\n", TrackList[i], TrackList[i + 1]); free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } free(TrackList); } } + playing = true; first = true; player->output->Command(player, OUTPUT_OPEN, NULL); ret = (player->playback->Command(player, PLAYBACK_PLAY, NULL) == 0); + if (ret && !isHTTP) playing = ret = (player->playback->Command(player, PLAYBACK_PAUSE, NULL) == 0); } @@ -219,17 +238,22 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in bool cPlayback::Stop(void) { lt_info("%s playing %d\n", __func__, playing); + if (player && player->playback) player->playback->Command(player, PLAYBACK_STOP, NULL); + if (player && player->output) player->output->Command(player, OUTPUT_CLOSE, NULL); + if (player && player->output) { player->output->Command(player, OUTPUT_DEL, (void *)"audio"); player->output->Command(player, OUTPUT_DEL, (void *)"video"); } + if (player && player->playback) player->playback->Command(player, PLAYBACK_CLOSE, NULL); + playing = false; return true; } @@ -238,6 +262,7 @@ bool cPlayback::SetAPid(int pid, bool /* ac3 */) { lt_info("%s\n", __func__); int i = pid; + if (pid != mAudioStream) { if (player && player->playback) @@ -257,6 +282,7 @@ bool cPlayback::SetSubtitlePid(int pid) { lt_info("%s\n", __func__); int i = pid; + if (pid != mSubtitleStream) { if (player && player->playback) @@ -269,11 +295,13 @@ bool cPlayback::SetSubtitlePid(int pid) bool cPlayback::SetTeletextPid(int pid) { lt_info("%s\n", __func__); + //int i = pid; + if (pid != mTeletextStream) { - //if(player && player->playback) - //player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i); + //if (player && player->playback) + // player->playback->Command(player, PLAYBACK_SWITCH_TELETEXT, (void*)&i); mTeletextStream = pid; } return true; @@ -282,6 +310,7 @@ bool cPlayback::SetTeletextPid(int pid) bool cPlayback::SetSpeed(int speed) { lt_info("%s playing %d speed %d\n", __func__, playing, speed); + if (!decoders_closed) { audioDecoder->closeDevice(); @@ -295,12 +324,15 @@ bool cPlayback::SetSpeed(int speed) playing = true; } } + if (!playing) return false; + if (player && player->playback) { int result = 0; nPlaybackSpeed = speed; + if (speed > 1) { /* direction switch ? */ @@ -337,11 +369,13 @@ bool cPlayback::SetSpeed(int speed) { result = player->playback->Command(player, PLAYBACK_CONTINUE, NULL); } + if (init_jump > -1) { SetPosition(init_jump); init_jump = -1; } + if (result != 0) { printf("returning false\n"); @@ -369,6 +403,7 @@ bool cPlayback::GetPosition(int &position, int &duration) { bool got_duration = false; lt_debug("%s %d %d\n", __func__, position, duration); + /* hack: if the file is growing (timeshift), then determine its length * by comparing the mtime with the mtime of the xml file */ if (pm == PLAYMODE_TS) @@ -390,17 +425,21 @@ bool cPlayback::GetPosition(int &position, int &duration) } } } + if (!playing) return false; + if (player && player->playback && !player->playback->isPlaying) { lt_info("%s !!!!EOF!!!! < -1\n", __func__); position = duration + 1000; return false; } + int64_t vpts = 0; if (player && player->playback) player->playback->Command(player, PLAYBACK_PTS, &vpts); + if (vpts <= 0) { //printf("ERROR: vpts==0"); @@ -410,21 +449,31 @@ bool cPlayback::GetPosition(int &position, int &duration) /* len is in nanoseconds. we have 90 000 pts per second. */ position = vpts / 90; } + if (got_duration) return true; + int64_t length = 0; + if (player && player->playback) player->playback->Command(player, PLAYBACK_LENGTH, &length); + if (length <= 0) + { duration = duration + 1000; + } else + { duration = length * 1000; + } + return true; } bool cPlayback::SetPosition(int position, bool absolute) { lt_info("%s %d\n", __func__, position); + if (playing && first) { /* the calling sequence is: @@ -437,9 +486,12 @@ bool cPlayback::SetPosition(int position, bool absolute) first = false; return false; } + int64_t pos = (position / 1000.0); + if (player && player->playback) player->playback->Command(player, absolute ? PLAYBACK_SEEK_ABS : PLAYBACK_SEEK, (void *)&pos); + return true; } @@ -448,6 +500,7 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu lt_info("%s\n", __func__); int max_numpida = *numpida; *numpida = 0; + if (player && player->manager && player->manager->audio) { char **TrackList = NULL; @@ -467,9 +520,9 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu { apids[j] = _pid; // atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC - if (!strncmp("A_MPEG/L3", TrackList[i + 1], 9)) + if (!strncmp("A_MPEG/L3", TrackList[i + 1], 9)) ac3flags[j] = 3; - if (!strncmp("A_MP3", TrackList[i + 1], 5)) + if (!strncmp("A_MP3", TrackList[i + 1], 5)) ac3flags[j] = 4; else if (!strncmp("A_AC3", TrackList[i + 1], 5)) ac3flags[j] = 1; @@ -502,8 +555,10 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language) { lt_info("%s\n", __func__); + int max_numpids = *numpids; *numpids = 0; + if (player && player->manager && player->manager->subtitle) { char **TrackList = NULL; @@ -539,8 +594,8 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids lt_info("%s\n", __func__); //int max_numpids = *numpids; *numpids = 0; - /* - if (player && player->manager && player->manager->teletext) + +/* if (player && player->manager && player->manager->teletext) { char **TrackList = NULL; player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); @@ -569,16 +624,15 @@ void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids free(TrackList); *numpids = j; } - } - */ + } */ } int cPlayback::GetTeletextPid(void) { lt_info("%s\n", __func__); int pid = -1; - /* - if (player && player->manager && player->manager->teletext) + +/* if (player && player->manager && player->manager->teletext) { char **TrackList = NULL; player->manager->teletext->Command(player, MANAGER_LIST, &TrackList); @@ -602,8 +656,8 @@ int cPlayback::GetTeletextPid(void) } free(TrackList); } - } - */ + } */ + printf("teletext pid id %d (0x%x)\n", pid, pid); return pid; } @@ -625,6 +679,7 @@ void cPlayback::GetChapters(std::vector &positions, std::vectormanager && player->manager->chapter) { char **TrackList = NULL; @@ -681,6 +736,7 @@ cPlayback::cPlayback(int num __attribute__((unused))) cPlayback::~cPlayback() { lt_info("%s\n", __func__); + if (player) free(player); player = NULL; @@ -727,6 +783,7 @@ void cPlayback::ReleaseAVFormatContext() bool cPlayback::IsPlaying(void) const { lt_info("%s\n", __func__); + /* konfetti: there is no event/callback mechanism in libeplayer2 * so in case of ending playback we have no information on a * terminated stream currently (or did I oversee it?). @@ -736,6 +793,7 @@ bool cPlayback::IsPlaying(void) const { return player->playback->isPlaying; } + return playing; } #endif From f57a31176999f902ed80f10529ecc61fdb36ce40 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 29 Aug 2018 13:09:21 +0200 Subject: [PATCH 43/72] [libarmbox] Change Makefile.am Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/ecfa47621fd3e10eed85aed843637f10bee86255 Author: max_10 Date: 2018-08-29 (Wed, 29 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/Makefile.am | 61 ++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index 7ba03f2..0db258d 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -1,30 +1,43 @@ AUTOMAKE_OPTIONS = subdir-objects +AM_CFLAGS = -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE + +CXXFLAGS = -Wall noinst_LTLIBRARIES = libeplayer3_arm.la -AM_CFLAGS = -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE +AM_CPPFLAGS = -I$(srcdir)/include +AM_CPPFLAGS += -I$(top_srcdir)/include +AM_CPPFLAGS += -I$(srcdir)/external -AM_CPPFLAGS = -I$(srcdir)/include -AM_CPPFLAGS += -I$(top_srcdir)/include -AM_CPPFLAGS += -I$(srcdir)/external +AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing -AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing +SOURCE_FILES = container/container.c +SOURCE_FILES += container/container_ffmpeg.c +SOURCE_FILES += manager/manager.c +SOURCE_FILES += manager/audio.c +SOURCE_FILES += manager/video.c +SOURCE_FILES += manager/chapter.c +SOURCE_FILES += manager/subtitle.c +SOURCE_FILES += output/output_subtitle.c +SOURCE_FILES += output/output.c +SOURCE_FILES += output/writer/common/pes.c +SOURCE_FILES += output/writer/common/misc.c +SOURCE_FILES += output/writer/common/writer.c +SOURCE_FILES += output/linuxdvb_buffering.c +SOURCE_FILES += playback/playback.c +SOURCE_FILES += external/ffmpeg/src/bitstream.c +SOURCE_FILES += external/ffmpeg/src/latmenc.c +SOURCE_FILES += external/ffmpeg/src/mpeg4audio.c -libeplayer3_arm_la_SOURCES = \ - container/container.c \ - container/container_ffmpeg.c \ - manager/manager.c \ - manager/audio.c \ - manager/video.c \ - manager/subtitle.c \ - manager/chapter.c \ +#AM_CFLAGS += -DHAVE_FLV2MPEG4_CONVERTER +#AM_CPPFLAGS += -I$(srcdir)/external/flv2mpeg4 +#SOURCE_FILES += external/flv2mpeg4/src/m4vencode.c +#SOURCE_FILES += external/flv2mpeg4/src/flvdecoder.c +#SOURCE_FILES += external/flv2mpeg4/src/dcprediction.c +#SOURCE_FILES += external/flv2mpeg4/src/flv2mpeg4.c + +SOURCE_FILES += \ output/linuxdvb_mipsel.c \ - output/linuxdvb_buffering.c \ - output/output_subtitle.c \ - output/output.c \ - output/writer/common/pes.c \ - output/writer/common/misc.c \ - output/writer/common/writer.c \ output/writer/mipsel/writer.c \ output/writer/mipsel/aac.c \ output/writer/mipsel/ac3.c \ @@ -42,15 +55,13 @@ libeplayer3_arm_la_SOURCES = \ output/writer/mipsel/divx3.c \ output/writer/mipsel/vp.c \ output/writer/mipsel/wmv.c \ - output/writer/mipsel/vc1.c \ - playback/playback.c \ - external/ffmpeg/src/bitstream.c \ - external/ffmpeg/src/latmenc.c \ - external/ffmpeg/src/mpeg4audio.c + output/writer/mipsel/vc1.c +libeplayer3_arm_la_SOURCES = $(SOURCE_FILES) -LIBEPLAYER3_LIBS = libeplayer3_arm.la -lpthread -lavformat -lavcodec -lavutil -lswresample -lz -lm +LIBEPLAYER3_LIBS = libeplayer3_arm.la -lpthread -lavformat -lavcodec -lavutil -lswresample bin_PROGRAMS = eplayer3 eplayer3_SOURCES = main/exteplayer.c eplayer3_LDADD = $(LIBEPLAYER3_LIBS) +eplayer3_DEPENDENCIES = libeplayer3_arm.la From 32c26c582a46d17290b70c41038a0233b6e705c6 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 29 Aug 2018 14:29:29 +0200 Subject: [PATCH 44/72] [libarmbox] add libeplayer3-arm --enable-flv2mpeg4 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/3464282278dc92ac8b1bf8edde682957e84c57c7 Author: max_10 Date: 2018-08-29 (Wed, 29 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- acinclude.m4 | 6 +++--- configure.ac | 9 +++++++++ libeplayer3-arm/Makefile.am | 14 ++++++++------ 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/acinclude.m4 b/acinclude.m4 index b9d9be1..6b9232b 100644 --- a/acinclude.m4 +++ b/acinclude.m4 @@ -152,11 +152,11 @@ AC_SUBST(PLUGINDIR) AC_SUBST(THEMESDIR) dnl end workaround -AC_DEFUN([TUXBOX_BOXTYPE],[ +AC_DEFUN([TUXBOX_BOXTYPE], [ AC_ARG_WITH(boxtype, - [ --with-boxtype valid values: tripledragon,spark,azbox,generic,duckbox,spark7162,armbox], + AS_HELP_STRING([--with-boxtype], [valid values: tripledragon, spark, azbox, generic, armbox, duckbox, spark7162]), [case "${withval}" in - tripledragon|azbox|generic) + tripledragon|azbox|generic|armbox) BOXTYPE="$withval" ;; spark|spark7162) diff --git a/configure.ac b/configure.ac index e386150..0e56456 100644 --- a/configure.ac +++ b/configure.ac @@ -62,6 +62,15 @@ if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then PKG_CHECK_MODULES([SWRESAMPLE], [libswresample]) fi +AC_ARG_ENABLE(flv2mpeg4, + AS_HELP_STRING(--enable-flv2mpeg4, use flv2mpeg4 libeplayer3-arm), + ,[enable_flv2mpeg4=no]) + +AM_CONDITIONAL(FLV2MPEG4, test "$enable_flv2mpeg4" = "yes") +if test "$enable_flv2mpeg4" = "yes"; then + AC_DEFINE(ENABLE_FLV2MPEG4, 1, [use flv2mpeg4 libeplayer3-arm]) +fi + AC_OUTPUT([ Makefile common/Makefile diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index 0db258d..193f427 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -29,12 +29,14 @@ SOURCE_FILES += external/ffmpeg/src/bitstream.c SOURCE_FILES += external/ffmpeg/src/latmenc.c SOURCE_FILES += external/ffmpeg/src/mpeg4audio.c -#AM_CFLAGS += -DHAVE_FLV2MPEG4_CONVERTER -#AM_CPPFLAGS += -I$(srcdir)/external/flv2mpeg4 -#SOURCE_FILES += external/flv2mpeg4/src/m4vencode.c -#SOURCE_FILES += external/flv2mpeg4/src/flvdecoder.c -#SOURCE_FILES += external/flv2mpeg4/src/dcprediction.c -#SOURCE_FILES += external/flv2mpeg4/src/flv2mpeg4.c +if ENABLE_FLV2MPEG4 +AM_CFLAGS += -DHAVE_FLV2MPEG4_CONVERTER +AM_CPPFLAGS += -I$(srcdir)/external/flv2mpeg4 +SOURCE_FILES += external/flv2mpeg4/src/m4vencode.c +SOURCE_FILES += external/flv2mpeg4/src/flvdecoder.c +SOURCE_FILES += external/flv2mpeg4/src/dcprediction.c +SOURCE_FILES += external/flv2mpeg4/src/flv2mpeg4.c +endif SOURCE_FILES += \ output/linuxdvb_mipsel.c \ From 934dadbfd4d917ad5fd7298ebdae86741b0963f6 Mon Sep 17 00:00:00 2001 From: max_10 Date: Wed, 29 Aug 2018 14:33:31 +0200 Subject: [PATCH 45/72] [libarmbox] fix last commit Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/2f4df23958b6442a16f604f50f28e851f89e9aa4 Author: max_10 Date: 2018-08-29 (Wed, 29 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- configure.ac | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/configure.ac b/configure.ac index 0e56456..56eb4ba 100644 --- a/configure.ac +++ b/configure.ac @@ -66,7 +66,7 @@ AC_ARG_ENABLE(flv2mpeg4, AS_HELP_STRING(--enable-flv2mpeg4, use flv2mpeg4 libeplayer3-arm), ,[enable_flv2mpeg4=no]) -AM_CONDITIONAL(FLV2MPEG4, test "$enable_flv2mpeg4" = "yes") +AM_CONDITIONAL(ENABLE_FLV2MPEG4, test "$enable_flv2mpeg4" = "yes") if test "$enable_flv2mpeg4" = "yes"; then AC_DEFINE(ENABLE_FLV2MPEG4, 1, [use flv2mpeg4 libeplayer3-arm]) fi From 7553673d40cdcebe6dbbafc52bcdb8b7c2ed2ce1 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 30 Aug 2018 14:05:36 +0200 Subject: [PATCH 46/72] [libarmbox] libeplayer3-arm code format Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/c49f9bebbafd404897a6766462c97ce3a7bbbe82 Author: max_10 Date: 2018-08-30 (Thu, 30 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 86 ++++++++++++------- libeplayer3-arm/include/container.h | 1 - libeplayer3-arm/include/manager.h | 2 +- libeplayer3-arm/include/playback.h | 2 +- libeplayer3-arm/main/exteplayer.c | 32 ++++--- libeplayer3-arm/manager/audio.c | 14 +-- libeplayer3-arm/manager/subtitle.c | 17 ++-- libeplayer3-arm/manager/video.c | 14 +-- libeplayer3-arm/output/linuxdvb_mipsel.c | 6 +- libeplayer3-arm/output/output.c | 1 + libeplayer3-arm/output/output_subtitle.c | 3 +- libeplayer3-arm/output/writer/common/writer.c | 2 +- libeplayer3-arm/output/writer/mipsel/dts.c | 1 + libeplayer3-arm/output/writer/mipsel/wma.c | 1 + libeplayer3-arm/playback/playback.c | 46 ++++++---- 15 files changed, 138 insertions(+), 90 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 5f84216..334d326 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -105,6 +105,7 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); #define cERR_CONTAINER_FFMPEG_END_OF_FILE -10 #define IPTV_AV_CONTEXT_MAX_NUM 2 + /* ***************************** */ /* Types */ /* ***************************** */ @@ -548,8 +549,7 @@ 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; + int64_t currentVideoPts = -1; int64_t currentAudioPts = -1; @@ -561,7 +561,6 @@ static void FFMPEGThread(Context_t *context) int64_t showtime = 0; int64_t bofcount = 0; - //int32_t err = 0; AudioVideoOut_t avOut; g_context = context; @@ -583,13 +582,14 @@ static void FFMPEGThread(Context_t *context) memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context)); #endif ffmpeg_printf(10, "\n"); + while (context->playback->isCreationPhase) { ffmpeg_printf(10, "Thread waiting for end of init phase...\n"); usleep(1000); } ffmpeg_printf(10, "Running!\n"); - + #ifdef __sh__ uint32_t bufferSize = 0; context->output->Command(context, OUTPUT_GET_BUFFER_SIZE, &bufferSize); @@ -597,6 +597,7 @@ static void FFMPEGThread(Context_t *context) #endif int8_t isWaitingForFinish = 0; + while (context && context->playback && context->playback->isPlaying) { /* When user press PAUSE we call pause on AUDIO and VIDEO decoders, @@ -636,19 +637,24 @@ static void FFMPEGThread(Context_t *context) } continue; } - if (context->playback->BackWard && av_gettime() >= showtime) { + + if (context->playback->BackWard && av_gettime() >= showtime) + { context->output->Command(context, OUTPUT_CLEAR, "video"); - if (bofcount == 1) { - showtime = av_gettime(); - usleep(100000); - continue; + if (bofcount == 1) + { + showtime = av_gettime(); + usleep(100000); + continue; } - if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) { + if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) + { off_t pos = avio_tell(avContextTab[0]->pb); - if (pos > 0) { + if (pos > 0) + { float br; if (avContextTab[0]->bit_rate) br = avContextTab[0]->bit_rate / 8.0; @@ -669,7 +675,7 @@ static void FFMPEGThread(Context_t *context) seek_target_seconds = AV_TIME_BASE; do_seek_target_seconds = 1; } - showtime = av_gettime() + 300000; //jump back every 300ms + showtime = av_gettime() + 300000; //jump back every 300ms } else { @@ -770,15 +776,16 @@ static void FFMPEGThread(Context_t *context) if (!isWaitingForFinish && (ffmpegStatus = av_read_frame(avContextTab[cAVIdx], &packet)) == 0) { - int64_t pts = 0; - int64_t dts = 0; - Track_t *videoTrack = NULL; - Track_t *audioTrack = NULL; + int64_t pts = 0; + int64_t dts = 0; + 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) { if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) @@ -992,6 +999,7 @@ static void FFMPEGThread(Context_t *context) decoded_frame = NULL; } } + #if (LIBAVFORMAT_VERSION_MAJOR > 57) || ((LIBAVFORMAT_VERSION_MAJOR == 57) && (LIBAVFORMAT_VERSION_MINOR > 32)) while (packet.size > 0 || (!packet.size && !packet.data)) #else @@ -1059,6 +1067,7 @@ static void FFMPEGThread(Context_t *context) continue; } #endif + int32_t e = 0; if (!swr) { @@ -1085,6 +1094,7 @@ static void FFMPEGThread(Context_t *context) { 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; @@ -1108,7 +1118,6 @@ static void FFMPEGThread(Context_t *context) 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) { @@ -1344,6 +1353,7 @@ static void FFMPEGThread(Context_t *context) hasPlayThreadStarted = 0; context->playback->isPlaying = 0; PlaybackDieNow(1); + ffmpeg_printf(10, "terminating\n"); } @@ -1886,13 +1896,16 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) } ffmpeg_printf(10, "filename %s\n", playFilesNames->szFirstFile); + if (playFilesNames->szSecondFile) { ffmpeg_printf(10, "second filename %s\n", playFilesNames->szSecondFile); } + /* initialize ffmpeg */ avcodec_register_all(); av_register_all(); + avformat_network_init(); // SULGE DEBUG ENABLED @@ -1902,7 +1915,8 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) context->playback->abortRequested = 0; int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ - playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); + playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); + if (0 != res) { return res; @@ -1911,7 +1925,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0') { res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \ - playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); + playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); } if (0 != res) @@ -1970,6 +1984,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 uint32_t cAVIdx = 0; + for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1) { if (NULL == avContextTab[cAVIdx]) @@ -2080,6 +2095,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; @@ -2096,6 +2112,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 */ track.aspect_ratio_num = stream->sample_aspect_ratio.num; track.aspect_ratio_den = stream->sample_aspect_ratio.den; + if (0 == track.aspect_ratio_num || 0 == track.aspect_ratio_den) { track.aspect_ratio_num = get_codecpar(stream)->sample_aspect_ratio.num; @@ -2115,6 +2132,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } /* fixme: revise this */ + if (track.frame_rate < 23970) { track.TimeScale = 1001; @@ -2179,6 +2197,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 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; @@ -2197,6 +2216,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 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"); @@ -2514,7 +2534,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 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; @@ -2595,6 +2617,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } releaseMutex(__FILE__, __FUNCTION__, __LINE__); + return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2623,14 +2646,12 @@ static int32_t container_ffmpeg_play(Context_t *context) 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; } } @@ -2641,6 +2662,7 @@ static int32_t container_ffmpeg_play(Context_t *context) } ffmpeg_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -2670,6 +2692,7 @@ static int32_t container_ffmpeg_stop(Context_t *context) { /* force close */ ffmpeg_err("Timeout waiting for thread!\n"); + ret = cERR_CONTAINER_FFMPEG_ERR; /* to speed up close - we are in separate process for the moment this process will * be closed and whole resources will be free by the system @@ -2921,15 +2944,16 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab } 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) { /* konfetti: for ts streams seeking frame per seconds does not work (why?). - * I take this algo partly from ffplay.c. - * - * seeking per HTTP does still not work very good. forward seeks everytime - * about 10 seconds, backward does not work. - */ + * I take this algo partly from ffplay.c. + * + * 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); @@ -3027,6 +3051,7 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __ { ffmpeg_printf(10, "track %d\n", *arg); getMutex(__FILE__, __FUNCTION__, __LINE__); + if (context->manager->audio) { Track_t *Tracks = NULL; @@ -3127,7 +3152,7 @@ static int32_t container_ffmpeg_get_info(Context_t *context, char **infoString) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -static int container_ffmpeg_get_metadata(Context_t * context, char ***p) +static int container_ffmpeg_get_metadata(Context_t *context, char ***p) { Track_t *videoTrack = NULL; Track_t *audioTrack = NULL; @@ -3249,12 +3274,12 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen } case CONTAINER_SWITCH_AUDIO: { - ret = container_ffmpeg_switch_audio(context, (int32_t *) argument); + ret = container_ffmpeg_switch_audio(context, (int32_t *)argument); break; } case CONTAINER_SWITCH_SUBTITLE: { - ret = container_ffmpeg_switch_subtitle(context, (int32_t *) argument); + ret = container_ffmpeg_switch_subtitle(context, (int32_t *)argument); break; } case CONTAINER_INFO: @@ -3286,7 +3311,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen } case CONTAINER_GET_METADATA: { - ret = container_ffmpeg_get_metadata(context, (char ***) argument); + ret = container_ffmpeg_get_metadata(context, (char ***)argument); break; } default: @@ -3296,6 +3321,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen } ffmpeg_printf(50, "exiting with value %d\n", ret); + return ret; } diff --git a/libeplayer3-arm/include/container.h b/libeplayer3-arm/include/container.h index a8a87e0..dc1a585 100644 --- a/libeplayer3-arm/include/container.h +++ b/libeplayer3-arm/include/container.h @@ -45,7 +45,6 @@ typedef struct ContainerHandler_s { char *Name; Container_t *selectedContainer; - int (* Command)(Context_t *, ContainerCmd_t, void *); } ContainerHandler_t; diff --git a/libeplayer3-arm/include/manager.h b/libeplayer3-arm/include/manager.h index baed788..1363271 100644 --- a/libeplayer3-arm/include/manager.h +++ b/libeplayer3-arm/include/manager.h @@ -44,7 +44,7 @@ typedef struct Track_s /* new field for ffmpeg - add at the end so no problem * can occur with not changed srt saa container */ - char *language; + char *language; /* length of track */ int64_t duration; diff --git a/libeplayer3-arm/include/playback.h b/libeplayer3-arm/include/playback.h index 68a7fc8..b6d9b63 100644 --- a/libeplayer3-arm/include/playback.h +++ b/libeplayer3-arm/include/playback.h @@ -4,7 +4,7 @@ #include #include -typedef void( * PlaybackDieNowCallback )(); +typedef void(* PlaybackDieNowCallback)(); bool PlaybackDieNowRegisterCallback(PlaybackDieNowCallback callback); typedef enum { diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 7538799..2adfb22 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -252,11 +252,12 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac ptrManager->Command(g_player, MANAGER_LIST, &TrackList); if (NULL != TrackList) { - int i = 0, Id = -1; + int i = 0; + int Id = -1; char * pch; char Name[] = " "; fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]); - for (i = 0; TrackList[i] != NULL; i+=2) + for (i = 0; TrackList[i] != NULL; i += 2) { pch = strtok(TrackList[i], " "); if (pch != NULL) { @@ -272,7 +273,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac } fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", Id, TrackList[i+1], Name); free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } fprintf(stderr, "]}\n"); free(TrackList); @@ -297,7 +298,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac else // video { fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \ - argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den); + argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den); } free(track->Encoding); free(track->Name); @@ -336,7 +337,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac { int i = 0; char * pch; - for (i = 0; TrackList[i] != NULL; i+=2) + for (i = 0; TrackList[i] != NULL; i += 2) { if (idx == i) { @@ -345,7 +346,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac id = atoi(pch); } free(TrackList[i]); - free(TrackList[i+1]); + free(TrackList[i + 1]); } free(TrackList); } @@ -501,7 +502,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac static void UpdateVideoTrack() { - HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); + HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc"); } static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB) @@ -657,6 +658,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * ret = 0; playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH); playbackFiles->szFirstFile[0] = '\0'; + if (NULL == strstr(argv[optind], "://")) { strcpy(playbackFiles->szFirstFile, "file://"); @@ -692,6 +694,7 @@ int main(int argc, char *argv[]) PlayFiles_t playbackFiles; memset(&playbackFiles, 0x00, sizeof(playbackFiles)); + if (0 != ParseParams(argc, argv, &playbackFiles, &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"); @@ -815,24 +818,24 @@ int main(int argc, char *argv[]) { PlaybackDieNowRegisterCallback(TerminateWakeUp); - HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc"); - HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "al"); + HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc"); + HandleTracks(g_player->manager->audio, (PlaybackCmd_t) -1, "al"); if (audioTrackIdx >= 0) { static char cmd[128] = ""; // static to not allocate on stack sprintf(cmd, "ai%d\n", audioTrackIdx); commandRetVal = HandleTracks(g_player->manager->audio, PLAYBACK_SWITCH_AUDIO, cmd); } - HandleTracks(g_player->manager->audio, (PlaybackCmd_t) - 1, "ac"); + HandleTracks(g_player->manager->audio, (PlaybackCmd_t) -1, "ac"); - HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sl"); + HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) -1, "sl"); if (subtitleTrackIdx >= 0) { static char cmd[128] = ""; // static to not allocate on stack sprintf(cmd, "si%d\n", subtitleTrackIdx); commandRetVal = HandleTracks(g_player->manager->subtitle, PLAYBACK_SWITCH_SUBTITLE, cmd); } - HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) - 1, "sc"); + HandleTracks(g_player->manager->subtitle, (PlaybackCmd_t) -1, "sc"); } while (g_player->playback->isPlaying && 0 == PlaybackDieNow(0)) @@ -854,7 +857,7 @@ int main(int argc, char *argv[]) { case 'v': { - HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, argvBuff); + HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, argvBuff); break; } case 'a': @@ -965,10 +968,12 @@ int main(int argc, char *argv[]) commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PTS, &pts); CurrentSec = (int32_t)(pts / 90000); + if (0 == commandRetVal) { fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); } + if (0 == commandRetVal || force) { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); @@ -1015,6 +1020,7 @@ int main(int argc, char *argv[]) { 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); diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index 6543f51..d4eef50 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -128,6 +128,7 @@ static int ManagerAdd(Context_t *context, Track_t track) } audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + return cERR_AUDIO_MGR_NO_ERROR; } @@ -137,6 +138,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) char **tracklist = NULL; audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + if (Tracks != NULL) { tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1)); @@ -160,9 +162,9 @@ static char **ManagerList(Context_t *context __attribute__((unused))) 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; @@ -256,7 +258,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) { container_ffmpeg_update_tracks(context, context->playback->uri, 0); // *((TrackDescription_t **)argument) = ManagerList(context); - *((char ** *) argument) = (char **) ManagerList(context); + *((char ***)argument) = (char **)ManagerList(context); break; } case MANAGER_REF_LIST: @@ -279,7 +281,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } else { - *((int *)argument) = (int) - 1; + *((int *)argument) = (int) -1; } break; } @@ -292,9 +294,9 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) if (track) { memset(track, 0, sizeof(TrackDescription_t)); - track->Id = Tracks[CurrentTrack].Id; - track->Name = strdup(Tracks[CurrentTrack].Name); - track->Encoding = strdup(Tracks[CurrentTrack].Encoding); + track->Id = Tracks[CurrentTrack].Id; + track->Name = strdup(Tracks[CurrentTrack].Name); + track->Encoding = strdup(Tracks[CurrentTrack].Encoding); } } else diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index 144cb5c..db1761a 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -134,8 +134,8 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) static char **ManagerList(Context_t *context __attribute__((unused))) { - char **tracklist = NULL; int i = 0, j = 0; + char **tracklist = NULL; subtitle_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); @@ -162,7 +162,6 @@ static char **ManagerList(Context_t *context __attribute__((unused))) tracklist[j] = strdup(tmp); tracklist[j + 1] = strdup(Tracks[i].Encoding); } - tracklist[j] = NULL; } @@ -219,7 +218,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_LIST: { container_ffmpeg_update_tracks(context, context->playback->uri, 0); - *((char ** *)argument) = (char **)ManagerList(context); + *((char ***)argument) = (char **)ManagerList(context); break; } case MANAGER_GET: @@ -230,7 +229,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } else { - *((int *)argument) = (int) - 1; + *((int *)argument) = (int) -1; } break; } @@ -243,9 +242,9 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) if (track) { memset(track, 0, sizeof(TrackDescription_t)); - track->Id = Tracks[CurrentTrack].Id; - track->Name = strdup(Tracks[CurrentTrack].Name); - track->Encoding = strdup(Tracks[CurrentTrack].Encoding); + track->Id = Tracks[CurrentTrack].Id; + track->Name = strdup(Tracks[CurrentTrack].Name); + track->Encoding = strdup(Tracks[CurrentTrack].Encoding); } } else @@ -332,12 +331,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } default: - subtitle_mgr_err("%s:%s: ContainerCmd not supported!", __FILE__, __FUNCTION__); + subtitle_mgr_err("%s::%s ContainerCmd not supported!", __FILE__, __FUNCTION__); ret = cERR_SUBTITLE_MGR_ERROR; break; } - subtitle_mgr_printf(50, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); + subtitle_mgr_printf(50, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret); return ret; } diff --git a/libeplayer3-arm/manager/video.c b/libeplayer3-arm/manager/video.c index 8a94d4a..93b7073 100644 --- a/libeplayer3-arm/manager/video.c +++ b/libeplayer3-arm/manager/video.c @@ -97,7 +97,7 @@ static int ManagerAdd(Context_t *context, Track_t track) if (Tracks == NULL) { - video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + video_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return cERR_VIDEO_MGR_ERROR; } @@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context, Track_t track) } else { - video_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); + video_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); return cERR_VIDEO_MGR_ERROR; } @@ -128,6 +128,7 @@ static int ManagerAdd(Context_t *context, Track_t track) } video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + return cERR_VIDEO_MGR_NO_ERROR; } @@ -144,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) if (tracklist == NULL) { - video_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + video_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } @@ -164,6 +165,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) } video_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); + return tracklist; } @@ -213,7 +215,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_LIST: { container_ffmpeg_update_tracks(context, context->playback->uri, 0); - *((char ** *)argument) = (char **)ManagerList(context); + *((char ***)argument) = (char **)ManagerList(context); break; } case MANAGER_GET: @@ -224,7 +226,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } else { - *((int *)argument) = (int) - 1; + *((int *)argument) = (int) -1; } break; } @@ -342,7 +344,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } - video_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); + video_mgr_printf(10, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret); return ret; } diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 58afc9b..455fc8e 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -252,6 +252,7 @@ int LinuxDvbPlay(Context_t *context, char *type) 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); @@ -324,7 +325,6 @@ int LinuxDvbPlay(Context_t *context, char *type) ret = cERR_LINUXDVB_NO_ERROR; return ret; - //return 0; } int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) @@ -354,6 +354,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) ioctl(videofd, VIDEO_FAST_FORWARD, 0); ioctl(videofd, VIDEO_SELECT_SOURCE, VIDEO_SOURCE_DEMUX); } + if (audio && audiofd != -1) { if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) @@ -634,6 +635,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i } *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; + return ret; } @@ -1095,7 +1097,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) case OUTPUT_GET_BUFFER_SIZE: { ret = cERR_LINUXDVB_NO_ERROR; - *((uint32_t*)argument) = LinuxDvbBuffGetSize(); + *((uint32_t *)argument) = LinuxDvbBuffGetSize(); break; } default: diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 60760e8..0544137 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -90,6 +90,7 @@ static void printOutputCapabilities() for (i = 0; AvailableOutput[i] != NULL; i++) { output_printf(10, "\t%s : ", AvailableOutput[i]->Name); + for (j = 0; AvailableOutput[i]->Capabilities[j] != NULL; j++) { output_printf(10, "%s ", AvailableOutput[i]->Capabilities[j]); diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index 16fc2bb..5810440 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -266,8 +266,6 @@ 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__); @@ -341,6 +339,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument __att } subtitle_printf(50, "exiting with value %d\n", ret); + return ret; } diff --git a/libeplayer3-arm/output/writer/common/writer.c b/libeplayer3-arm/output/writer/common/writer.c index b866e2a..0ad4b3e 100644 --- a/libeplayer3-arm/output/writer/common/writer.c +++ b/libeplayer3-arm/output/writer/common/writer.c @@ -70,5 +70,5 @@ if (debug_level >= level) printf(x); } while (0) void FlushPipe(int pipefd) { char tmp; - while(1 == read(pipefd, &tmp, 1)); + while (1 == read(pipefd, &tmp, 1)); } diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index 34548ba..7e1ea7a 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -52,6 +52,7 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ + #define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size. #define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE) #define PES_AUDIO_PACKET_SIZE 2028 diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index 15d6b2d..e953ed8 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -169,6 +169,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 call->WriteV(call->fd, iov, 2); } diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 098cc4d..e2bfd7e 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -54,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 */ #define MAX_PLAYBACK_DIE_NOW_CALLBACKS 10 @@ -140,6 +140,7 @@ static void SupervisorThread(Context_t *context) { usleep(100000); } + playback_printf(10, "<\n"); hasThreadStarted = 2; PlaybackTerminate(context); @@ -293,6 +294,7 @@ static int PlaybackPlay(Context_t *context) { playback_err("OUTPUT_PLAY failed!\n"); playback_err("clearing isCreationPhase!\n"); + context->playback->isCreationPhase = 0; // allow thread to go into next state context->playback->isPlaying = 0; context->playback->isPaused = 0; @@ -300,6 +302,7 @@ static int PlaybackPlay(Context_t *context) context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 0; + if (context->container && context->container->selectedContainer) context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); } @@ -317,7 +320,8 @@ static int PlaybackPlay(Context_t *context) int error; pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); - if ((error = pthread_create(&supervisorThread, &attr, (void *) &SupervisorThread, context)) != 0) + + if ((error = pthread_create(&supervisorThread, &attr, (void *)&SupervisorThread, context)) != 0) { playback_printf(10, "Error creating thread, error:%d:%s\n", error, strerror(error)); ret = cERR_PLAYBACK_ERROR; @@ -331,13 +335,14 @@ static int PlaybackPlay(Context_t *context) playback_printf(10, "clearing isCreationPhase!\n"); context->playback->isCreationPhase = 0; // allow thread to go into next state + if (context->container && context->container->selectedContainer) ret = context->container->selectedContainer->Command(context, CONTAINER_PLAY, NULL); + if (ret != 0) { playback_err("CONTAINER_PLAY failed!\n"); } - } } else @@ -362,10 +367,9 @@ static int PlaybackPause(Context_t *context) if (context->playback->SlowMotion) context->output->Command(context, OUTPUT_CLEAR, NULL); - context->playback->isPaused = 1; - context->output->Command(context, OUTPUT_PAUSE, NULL); + context->playback->isPaused = 1; //context->playback->isPlaying = 1; context->playback->isForwarding = 0; context->playback->BackWard = 0; @@ -395,6 +399,8 @@ static int32_t PlaybackContinue(Context_t *context) if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard) context->output->Command(context, OUTPUT_CLEAR, NULL); + context->output->Command(context, OUTPUT_CONTINUE, NULL); + if (context->playback->BackWard) context->output->Command(context, OUTPUT_AUDIOMUTE, "0"); @@ -404,7 +410,6 @@ static int32_t PlaybackContinue(Context_t *context) context->playback->BackWard = 0; context->playback->SlowMotion = 0; context->playback->Speed = 1; - context->output->Command(context, OUTPUT_CONTINUE, NULL); } else { @@ -413,6 +418,7 @@ static int32_t PlaybackContinue(Context_t *context) } playback_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -427,7 +433,6 @@ static int32_t PlaybackStop(Context_t *context) if (context && context->playback && context->playback->isPlaying) { - context->playback->isPaused = 0; context->playback->isPlaying = 0; context->playback->isForwarding = 0; @@ -437,7 +442,6 @@ static int32_t PlaybackStop(Context_t *context) context->output->Command(context, OUTPUT_STOP, NULL); context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); - } else { @@ -458,13 +462,13 @@ static int32_t PlaybackStop(Context_t *context) } playback_printf(10, "exiting with value %d\n", ret); + return ret; } static int32_t PlaybackTerminate(Context_t *context) { int32_t ret = cERR_PLAYBACK_NO_ERROR; - int wait_time = 20; playback_printf(20, "\n"); @@ -474,12 +478,13 @@ static int32_t PlaybackTerminate(Context_t *context) 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"); } + ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); + context->playback->isPaused = 0; context->playback->isPlaying = 0; context->playback->isForwarding = 0; @@ -487,7 +492,6 @@ static int32_t PlaybackTerminate(Context_t *context) context->playback->SlowMotion = 0; context->playback->Speed = 0; context->output->Command(context, OUTPUT_STOP, NULL); - ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); } else { @@ -512,6 +516,7 @@ static int32_t PlaybackTerminate(Context_t *context) } playback_printf(20, "exiting with value %d\n", ret); + return ret; } @@ -529,6 +534,7 @@ static int PlaybackFastForward(Context_t *context, int *speed) playback_err("speed %d out of range (1 - %d) \n", *speed, cMaxSpeed_ff); return cERR_PLAYBACK_ERROR; } + context->playback->isForwarding = 1; context->playback->Speed = *speed; playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed); @@ -561,6 +567,7 @@ static int PlaybackFastBackward(Context_t *context, int *speed) playback_err("speed %d out of range (0 - %d) \n", *speed, cMaxSpeed_fr); return cERR_PLAYBACK_ERROR; } + if (*speed == 0) { context->playback->BackWard = 0; @@ -601,6 +608,7 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed) { if (context->playback->isPaused) PlaybackContinue(context); + switch (*speed) { case 2: @@ -613,7 +621,9 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed) context->playback->SlowMotion = 8; break; } + playback_printf(20, "SlowMotion: %d x {%d}\n", *speed, context->playback->SlowMotion); + context->output->Command(context, OUTPUT_SLOWMOTION, NULL); } else @@ -726,6 +736,7 @@ static int32_t PlaybackLength(Context_t *context, int64_t *length) } playback_printf(20, "exiting with value %d\n", ret); + return ret; } @@ -753,7 +764,6 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track) if (nextrackid != curtrackid) { - //PlaybackPause(context); if (context->output && context->output->audio) { @@ -774,6 +784,7 @@ static int32_t PlaybackSwitchAudio(Context_t *context, int32_t *track) } playback_printf(10, "exiting with value %d\n", ret); + return ret; } @@ -860,7 +871,6 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument playback_printf(20, "Command %d\n", command); - switch (command) { case PLAYBACK_OPEN: @@ -898,6 +908,11 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument ret = PlaybackTerminate(context); break; } + case PLAYBACK_FASTFORWARD: + { + ret = PlaybackFastForward(context, (int *)argument); + break; + } case PLAYBACK_SEEK: { ret = PlaybackSeek(context, (int64_t *)argument, 0); @@ -943,11 +958,6 @@ static int32_t Command(Context_t *context, PlaybackCmd_t command, void *argument ret = PlaybackFastBackward(context, (int *)argument); break; } - case PLAYBACK_FASTFORWARD: - { - ret = PlaybackFastForward(context, (int *)argument); - break; - } case PLAYBACK_GET_FRAME_COUNT: { ret = PlaybackGetFrameCount(context, (uint64_t *)argument); From 207e36bbb368d6c139353cf8d2593549c0aa1cc7 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 30 Aug 2018 21:19:18 +0200 Subject: [PATCH 47/72] [libarmbox] libeplayer3-arm code format Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/f66e4edd3f6c25364ad49ed98749dbc958116fc6 Author: max_10 Date: 2018-08-30 (Thu, 30 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 4 ++-- libeplayer3-arm/manager/audio.c | 12 ++++++------ libeplayer3-arm/manager/subtitle.c | 9 +++++++-- libeplayer3-arm/output/output.c | 20 ++++++++++++++++++++ 4 files changed, 35 insertions(+), 10 deletions(-) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 334d326..6729a04 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -80,13 +80,13 @@ static short debug_level = 1; #define ffmpeg_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 ffmpeg_printf(level, fmt, x...) #endif #ifndef FFMPEG_SILENT -#define ffmpeg_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) +#define ffmpeg_err(fmt, x...) do { printf("[%s::%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) #else #define ffmpeg_err(fmt, x...) #endif diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index d4eef50..9e029e8 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -46,7 +46,7 @@ static short debug_level = 40; #define audio_mgr_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] \n" fmt, __FILE__, __FUNCTION__, ## x); } while (0) +if (debug_level >= level) printf("[%s::%s] \n" fmt, __FILE__, __FUNCTION__, ## x); } while (0) #else #define audio_mgr_printf(level, x...) #endif @@ -97,7 +97,7 @@ static int ManagerAdd(Context_t *context, Track_t track) if (Tracks == NULL) { - audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return cERR_AUDIO_MGR_ERROR; } @@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context, Track_t track) } else { - audio_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); + audio_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); return cERR_AUDIO_MGR_ERROR; } @@ -145,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) if (tracklist == NULL) { - audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } @@ -183,7 +183,7 @@ static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused if (tracklist == NULL) { - audio_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } @@ -384,7 +384,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } - audio_mgr_printf(10, "%s:%s: returning %d\n", __FILE__, __FUNCTION__, ret); + audio_mgr_printf(10, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret); return ret; } diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index db1761a..5386bde 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -118,7 +118,7 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) } else { - subtitle_mgr_err("%s:%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); + subtitle_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); return cERR_SUBTITLE_MGR_ERROR; } @@ -145,7 +145,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) if (tracklist == NULL) { - subtitle_mgr_err("%s:%s malloc failed\n", __FILE__, __FUNCTION__); + subtitle_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); return NULL; } @@ -223,6 +223,8 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } case MANAGER_GET: { + subtitle_mgr_printf(20, "%s::%s MANAGER_GET\n", FILENAME, __FUNCTION__); + if (TrackCount > 0 && CurrentTrack >= 0) { *((int *)argument) = (int)Tracks[CurrentTrack].Id; @@ -255,6 +257,8 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } case MANAGER_GET_TRACK: { + subtitle_mgr_printf(20, "%s::%s MANAGER_GET_TRACK\n", FILENAME, __FUNCTION__); + if ((TrackCount > 0) && (CurrentTrack >= 0)) { *((Track_t **)argument) = (Track_t *) &Tracks[CurrentTrack]; @@ -292,6 +296,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) case MANAGER_SET: { int i; + subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument)); if (*((int *)argument) < 0) diff --git a/libeplayer3-arm/output/output.c b/libeplayer3-arm/output/output.c index 0544137..c1b3ce4 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -192,10 +192,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_CLOSE, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_CLOSE, "audio"); } + if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_CLOSE, "subtitle"); @@ -239,6 +241,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret = context->output->audio->Command(context, OUTPUT_PLAY, "audio"); } + if (!ret) { if (context->playback->isSubtitle) @@ -261,10 +264,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_STOP, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_STOP, "audio"); } + if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_STOP, "subtitle"); @@ -284,10 +289,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_FLUSH, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_FLUSH, "audio"); } + if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_FLUSH, "subtitle"); @@ -307,10 +314,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_PAUSE, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_PAUSE, "audio"); } + if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_PAUSE, "subtitle"); @@ -330,6 +339,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_FASTFORWARD, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_FASTFORWARD, "audio"); @@ -349,6 +359,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_REVERSE, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_REVERSE, "audio"); @@ -368,10 +379,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_CONTINUE, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_CONTINUE, "audio"); } + if (context->playback->isSubtitle) { ret |= context->output->subtitle->Command(context, OUTPUT_CONTINUE, "subtitle"); @@ -406,10 +419,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_CLEAR, "video"); } + if (context->playback->isAudio && (argument == NULL || *(char *) argument == 'a')) { ret |= context->output->audio->Command(context, OUTPUT_CLEAR, "audio"); } + if (context->playback->isSubtitle && (argument == NULL || *(char *) argument == 's')) { ret |= context->output->subtitle->Command(context, OUTPUT_CLEAR, "subtitle"); @@ -429,6 +444,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { return context->output->video->Command(context, OUTPUT_PTS, argument); } + if (context->playback->isAudio) { return context->output->audio->Command(context, OUTPUT_PTS, argument); @@ -448,10 +464,12 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { return context->output->audio->Command(context, OUTPUT_SWITCH, "audio"); } + if (context->playback->isVideo) { return context->output->video->Command(context, OUTPUT_SWITCH, "video"); } + if (context->playback->isSubtitle) { return context->output->subtitle->Command(context, OUTPUT_SWITCH, "subtitle"); @@ -471,6 +489,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { ret |= context->output->video->Command(context, OUTPUT_SLOWMOTION, "video"); } + if (context->playback->isAudio) { ret |= context->output->audio->Command(context, OUTPUT_SLOWMOTION, "audio"); @@ -520,6 +539,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) { return context->output->video->Command(context, OUTPUT_GET_FRAME_COUNT, argument); } + if (context->playback->isAudio) { return context->output->audio->Command(context, OUTPUT_GET_FRAME_COUNT, argument); From da04353262e1ee5616510008bc03b0df245a087d Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 30 Aug 2018 21:24:46 +0200 Subject: [PATCH 48/72] [libarmbox] libeplayer3-arm reactivate hdmi output which is stopped when neutrino shutdown Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/fcdb2a72d5d97a55122c261b39f82054da8147cd Author: max_10 Date: 2018-08-30 (Thu, 30 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 2adfb22..019a91d 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -678,6 +678,8 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * int main(int argc, char *argv[]) { + system("echo 'encoder' > /proc/stb/avs/0/input"); + pthread_t termThread; int isTermThreadStarted = 0; From e1460f18072be3bade3ef8f89505e348a2e6c37f Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 1 Sep 2018 12:59:15 +0200 Subject: [PATCH 49/72] reset seek position at the end of playback Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/3e66284a1df692f45e2e92e860d4de3c4a9edad7 Author: Jacek Jendrzej Date: 2018-09-01 (Sat, 01 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 6729a04..59fa887 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -1352,6 +1352,8 @@ static void FFMPEGThread(Context_t *context) hasPlayThreadStarted = 0; context->playback->isPlaying = 0; + seek_target_seconds = 0; + do_seek_target_seconds = 0; PlaybackDieNow(1); ffmpeg_printf(10, "terminating\n"); From c22f83ad964505bca02c1a09bae98a319664be29 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Sat, 1 Sep 2018 12:59:15 +0200 Subject: [PATCH 50/72] reset seek position at the end of playback Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/300d9101823464be21568cf096739027fd6d6297 Author: Jacek Jendrzej Date: 2018-09-01 (Sat, 01 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/container/container_ffmpeg.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 5f84216..bb12b6e 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -1343,6 +1343,8 @@ static void FFMPEGThread(Context_t *context) hasPlayThreadStarted = 0; context->playback->isPlaying = 0; + seek_target_seconds = 0; + do_seek_target_seconds = 0; PlaybackDieNow(1); ffmpeg_printf(10, "terminating\n"); } From ffd7ba8144621b31654fd507c29e95d4b2937ac5 Mon Sep 17 00:00:00 2001 From: Frankenstone Date: Sun, 19 Aug 2018 18:18:55 +0200 Subject: [PATCH 51/72] fix CEC TV ON after deepstandby - init 4 / init 3 Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/5a6210b0237cda09ea3f3418bc0c3272c1a54630 Author: Frankenstone Date: 2018-08-19 (Sun, 19 Aug 2018) ------------------ This commit was generated by Migit --- libeplayer3-arm/main/exteplayer.c | 1 + 1 file changed, 1 insertion(+) diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 7538799..6bea361 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -676,6 +676,7 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * int main(int argc, char *argv[]) { + system("echo 'encoder' > /proc/stb/avs/0/input"); pthread_t termThread; int isTermThreadStarted = 0; From 290f6cfa6c36f1ce5e9d5feca30437f0a22b07e7 Mon Sep 17 00:00:00 2001 From: BPanther Date: Tue, 28 Aug 2018 07:46:08 +0200 Subject: [PATCH 52/72] vusolo4k: small fix - but not yet ready Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/21537844c042e8aebb0699d2676b5f960119da1e Author: BPanther Date: 2018-08-28 (Tue, 28 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/hardware_caps.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libarmbox/hardware_caps.c b/libarmbox/hardware_caps.c index 1190939..782e35d 100644 --- a/libarmbox/hardware_caps.c +++ b/libarmbox/hardware_caps.c @@ -7,6 +7,7 @@ * License: GPL v2 or later */ +#include #include #include #include @@ -28,6 +29,23 @@ hw_caps_t *get_hwcaps(void) memset(&caps, 0, sizeof(hw_caps_t)); +#if BOXMODEL_VUSOLO4K + initialized = 1; + caps.has_CI = 1; + caps.can_cec = 1; + caps.can_shutdown = 1; + caps.display_xres = 480; + caps.display_yres = 320; + caps.display_type = HW_DISPLAY_GFX; + caps.display_can_deepstandby = 1; + caps.display_can_set_brightness = 1; + caps.display_has_statusline = 1; + caps.has_button_timer = 1; + caps.has_HDMI = 1; + strcpy(caps.boxvendor, "VU"); + strcpy(caps.boxname, "SOLO4K"); + strcpy(caps.boxarch, "BCM7376"); +#else initialized = 1; caps.has_CI = 1; caps.can_cec = 1; @@ -42,5 +60,6 @@ hw_caps_t *get_hwcaps(void) strcpy(caps.boxvendor, "AX-Technologies"); strcpy(caps.boxname, "HD51"); strcpy(caps.boxarch, "BCM7251S"); +#endif return ∩︀ } From 6bbf1dab8ba56441aa6a44e5200effc75cb66ebf Mon Sep 17 00:00:00 2001 From: BPanther Date: Wed, 5 Sep 2018 18:08:50 +0200 Subject: [PATCH 53/72] small fix Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b4fa159c5c42ca0b594a99b29fd8da2a67ea6305 Author: BPanther Date: 2018-09-05 (Wed, 05 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- common/ca_ci.cpp | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/common/ca_ci.cpp b/common/ca_ci.cpp index aa1fbc6..0f6c05d 100644 --- a/common/ca_ci.cpp +++ b/common/ca_ci.cpp @@ -1652,6 +1652,13 @@ FROM_FIRST: bool cCA::SendCaPMT(eDVBCISlot* slot) { printf("%s -> %s\n", FILENAME, __func__); + if (slot->fd > 0) + { +#if HAVE_ARM_HARDWARE + setInputSource(slot, true); +#endif + setSource(slot); + } if ((slot->fd > 0) && (slot->camIsReady)) { if (slot->hasCAManager) @@ -1667,14 +1674,6 @@ bool cCA::SendCaPMT(eDVBCISlot* slot) slot->camgrSession->sendSPDU(0x90, 0, 0, slot->pmtdata, slot->pmtlen); } } - - if (slot->fd > 0) - { -#if HAVE_ARM_HARDWARE - setInputSource(slot, true); -#endif - setSource(slot); - } return true; } From 8f8679f11391c50ac593c687fae2517c84c18835 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 16:57:11 +0200 Subject: [PATCH 54/72] Revert "fix missing compiler include" This reverts commit f4bbd252ceac62f593ec586b3febec6565a4eeb0. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/c18e94c2c95b1208abecb67b5560a3737a828758 Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- libeplayer3/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index 602c42c..814d106 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -4,7 +4,7 @@ noinst_LTLIBRARIES = libeplayer3.la AM_CPPFLAGS = -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS AM_CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE -AM_CPPFLAGS += -I$(srcdir)/include -I$(top_srcdir)/include +AM_CPPFLAGS += -I$(srcdir)/include AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing libeplayer3_la_SOURCES = \ From 09b8c49c8b12f77d6be164ab708da0c82bc31ac0 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 16:58:06 +0200 Subject: [PATCH 55/72] Revert "changed raspi to own thread class" This reverts commit a93605761900887923e05d323525ec608bca003c. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/9138f023f2c29780824c9b4401444c73cfc0b8af Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- raspi/Makefile.am | 3 ++- raspi/glfb.cpp | 10 +++++----- raspi/glfb.h | 6 +++--- raspi/init.cpp | 8 ++++---- 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/raspi/Makefile.am b/raspi/Makefile.am index 3bc2d31..32cd87a 100644 --- a/raspi/Makefile.am +++ b/raspi/Makefile.am @@ -10,7 +10,8 @@ AM_CPPFLAGS += \ AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_LDFLAGS = \ - -L/opt/vc/lib/ -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt + -L/opt/vc/lib/ -lopenmaxil -lbcm_host -lvcos -lvchiq_arm -lpthread -lrt \ + -lOpenThreads libraspi_la_SOURCES = \ hardware_caps.c \ diff --git a/raspi/glfb.cpp b/raspi/glfb.cpp index 764afa9..45d6473 100644 --- a/raspi/glfb.cpp +++ b/raspi/glfb.cpp @@ -19,7 +19,7 @@ */ #include -#include +#include #include "glfb.h" #include "bcm_host.h" @@ -47,8 +47,8 @@ static int curr_res; static int pitch; static VC_IMAGE_TYPE_T type = VC_IMAGE_ARGB8888; -static Mutex blit_mutex; -static Condition blit_cond; +static OpenThreads::Mutex blit_mutex; +static OpenThreads::Condition blit_cond; static bool goodbye = false; /* if set main loop is left */ static bool ready = false; /* condition predicate */ @@ -71,7 +71,7 @@ GLFramebuffer::GLFramebuffer(int x, int y) si.red.offset = 16; si.transp.offset = 24; - Thread::start(); + OpenThreads::Thread::start(); while (!ready) usleep(1); } @@ -80,7 +80,7 @@ GLFramebuffer::~GLFramebuffer() { goodbye = true; blit(); /* wake up thread */ - Thread::join(); + OpenThreads::Thread::join(); } void GLFramebuffer::run() diff --git a/raspi/glfb.h b/raspi/glfb.h index 68e2055..c5fcce6 100644 --- a/raspi/glfb.h +++ b/raspi/glfb.h @@ -17,11 +17,11 @@ #ifndef __glthread__ #define __glthread__ -#include +#include #include #include /* for screeninfo etc. */ -class GLFramebuffer : public Thread +class GLFramebuffer : public OpenThreads::Thread { public: GLFramebuffer(int x, int y); @@ -34,7 +34,7 @@ private: void *pdata; /* not yet used */ fb_var_screeninfo si; std::vector osd_buf; /* silly bounce buffer */ - void run(); /* for Thread */ + void run(); /* for OpenThreads::Thread */ void setup(); void blit_osd(); diff --git a/raspi/init.cpp b/raspi/init.cpp index 6e6adfc..47f6d9e 100644 --- a/raspi/init.cpp +++ b/raspi/init.cpp @@ -32,7 +32,7 @@ #include #include -#include +#include #include "init_td.h" #include "lt_debug.h" @@ -69,7 +69,7 @@ static void init_keymap(void) kmap[KEY_F8] = KEY_SLEEP; } -class Input: public Thread +class Input: public OpenThreads::Thread { public: Input(); @@ -82,13 +82,13 @@ class Input: public Thread Input::Input() { Init(); - Thread::start(); + start(); } Input::~Input() { running = false; - Thread::join(); + join(); } static int dirfilter(const struct dirent *d) From 9a0a03c7338e1b62f293c8fd3902c045b09e15c5 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:18:35 +0200 Subject: [PATCH 56/72] Revert "change libeplayer3 to own thread class" This reverts commit 3f238feb60426c4e4720e6a42c8697174549d0b2. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b313db12a14a5b167285065015e389076ce6c8de Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- libeplayer3/include/input.h | 6 +++-- libeplayer3/include/manager.h | 6 +++-- libeplayer3/include/output.h | 6 +++-- libeplayer3/include/player.h | 6 +++-- libeplayer3/input.cpp | 10 +++---- libeplayer3/manager.cpp | 14 +++++----- libeplayer3/output.cpp | 50 +++++++++++++++++------------------ libeplayer3/player.cpp | 4 +-- 8 files changed, 55 insertions(+), 47 deletions(-) diff --git a/libeplayer3/include/input.h b/libeplayer3/include/input.h index 2488cf9..d27e0fa 100644 --- a/libeplayer3/include/input.h +++ b/libeplayer3/include/input.h @@ -26,7 +26,9 @@ #include #include -#include +#include +#include +#include extern "C" { #include @@ -46,7 +48,7 @@ class Input friend int interrupt_cb(void *arg); private: - Mutex mutex; + OpenThreads::Mutex mutex; Track *videoTrack; Track *audioTrack; diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index 41ef416..364595b 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -26,7 +26,9 @@ #include #include -#include +#include +#include +#include extern "C" { #include @@ -64,7 +66,7 @@ class Manager private: Player *player; - Mutex mutex; + OpenThreads::Mutex mutex; std::map videoTracks, audioTracks, subtitleTracks, teletextTracks; std::map Programs; void addTrack(std::map &tracks, Track &track); diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index 2fec93e..b154427 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -26,7 +26,9 @@ #include #include -#include +#include +#include +#include extern "C" { #include @@ -48,7 +50,7 @@ class Output int videofd; int audiofd; Writer *videoWriter, *audioWriter; - Mutex audioMutex, videoMutex; + OpenThreads::Mutex audioMutex, videoMutex; Track *audioTrack, *videoTrack; Player *player; public: diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index 93629a6..b675adc 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -21,7 +21,9 @@ #ifndef __PLAYER_H__ #define __PLAYER_H__ -#include +#include +#include +#include extern "C" { #include @@ -61,7 +63,7 @@ class Player { Input input; Output output; Manager manager; - Mutex chapterMutex; + OpenThreads::Mutex chapterMutex; std::vector chapters; pthread_t playThread; diff --git a/libeplayer3/input.cpp b/libeplayer3/input.cpp index 9af9aae..30f4d68 100644 --- a/libeplayer3/input.cpp +++ b/libeplayer3/input.cpp @@ -291,17 +291,17 @@ static int lock_callback(void **mutex, enum AVLockOp op) { switch (op) { case AV_LOCK_CREATE: - *mutex = (void *) new Mutex; + *mutex = (void *) new OpenThreads::Mutex; return !*mutex; case AV_LOCK_DESTROY: - delete static_cast(*mutex); + delete static_cast(*mutex); *mutex = NULL; return 0; case AV_LOCK_OBTAIN: - static_cast(*mutex)->lock(); + static_cast(*mutex)->lock(); return 0; case AV_LOCK_RELEASE: - static_cast(*mutex)->unlock(); + static_cast(*mutex)->unlock(); return 0; default: return -1; @@ -657,7 +657,7 @@ bool Input::Stop() av_log(NULL, AV_LOG_QUIET, "%s", ""); if (avfc) { - ScopedLock lock(mutex); + OpenThreads::ScopedLock lock(mutex); for (unsigned int i = 0; i < avfc->nb_streams; i++) avcodec_close(avfc->streams[i]->codec); avformat_close_input(&avfc); diff --git a/libeplayer3/manager.cpp b/libeplayer3/manager.cpp index 275205c..da39024 100644 --- a/libeplayer3/manager.cpp +++ b/libeplayer3/manager.cpp @@ -25,7 +25,7 @@ void Manager::addTrack(std::map &tracks, Track &track) { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); std::map::iterator it = tracks.find(track.pid); if (it == tracks.end()) { Track *t = new Track; @@ -59,7 +59,7 @@ std::vector Manager::getTracks(std::map &tracks) { player->input.UpdateTracks(); std::vector res; - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); for(std::map::iterator it = tracks.begin(); it != tracks.end(); ++it) if (!it->second->inactive && !it->second->hidden) res.push_back(*it->second); @@ -88,7 +88,7 @@ std::vector Manager::getTeletextTracks() Track *Manager::getTrack(std::map &tracks, int pid) { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); std::map::iterator it = tracks.find(pid); if (it != tracks.end() && !it->second->inactive) return it->second; @@ -116,7 +116,7 @@ Track *Manager::getTeletextTrack(int pid) bool Manager::initTrackUpdate() { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); for (std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) it->second->inactive = !it->second->is_static; @@ -140,7 +140,7 @@ void Manager::addProgram(Program &program) std::vector Manager::getPrograms(void) { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); std::vector res; for (std::map::iterator it = Programs.begin(); it != Programs.end(); ++it) res.push_back(it->second); @@ -149,7 +149,7 @@ std::vector Manager::getPrograms(void) bool Manager::selectProgram(const int id) { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); std::map::iterator i = Programs.find(id); if (i != Programs.end()) { @@ -236,7 +236,7 @@ bool Manager::selectProgram(const int id) void Manager::clearTracks() { - ScopedLock m_lock(mutex); + OpenThreads::ScopedLock m_lock(mutex); for (std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) delete it->second; diff --git a/libeplayer3/output.cpp b/libeplayer3/output.cpp index 431dcb5..11e4eb7 100644 --- a/libeplayer3/output.cpp +++ b/libeplayer3/output.cpp @@ -68,9 +68,9 @@ Output::~Output() bool Output::Open() { - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); - + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); + if (videofd < 0) videofd = open(VIDEODEV, O_RDWR); @@ -102,8 +102,8 @@ bool Output::Close() { Stop(); - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1) { close(videofd); @@ -124,8 +124,8 @@ bool Output::Play() { bool ret = true; - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); AVCodecContext *avcc; @@ -154,8 +154,8 @@ bool Output::Stop() { bool ret = true; - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1) { ioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); @@ -180,8 +180,8 @@ bool Output::Pause() { bool ret = true; - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1) { if (dioctl(videofd, VIDEO_FREEZE, NULL)) @@ -200,8 +200,8 @@ bool Output::Continue() { bool ret = true; - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1 && dioctl(videofd, VIDEO_CONTINUE, NULL)) ret = false; @@ -214,7 +214,7 @@ bool Output::Continue() bool Output::Mute(bool b) { - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock a_lock(audioMutex); //AUDIO_SET_MUTE has no effect with new player return audiofd > -1 && !dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL); } @@ -224,8 +224,8 @@ bool Output::Flush() { bool ret = true; - ScopedLock v_lock(videoMutex); - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (videofd > -1 && ioctl(videofd, VIDEO_FLUSH, NULL)) ret = false; @@ -246,31 +246,31 @@ bool Output::Flush() bool Output::FastForward(int speed) { - ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock v_lock(videoMutex); return videofd > -1 && !dioctl(videofd, VIDEO_FAST_FORWARD, speed); } bool Output::SlowMotion(int speed) { - ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock v_lock(videoMutex); return videofd > -1 && !dioctl(videofd, VIDEO_SLOWMOTION, speed); } bool Output::AVSync(bool b) { - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock a_lock(audioMutex); return audiofd > -1 && !dioctl(audiofd, AUDIO_SET_AV_SYNC, b); } bool Output::ClearAudio() { - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock a_lock(audioMutex); return audiofd > -1 && !ioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); } bool Output::ClearVideo() { - ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock v_lock(videoMutex); return videofd > -1 && !ioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); } @@ -302,7 +302,7 @@ bool Output::GetFrameCount(int64_t &framecount) bool Output::SwitchAudio(Track *track) { - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock a_lock(audioMutex); if (audioTrack && track->stream == audioTrack->stream) return true; if (audiofd > -1) { @@ -329,7 +329,7 @@ bool Output::SwitchAudio(Track *track) bool Output::SwitchVideo(Track *track) { - ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock v_lock(videoMutex); if (videoTrack && track->stream == videoTrack->stream) return true; if (videofd > -1) { @@ -355,11 +355,11 @@ bool Output::Write(AVStream *stream, AVPacket *packet, int64_t pts) { switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { - ScopedLock v_lock(videoMutex); + OpenThreads::ScopedLock v_lock(videoMutex); return videofd > -1 && videoWriter && videoWriter->Write(packet, pts); } case AVMEDIA_TYPE_AUDIO: { - ScopedLock a_lock(audioMutex); + OpenThreads::ScopedLock a_lock(audioMutex); return audiofd > -1 && audioWriter && audioWriter->Write(packet, pts); } default: diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index 2c0bfe5..37ad7c1 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -372,7 +372,7 @@ bool Player::GetChapters(std::vector &positions, std::vector & positions.clear(); titles.clear(); input.UpdateTracks(); - ScopedLock m_lock(chapterMutex); + OpenThreads::ScopedLock m_lock(chapterMutex); for (std::vector::iterator it = chapters.begin(); it != chapters.end(); ++it) { positions.push_back(it->start/1000); titles.push_back(it->title); @@ -382,7 +382,7 @@ bool Player::GetChapters(std::vector &positions, std::vector & void Player::SetChapters(std::vector &Chapters) { - ScopedLock m_lock(chapterMutex); + OpenThreads::ScopedLock m_lock(chapterMutex); chapters = Chapters; } From 4cabdf7d12cf7325eb6db5c3631e74dda4f5218d Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:42:13 +0200 Subject: [PATCH 57/72] Revert "move libthread to libstb-hal" This reverts commit d5cea508e05a6b38b1edf38d7725cd41217d7c6a. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/6b8b8cd55145e171b75123cf3a4ba9624c62e040 Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- Makefile.am | 5 +- common/Makefile.am | 2 + {libthread => common}/mutex_abstraction.cpp | 12 +---- {include => common}/mutex_abstraction.h | 9 +--- common/thread_abstraction.cpp | 34 ++++++++++++ common/thread_abstraction.h | 25 +++++++++ configure.ac | 1 - generic-pc/audio.cpp | 4 +- generic-pc/audio_lib.h | 3 +- generic-pc/dmx.cpp | 31 +++-------- generic-pc/glfb.cpp | 4 +- generic-pc/glfb.h | 6 +-- generic-pc/video.cpp | 4 +- generic-pc/video_lib.h | 6 +-- include/condition_abstraction.h | 23 -------- include/reentrant_mutex.h | 16 ------ include/scoped_lock.h | 18 ------- include/thread_abstraction.h | 30 ----------- libthread/Makefile.am | 16 ------ libthread/condition_abstraction.cpp | 27 ---------- libthread/reentrant_mutex.cpp | 11 ---- libthread/scoped_lock.cpp | 12 ----- libthread/thread_abstraction.cpp | 58 --------------------- 23 files changed, 85 insertions(+), 272 deletions(-) rename {libthread => common}/mutex_abstraction.cpp (52%) rename {include => common}/mutex_abstraction.h (68%) create mode 100644 common/thread_abstraction.cpp create mode 100644 common/thread_abstraction.h delete mode 100644 include/condition_abstraction.h delete mode 100644 include/reentrant_mutex.h delete mode 100644 include/scoped_lock.h delete mode 100644 include/thread_abstraction.h delete mode 100644 libthread/Makefile.am delete mode 100644 libthread/condition_abstraction.cpp delete mode 100644 libthread/reentrant_mutex.cpp delete mode 100644 libthread/scoped_lock.cpp delete mode 100644 libthread/thread_abstraction.cpp diff --git a/Makefile.am b/Makefile.am index 5466534..c26789f 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,12 +2,11 @@ ACLOCAL_AMFLAGS = -I m4 lib_LTLIBRARIES = libstb-hal.la libstb_hal_la_SOURCES = -SUBDIRS = common tools libthread +SUBDIRS = common tools #bin_PROGRAMS = libstb-hal-test libstb_hal_la_LIBADD = \ - common/libcommon.la \ - libthread/libthread.la + common/libcommon.la #libstb_hal_test_SOURCES = libtest.cpp diff --git a/common/Makefile.am b/common/Makefile.am index 17395fc..86f3517 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -31,6 +31,8 @@ endif endif libcommon_la_SOURCES += \ + thread_abstraction.cpp \ + mutex_abstraction.cpp \ lt_debug.cpp \ proc_tools.c \ pwrmngr.cpp diff --git a/libthread/mutex_abstraction.cpp b/common/mutex_abstraction.cpp similarity index 52% rename from libthread/mutex_abstraction.cpp rename to common/mutex_abstraction.cpp index 906407a..a5a886f 100644 --- a/libthread/mutex_abstraction.cpp +++ b/common/mutex_abstraction.cpp @@ -1,4 +1,4 @@ -#include +#include "mutex_abstraction.h" Mutex::Mutex() : mMutex() @@ -6,16 +6,6 @@ Mutex::Mutex() : pthread_mutex_init(&mMutex, 0); } -Mutex::Mutex(int attr) : - mMutex() -{ - pthread_mutexattr_t Attr; - - pthread_mutexattr_init(&Attr); - pthread_mutexattr_settype(&Attr, attr); - pthread_mutex_init(&mMutex, &Attr); -} - Mutex::~Mutex() { pthread_mutex_destroy(&mMutex); diff --git a/include/mutex_abstraction.h b/common/mutex_abstraction.h similarity index 68% rename from include/mutex_abstraction.h rename to common/mutex_abstraction.h index 3ea5357..c2b78d8 100644 --- a/include/mutex_abstraction.h +++ b/common/mutex_abstraction.h @@ -5,21 +5,16 @@ class Mutex { - friend class Condition; - pthread_mutex_t mMutex; Mutex(const Mutex&); const Mutex& operator=(const Mutex&); - protected: - explicit Mutex(int); - public: Mutex(); virtual ~Mutex(); - virtual void lock(); - virtual void unlock(); + void lock(); + void unlock(); }; #endif diff --git a/common/thread_abstraction.cpp b/common/thread_abstraction.cpp new file mode 100644 index 0000000..0494fc4 --- /dev/null +++ b/common/thread_abstraction.cpp @@ -0,0 +1,34 @@ +#include "thread_abstraction.h" + +SimpleThread::SimpleThread() : + mIsRunning(false), + mThread() +{ +} + +SimpleThread::~SimpleThread() +{ + // if thread is still running on object destruction, cancel thread the hard way: + if (mIsRunning) + { + pthread_cancel(mThread); + } +} + +void SimpleThread::startThread() +{ + mIsRunning = true; + pthread_create(&mThread, 0, &SimpleThread::runThread, this); +} + +void SimpleThread::joinThread() +{ + pthread_join(mThread, 0); + mIsRunning = false; +} + +void* SimpleThread::runThread(void* ptr) +{ + static_cast(ptr)->run(); + return 0; +} diff --git a/common/thread_abstraction.h b/common/thread_abstraction.h new file mode 100644 index 0000000..45a20b6 --- /dev/null +++ b/common/thread_abstraction.h @@ -0,0 +1,25 @@ +#ifndef _SIMPLETHREAD_ABSTRACTION_H +#define _SIMPLETHREAD_ABSTRACTION_H + +#include + +class SimpleThread +{ + bool mIsRunning; + pthread_t mThread; + + static void* runThread(void*); + SimpleThread(const SimpleThread&); + const SimpleThread& operator=(const SimpleThread&); + + public: + SimpleThread(); + ~SimpleThread(); + void startThread(); + void joinThread(); + + protected: + virtual void run() = 0; +}; + +#endif diff --git a/configure.ac b/configure.ac index 56eb4ba..767eee6 100644 --- a/configure.ac +++ b/configure.ac @@ -76,7 +76,6 @@ Makefile common/Makefile libeplayer3/Makefile libeplayer3-arm/Makefile -libthread/Makefile azbox/Makefile generic-pc/Makefile libduckbox/Makefile diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 1bba357..0ee8b3b 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -104,7 +104,7 @@ int cAudio::Start(void) { lt_debug("%s >\n", __func__); if (! HAL_nodec) - Thread::startThread(); + SimpleThread::startThread(); lt_debug("%s <\n", __func__); return 0; } @@ -115,7 +115,7 @@ int cAudio::Stop(void) if (thread_started) { thread_started = false; - Thread::joinThread(); + SimpleThread::joinThread(); } lt_debug("%s <\n", __func__); return 0; diff --git a/generic-pc/audio_lib.h b/generic-pc/audio_lib.h index dc09c8d..6bcd80a 100644 --- a/generic-pc/audio_lib.h +++ b/generic-pc/audio_lib.h @@ -4,7 +4,6 @@ #define _AUDIO_LIB_H_ #include -#include #include "cs_types.h" typedef enum @@ -38,7 +37,7 @@ typedef enum AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP } AUDIO_FORMAT; -class cAudio : public Thread +class cAudio : public SimpleThread { friend class cPlayback; private: diff --git a/generic-pc/dmx.cpp b/generic-pc/dmx.cpp index 6609693..769a971 100644 --- a/generic-pc/dmx.cpp +++ b/generic-pc/dmx.cpp @@ -64,15 +64,12 @@ static const char *DMX_T[] = { }; /* map the device numbers. for now only demux0 is used */ -#define NUM_DEMUXDEV 1 -static const char *devname[NUM_DEMUXDEV] = { +static const char *devname[] = { "/dev/dvb/adapter0/demux0", + "/dev/dvb/adapter0/demux0", + "/dev/dvb/adapter0/demux0" }; -#define NUM_DEMUX 1 -static int dmx_source[NUM_DEMUX] = { 0 }; -static bool init[NUM_DEMUXDEV] = { false }; - /* uuuugly */ static int dmx_tp_count = 0; #define MAX_TS_COUNT 8 @@ -492,28 +489,12 @@ int cDemux::getUnit(void) bool cDemux::SetSource(int unit, int source) { - //lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source); - //return true; - if (unit >= NUM_DEMUX || unit < 0) { - 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); - if (source < 0 || source >= NUM_DEMUXDEV) - lt_info_c("%s(%d, %d) ERROR: source %d out of range!\n", __func__, unit, source, source); - else - dmx_source[unit] = source; + lt_info_c("%s(%d, %d): not implemented yet\n", __func__, unit, source); return true; } int cDemux::GetSource(int unit) { - //lt_info_c("%s(%d): not implemented yet\n", __func__, unit); - //return 0; - if (unit >= NUM_DEMUX || unit < 0) { - 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]); - return dmx_source[unit]; + lt_info_c("%s(%d): not implemented yet\n", __func__, unit); + return 0; } diff --git a/generic-pc/glfb.cpp b/generic-pc/glfb.cpp index a838997..3cffd0e 100644 --- a/generic-pc/glfb.cpp +++ b/generic-pc/glfb.cpp @@ -97,7 +97,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn if (input_fd < 0) lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); initKeys(); - Thread::startThread(); + SimpleThread::startThread(); while (!mInitDone) usleep(1); } @@ -105,7 +105,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn GLFramebuffer::~GLFramebuffer() { mShutDown = true; - Thread::joinThread(); + SimpleThread::joinThread(); if (input_fd >= 0) close(input_fd); } diff --git a/generic-pc/glfb.h b/generic-pc/glfb.h index 6cb803d..755a01f 100644 --- a/generic-pc/glfb.h +++ b/generic-pc/glfb.h @@ -18,8 +18,8 @@ #ifndef __glthread__ #define __glthread__ -#include -#include +#include "../common/thread_abstraction.h" +#include "../common/mutex_abstraction.h" #include #include @@ -31,7 +31,7 @@ extern "C" { #include } -class GLFramebuffer : public Thread +class GLFramebuffer : public SimpleThread { public: GLFramebuffer(int x, int y); diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index abcfd75..06ea690 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -145,7 +145,7 @@ int cVideo::Start(void *, unsigned short, unsigned short, void *) { lt_debug("%s running %d >\n", __func__, thread_running); if (!thread_running && !HAL_nodec) - Thread::startThread(); + SimpleThread::startThread(); lt_debug("%s running %d <\n", __func__, thread_running); return 0; } @@ -155,7 +155,7 @@ int cVideo::Stop(bool) lt_debug("%s running %d >\n", __func__, thread_running); if (thread_running) { thread_running = false; - Thread::joinThread(); + SimpleThread::joinThread(); } lt_debug("%s running %d <\n", __func__, thread_running); return 0; diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index a8274e8..144b53f 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -1,8 +1,8 @@ #ifndef _VIDEO_LIB_H #define _VIDEO_LIB_H -#include -#include +#include "../common/thread_abstraction.h" +#include "../common/mutex_abstraction.h" #include #include #include "cs_types.h" @@ -121,7 +121,7 @@ typedef enum #define VDEC_MAXBUFS 0x30 -class cVideo : public Thread +class cVideo : public SimpleThread { friend class GLFramebuffer; friend class cDemux; diff --git a/include/condition_abstraction.h b/include/condition_abstraction.h deleted file mode 100644 index 8374efa..0000000 --- a/include/condition_abstraction.h +++ /dev/null @@ -1,23 +0,0 @@ -#ifndef _CONDITION_ABSTRACTION_H -#define _CONDITION_ABSTRACTION_H - -#include - -#include "mutex_abstraction.h" - -class Condition -{ - pthread_cond_t mCondition; - - Condition(const Condition&); - const Condition& operator=(const Condition&); - - public: - Condition(); - virtual ~Condition(); - virtual int wait(Mutex* const aMutex); - virtual int broadcast(); - virtual int signal(); -}; - -#endif diff --git a/include/reentrant_mutex.h b/include/reentrant_mutex.h deleted file mode 100644 index bf9f740..0000000 --- a/include/reentrant_mutex.h +++ /dev/null @@ -1,16 +0,0 @@ -#ifndef _REENTRANT_MUTEX_H -#define _REENTRANT_MUTEX_H - -#include "mutex_abstraction.h" - -class ReentrantMutex : public Mutex -{ - ReentrantMutex(const ReentrantMutex&); - const ReentrantMutex& operator=(const ReentrantMutex&); - - public: - ReentrantMutex(); - virtual ~ReentrantMutex(); -}; - -#endif diff --git a/include/scoped_lock.h b/include/scoped_lock.h deleted file mode 100644 index 0c1fdb2..0000000 --- a/include/scoped_lock.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef _SCOPED_LOCK_H -#define _SCOPED_LOCK_H - -#include "mutex_abstraction.h" - -class ScopedLock -{ - Mutex& mMutex; - - ScopedLock(const ScopedLock&); - const ScopedLock& operator=(const ScopedLock&); - - public: - ScopedLock(Mutex&); - ~ScopedLock(); -}; - -#endif diff --git a/include/thread_abstraction.h b/include/thread_abstraction.h deleted file mode 100644 index 12f9f76..0000000 --- a/include/thread_abstraction.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _THREAD_ABSTRACTION_H -#define _THREAD_ABSTRACTION_H - -#include - -class Thread -{ - bool mIsRunning; - pthread_t mThread; - - static void* runThread(void*); - Thread(const Thread&); - const Thread& operator=(const Thread&); - - public: - Thread(); - virtual ~Thread(); - int startThread(); - int cancelThread(); - int detachThread(); - int joinThread(); - - int setCancelModeDisable(); - int setSchedulePriority(int); - - protected: - virtual void run() = 0; -}; - -#endif diff --git a/libthread/Makefile.am b/libthread/Makefile.am deleted file mode 100644 index 9369b1f..0000000 --- a/libthread/Makefile.am +++ /dev/null @@ -1,16 +0,0 @@ -noinst_LTLIBRARIES = libthread.la - -AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS -AM_CPPFLAGS += \ - -I$(top_srcdir)/include - -AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing - -AM_LDFLAGS = -lpthread -lrt - -libthread_la_SOURCES = \ - condition_abstraction.cpp \ - reentrant_mutex.cpp \ - scoped_lock.cpp \ - thread_abstraction.cpp \ - mutex_abstraction.cpp diff --git a/libthread/condition_abstraction.cpp b/libthread/condition_abstraction.cpp deleted file mode 100644 index 68d246a..0000000 --- a/libthread/condition_abstraction.cpp +++ /dev/null @@ -1,27 +0,0 @@ -#include - -Condition::Condition() : - mCondition() -{ - pthread_cond_init(&mCondition, 0); -} - -Condition::~Condition() -{ - pthread_cond_destroy(&mCondition); -} - -int Condition::wait(Mutex* const aMutex) -{ - return pthread_cond_wait(&mCondition, &(aMutex->mMutex)); -} - -int Condition::broadcast() -{ - return pthread_cond_broadcast(&mCondition); -} - -int Condition::signal() -{ - return pthread_cond_signal(&mCondition); -} diff --git a/libthread/reentrant_mutex.cpp b/libthread/reentrant_mutex.cpp deleted file mode 100644 index 82c3069..0000000 --- a/libthread/reentrant_mutex.cpp +++ /dev/null @@ -1,11 +0,0 @@ -#include - -ReentrantMutex::ReentrantMutex() : - Mutex(PTHREAD_MUTEX_RECURSIVE) -{ -} - -ReentrantMutex::~ReentrantMutex() -{ - //safely destroyed in ~Mutex(); -} diff --git a/libthread/scoped_lock.cpp b/libthread/scoped_lock.cpp deleted file mode 100644 index 7ff573d..0000000 --- a/libthread/scoped_lock.cpp +++ /dev/null @@ -1,12 +0,0 @@ -#include - -ScopedLock::ScopedLock(Mutex& aMutex) : - mMutex(aMutex) -{ - mMutex.lock(); -} - -ScopedLock::~ScopedLock() -{ - mMutex.unlock(); -} diff --git a/libthread/thread_abstraction.cpp b/libthread/thread_abstraction.cpp deleted file mode 100644 index afaff86..0000000 --- a/libthread/thread_abstraction.cpp +++ /dev/null @@ -1,58 +0,0 @@ -#include - -Thread::Thread() : - mIsRunning(false), - mThread() -{ -} - -Thread::~Thread() -{ - // if thread is still running on object destruction, cancel thread the hard way: - if (mIsRunning) - { - pthread_cancel(mThread); - } -} - -int Thread::startThread() -{ - mIsRunning = true; - return pthread_create(&mThread, 0, &Thread::runThread, this); -} - -int Thread::cancelThread() -{ - return pthread_cancel(mThread); - mIsRunning = false; -} - -int Thread::detachThread() -{ - mIsRunning = false; // thread shall not cancel on object destruction! - return pthread_detach(mThread); -} - -int Thread::joinThread() -{ - int ret = pthread_join(mThread, 0); - mIsRunning = false; - return ret; -} - -int Thread::setCancelModeDisable() -{ - return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, 0); -} - -int Thread::setSchedulePriority(int prio) -{ - return pthread_setschedprio(mThread, prio); -} - -void* Thread::runThread(void* ptr) -{ - Thread* t = static_cast(ptr); - t->run(); - return 0; -} From c36afa86ec77a337081d01b03d0ed27023e382ef Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:42:46 +0200 Subject: [PATCH 58/72] Revert "fix thread namespace" This reverts commit 03a7525218ce205ec0a508109ff9ca4179bc7408. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/1790425e86565fd2f2c77067c0b36cc9d10d50ac Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- common/thread_abstraction.cpp | 14 +++++++------- common/thread_abstraction.h | 14 +++++++------- generic-pc/audio.cpp | 4 ++-- generic-pc/audio_lib.h | 2 +- generic-pc/glfb.cpp | 4 ++-- generic-pc/glfb.h | 2 +- generic-pc/video.cpp | 4 ++-- generic-pc/video_lib.h | 2 +- 8 files changed, 23 insertions(+), 23 deletions(-) diff --git a/common/thread_abstraction.cpp b/common/thread_abstraction.cpp index 0494fc4..271755c 100644 --- a/common/thread_abstraction.cpp +++ b/common/thread_abstraction.cpp @@ -1,12 +1,12 @@ #include "thread_abstraction.h" -SimpleThread::SimpleThread() : +Thread::Thread() : mIsRunning(false), mThread() { } -SimpleThread::~SimpleThread() +Thread::~Thread() { // if thread is still running on object destruction, cancel thread the hard way: if (mIsRunning) @@ -15,20 +15,20 @@ SimpleThread::~SimpleThread() } } -void SimpleThread::startThread() +void Thread::startThread() { mIsRunning = true; - pthread_create(&mThread, 0, &SimpleThread::runThread, this); + pthread_create(&mThread, 0, &Thread::runThread, this); } -void SimpleThread::joinThread() +void Thread::joinThread() { pthread_join(mThread, 0); mIsRunning = false; } -void* SimpleThread::runThread(void* ptr) +void* Thread::runThread(void* ptr) { - static_cast(ptr)->run(); + ((Thread*)ptr)->run(); return 0; } diff --git a/common/thread_abstraction.h b/common/thread_abstraction.h index 45a20b6..3c3e35f 100644 --- a/common/thread_abstraction.h +++ b/common/thread_abstraction.h @@ -1,20 +1,20 @@ -#ifndef _SIMPLETHREAD_ABSTRACTION_H -#define _SIMPLETHREAD_ABSTRACTION_H +#ifndef _THREAD_ABSTRACTION_H +#define _THREAD_ABSTRACTION_H #include -class SimpleThread +class Thread { bool mIsRunning; pthread_t mThread; static void* runThread(void*); - SimpleThread(const SimpleThread&); - const SimpleThread& operator=(const SimpleThread&); + Thread(const Thread&); + const Thread& operator=(const Thread&); public: - SimpleThread(); - ~SimpleThread(); + Thread(); + ~Thread(); void startThread(); void joinThread(); diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 0ee8b3b..d5605f0 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -104,7 +104,7 @@ int cAudio::Start(void) { lt_debug("%s >\n", __func__); if (! HAL_nodec) - SimpleThread::startThread(); + startThread(); lt_debug("%s <\n", __func__); return 0; } @@ -115,7 +115,7 @@ int cAudio::Stop(void) if (thread_started) { thread_started = false; - SimpleThread::joinThread(); + joinThread(); } lt_debug("%s <\n", __func__); return 0; diff --git a/generic-pc/audio_lib.h b/generic-pc/audio_lib.h index 6bcd80a..0670cd9 100644 --- a/generic-pc/audio_lib.h +++ b/generic-pc/audio_lib.h @@ -37,7 +37,7 @@ typedef enum AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP } AUDIO_FORMAT; -class cAudio : public SimpleThread +class cAudio : public Thread { friend class cPlayback; private: diff --git a/generic-pc/glfb.cpp b/generic-pc/glfb.cpp index 3cffd0e..fa35e88 100644 --- a/generic-pc/glfb.cpp +++ b/generic-pc/glfb.cpp @@ -97,7 +97,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn if (input_fd < 0) lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); initKeys(); - SimpleThread::startThread(); + startThread(); while (!mInitDone) usleep(1); } @@ -105,7 +105,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn GLFramebuffer::~GLFramebuffer() { mShutDown = true; - SimpleThread::joinThread(); + joinThread(); if (input_fd >= 0) close(input_fd); } diff --git a/generic-pc/glfb.h b/generic-pc/glfb.h index 755a01f..aa4017d 100644 --- a/generic-pc/glfb.h +++ b/generic-pc/glfb.h @@ -31,7 +31,7 @@ extern "C" { #include } -class GLFramebuffer : public SimpleThread +class GLFramebuffer : public Thread { public: GLFramebuffer(int x, int y); diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index 06ea690..8544e8b 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -145,7 +145,7 @@ int cVideo::Start(void *, unsigned short, unsigned short, void *) { lt_debug("%s running %d >\n", __func__, thread_running); if (!thread_running && !HAL_nodec) - SimpleThread::startThread(); + startThread(); lt_debug("%s running %d <\n", __func__, thread_running); return 0; } @@ -155,7 +155,7 @@ int cVideo::Stop(bool) lt_debug("%s running %d >\n", __func__, thread_running); if (thread_running) { thread_running = false; - SimpleThread::joinThread(); + joinThread(); } lt_debug("%s running %d <\n", __func__, thread_running); return 0; diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index 144b53f..2b8e14e 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -121,7 +121,7 @@ typedef enum #define VDEC_MAXBUFS 0x30 -class cVideo : public SimpleThread +class cVideo : public Thread { friend class GLFramebuffer; friend class cDemux; From d45c3835a83287b94d7fafb7baf2808cbb0aeda8 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:45:07 +0200 Subject: [PATCH 59/72] Revert "add changed files" This reverts commit 7f2f83b16e94b73b309a086fbee049b8fc7f76e3. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b6aeafc446e2a3cc09a54ba1f675c29f6fbe3f11 Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- common/Makefile.am | 2 -- common/thread_abstraction.cpp | 1 - generic-pc/Makefile.am | 1 + generic-pc/audio.cpp | 5 +++-- generic-pc/audio_lib.h | 3 ++- generic-pc/glfb.cpp | 4 ++-- generic-pc/glfb.h | 9 ++++----- generic-pc/video.cpp | 4 ++-- generic-pc/video_lib.h | 9 ++++----- 9 files changed, 18 insertions(+), 20 deletions(-) diff --git a/common/Makefile.am b/common/Makefile.am index 86f3517..17395fc 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -31,8 +31,6 @@ endif endif libcommon_la_SOURCES += \ - thread_abstraction.cpp \ - mutex_abstraction.cpp \ lt_debug.cpp \ proc_tools.c \ pwrmngr.cpp diff --git a/common/thread_abstraction.cpp b/common/thread_abstraction.cpp index 271755c..57b7759 100644 --- a/common/thread_abstraction.cpp +++ b/common/thread_abstraction.cpp @@ -30,5 +30,4 @@ void Thread::joinThread() void* Thread::runThread(void* ptr) { ((Thread*)ptr)->run(); - return 0; } diff --git a/generic-pc/Makefile.am b/generic-pc/Makefile.am index baf15da..fd230bd 100644 --- a/generic-pc/Makefile.am +++ b/generic-pc/Makefile.am @@ -9,6 +9,7 @@ AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_LDFLAGS = \ -lglut -lGL -lGLU -lGLEW -lao \ + -lOpenThreads \ @AVFORMAT_LIBS@ \ @AVUTIL_LIBS@ \ @AVCODEC_LIBS@ \ diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index d5605f0..03558f8 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -29,6 +29,7 @@ #define lt_debug(args...) _lt_debug(HAL_DEBUG_AUDIO, this, args) #define lt_info(args...) _lt_info(HAL_DEBUG_AUDIO, this, args) +#include extern "C" { #include @@ -104,7 +105,7 @@ int cAudio::Start(void) { lt_debug("%s >\n", __func__); if (! HAL_nodec) - startThread(); + OpenThreads::Thread::start(); lt_debug("%s <\n", __func__); return 0; } @@ -115,7 +116,7 @@ int cAudio::Stop(void) if (thread_started) { thread_started = false; - joinThread(); + OpenThreads::Thread::join(); } lt_debug("%s <\n", __func__); return 0; diff --git a/generic-pc/audio_lib.h b/generic-pc/audio_lib.h index 0670cd9..fc96d27 100644 --- a/generic-pc/audio_lib.h +++ b/generic-pc/audio_lib.h @@ -4,6 +4,7 @@ #define _AUDIO_LIB_H_ #include +#include #include "cs_types.h" typedef enum @@ -37,7 +38,7 @@ typedef enum AUDIO_FMT_ADVANCED = AUDIO_FMT_MLP } AUDIO_FORMAT; -class cAudio : public Thread +class cAudio : public OpenThreads::Thread { friend class cPlayback; private: diff --git a/generic-pc/glfb.cpp b/generic-pc/glfb.cpp index fa35e88..099f213 100644 --- a/generic-pc/glfb.cpp +++ b/generic-pc/glfb.cpp @@ -97,7 +97,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn if (input_fd < 0) lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); initKeys(); - startThread(); + OpenThreads::Thread::start(); while (!mInitDone) usleep(1); } @@ -105,7 +105,7 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn GLFramebuffer::~GLFramebuffer() { mShutDown = true; - joinThread(); + OpenThreads::Thread::join(); if (input_fd >= 0) close(input_fd); } diff --git a/generic-pc/glfb.h b/generic-pc/glfb.h index aa4017d..78376ba 100644 --- a/generic-pc/glfb.h +++ b/generic-pc/glfb.h @@ -18,9 +18,8 @@ #ifndef __glthread__ #define __glthread__ -#include "../common/thread_abstraction.h" -#include "../common/mutex_abstraction.h" - +#include +#include #include #include #include @@ -31,7 +30,7 @@ extern "C" { #include } -class GLFramebuffer : public Thread +class GLFramebuffer : public OpenThreads::Thread { public: GLFramebuffer(int x, int y); @@ -67,7 +66,7 @@ private: bool mFullscreen; /* fullscreen? */ bool mReInit; /* setup things for GL */ - Mutex mReInitLock; + OpenThreads::Mutex mReInitLock; bool mShutDown; /* if set main loop is left */ bool mInitDone; /* condition predicate */ // OpenThreads::Condition mInitCond; /* condition variable for init */ diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index 8544e8b..dcfb341 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -145,7 +145,7 @@ int cVideo::Start(void *, unsigned short, unsigned short, void *) { lt_debug("%s running %d >\n", __func__, thread_running); if (!thread_running && !HAL_nodec) - startThread(); + OpenThreads::Thread::start(); lt_debug("%s running %d <\n", __func__, thread_running); return 0; } @@ -155,7 +155,7 @@ int cVideo::Stop(bool) lt_debug("%s running %d >\n", __func__, thread_running); if (thread_running) { thread_running = false; - joinThread(); + OpenThreads::Thread::join(); } lt_debug("%s running %d <\n", __func__, thread_running); return 0; diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index 2b8e14e..ca130f5 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -1,8 +1,8 @@ #ifndef _VIDEO_LIB_H #define _VIDEO_LIB_H -#include "../common/thread_abstraction.h" -#include "../common/mutex_abstraction.h" +#include +#include #include #include #include "cs_types.h" @@ -121,7 +121,7 @@ typedef enum #define VDEC_MAXBUFS 0x30 -class cVideo : public Thread +class cVideo : public OpenThreads::Thread { friend class GLFramebuffer; friend class cDemux; @@ -211,8 +211,7 @@ class cVideo : public Thread bool thread_running; VIDEO_FORMAT v_format; VIDEO_STD v_std; - //OpenThreads::Mutex buf_m; - Mutex buf_m; + OpenThreads::Mutex buf_m; DISPLAY_AR display_aspect; DISPLAY_AR_MODE display_crop; int output_h; From e9b7d18af8fc4162f7d816ac06e4c6e44dab6adf Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:45:31 +0200 Subject: [PATCH 60/72] Revert "add mutex and thread abstraction to common files" This reverts commit 65ee259b43a521e42464d728d5d9953067446184. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/6c46000264e7c4e0039db916c07a60d893836311 Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- {common => generic-pc}/mutex_abstraction.cpp | 0 {common => generic-pc}/mutex_abstraction.h | 0 {common => generic-pc}/thread_abstraction.cpp | 0 {common => generic-pc}/thread_abstraction.h | 0 4 files changed, 0 insertions(+), 0 deletions(-) rename {common => generic-pc}/mutex_abstraction.cpp (100%) rename {common => generic-pc}/mutex_abstraction.h (100%) rename {common => generic-pc}/thread_abstraction.cpp (100%) rename {common => generic-pc}/thread_abstraction.h (100%) diff --git a/common/mutex_abstraction.cpp b/generic-pc/mutex_abstraction.cpp similarity index 100% rename from common/mutex_abstraction.cpp rename to generic-pc/mutex_abstraction.cpp diff --git a/common/mutex_abstraction.h b/generic-pc/mutex_abstraction.h similarity index 100% rename from common/mutex_abstraction.h rename to generic-pc/mutex_abstraction.h diff --git a/common/thread_abstraction.cpp b/generic-pc/thread_abstraction.cpp similarity index 100% rename from common/thread_abstraction.cpp rename to generic-pc/thread_abstraction.cpp diff --git a/common/thread_abstraction.h b/generic-pc/thread_abstraction.h similarity index 100% rename from common/thread_abstraction.h rename to generic-pc/thread_abstraction.h From bdb92dbb745bbd67e407fc0c1c5635108f8c5313 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 17:45:51 +0200 Subject: [PATCH 61/72] Revert "add mutex and thread abstraction" This reverts commit e36707596a774f4bb8511a78e3e2abf13c2cd823. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/20ea3c14b79249d6c4959e3a28ff4cbcdf78448a Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ This commit was generated by Migit --- generic-pc/mutex_abstraction.cpp | 22 --------------------- generic-pc/mutex_abstraction.h | 20 ------------------- generic-pc/thread_abstraction.cpp | 33 ------------------------------- generic-pc/thread_abstraction.h | 25 ----------------------- 4 files changed, 100 deletions(-) delete mode 100644 generic-pc/mutex_abstraction.cpp delete mode 100644 generic-pc/mutex_abstraction.h delete mode 100644 generic-pc/thread_abstraction.cpp delete mode 100644 generic-pc/thread_abstraction.h diff --git a/generic-pc/mutex_abstraction.cpp b/generic-pc/mutex_abstraction.cpp deleted file mode 100644 index a5a886f..0000000 --- a/generic-pc/mutex_abstraction.cpp +++ /dev/null @@ -1,22 +0,0 @@ -#include "mutex_abstraction.h" - -Mutex::Mutex() : - mMutex() -{ - pthread_mutex_init(&mMutex, 0); -} - -Mutex::~Mutex() -{ - pthread_mutex_destroy(&mMutex); -} - -void Mutex::lock() -{ - pthread_mutex_lock(&mMutex); -} - -void Mutex::unlock() -{ - pthread_mutex_unlock(&mMutex); -} diff --git a/generic-pc/mutex_abstraction.h b/generic-pc/mutex_abstraction.h deleted file mode 100644 index c2b78d8..0000000 --- a/generic-pc/mutex_abstraction.h +++ /dev/null @@ -1,20 +0,0 @@ -#ifndef _MUTEX_ABSTRACTION_H -#define _MUTEX_ABSTRACTION_H - -#include - -class Mutex -{ - pthread_mutex_t mMutex; - - Mutex(const Mutex&); - const Mutex& operator=(const Mutex&); - - public: - Mutex(); - virtual ~Mutex(); - void lock(); - void unlock(); -}; - -#endif diff --git a/generic-pc/thread_abstraction.cpp b/generic-pc/thread_abstraction.cpp deleted file mode 100644 index 57b7759..0000000 --- a/generic-pc/thread_abstraction.cpp +++ /dev/null @@ -1,33 +0,0 @@ -#include "thread_abstraction.h" - -Thread::Thread() : - mIsRunning(false), - mThread() -{ -} - -Thread::~Thread() -{ - // if thread is still running on object destruction, cancel thread the hard way: - if (mIsRunning) - { - pthread_cancel(mThread); - } -} - -void Thread::startThread() -{ - mIsRunning = true; - pthread_create(&mThread, 0, &Thread::runThread, this); -} - -void Thread::joinThread() -{ - pthread_join(mThread, 0); - mIsRunning = false; -} - -void* Thread::runThread(void* ptr) -{ - ((Thread*)ptr)->run(); -} diff --git a/generic-pc/thread_abstraction.h b/generic-pc/thread_abstraction.h deleted file mode 100644 index 3c3e35f..0000000 --- a/generic-pc/thread_abstraction.h +++ /dev/null @@ -1,25 +0,0 @@ -#ifndef _THREAD_ABSTRACTION_H -#define _THREAD_ABSTRACTION_H - -#include - -class Thread -{ - bool mIsRunning; - pthread_t mThread; - - static void* runThread(void*); - Thread(const Thread&); - const Thread& operator=(const Thread&); - - public: - Thread(); - ~Thread(); - void startThread(); - void joinThread(); - - protected: - virtual void run() = 0; -}; - -#endif From 4a95992d39d5ca9b27847d8b86251a2ce6e3f1b3 Mon Sep 17 00:00:00 2001 From: max_10 Date: Thu, 20 Sep 2018 18:18:46 +0200 Subject: [PATCH 62/72] fix mutex revert Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/62be12fc8860a5f4c2ae71a027ce64d58d7aa7e4 Author: max_10 Date: 2018-09-20 (Thu, 20 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- generic-pc/audio_lib.h | 2 +- generic-pc/video_lib.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/generic-pc/audio_lib.h b/generic-pc/audio_lib.h index fc96d27..375208c 100644 --- a/generic-pc/audio_lib.h +++ b/generic-pc/audio_lib.h @@ -4,7 +4,7 @@ #define _AUDIO_LIB_H_ #include -#include +#include #include "cs_types.h" typedef enum diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index ca130f5..694965c 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -220,7 +220,7 @@ class cVideo : public OpenThreads::Thread int pig_w; int pig_h; bool pig_changed; - Mutex still_m; + OpenThreads::Mutex still_m; bool stillpicture; }; From 2335688d58a6125e74ab86bda67e543c791b9070 Mon Sep 17 00:00:00 2001 From: Jacek Jendrzej Date: Tue, 14 Mar 2017 21:31:02 +0100 Subject: [PATCH 63/72] fix audio video rate info Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/ffef2649e45a9a8bd91d8ff99d1f389567ae9a1c Author: Jacek Jendrzej Date: 2017-03-14 (Tue, 14 Mar 2017) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- generic-pc/audio.cpp | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 03558f8..54d5457 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -203,7 +203,30 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m bitrate = 0; /* not used, but easy to get :-) */ mode = 0; /* default: stereo */ if (c) { - type = (c->codec_id != AV_CODEC_ID_MP2); /* only mpeg / not mpeg is indicated */ + switch (c->codec_id) { + case AV_CODEC_ID_MP2: + type = AUDIO_FMT_MPEG; + break; + case AV_CODEC_ID_MP3: + type = AUDIO_FMT_MP3; + break; + case AV_CODEC_ID_AC3: + case AV_CODEC_ID_TRUEHD: + type = AUDIO_FMT_DOLBY_DIGITAL; + break; + case AV_CODEC_ID_EAC3: + type = AUDIO_FMT_DD_PLUS; + break; + case AV_CODEC_ID_AAC: + type = AUDIO_FMT_AAC; + break; + case AV_CODEC_ID_DTS: + type = AUDIO_FMT_DTS; + break; + case AV_CODEC_ID_MLP: + type = AUDIO_FMT_MLP; + break; + } freq = c->sample_rate; bitrate = c->bit_rate; if (c->channels == 1) From 49de6bdc5f9601daea75bad88506d62207ff6ba6 Mon Sep 17 00:00:00 2001 From: vanhofen Date: Fri, 17 Mar 2017 11:19:27 +0100 Subject: [PATCH 64/72] generic-pc/audio.cpp: add default-section to c->codec_id switch ... to avoid compiler warnings Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/01d57e6199082842823d24bbc377f629c3121b6f Author: vanhofen Date: 2017-03-17 (Fri, 17 Mar 2017) Origin message was: ------------------ - generic-pc/audio.cpp: add default-section to c->codec_id switch ... to avoid compiler warnings ------------------ This commit was generated by Migit --- generic-pc/audio.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 54d5457..862bf2b 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -225,7 +225,9 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m break; case AV_CODEC_ID_MLP: type = AUDIO_FMT_MLP; - break; + break; + default: + break; } freq = c->sample_rate; bitrate = c->bit_rate; From cdee46683174de116df16c712ca8ecf9f61170a2 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Mon, 21 Oct 2013 17:44:31 +0200 Subject: [PATCH 65/72] generic-pc: don't crash in getAudioInfo if no codec is set Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/08063acf06dd334d2e78347d56bd1117b79f3e6e Author: Stefan Seyfried Date: 2013-10-21 (Mon, 21 Oct 2013) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- generic-pc/audio.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/generic-pc/audio.cpp b/generic-pc/audio.cpp index 862bf2b..e3ea30a 100644 --- a/generic-pc/audio.cpp +++ b/generic-pc/audio.cpp @@ -202,6 +202,7 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m freq = 0; bitrate = 0; /* not used, but easy to get :-) */ mode = 0; /* default: stereo */ + printf("cAudio::getAudioInfo c %p\n", c); if (c) { switch (c->codec_id) { case AV_CODEC_ID_MP2: @@ -266,7 +267,7 @@ void cAudio::getAudioInfo(int &type, int &layer, int &freq, int &bitrate, int &m } } lt_debug("%s t: %d l: %d f: %d b: %d m: %d codec_id: %x\n", - __func__, type, layer, freq, bitrate, mode, c ? c->codec_id : 0); + __func__, type, layer, freq, bitrate, mode, c?c->codec_id:-1); }; void cAudio::SetSRS(int /*iq_enable*/, int /*nmgr_enable*/, int /*iq_mode*/, int /*iq_level*/) From 7a9b660388020cd72b1d7fd765d206817597bc88 Mon Sep 17 00:00:00 2001 From: Stefan Seyfried Date: Sun, 30 Oct 2016 13:08:34 +0100 Subject: [PATCH 66/72] generic-pc: add alternative clutter based framebuffer Add a framebuffer implementation based on clutter instead of "raw" OpenGL. The performance is slightly worse, but it might bring some platform abstraction and other benefits for the future. Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/dd6921140d7d79b01ffafa649b8f01b46a99f762 Author: Stefan Seyfried Date: 2016-10-30 (Sun, 30 Oct 2016) ------------------ This commit was generated by Migit --- configure.ac | 15 ++ generic-pc/Makefile.am | 22 +- generic-pc/clutterfb.cpp | 481 +++++++++++++++++++++++++++++++++++++++ generic-pc/glfb.cpp | 1 + generic-pc/glfb.h | 33 ++- generic-pc/video.cpp | 20 +- 6 files changed, 553 insertions(+), 19 deletions(-) create mode 100644 generic-pc/clutterfb.cpp diff --git a/configure.ac b/configure.ac index 767eee6..e149c33 100644 --- a/configure.ac +++ b/configure.ac @@ -20,6 +20,18 @@ AC_DISABLE_STATIC AC_SYS_LARGEFILE AC_PROG_LIBTOOL +AC_ARG_ENABLE(clutter, + AS_HELP_STRING(--enable-clutter, use clutter instead of OpenGL), + ,[enable_clutter=no]) + +AM_CONDITIONAL(USE_CLUTTER,test "$enable_clutter" = "yes") +AM_CONDITIONAL(USE_OPENGL,test "$enable_clutter" = "no") +if test "$enable_clutter" = "yes"; then + AC_DEFINE(USE_CLUTTER,1,[use clutter instead of opengl]) +else + AC_DEFINE(USE_OPENGL,1,[use opengl instead of clutter]) +fi + if test x"$BOXTYPE" = x"tripledragon"; then PKG_CHECK_MODULES([DIRECTFB], [directfb]) fi @@ -54,6 +66,9 @@ if test x$BOXTYPE = xarmbox -a "$enable_gstreamer_10" = "yes"; then fi if test x$BOXTYPE = xgeneric -a x$BOXMODEL != xraspi; then + if test x"$enable_clutter" = xyes; then + PKG_CHECK_MODULES([CLUTTER], [clutter-1.0]) + fi PKG_CHECK_MODULES([AVFORMAT], [libavformat >= 53.21.1]) PKG_CHECK_MODULES([AVCODEC], [libavcodec >= 54.28.0]) # don't know which version is exactly needed here... diff --git a/generic-pc/Makefile.am b/generic-pc/Makefile.am index fd230bd..e2b6a5e 100644 --- a/generic-pc/Makefile.am +++ b/generic-pc/Makefile.am @@ -1,30 +1,44 @@ noinst_LTLIBRARIES = libgeneric.la AM_CPPFLAGS = -D__STDC_FORMAT_MACROS -D__STDC_CONSTANT_MACROS +AM_CPPFLAGS += -Wfatal-errors AM_CPPFLAGS += \ -I$(top_srcdir)/common \ - -I$(top_srcdir)/include + -I$(top_srcdir)/include \ + @AVUTIL_CFLAGS@ \ + @CLUTTER_CFLAGS@ AM_CXXFLAGS = -fno-rtti -fno-exceptions -fno-strict-aliasing AM_LDFLAGS = \ - -lglut -lGL -lGLU -lGLEW -lao \ + -lao \ -lOpenThreads \ @AVFORMAT_LIBS@ \ @AVUTIL_LIBS@ \ @AVCODEC_LIBS@ \ @SWRESAMPLE_LIBS@ \ - @SWSCALE_LIBS@ + @SWSCALE_LIBS@ \ + @CLUTTER_LIBS@ + +if USE_OPENGL +AM_LDFLAGS += -lglut -lGL -lGLU -lGLEW -lao +endif libgeneric_la_SOURCES = \ hardware_caps.c \ dmx.cpp \ video.cpp \ audio.cpp \ - glfb.cpp \ init.cpp \ record.cpp +if USE_CLUTTER +libgeneric_la_SOURCES += clutterfb.cpp +endif +if USE_OPENGL +libgeneric_la_SOURCES += glfb.cpp +endif + if ENABLE_GSTREAMER_01 libgeneric_la_SOURCES += \ playback_gst_01.cpp diff --git a/generic-pc/clutterfb.cpp b/generic-pc/clutterfb.cpp new file mode 100644 index 0000000..2c61def --- /dev/null +++ b/generic-pc/clutterfb.cpp @@ -0,0 +1,481 @@ +/* + Framebuffer implementation using clutter https://developer.gnome.org/clutter/ + Copyright (C) 2016 Stefan Seyfried + + based on the openGL framebuffer implementation + Copyright 2010 Carsten Juttner + Copyright 2012,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 . + + TODO: AV-Sync code is "experimental" at best +*/ + +#include "config.h" +#include + +#include +#include + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include "glfb_priv.h" +#include "video_priv.h" +#include "audio_priv.h" + +#include + +#include "lt_debug.h" + +#define lt_debug_c(args...) _lt_debug(HAL_DEBUG_INIT, NULL, args) +#define lt_info_c(args...) _lt_info(HAL_DEBUG_INIT, NULL, args) +#define lt_debug(args...) _lt_debug(HAL_DEBUG_INIT, this, args) +#define lt_info(args...) _lt_info(HAL_DEBUG_INIT, this, args) + + +extern VDec *vdec; +extern ADec *adec; + +/* the private class that does stuff only needed inside libstb-hal. + * is used e.g. by cVideo... */ +GLFbPC *glfb_priv = NULL; + +GLFramebuffer::GLFramebuffer(int x, int y) +{ + Init(); + glfb_priv = new GLFbPC(x, y, osd_buf); + si = glfb_priv->getScreenInfo(); + start(); + while (!glfb_priv->mInitDone) + usleep(1); +} + +GLFramebuffer::~GLFramebuffer() +{ + glfb_priv->mShutDown = true; + join(); + delete glfb_priv; + glfb_priv = NULL; +} + +void GLFramebuffer::blit() +{ + glfb_priv->blit(); +} + +GLFbPC::GLFbPC(int x, int y, std::vector &buf): mReInit(true), mShutDown(false), mInitDone(false) +{ + osd_buf = &buf; + mState.width = x; + mState.height = y; + mX = &_mX[0]; + mY = &_mY[0]; + *mX = x; + *mY = y; + av_reduce(&mOA.num, &mOA.den, x, y, INT_MAX); + mVA = mOA; /* initial aspect ratios are from the FB resolution, those */ + _mVA = mVA; /* will be updated by the videoDecoder functions anyway */ + mVAchanged = true; + mCrop = DISPLAY_AR_MODE_PANSCAN; + zoom = 1.0; + xscale = 1.0; + const char *tmp = getenv("GLFB_FULLSCREEN"); + mFullscreen = !!(tmp); + + mState.blit = true; + last_apts = 0; + + /* linux framebuffer compat mode */ + si.bits_per_pixel = 32; + si.xres = mState.width; + si.xres_virtual = si.xres; + si.yres = mState.height; + si.yres_virtual = si.yres; + si.blue.length = 8; + si.blue.offset = 0; + si.green.length = 8; + si.green.offset = 8; + si.red.length = 8; + si.red.offset = 16; + si.transp.length = 8; + si.transp.offset = 24; + + unlink("/tmp/neutrino.input"); + mkfifo("/tmp/neutrino.input", 0600); + input_fd = open("/tmp/neutrino.input", O_RDWR|O_CLOEXEC|O_NONBLOCK); + if (input_fd < 0) + lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); + initKeys(); +} + +GLFbPC::~GLFbPC() +{ + mShutDown = true; + if (input_fd >= 0) + close(input_fd); + osd_buf->clear(); +} + +void GLFbPC::initKeys() +{ + mKeyMap[CLUTTER_KEY_Up] = KEY_UP; + mKeyMap[CLUTTER_KEY_Down] = KEY_DOWN; + mKeyMap[CLUTTER_KEY_Left] = KEY_LEFT; + mKeyMap[CLUTTER_KEY_Right] = KEY_RIGHT; + + mKeyMap[CLUTTER_KEY_F1] = KEY_RED; + mKeyMap[CLUTTER_KEY_F2] = KEY_GREEN; + mKeyMap[CLUTTER_KEY_F3] = KEY_YELLOW; + mKeyMap[CLUTTER_KEY_F4] = KEY_BLUE; + + mKeyMap[CLUTTER_KEY_F5] = KEY_WWW; + mKeyMap[CLUTTER_KEY_F6] = KEY_SUBTITLE; + mKeyMap[CLUTTER_KEY_F7] = KEY_MOVE; + mKeyMap[CLUTTER_KEY_F8] = KEY_SLEEP; + + mKeyMap[CLUTTER_KEY_Page_Up] = KEY_PAGEUP; + mKeyMap[CLUTTER_KEY_Page_Down] = KEY_PAGEDOWN; + + mKeyMap[CLUTTER_KEY_Return] = KEY_OK; + mKeyMap[CLUTTER_KEY_Escape] = KEY_EXIT; + mKeyMap['e'] = KEY_EPG; + mKeyMap['i'] = KEY_INFO; + mKeyMap['m'] = KEY_MENU; + + mKeyMap['+'] = KEY_VOLUMEUP; + mKeyMap['-'] = KEY_VOLUMEDOWN; + mKeyMap['.'] = KEY_MUTE; + mKeyMap['h'] = KEY_HELP; + mKeyMap['p'] = KEY_POWER; + + mKeyMap['0'] = KEY_0; + mKeyMap['1'] = KEY_1; + mKeyMap['2'] = KEY_2; + mKeyMap['3'] = KEY_3; + mKeyMap['4'] = KEY_4; + mKeyMap['5'] = KEY_5; + mKeyMap['6'] = KEY_6; + mKeyMap['7'] = KEY_7; + mKeyMap['8'] = KEY_8; + mKeyMap['9'] = KEY_9; +} + +static ClutterActor *stage = NULL; +static ClutterActor *fb_actor = NULL; +static ClutterActor *vid_actor = NULL; +static ClutterTimeline *tl = NULL; +void GLFramebuffer::run() +{ + int argc = 1; + int x = glfb_priv->mState.width; + int y = glfb_priv->mState.height; + /* some dummy commandline for GLUT to be happy */ + char *a = (char *)"neutrino"; + char **argv = (char **)malloc(sizeof(char *) * 2); + argv[0] = a; + argv[1] = NULL; + lt_info("GLFB: GL thread starting x %d y %d\n", x, y); + if (clutter_init(&argc, &argv) != CLUTTER_INIT_SUCCESS) { + lt_info("GLFB: error initializing clutter\n"); + return; + } + lt_info("GLFB: %s:%d\n", __func__, __LINE__); + ClutterColor stage_color = { 0, 0, 0, 255 }; + stage = clutter_stage_new(); + clutter_actor_set_size(stage, x, y); + clutter_actor_set_background_color(stage, &stage_color); + clutter_actor_set_content_gravity(stage, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); + //g_signal_connect(stage, "destroy", G_CALLBACK(clutter_main_quit), NULL); + g_signal_connect(stage, "key-press-event", G_CALLBACK(GLFbPC::keyboardcb), (void *)1); + g_signal_connect(stage, "key-release-event", G_CALLBACK(GLFbPC::keyboardcb), NULL); + clutter_stage_set_user_resizable(CLUTTER_STAGE (stage), TRUE); + clutter_actor_grab_key_focus(stage); + clutter_actor_show(stage); + + /* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */ + int fbmem = x * y * 4 * 2; + osd_buf.resize(fbmem); + lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data()); + + /* video plane is below FB plane, so it comes first */ + vid_actor = clutter_actor_new(); + ClutterContent *fb = clutter_image_new(); + /* osd_buf, because it starts up black */ + if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGR_888, x, y, x*3, NULL)) { + lt_info("GLFB::%s clutter_image_set_data failed? (vid)\n", __func__); + _exit(1); /* life is hard */ + } + clutter_actor_set_content(vid_actor, fb); + g_object_unref(fb); + clutter_actor_set_size(vid_actor, x, y); + clutter_actor_set_position(vid_actor, 0, 0); + clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0)); + clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0)); + clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0)); + clutter_actor_add_constraint(vid_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0)); + clutter_actor_set_content_gravity(vid_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); + clutter_actor_set_pivot_point(vid_actor, 0.5, 0.5); + clutter_actor_add_child(stage, vid_actor); + clutter_actor_show(vid_actor); + + fb_actor = clutter_actor_new(); + fb = clutter_image_new(); + if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf.data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) { + lt_info("GLFB::%s clutter_image_set_data failed? (osd)\n", __func__); + _exit(1); /* life is hard */ + } + clutter_actor_set_content(fb_actor, fb); + g_object_unref(fb); + clutter_actor_set_size(fb_actor, x, y); + clutter_actor_set_position(fb_actor, 0, 0); + clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_WIDTH, 0)); + clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_HEIGHT, 0)); + clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_X, 0)); + clutter_actor_add_constraint(fb_actor, clutter_bind_constraint_new(stage, CLUTTER_BIND_Y, 0)); + clutter_actor_set_content_gravity(fb_actor, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT); + clutter_actor_add_child(stage, fb_actor); + clutter_actor_show(fb_actor); + + glfb_priv->mInitDone = true; /* signal that setup is finished */ + tl = clutter_timeline_new(100); + g_signal_connect(tl, "new-frame", G_CALLBACK(GLFbPC::rendercb), NULL); + clutter_timeline_set_repeat_count(tl, -1); + clutter_timeline_start(tl); + clutter_main(); + lt_info("GLFB: GL thread stopping\n"); +} + +/* static */ void GLFbPC::rendercb() +{ + glfb_priv->render(); +} + +/* static */ bool GLFbPC::keyboardcb(ClutterActor * /*actor*/, ClutterEvent *event, gpointer user_data) +{ + guint key = clutter_event_get_key_symbol (event); + int keystate = user_data ? 1 : 0; + lt_info_c("GLFB::%s: 0x%x, %d\n", __func__, key, keystate); + + struct input_event ev; + if (key == 'f' && keystate) + { + lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on"); + glfb_priv->mFullscreen = !(glfb_priv->mFullscreen); + glfb_priv->mReInit = true; + return true; + } + std::map::const_iterator i = glfb_priv->mKeyMap.find(key); + if (i == glfb_priv->mKeyMap.end()) + return true; + ev.code = i->second; + ev.value = keystate; /* key own */ + ev.type = EV_KEY; + gettimeofday(&ev.time, NULL); + lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code); + write(glfb_priv->input_fd, &ev, sizeof(ev)); + return true; +} + +int sleep_us = 30000; + +void GLFbPC::render() +{ + if(mShutDown) + clutter_main_quit(); + + mReInitLock.lock(); + if (mReInit) + { + int xoff = 0; + int yoff = 0; + mVAchanged = true; + mReInit = false; +#if 0 + mX = &_mX[mFullscreen]; + mY = &_mY[mFullscreen]; +#endif + *mX = *mY * mOA.num / mOA.den; + if (mFullscreen) { + clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), TRUE); + clutter_actor_show(stage); + clutter_stage_ensure_redraw(CLUTTER_STAGE(stage)); + } else { + clutter_stage_set_fullscreen(CLUTTER_STAGE(stage), FALSE); +// *mX = *mY * mOA.num / mOA.den; + clutter_actor_set_size(stage, *mX, *mY); + } + lt_info("%s: reinit mX:%d mY:%d xoff:%d yoff:%d fs %d\n", + __func__, *mX, *mY, xoff, yoff, mFullscreen); + } + mReInitLock.unlock(); + + bltDisplayBuffer(); /* decoded video stream */ + if (mState.blit) { + /* only blit manually after fb->blit(), this helps to find missed blit() calls */ + mState.blit = false; + lt_debug("GLFB::%s blit!\n", __func__); + bltOSDBuffer(); /* OSD */ + } + + if (mVAchanged) + { + mVAchanged = false; + zoom = 1.0; + float xzoom = 1.0; + //xscale = 1.0; + int cmp = av_cmp_q(mVA, mOA); + const AVRational a149 = { 14, 9 }; + switch (cmp) { + default: + case INT_MIN: /* invalid */ + case 0: /* identical */ + lt_debug("%s: mVA == mOA (or fullscreen mode :-)\n", __func__); + break; + case 1: /* mVA > mOA -- video is wider than display */ + lt_debug("%s: mVA > mOA\n", __func__); + switch (mCrop) { + case DISPLAY_AR_MODE_PANSCAN: + zoom = av_q2d(mVA) / av_q2d(mOA); + break; + case DISPLAY_AR_MODE_LETTERBOX: + break; + case DISPLAY_AR_MODE_PANSCAN2: + zoom = av_q2d(a149) / av_q2d(mOA); + break; + case DISPLAY_AR_MODE_NONE: + xzoom = av_q2d(mOA) / av_q2d(mVA); + zoom = av_q2d(mVA) / av_q2d(mOA); + break; + default: + break; + } + break; + case -1: /* mVA < mOA -- video is taller than display */ + lt_debug("%s: mVA < mOA\n", __func__); + switch (mCrop) { + case DISPLAY_AR_MODE_LETTERBOX: + break; + case DISPLAY_AR_MODE_PANSCAN2: + if (av_cmp_q(a149, mOA) < 0) { + zoom = av_q2d(mVA) * av_q2d(a149) / av_q2d(mOA); + break; + } + /* fallthrough for output format 14:9 */ + case DISPLAY_AR_MODE_PANSCAN: + zoom = av_q2d(mOA) / av_q2d(mVA); + break; + case DISPLAY_AR_MODE_NONE: + xzoom = av_q2d(mOA) / av_q2d(mVA); + break; + default: + break; + } + break; + } + lt_debug("zoom: %f xscale: %f xzoom: %f\n", zoom, xscale,xzoom); + clutter_actor_set_scale(vid_actor, xscale*zoom*xzoom, zoom); + } + clutter_timeline_stop(tl); + clutter_timeline_set_delay(tl, sleep_us/1000); + clutter_timeline_start(tl); +} + +void GLFbPC::bltOSDBuffer() +{ + // lt_info("%s\n", __func__); + int x = glfb_priv->mState.width; + int y = glfb_priv->mState.height; + ClutterContent *fb = clutter_image_new(); + if (!clutter_image_set_data(CLUTTER_IMAGE(fb), osd_buf->data(), COGL_PIXEL_FORMAT_BGRA_8888, x, y, x*4, NULL)) { + lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__); + _exit(1); /* life is hard */ + } + clutter_actor_set_content(fb_actor, fb); + g_object_unref(fb); + clutter_actor_show(fb_actor); +} + +void GLFbPC::bltDisplayBuffer() +{ + // lt_info("GLFB::%s vdec: %p\n", __func__, vdec); + if (!vdec) /* cannot start yet */ + return; + static bool warn = true; + VDec::SWFramebuffer *buf = vdec->getDecBuf(); + if (!buf) { + if (warn) + lt_info("GLFB::%s did not get a buffer...\n", __func__); + warn = false; + return; + } + warn = true; + int w = buf->width(), h = buf->height(); + if (w == 0 || h == 0) + return; + + AVRational a = buf->AR(); + if (a.den != 0 && a.num != 0 && av_cmp_q(a, _mVA)) { + _mVA = a; + /* _mVA is the raw buffer's aspect, mVA is the real scaled output aspect */ + av_reduce(&mVA.num, &mVA.den, w * a.num, h * a.den, INT_MAX); + // mVA.num: 16 mVA.den: 9 w: 720 h: 576 + // 16*576/720/9 = 1.42222 + xscale = (double)mVA.num*h/(double)mVA.den/w; + mVAchanged = true; + } + + ClutterContent *fb = clutter_image_new(); + if (!clutter_image_set_data(CLUTTER_IMAGE(fb), &(*buf)[0], COGL_PIXEL_FORMAT_BGR_888, w, h, w*3, NULL)) { + lt_info("GLFB::%s clutter_image_set_data failed?\n", __func__); + _exit(1); /* life is hard */ + } + clutter_actor_set_content(vid_actor, fb); + g_object_unref(fb); + clutter_actor_show(vid_actor); + + /* "rate control" mechanism starts here... + * this implementation is pretty naive and not working too well, but + * better this than nothing... :-) */ + int64_t apts = 0; + int64_t vpts = buf->pts(); + if (adec) + apts = adec->getPts(); + if (apts != last_apts) { + int rate, dummy1, dummy2; + if (apts < vpts) + sleep_us = (sleep_us * 2 + (vpts - apts)*10/9) / 3; + else if (sleep_us > 1000) + sleep_us -= 1000; + last_apts = apts; + vdec->getPictureInfo(dummy1, dummy2, rate); + if (rate > 0) + rate = 2000000 / rate; /* limit to half the frame rate */ + else + rate = 50000; /* minimum 20 fps */ + if (sleep_us > rate) + sleep_us = rate; + else if (sleep_us < 1) + sleep_us = 1; + } + lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n", + buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, vdec->buf_num); +} diff --git a/generic-pc/glfb.cpp b/generic-pc/glfb.cpp index 099f213..3811056 100644 --- a/generic-pc/glfb.cpp +++ b/generic-pc/glfb.cpp @@ -22,6 +22,7 @@ TODO: AV-Sync code is "experimental" at best */ +#include "config.h" #include #include diff --git a/generic-pc/glfb.h b/generic-pc/glfb.h index 78376ba..bc7b9f5 100644 --- a/generic-pc/glfb.h +++ b/generic-pc/glfb.h @@ -1,6 +1,6 @@ /* Copyright 2010 Carsten Juttner - Copyright 2012,2013 Stefan Seyfried + Copyright 2012,2013,2016 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 @@ -18,14 +18,20 @@ #ifndef __glthread__ #define __glthread__ +#include #include #include #include #include +#if USE_OPENGL #include #include #include #include /* for screeninfo etc. */ +#endif +#if USE_CLUTTER +#include +#endif extern "C" { #include } @@ -35,18 +41,15 @@ class GLFramebuffer : public OpenThreads::Thread public: GLFramebuffer(int x, int y); ~GLFramebuffer(); - void run(); std::vector *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */ - int getOSDWidth() { return mState.width; } int getOSDHeight() { return mState.height; } void blit() { mState.blit = true; } - + fb_var_screeninfo getScreenInfo() { return screeninfo; } void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; } void clear(); - fb_var_screeninfo getScreenInfo() { return screeninfo; } int getWindowID() { return GLWinID; } private: @@ -74,33 +77,45 @@ private: std::vector mOSDBuffer; /* silly bounce buffer */ +#if USE_OPENGL std::map mKeyMap; std::map mSpecialMap; +#endif +#if USE_CLUTTER + std::map mKeyMap; +#endif int input_fd; int64_t last_apts; static void rendercb(); /* callback for GLUT */ void render(); /* actual render function */ +#if USE_OPENGL static void keyboardcb(unsigned char key, int x, int y); static void specialcb(int key, int x, int y); static void resizecb(int w, int h); void checkReinit(int w, int h); /* e.g. in case window was resized */ + void setupGLObjects(); /* PBOs, textures and stuff */ + void releaseGLObjects(); + void drawSquare(float size, float x_factor = 1); /* do not be square */ +#endif +#if USE_CLUTTER + static bool keyboardcb(ClutterActor *actor, ClutterEvent *event, gpointer user_data); +#endif void initKeys(); /* setup key bindings for window */ void setupCtx(); /* create the window and make the context current */ void setupOSDBuffer(); /* create the OSD buffer */ - void setupGLObjects(); /* PBOs, textures and stuff */ - void releaseGLObjects(); - void drawSquare(float size, float x_factor = 1); /* do not be square */ struct { int width; /* width and height, fixed for a framebuffer instance */ int height; + bool blit; +#if USE_OPENGL GLuint osdtex; /* holds the OSD texture */ GLuint pbo; /* PBO we use for transfer to texture */ GLuint displaytex; /* holds the display texture */ GLuint displaypbo; - bool blit; +#endif } mState; void bltOSDBuffer(); diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index dcfb341..8237305 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -23,6 +23,7 @@ * TODO: buffer handling surely needs some locking... */ +#include "config.h" #include #include #include @@ -39,6 +40,13 @@ extern "C" { /* my own buf 256k */ #define DMX_BUF_SZ 0x20000 +#if USE_OPENGL +#define VDEC_PIXFMT AV_PIX_FMT_RGB32 +#endif +#if USE_CLUTTER +#define VDEC_PIXFMT AV_PIX_FMT_BGR24 +#endif + #include "video_lib.h" #include "dmx_hal.h" #include "glfb.h" @@ -294,9 +302,9 @@ void cVideo::ShowPicture(const char *fname) if (avpkt.size > len) lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len); if (got_frame) { - unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, c->width, c->height, 1); + unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1); struct SwsContext *convert = sws_getContext(c->width, c->height, c->pix_fmt, - c->width, c->height, AV_PIX_FMT_RGB32, + c->width, c->height, VDEC_PIXFMT, SWS_BICUBIC, 0, 0, 0); if (!convert) lt_info("%s: ERROR setting up SWS context\n", __func__); @@ -305,7 +313,7 @@ void cVideo::ShowPicture(const char *fname) SWFramebuffer *f = &buffers[buf_in]; if (f->size() < need) f->resize(need); - av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], AV_PIX_FMT_RGB32, + av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT, c->width, c->height, 1); sws_scale(convert, frame->data, frame->linesize, 0, c->height, rgbframe->data, rgbframe->linesize); @@ -538,10 +546,10 @@ void cVideo::run(void) lt_info("%s: WARN: pkt->size %d != len %d\n", __func__, avpkt.size, len); still_m.lock(); if (got_frame && ! stillpicture) { - unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, c->width, c->height, 1); + unsigned int need = av_image_get_buffer_size(VDEC_PIXFMT, c->width, c->height, 1); convert = sws_getCachedContext(convert, c->width, c->height, c->pix_fmt, - c->width, c->height, AV_PIX_FMT_RGB32, + c->width, c->height, VDEC_PIXFMT, SWS_BICUBIC, 0, 0, 0); if (!convert) lt_info("%s: ERROR setting up SWS context\n", __func__); @@ -550,7 +558,7 @@ void cVideo::run(void) SWFramebuffer *f = &buffers[buf_in]; if (f->size() < need) f->resize(need); - av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], AV_PIX_FMT_RGB32, + av_image_fill_arrays(rgbframe->data, rgbframe->linesize, &(*f)[0], VDEC_PIXFMT, c->width, c->height, 1); sws_scale(convert, frame->data, frame->linesize, 0, c->height, rgbframe->data, rgbframe->linesize); From b33c55deef03e94f0619239107f4257de6e269ef Mon Sep 17 00:00:00 2001 From: max_10 Date: Fri, 21 Sep 2018 19:00:11 +0200 Subject: [PATCH 67/72] generic-pc: rework glfb (thx seife) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/f2136cc7a6881791463d6fbc8cf051109a06be05 Author: max_10 Date: 2018-09-21 (Fri, 21 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- generic-pc/glfb.cpp | 179 +++++++++++++++++------------ generic-pc/{glfb.h => glfb_priv.h} | 38 +++--- generic-pc/init.cpp | 1 + generic-pc/video.cpp | 33 ++++-- generic-pc/video_lib.h | 4 +- include/glfb.h | 50 ++++++-- 6 files changed, 191 insertions(+), 114 deletions(-) rename generic-pc/{glfb.h => glfb_priv.h} (82%) diff --git a/generic-pc/glfb.cpp b/generic-pc/glfb.cpp index 3811056..19d1f29 100644 --- a/generic-pc/glfb.cpp +++ b/generic-pc/glfb.cpp @@ -38,8 +38,7 @@ #include #include #include -#include "glfb.h" -#include +#include "glfb_priv.h" #include "video_lib.h" #include "audio_lib.h" @@ -54,10 +53,36 @@ extern cVideo *videoDecoder; extern cAudio *audioDecoder; -static GLFramebuffer *gThiz = 0; /* GLUT does not allow for an arbitrary argument to the render func */ +/* the private class that does stuff only needed inside libstb-hal. + * is used e.g. by cVideo... */ +GLFbPC *glfb_priv = NULL; -GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mInitDone(false) +GLFramebuffer::GLFramebuffer(int x, int y) { + Init(); + glfb_priv = new GLFbPC(x, y, osd_buf); + si = glfb_priv->getScreenInfo(); + start(); + while (!glfb_priv->mInitDone) + usleep(1); +} + +GLFramebuffer::~GLFramebuffer() +{ + glfb_priv->mShutDown = true; + join(); + delete glfb_priv; + glfb_priv = NULL; +} + +void GLFramebuffer::blit() +{ + glfb_priv->blit(); +} + +GLFbPC::GLFbPC(int x, int y, std::vector &buf): mReInit(true), mShutDown(false), mInitDone(false) +{ + osd_buf = &buf; mState.width = x; mState.height = y; mX = &_mX[0]; @@ -78,19 +103,19 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn last_apts = 0; /* linux framebuffer compat mode */ - screeninfo.bits_per_pixel = 32; - screeninfo.xres = mState.width; - screeninfo.xres_virtual = screeninfo.xres; - screeninfo.yres = mState.height; - screeninfo.yres_virtual = screeninfo.yres; - screeninfo.blue.length = 8; - screeninfo.blue.offset = 0; - screeninfo.green.length = 8; - screeninfo.green.offset = 8; - screeninfo.red.length = 8; - screeninfo.red.offset = 16; - screeninfo.transp.length = 8; - screeninfo.transp.offset = 24; + si.bits_per_pixel = 32; + si.xres = mState.width; + si.xres_virtual = si.xres; + si.yres = mState.height; + si.yres_virtual = si.yres; + si.blue.length = 8; + si.blue.offset = 0; + si.green.length = 8; + si.green.offset = 8; + si.red.length = 8; + si.red.offset = 16; + si.transp.length = 8; + si.transp.offset = 24; unlink("/tmp/neutrino.input"); mkfifo("/tmp/neutrino.input", 0600); @@ -98,21 +123,22 @@ GLFramebuffer::GLFramebuffer(int x, int y): mReInit(true), mShutDown(false), mIn if (input_fd < 0) lt_info("%s: could not open /tmp/neutrino.input FIFO: %m\n", __func__); initKeys(); - OpenThreads::Thread::start(); - while (!mInitDone) - usleep(1); } -GLFramebuffer::~GLFramebuffer() +GLFbPC::~GLFbPC() { mShutDown = true; - OpenThreads::Thread::join(); if (input_fd >= 0) close(input_fd); + osd_buf->clear(); } -void GLFramebuffer::initKeys() +void GLFbPC::initKeys() { + /* + Keep in sync with initKeys() in clutterfb.cpp + */ + mSpecialMap[GLUT_KEY_UP] = KEY_UP; mSpecialMap[GLUT_KEY_DOWN] = KEY_DOWN; mSpecialMap[GLUT_KEY_LEFT] = KEY_LEFT; @@ -133,8 +159,8 @@ void GLFramebuffer::initKeys() mSpecialMap[GLUT_KEY_F11] = KEY_NEXT; mSpecialMap[GLUT_KEY_F12] = KEY_PREVIOUS; - mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP; - mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN; + mSpecialMap[GLUT_KEY_PAGE_UP] = KEY_PAGEUP; + mSpecialMap[GLUT_KEY_PAGE_DOWN] = KEY_PAGEDOWN; mKeyMap[0x0d] = KEY_OK; mKeyMap[0x1b] = KEY_EXIT; @@ -177,9 +203,21 @@ void GLFramebuffer::initKeys() void GLFramebuffer::run() { - setupCtx(); - setupOSDBuffer(); - mInitDone = true; /* signal that setup is finished */ + int argc = 1; + int x = glfb_priv->mState.width; + int y = glfb_priv->mState.height; + /* some dummy commandline for GLUT to be happy */ + char const *argv[2] = { "neutrino", 0 }; + lt_info("GLFB: GL thread starting x %d y %d\n", x, y); + glutInit(&argc, const_cast(argv)); + glutInitWindowSize(x, y); + glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); + glutCreateWindow("Neutrino"); + /* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */ + int fbmem = x * y * 4 * 2; + osd_buf.resize(fbmem); + lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf.data()); + glfb_priv->mInitDone = true; /* signal that setup is finished */ /* init the good stuff */ GLenum err = glewInit(); @@ -194,16 +232,15 @@ void GLFramebuffer::run() } else { - gThiz = this; glutSetCursor(GLUT_CURSOR_NONE); - glutDisplayFunc(GLFramebuffer::rendercb); - glutKeyboardFunc(GLFramebuffer::keyboardcb); - glutSpecialFunc(GLFramebuffer::specialcb); - glutReshapeFunc(GLFramebuffer::resizecb); - setupGLObjects(); /* needs GLEW prototypes */ + glutDisplayFunc(GLFbPC::rendercb); + glutKeyboardFunc(GLFbPC::keyboardcb); + glutSpecialFunc(GLFbPC::specialcb); + glutReshapeFunc(GLFbPC::resizecb); + glfb_priv->setupGLObjects(); /* needs GLEW prototypes */ glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, GLUT_ACTION_CONTINUE_EXECUTION); glutMainLoop(); - releaseGLObjects(); + glfb_priv->releaseGLObjects(); } } else @@ -211,21 +248,20 @@ void GLFramebuffer::run() lt_info("GLFB: GL thread stopping\n"); } - -void GLFramebuffer::setupCtx() +#if 0 +void GLFbPC::setupCtx() { int argc = 1; /* some dummy commandline for GLUT to be happy */ char const *argv[2] = { "neutrino", 0 }; - lt_info("GLFB: GL thread starting\n"); + lt_info("GLFB: GL thread starting x %d y %d\n", mX[0], mY[0]); glutInit(&argc, const_cast(argv)); glutInitWindowSize(mX[0], mY[0]); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); glutCreateWindow("Neutrino"); - GLWinID = glXGetCurrentDrawable(); // this was the holy grail to get the right window handle for gstreamer :D } -void GLFramebuffer::setupOSDBuffer() +void GLFbPC::setupOSDBuffer() { /* the OSD buffer size can be decoupled from the actual window size since the GL can blit-stretch with no trouble at all, ah, the luxury of ignorance... */ @@ -234,12 +270,13 @@ void GLFramebuffer::setupOSDBuffer() { /* 32bit FB depth, *2 because tuxtxt uses a shadow buffer */ int fbmem = mState.width * mState.height * 4 * 2; - mOSDBuffer.resize(fbmem); - lt_info("GLFB: OSD buffer set to %d bytes\n", fbmem); + osd_buf->resize(fbmem); + lt_info("GLFB: OSD buffer set to %d bytes at 0x%p\n", fbmem, osd_buf->data()); } } +#endif -void GLFramebuffer::setupGLObjects() +void GLFbPC::setupGLObjects() { unsigned char buf[4] = { 0, 0, 0, 0 }; /* 1 black pixel */ glGenTextures(1, &mState.osdtex); @@ -267,7 +304,7 @@ void GLFramebuffer::setupGLObjects() } -void GLFramebuffer::releaseGLObjects() +void GLFbPC::releaseGLObjects() { glDeleteBuffers(1, &mState.pbo); glDeleteBuffers(1, &mState.displaypbo); @@ -276,56 +313,56 @@ void GLFramebuffer::releaseGLObjects() } -/* static */ void GLFramebuffer::rendercb() +/* static */ void GLFbPC::rendercb() { - gThiz->render(); + glfb_priv->render(); } -/* static */ void GLFramebuffer::keyboardcb(unsigned char key, int /*x*/, int /*y*/) +/* static */ void GLFbPC::keyboardcb(unsigned char key, int /*x*/, int /*y*/) { lt_debug_c("GLFB::%s: 0x%x\n", __func__, key); struct input_event ev; if (key == 'f') { - lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, gThiz->mFullscreen?"off":"on"); - gThiz->mFullscreen = !(gThiz->mFullscreen); - gThiz->mReInit = true; + lt_info_c("GLFB::%s: toggle fullscreen %s\n", __func__, glfb_priv->mFullscreen?"off":"on"); + glfb_priv->mFullscreen = !(glfb_priv->mFullscreen); + glfb_priv->mReInit = true; return; } - std::map::const_iterator i = gThiz->mKeyMap.find(key); - if (i == gThiz->mKeyMap.end()) + std::map::const_iterator i = glfb_priv->mKeyMap.find(key); + if (i == glfb_priv->mKeyMap.end()) return; ev.code = i->second; ev.value = 1; /* key own */ ev.type = EV_KEY; gettimeofday(&ev.time, NULL); lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code); - write(gThiz->input_fd, &ev, sizeof(ev)); + write(glfb_priv->input_fd, &ev, sizeof(ev)); ev.value = 0; /* neutrino is stupid, so push key up directly after key down */ - write(gThiz->input_fd, &ev, sizeof(ev)); + write(glfb_priv->input_fd, &ev, sizeof(ev)); } -/* static */ void GLFramebuffer::specialcb(int key, int /*x*/, int /*y*/) +/* static */ void GLFbPC::specialcb(int key, int /*x*/, int /*y*/) { lt_debug_c("GLFB::%s: 0x%x\n", __func__, key); struct input_event ev; - std::map::const_iterator i = gThiz->mSpecialMap.find(key); - if (i == gThiz->mSpecialMap.end()) + std::map::const_iterator i = glfb_priv->mSpecialMap.find(key); + if (i == glfb_priv->mSpecialMap.end()) return; ev.code = i->second; ev.value = 1; ev.type = EV_KEY; gettimeofday(&ev.time, NULL); lt_debug_c("GLFB::%s: pushing 0x%x\n", __func__, ev.code); - write(gThiz->input_fd, &ev, sizeof(ev)); + write(glfb_priv->input_fd, &ev, sizeof(ev)); ev.value = 0; - write(gThiz->input_fd, &ev, sizeof(ev)); + write(glfb_priv->input_fd, &ev, sizeof(ev)); } int sleep_us = 30000; -void GLFramebuffer::render() +void GLFbPC::render() { if(mShutDown) glutLeaveMainLoop(); @@ -453,12 +490,12 @@ void GLFramebuffer::render() glutPostRedisplay(); } -/* static */ void GLFramebuffer::resizecb(int w, int h) +/* static */ void GLFbPC::resizecb(int w, int h) { - gThiz->checkReinit(w, h); + glfb_priv->checkReinit(w, h); } -void GLFramebuffer::checkReinit(int x, int y) +void GLFbPC::checkReinit(int x, int y) { static int last_x = 0, last_y = 0; @@ -478,7 +515,7 @@ void GLFramebuffer::checkReinit(int x, int y) last_y = y; } -void GLFramebuffer::drawSquare(float size, float x_factor) +void GLFbPC::drawSquare(float size, float x_factor) { GLfloat vertices[] = { 1.0f, 1.0f, @@ -534,11 +571,11 @@ void GLFramebuffer::drawSquare(float size, float x_factor) } -void GLFramebuffer::bltOSDBuffer() +void GLFbPC::bltOSDBuffer() { /* FIXME: copy each time */ glBindBuffer(GL_PIXEL_UNPACK_BUFFER, mState.pbo); - glBufferData(GL_PIXEL_UNPACK_BUFFER, mOSDBuffer.size(), &mOSDBuffer[0], GL_STREAM_DRAW_ARB); + glBufferData(GL_PIXEL_UNPACK_BUFFER, osd_buf->size(), osd_buf->data(), GL_STREAM_DRAW_ARB); glBindTexture(GL_TEXTURE_2D, mState.osdtex); glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, mState.width, mState.height, GL_BGRA, GL_UNSIGNED_BYTE, 0); @@ -546,7 +583,7 @@ void GLFramebuffer::bltOSDBuffer() glBindBuffer(GL_PIXEL_UNPACK_BUFFER, 0); } -void GLFramebuffer::bltDisplayBuffer() +void GLFbPC::bltDisplayBuffer() { if (!videoDecoder) /* cannot start yet */ return; @@ -554,7 +591,7 @@ void GLFramebuffer::bltDisplayBuffer() cVideo::SWFramebuffer *buf = videoDecoder->getDecBuf(); if (!buf) { if (warn) - lt_debug("GLFB::%s did not get a buffer...\n", __func__); + lt_info("GLFB::%s did not get a buffer...\n", __func__); warn = false; return; } @@ -607,9 +644,3 @@ void GLFramebuffer::bltDisplayBuffer() lt_debug("vpts: 0x%" PRIx64 " apts: 0x%" PRIx64 " diff: %6.3f sleep_us %d buf %d\n", buf->pts(), apts, (buf->pts() - apts)/90000.0, sleep_us, videoDecoder->buf_num); } - -void GLFramebuffer::clear() -{ - /* clears front and back buffer */ - memset(&mOSDBuffer[0], 0, mOSDBuffer.size()); -} diff --git a/generic-pc/glfb.h b/generic-pc/glfb_priv.h similarity index 82% rename from generic-pc/glfb.h rename to generic-pc/glfb_priv.h index bc7b9f5..a51545a 100644 --- a/generic-pc/glfb.h +++ b/generic-pc/glfb_priv.h @@ -14,12 +14,14 @@ You should have received a copy of the GNU General Public License along with this program. If not, see . + + ******************************************************************** + private stuff of the GLFB thread that is only used inside libstb-hal + and not exposed to the application. */ -#ifndef __glthread__ -#define __glthread__ -#include -#include +#ifndef __glfb_priv__ +#define __glfb_priv__ #include #include #include @@ -32,28 +34,26 @@ #if USE_CLUTTER #include #endif +#include "glfb.h" extern "C" { #include } -class GLFramebuffer : public OpenThreads::Thread +class GLFbPC { public: - GLFramebuffer(int x, int y); - ~GLFramebuffer(); - void run(); - std::vector *getOSDBuffer() { return &mOSDBuffer; } /* pointer to OSD bounce buffer */ + GLFbPC(int x, int y, std::vector &buf); + ~GLFbPC(); + std::vector *getOSDBuffer() { return osd_buf; } /* pointer to OSD bounce buffer */ int getOSDWidth() { return mState.width; } int getOSDHeight() { return mState.height; } - void blit() { mState.blit = true; } - fb_var_screeninfo getScreenInfo() { return screeninfo; } + void blit() { mState.blit = true; }; + fb_var_screeninfo getScreenInfo() { return si; } void setOutputFormat(AVRational a, int h, int c) { mOA = a; *mY = h; mCrop = c; mReInit = true; } - - void clear(); - int getWindowID() { return GLWinID; } - +/* just make everything public for simplicity - this is only used inside libstb-hal anyway private: - fb_var_screeninfo screeninfo; +*/ + fb_var_screeninfo si; int *mX; int *mY; int _mX[2]; /* output window size */ @@ -65,7 +65,6 @@ private: float zoom; /* for cropping */ float xscale; /* and aspect ratio */ int mCrop; /* DISPLAY_AR_MODE */ - int GLWinID; bool mFullscreen; /* fullscreen? */ bool mReInit; /* setup things for GL */ @@ -75,7 +74,7 @@ private: // OpenThreads::Condition mInitCond; /* condition variable for init */ // mutable OpenThreads::Mutex mMutex; /* lock our data */ - std::vector mOSDBuffer; /* silly bounce buffer */ + std::vector *osd_buf; /* silly bounce buffer */ #if USE_OPENGL std::map mKeyMap; @@ -86,6 +85,7 @@ private: #endif int input_fd; int64_t last_apts; + void run(); static void rendercb(); /* callback for GLUT */ void render(); /* actual render function */ @@ -103,8 +103,10 @@ private: #endif void initKeys(); /* setup key bindings for window */ +#if 0 void setupCtx(); /* create the window and make the context current */ void setupOSDBuffer(); /* create the OSD buffer */ +#endif struct { int width; /* width and height, fixed for a framebuffer instance */ diff --git a/generic-pc/init.cpp b/generic-pc/init.cpp index b641fd8..fa2a01c 100644 --- a/generic-pc/init.cpp +++ b/generic-pc/init.cpp @@ -1,4 +1,5 @@ #include +#include #include #include "init_td.h" diff --git a/generic-pc/video.cpp b/generic-pc/video.cpp index 8237305..be89bf2 100644 --- a/generic-pc/video.cpp +++ b/generic-pc/video.cpp @@ -49,7 +49,7 @@ extern "C" { #include "video_lib.h" #include "dmx_hal.h" -#include "glfb.h" +#include "glfb_priv.h" #include "lt_debug.h" #define lt_debug(args...) _lt_debug(TRIPLE_DEBUG_VIDEO, this, args) #define lt_info(args...) _lt_info(TRIPLE_DEBUG_VIDEO, this, args) @@ -57,7 +57,7 @@ extern "C" { cVideo *videoDecoder = NULL; extern cDemux *videoDemux; -extern GLFramebuffer *glfb; +extern GLFbPC *glfb_priv; int system_rev = 0; extern bool HAL_nodec; @@ -111,7 +111,7 @@ int cVideo::setAspectRatio(int vformat, int cropping) if (cropping >= 0) display_crop = (DISPLAY_AR_MODE) cropping; if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */ - glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); + glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); return 0; } @@ -222,7 +222,7 @@ int cVideo::SetVideoSystem(int system, bool) // v_std = (VIDEO_STD) system; output_h = h; if (display_aspect < DISPLAY_AR_RAW && output_h > 0) /* don't know what to do with this */ - glfb->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); + glfb_priv->setOutputFormat(aspect_ratios[display_aspect], output_h, display_crop); return 0; } @@ -369,6 +369,7 @@ void cVideo::Pig(int x, int y, int w, int h, int /*osd_w*/, int /*osd_h*/, int / pig_y = y; pig_w = w; pig_h = h; + pig_changed = true; } void cVideo::getPictureInfo(int &width, int &height, int &rate) @@ -572,10 +573,18 @@ void cVideo::run(void) f->width(c->width); f->height(c->height); int64_t vpts = av_frame_get_best_effort_timestamp(frame); + /* a/v delay determined experimentally :-) */ +#if USE_OPENGL if (v_format == VIDEO_FORMAT_MPEG2) vpts += 90000*4/10; /* 400ms */ else vpts += 90000*3/10; /* 300ms */ +#endif +#if USE_CLUTTER + /* no idea why there's a difference between OpenGL and clutter rendering... */ + if (v_format == VIDEO_FORMAT_MPEG2) + vpts += 90000*3/10; /* 300ms */ +#endif f->pts(vpts); AVRational a = av_guess_sample_aspect_ratio(avfc, avfc->streams[0], frame); f->AR(a); @@ -675,8 +684,8 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge std::vector *osd = NULL; std::vector s_osd; /* scaled OSD */ int vid_w = 0, vid_h = 0; - int osd_w = glfb->getOSDWidth(); - int osd_h = glfb->getOSDHeight(); + int osd_w = glfb_priv->getOSDWidth(); + int osd_h = glfb_priv->getOSDHeight(); xres = osd_w; yres = osd_h; if (get_video) { @@ -700,24 +709,26 @@ bool cVideo::GetScreenImage(unsigned char * &data, int &xres, int &yres, bool ge yres = osd_h; } if (get_osd) - osd = glfb->getOSDBuffer(); + osd = glfb_priv->getOSDBuffer(); unsigned int need = av_image_get_buffer_size(AV_PIX_FMT_RGB32, xres, yres, 1); data = (unsigned char *)realloc(data, need); /* will be freed by caller */ if (data == NULL) /* out of memory? */ return false; if (get_video) { - //memcpy dont work with copy BGR24 to RGB32 +#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32 if (vid_w != xres || vid_h != yres){ /* scale video into data... */ - bool ret = swscale(&video[0], data, vid_w, vid_h, xres, yres, AV_PIX_FMT_RGB32); +#endif + bool ret = swscale(&video[0], data, vid_w, vid_h, xres, yres,VDEC_PIXFMT); if(!ret){ free(data); return false; } - //memcpy dont work with copy BGR24 to RGB32 - } else { /* get_video and no fancy scaling needed */ +#if USE_OPENGL //memcpy dont work with copy BGR24 to RGB32 + }else{ /* get_video and no fancy scaling needed */ memcpy(data, &video[0], xres * yres * sizeof(uint32_t)); } +#endif } if (get_osd && (osd_w != xres || osd_h != yres)) { diff --git a/generic-pc/video_lib.h b/generic-pc/video_lib.h index 694965c..1bec147 100644 --- a/generic-pc/video_lib.h +++ b/generic-pc/video_lib.h @@ -120,10 +120,10 @@ typedef enum } VIDEO_CONTROL; -#define VDEC_MAXBUFS 0x30 +#define VDEC_MAXBUFS 0x40 class cVideo : public OpenThreads::Thread { - friend class GLFramebuffer; + friend class GLFbPC; friend class cDemux; private: /* called from GL thread */ diff --git a/include/glfb.h b/include/glfb.h index ea7addd..5b95ce6 100644 --- a/include/glfb.h +++ b/include/glfb.h @@ -1,10 +1,42 @@ -#include -#if HAVE_GENERIC_HARDWARE -#if BOXMODEL_RASPI -#include "../raspi/glfb.h" -#else -#include "../generic-pc/glfb.h" -#endif -#else -#error glfb.h only works with HAVE_GENERIC_HARDWARE defined +/* + Copyright 2010 Carsten Juttner + Copyright 2012,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 __glfb__ +#define __glfb__ +#include +#include +#include /* for screeninfo etc. */ + +class GLFramebuffer : public OpenThreads::Thread +{ +public: + GLFramebuffer(int x, int y); + ~GLFramebuffer(); + std::vector *getOSDBuffer() { return &osd_buf; } /* pointer to OSD bounce buffer */ + void blit(); + fb_var_screeninfo getScreenInfo() { return si; } + +private: + fb_var_screeninfo si; + std::vector osd_buf; /* silly bounce buffer */ + void run(); /* for OpenThreads::Thread */ + void setup(); + void blit_osd(); + void *pdata; /* not yet used */ +}; #endif From 407321ca6974816497c249e3e843ec5622b40161 Mon Sep 17 00:00:00 2001 From: TangoCash Date: Tue, 25 Sep 2018 20:23:08 +0200 Subject: [PATCH 68/72] add frontpanel xres for sh4 (thx dbo) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/80251471d335b56b84a7e745fc65ce94ea742b6d Author: TangoCash Date: 2018-09-25 (Tue, 25 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libduckbox/hardware_caps.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libduckbox/hardware_caps.c b/libduckbox/hardware_caps.c index 56e9254..8550149 100644 --- a/libduckbox/hardware_caps.c +++ b/libduckbox/hardware_caps.c @@ -59,6 +59,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs913", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -70,6 +72,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs922", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -81,6 +85,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 1; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs910", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -92,6 +98,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "hdbox", 5)) { strcpy(caps.boxvendor, "DUCKBOX"); From d290b6d2cd2591634aa7a6f5bf9b5bcbdfe1b70c Mon Sep 17 00:00:00 2001 From: BPanther Date: Tue, 28 Aug 2018 07:46:08 +0200 Subject: [PATCH 69/72] vusolo4k: small fix - but not yet ready Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/35f15585ed5fc227fd918b042276cb41a998ad3f Author: BPanther Date: 2018-08-28 (Tue, 28 Aug 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/hardware_caps.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/libarmbox/hardware_caps.c b/libarmbox/hardware_caps.c index 1190939..782e35d 100644 --- a/libarmbox/hardware_caps.c +++ b/libarmbox/hardware_caps.c @@ -7,6 +7,7 @@ * License: GPL v2 or later */ +#include #include #include #include @@ -28,6 +29,23 @@ hw_caps_t *get_hwcaps(void) memset(&caps, 0, sizeof(hw_caps_t)); +#if BOXMODEL_VUSOLO4K + initialized = 1; + caps.has_CI = 1; + caps.can_cec = 1; + caps.can_shutdown = 1; + caps.display_xres = 480; + caps.display_yres = 320; + caps.display_type = HW_DISPLAY_GFX; + caps.display_can_deepstandby = 1; + caps.display_can_set_brightness = 1; + caps.display_has_statusline = 1; + caps.has_button_timer = 1; + caps.has_HDMI = 1; + strcpy(caps.boxvendor, "VU"); + strcpy(caps.boxname, "SOLO4K"); + strcpy(caps.boxarch, "BCM7376"); +#else initialized = 1; caps.has_CI = 1; caps.can_cec = 1; @@ -42,5 +60,6 @@ hw_caps_t *get_hwcaps(void) strcpy(caps.boxvendor, "AX-Technologies"); strcpy(caps.boxname, "HD51"); strcpy(caps.boxarch, "BCM7251S"); +#endif return ∩︀ } From 53a2e1cb80448b150c3d19a8ca91e1d5e577c190 Mon Sep 17 00:00:00 2001 From: TangoCash Date: Tue, 25 Sep 2018 20:23:08 +0200 Subject: [PATCH 70/72] add frontpanel xres for sh4 (thx dbo) Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/b428f7fc42013f0a20c761c70503bd5d638bd51a Author: TangoCash Date: 2018-09-25 (Tue, 25 Sep 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libduckbox/hardware_caps.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/libduckbox/hardware_caps.c b/libduckbox/hardware_caps.c index 56e9254..8550149 100644 --- a/libduckbox/hardware_caps.c +++ b/libduckbox/hardware_caps.c @@ -59,6 +59,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs913", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -70,6 +72,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs922", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -81,6 +85,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 1; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "ufs910", 6)) { strcpy(caps.boxvendor, "DUCKBOX"); @@ -92,6 +98,8 @@ hw_caps_t *get_hwcaps(void) caps.has_fan = 0; caps.has_CI = 2; caps.display_can_set_brightness = 1; + caps.display_type = HW_DISPLAY_LINE_TEXT; + caps.display_xres = 16; } else if (!strncmp(buf, "hdbox", 5)) { strcpy(caps.boxvendor, "DUCKBOX"); From 9242c9e1e4cc4c4e9f8ec6e1907a35bc2171ba65 Mon Sep 17 00:00:00 2001 From: max_10 Date: Mon, 1 Oct 2018 21:59:46 +0200 Subject: [PATCH 71/72] fix segfault subtitles selection - but not yet ready Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/abd93ba030056006abe6577fd9c2ad1ede56c835 Author: max_10 Date: 2018-10-01 (Mon, 01 Oct 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libarmbox/playback_libeplayer3.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index 0a2f1ed..78c21a5 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -69,6 +69,7 @@ bool cPlayback::Open(playmode_t PlayMode) { player->output->Command(player, OUTPUT_ADD, (void *)"audio"); player->output->Command(player, OUTPUT_ADD, (void *)"video"); + player->output->Command(player, OUTPUT_ADD, (void *)"subtitle"); } return 0; @@ -249,6 +250,7 @@ bool cPlayback::Stop(void) { player->output->Command(player, OUTPUT_DEL, (void *)"audio"); player->output->Command(player, OUTPUT_DEL, (void *)"video"); + player->output->Command(player, OUTPUT_DEL, (void *)"subtitle"); } if (player && player->playback) From 9e45bb2eb6b320b381dd5cf60b1fe5a757af9af0 Mon Sep 17 00:00:00 2001 From: redblue-pkt Date: Mon, 1 Oct 2018 21:55:31 +0200 Subject: [PATCH 72/72] fix backward Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/a7bba580e9135de79e3c497332240c1ad9f88ab4 Author: redblue-pkt Date: 2018-10-01 (Mon, 01 Oct 2018) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3-arm/playback/playback.c | 24 +++++++++++++++++------- 1 file changed, 17 insertions(+), 7 deletions(-) diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index e2bfd7e..257fb67 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -304,7 +304,7 @@ static int PlaybackPlay(Context_t *context) context->playback->Speed = 0; if (context->container && context->container->selectedContainer) - context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); + ret = context->container->selectedContainer->Command(context, CONTAINER_STOP, NULL); } else { @@ -568,19 +568,29 @@ static int PlaybackFastBackward(Context_t *context, int *speed) return cERR_PLAYBACK_ERROR; } + PlaybackContinue(context); + if (*speed == 0) { - context->playback->BackWard = 0; - context->playback->Speed = 0; /* reverse end */ + 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_AUDIOMUTE, "0"); } else { - context->playback->isSeeking = 1; - context->playback->Speed = *speed; - context->playback->BackWard = 1; + context->playback->isPaused = 0; + //context->playback->isPlaying = 0; + context->playback->isForwarding = 0; + context->playback->BackWard = 1; + context->playback->SlowMotion = 0; + context->playback->Speed = *speed; + context->playback->isSeeking = 1; context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); - playback_printf(1, "S %d B %d\n", context->playback->Speed, context->playback->BackWard); + playback_printf(1, "Speed: %d, Backward: %d\n", context->playback->Speed, context->playback->BackWard); } context->output->Command(context, OUTPUT_CLEAR, NULL);