diff --git a/Makefile.am b/Makefile.am index 0b8c4ad..6861392 100644 --- a/Makefile.am +++ b/Makefile.am @@ -49,6 +49,11 @@ libstb_hal_la_LIBADD += \ libdvbci/libdvbci.la endif if BOXTYPE_ARMBOX +if BOXMODEL_HD60 +SUBDIRS += libarmbox +libstb_hal_la_LIBADD += \ + libarmbox/libarmbox.la +else #libstb_hal_test_LDADD += -lasound SUBDIRS += libarmbox libdvbci libstb_hal_la_LIBADD += \ @@ -64,6 +69,8 @@ endif endif +endif + pkginclude_HEADERS = \ include/audio_hal.h \ include/ca.h \ diff --git a/common/Makefile.am b/common/Makefile.am index 5039a41..cb932ea 100644 --- a/common/Makefile.am +++ b/common/Makefile.am @@ -22,12 +22,18 @@ libcommon_la_SOURCES = \ ca_ci.cpp else if BOXTYPE_ARMBOX +if BOXMODEL_HD60 +libcommon_la_SOURCES = \ + ca.cpp +else libcommon_la_SOURCES = \ ca_ci.cpp +endif else libcommon_la_SOURCES = \ ca.cpp endif + endif libcommon_la_SOURCES += \ diff --git a/include/ca_hal.h b/include/ca_hal.h index 09e964f..eb4ce36 100644 --- a/include/ca_hal.h +++ b/include/ca_hal.h @@ -1,4 +1,4 @@ -#if HAVE_DUCKBOX_HARDWARE || HAVE_ARM_HARDWARE +#if HAVE_DUCKBOX_HARDWARE || (HAVE_ARM_HARDWARE && !BOXMODEL_HD60) #include "ca_ci.h" #else #include "ca.h" diff --git a/include/cs_api.h b/include/cs_api.h index 17c882d..42fff37 100644 --- a/include/cs_api.h +++ b/include/cs_api.h @@ -23,7 +23,7 @@ inline void cs_api_exit() #define cs_free_uncached free // Callback function helpers -#if HAVE_DUCKBOX_HARDWARE || HAVE_ARM_HARDWARE +#if HAVE_DUCKBOX_HARDWARE || (HAVE_ARM_HARDWARE && !BOXMODEL_HD60) void cs_register_messenger(cs_messenger messenger); #else static inline void cs_register_messenger(cs_messenger) { return; }; diff --git a/include/playback_hal.h b/include/playback_hal.h index d370cb6..9827e06 100644 --- a/include/playback_hal.h +++ b/include/playback_hal.h @@ -9,8 +9,12 @@ #if ENABLE_GSTREAMER_10 #include "../libarmbox/playback_gst.h" #else +#if BOXMODEL_HD60 +#include "../libarmbox/playback_hisilicon.h" +#else #include "../libarmbox/playback_libeplayer3.h" #endif +#endif #elif HAVE_AZBOX_HARDWARE #include "../libazbox/playback_lib.h" #elif HAVE_GENERIC_HARDWARE diff --git a/libarmbox/Makefile.am b/libarmbox/Makefile.am index d8453df..2143a42 100644 --- a/libarmbox/Makefile.am +++ b/libarmbox/Makefile.am @@ -32,11 +32,16 @@ AM_LDFLAGS += \ -lgsttag-1.0 \ -lgstmpegts-1.0 else +if BOXMODEL_HD60 +libarmbox_la_SOURCES += \ + playback_hisilicon.cpp +else libarmbox_la_SOURCES += \ playback_libeplayer3.cpp AM_CPPFLAGS += \ -I$(top_srcdir)/libeplayer3-arm/include +endif AM_LDFLAGS += \ -lass diff --git a/libarmbox/hisilicon.h b/libarmbox/hisilicon.h new file mode 100644 index 0000000..6563348 --- /dev/null +++ b/libarmbox/hisilicon.h @@ -0,0 +1,287 @@ +#ifndef _hisilicon_h +#define _hisilicon_h + +#define HI_FORMAT_MAX_URL_LEN (2048) +#define HI_FORMAT_MAX_FILE_NAME_LEN (512) +#define HI_FORMAT_TITLE_MAX_LEN (512) +#define HI_FORMAT_LANG_LEN (64) +#define HI_FORMAT_MAX_LANGUAGE_NUM (4) +#define HI_FORMAT_SERVICE_DESCRIPT_LEN (64) + +typedef uint8_t HI_U8; +typedef uint16_t HI_U16; +typedef uint32_t HI_U32; +typedef int8_t HI_S8; +typedef int16_t HI_S16; +typedef int32_t HI_S32; +typedef uint64_t HI_U64; +typedef int64_t HI_S64; +typedef void HI_VOID; +typedef char HI_CHAR; + +typedef enum +{ + HI_FALSE = 0, + HI_TRUE = 1, +} HI_BOOL; + +typedef enum hiFORMAT_SUBTITLE_TYPE_E +{ + HI_FORMAT_SUBTITLE_ASS = 0x0, /**< ASS subtitle */ + HI_FORMAT_SUBTITLE_LRC, /**< LRC subtitle */ + HI_FORMAT_SUBTITLE_SRT, /**< SRT subtitle */ + HI_FORMAT_SUBTITLE_SMI, /**< SMI subtitle */ + HI_FORMAT_SUBTITLE_SUB, /**< SUB subtitle */ + HI_FORMAT_SUBTITLE_TXT, /**< RAW UTF8 subtitle */ + HI_FORMAT_SUBTITLE_HDMV_PGS, /**< pgs subtitle */ + HI_FORMAT_SUBTITLE_DVB_SUB, /**< DVB subtitle */ + HI_FORMAT_SUBTITLE_DVD_SUB, /**< DVD subtitle */ + HI_FORMAT_SUBTITLE_TTML, /**< TTML subtitle */ + HI_FORMAT_SUBTITLE_WEBVTT, + HI_FORMAT_SUBTITLE_BUTT +} HI_FORMAT_SUBTITLE_TYPE_E; + +typedef enum hiFORMAT_AUDIO_TYPE_E +{ + HI_FORMAT_AUDIO_MP2 = 0x000, /**< MPEG audio layer 1, 2.*/ + HI_FORMAT_AUDIO_MP3, /**< MPEG audio layer 1, 2, 3.*/ + HI_FORMAT_AUDIO_AAC, + HI_FORMAT_AUDIO_AC3, + HI_FORMAT_AUDIO_DTS, + HI_FORMAT_AUDIO_VORBIS, + HI_FORMAT_AUDIO_DVAUDIO, + HI_FORMAT_AUDIO_WMAV1, + HI_FORMAT_AUDIO_WMAV2, + HI_FORMAT_AUDIO_MACE3, + HI_FORMAT_AUDIO_MACE6, + HI_FORMAT_AUDIO_VMDAUDIO, + HI_FORMAT_AUDIO_SONIC, + HI_FORMAT_AUDIO_SONIC_LS, + HI_FORMAT_AUDIO_FLAC, + HI_FORMAT_AUDIO_MP3ADU, + HI_FORMAT_AUDIO_MP3ON4, + HI_FORMAT_AUDIO_SHORTEN, + HI_FORMAT_AUDIO_ALAC, + HI_FORMAT_AUDIO_WESTWOOD_SND1, + HI_FORMAT_AUDIO_GSM, + HI_FORMAT_AUDIO_QDM2, + HI_FORMAT_AUDIO_COOK, + HI_FORMAT_AUDIO_TRUESPEECH, + HI_FORMAT_AUDIO_TTA, + HI_FORMAT_AUDIO_SMACKAUDIO, + HI_FORMAT_AUDIO_QCELP, + HI_FORMAT_AUDIO_WAVPACK, + HI_FORMAT_AUDIO_DSICINAUDIO, + HI_FORMAT_AUDIO_IMC, + HI_FORMAT_AUDIO_MUSEPACK7, + HI_FORMAT_AUDIO_MLP, + HI_FORMAT_AUDIO_GSM_MS, /**< as found in WAV.*/ + HI_FORMAT_AUDIO_ATRAC3, + HI_FORMAT_AUDIO_VOXWARE, + HI_FORMAT_AUDIO_APE, + HI_FORMAT_AUDIO_NELLYMOSER, + HI_FORMAT_AUDIO_MUSEPACK8, + HI_FORMAT_AUDIO_SPEEX, + HI_FORMAT_AUDIO_WMAVOICE, + HI_FORMAT_AUDIO_WMAPRO, + HI_FORMAT_AUDIO_WMALOSSLESS, + HI_FORMAT_AUDIO_ATRAC3P, + HI_FORMAT_AUDIO_EAC3, + HI_FORMAT_AUDIO_SIPR, + HI_FORMAT_AUDIO_MP1, + HI_FORMAT_AUDIO_TWINVQ, + HI_FORMAT_AUDIO_TRUEHD, + HI_FORMAT_AUDIO_MP4ALS, + HI_FORMAT_AUDIO_ATRAC1, + HI_FORMAT_AUDIO_BINKAUDIO_RDFT, + HI_FORMAT_AUDIO_BINKAUDIO_DCT, + HI_FORMAT_AUDIO_DRA, + HI_FORMAT_AUDIO_DTS_EXPRESS, + + HI_FORMAT_AUDIO_PCM = 0x100, /**< various PCM codecs. */ + HI_FORMAT_AUDIO_PCM_BLURAY = 0x121, + + HI_FORMAT_AUDIO_ADPCM = 0x130, /**< various ADPCM codecs. */ + + HI_FORMAT_AUDIO_AMR_NB = 0x160,/**< various AMR codecs. */ + HI_FORMAT_AUDIO_AMR_WB, + HI_FORMAT_AUDIO_AMR_AWB, + + HI_FORMAT_AUDIO_RA_144 = 0x170, /**< RealAudio codecs. */ + HI_FORMAT_AUDIO_RA_288, + + HI_FORMAT_AUDIO_DPCM = 0x180, /**< various DPCM codecs. */ + + HI_FORMAT_AUDIO_G711 = 0x190, /**< various G.7xx codecs. */ + HI_FORMAT_AUDIO_G722, + HI_FORMAT_AUDIO_G7231, + HI_FORMAT_AUDIO_G726, + HI_FORMAT_AUDIO_G728, + HI_FORMAT_AUDIO_G729AB, + + HI_FORMAT_AUDIO_MULTI = 0x1f0, /**< support multi codecs. */ + + HI_FORMAT_AUDIO_BUTT = 0x1ff, +} HI_FORMAT_AUDIO_TYPE_E; + +typedef enum hiFORMAT_VIDEO_TYPE_E +{ + HI_FORMAT_VIDEO_MPEG2 = 0x0, /**< MPEG2*/ + HI_FORMAT_VIDEO_MPEG4, /**< MPEG4 DIVX4 DIVX5*/ + HI_FORMAT_VIDEO_AVS, /**< AVS*/ + HI_FORMAT_VIDEO_H263, /**< H263*/ + HI_FORMAT_VIDEO_H264, /**< H264*/ + HI_FORMAT_VIDEO_REAL8, /**< REAL*/ + HI_FORMAT_VIDEO_REAL9, /**< REAL*/ + HI_FORMAT_VIDEO_VC1, /**< VC-1*/ + HI_FORMAT_VIDEO_VP6, /**< VP6*/ + HI_FORMAT_VIDEO_VP6F, /**< VP6F*/ + HI_FORMAT_VIDEO_VP6A, /**< VP6A*/ + HI_FORMAT_VIDEO_MJPEG, /**< MJPEG*/ + HI_FORMAT_VIDEO_SORENSON, /**< SORENSON SPARK*/ + HI_FORMAT_VIDEO_DIVX3, /**< DIVX3, not supported*/ + HI_FORMAT_VIDEO_RAW, /**< RAW*/ + HI_FORMAT_VIDEO_JPEG, /**< JPEG added for VENC*/ + HI_FORMAT_VIDEO_VP8, /** ('D'<<24) + ('C'<<16) + ('B'<<8) + 'A'). */ +} HI_FORMAT_AUD_INFO_S; + +typedef struct hiFORMAT_VID_INFO_S +{ + HI_S32 s32StreamIndex; /**< Stream index. The invalid value is ::HI_FORMAT_INVALID_STREAM_ID. */ + HI_U32 u32Format; /**< Video encoding format. For details about the value definition, see ::HI_FORMAT_VIDEO_TYPE_E. */ + HI_U16 u16RefFrameNum; /**< Number of reference frames. */ + HI_U16 u16Profile; /**< Profile level. */ + HI_U16 u16Width; /**< Width, in the unit of pixel. */ + HI_U16 u16Height; /**< Height, in the unit of pixel. */ + HI_U16 u16FpsInteger; /**< Integer part of the frame rate */ + HI_U16 u16FpsDecimal; /**< Decimal part of the frame rate */ + HI_U32 u32Bitrate; /**< Video bit rate, in the unit of bit/s. */ + HI_U32 u32CodecVersion; /**< Version of codec. */ + HI_U32 u32Rotate; /**< Video rotation angle, value is 90/180/270, default value is 0 */ + HI_U32 u32Reversed; + HI_BOOL bEnableTVP; + HI_U32 u32ExtradataSize; /**< Length of the extended data */ + HI_U8* pu8Extradata; /**< Extended data */ + HI_VOID* pCodecContext; /**< video decode context */ + HI_U32 u32Role; /**< Role descriptor value of mpeg dash. the most 8 bits is scheme value(refer to HI_FORMAT_ROLE_SCHEME_E), the left 24 bits is descriptor value, the descriptor value may be the bitwise '|' result of value define in HI_FORMAT_ROLE_VALUE_E*/ + HI_U32 u32Accessibility; /**< Accessbilitydescriptor value of mpeg dash. the most 8 bits is scheme value(refer to HI_FORMAT_ROLE_SCHEME_E), the left 24 bits is descriptor value, the descriptor value type is number*/ + HI_S64 s64Duration; /**< Duration of video stream, in the unit of ms. */ + HI_BOOL bNoPts; /** */ +} HI_FORMAT_VID_INFO_S; + +typedef struct hiFORMAT_SUB_INFO_S +{ + HI_S32 s32StreamIndex; /**< Stream index. The invalid value is ::HI_FORMAT_INVALID_STREAM_ID. */ + HI_U32 u32Format; /**< Subtitle format, For details about the value definition, see::HI_FORMAT_SUBTITLE_TYPE_E */ + HI_U32 u32CharSet; /**< Encoding type of the subtitle, the value range is as follows: + 1. The default value is 0. + 2. The value of the u32CharSet is the identified byte encoding value if the IdentStream byte encoding function (for details about the definition, see hi_charset_common.h) is set. + 3. If the ConvStream function (for details about the definition, see hi_charset_common.h) is set and the invoke interface is called to set the encoding type to be converted by implementing HI_FORMAT_INVOKE_SET_SOURCE_CODETYPE, the value of the u32CharSet is the configured encoding type */ + HI_BOOL bExtSub; /**< Whether subtitles are external subtitles. When bExtSub is HI_TRUE, the subtitles are external. When bExtSub is HI_FALSE, the subtitles are internal. */ + HI_U32 u32StreamNum; /**< contains stream number */ + HI_CHAR paszLanguage[HI_FORMAT_MAX_LANGUAGE_NUM][HI_FORMAT_LANG_LEN]; /**< Subtitle language */ + HI_U16 u16OriginalFrameWidth; /**< Width of the original image */ + HI_U16 u16OriginalFrameHeight; /**< Height of the original image */ + HI_U32 u32ExtradataSize; /**< Length of the extended data */ + HI_U8* pu8Extradata; /**< Extended data */ + HI_VOID* pCodecContext; /**< Audio decode context */ + HI_U32 u32Role; /**< Role descriptor value of mpeg dash. the most 8 bits is scheme value(refer to HI_FORMAT_ROLE_SCHEME_E), the left 24 bits is descriptor value, the descriptor value may be the bitwise '|' result of value define in HI_FORMAT_ROLE_VALUE_E*/ + HI_U32 u32Accessibility; /**< Accessibility descriptor value of mpeg dash. the most 8 bits is scheme value(refer to HI_FORMAT_ROLE_SCHEME_E), the left 24 bits is descriptor value, value type is number*/ + HI_CHAR paszFileName[HI_FORMAT_MAX_URL_LEN]; /**< File name of external subtitle. */ +} HI_FORMAT_SUB_INFO_S; + +typedef struct hiFORMAT_PROGRAM_INFO_S +{ + HI_U32 u32VidStreamNum; /**< Number of video streams */ + HI_FORMAT_VID_INFO_S* pastVidStream; /**< Video stream information */ + HI_U32 u32AudStreamNum; /**< Number of audio streams */ + HI_FORMAT_AUD_INFO_S* pastAudStream; /**< Audio stream information */ + HI_U32 u32SubStreamNum; /**< Number of subtitles */ + HI_FORMAT_SUB_INFO_S* pastSubStream; /**< Subtitle information */ + HI_CHAR aszServiceName[HI_FORMAT_SERVICE_DESCRIPT_LEN]; /**< Program service name info */ + HI_CHAR aszServiceProvider[HI_FORMAT_SERVICE_DESCRIPT_LEN]; /**< Program service provider info */ + HI_S64 s64ProgramDuration; + HI_S64 s64ProgramStartTime; +} HI_FORMAT_PROGRAM_INFO_S; + +typedef struct hiFORMAT_FILE_INFO_S +{ + HI_FORMAT_SOURCE_TYPE_E eSourceType; /**< File source type */ + HI_FORMAT_STREAM_TYPE_E eStreamType; /**< File stream type */ + HI_S64 s64FileSize; /**< File size, in the unit of byte. */ + HI_S64 s64StartTime; /**< Start time of playing a file, in the unit is ms. */ + HI_S64 s64Duration; /**< Total duration of a file, in the unit of ms. */ + HI_U32 u32Bitrate; /**< File bit rate, in the unit of bit/s. */ + HI_CHAR aszFileFormat[HI_FORMAT_TITLE_MAX_LEN]; /**< File demuxer info .Not used now*/ + HI_U32 u32ProgramNum; /**< Actual number of programs */ + HI_FORMAT_PROGRAM_INFO_S* pastProgramInfo; /**< Program information */ + HI_BOOL bIsDivx; /**< If the stream is DIVX restricted stream,HI_TRUE yes,HI_FALSE no */ + HI_BOOL bIsDrmFile; +} HI_FORMAT_FILE_INFO_S; + +#endif diff --git a/libarmbox/playback_hisilicon.cpp b/libarmbox/playback_hisilicon.cpp new file mode 100644 index 0000000..62c9639 --- /dev/null +++ b/libarmbox/playback_hisilicon.cpp @@ -0,0 +1,1285 @@ +/* + Copyright (C) 2018 TangoCash + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#define __USE_FILE_OFFSET64 1 +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include +#include + +#include "playback_hisilicon.h" +#include "hal_debug.h" + +#define hal_debug(args...) _hal_debug(HAL_DEBUG_PLAYBACK, this, args) +#define hal_debug_c(args...) _hal_debug(HAL_DEBUG_PLAYBACK, NULL, args) +#define hal_info(args...) _hal_info(HAL_DEBUG_PLAYBACK, this, args) + +#define MAX_PAYLOAD 4096 + +extern cAudio *audioDecoder; +extern cVideo *videoDecoder; + +//Used by Fileplay +bool cPlayback::Open(playmode_t PlayMode) +{ + const char *aPLAYMODE[] = + { + "PLAYMODE_TS", + "PLAYMODE_FILE" + }; + + pm = PlayMode; + got_vpts_ts = false; + vpts_ts = 0; + fn_ts = ""; + fn_xml = ""; + last_size = 0; + nPlaybackSpeed = 0; + init_jump = -1; + + return 0; +} + +void cPlayback::Close(void) +{ + hal_info("%s\n", __func__); + + //Dagobert: movieplayer does not call stop, it calls close ;) + if(playing) + Stop(); + +} + +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 __attribute__((unused))) +{ + bool ret = false; + + hal_info("%s - filename=%s vpid=%u vtype=%d apid=%u ac3=%d fd=%d\n", __func__, filename, vpid, vtype, apid, ac3, videoDecoder->fd); + + init_jump = -1; + //create playback path + mAudioStream = 0; + mSubtitleStream = -1; + mTeletextStream = -1; + unlink("/tmp/.id3coverart"); + + videoDecoder->closeDevice(); + videoDecoder->openDevice(); + + netlink_event::getInstance()->Start(this); + +#if 0 //for later use + video_event::getInstance()->Start(videoDecoder->fd); +#endif + + if (videoDecoder->fd >= 0) + { + struct video_command cmd = {0}; + struct argdata + { + uint32_t size; + void *arg; + } *argdata = (struct argdata*)cmd.raw.data; + cmd.cmd = 101; /* set url */ + argdata->arg = (void*)filename; + argdata->size = strlen(filename) + 1; + ::ioctl(videoDecoder->fd, VIDEO_COMMAND, &cmd); + cmd.cmd = 102; /* set useragent */ + argdata->arg = (void*)headers.c_str(); + argdata->size = headers.length() + 1; + ::ioctl(videoDecoder->fd, VIDEO_COMMAND, &cmd); + } + else return false; + + if (videoDecoder->fd >= 0) + { + ::ioctl(videoDecoder->fd, VIDEO_FAST_FORWARD, 0); + ::ioctl(videoDecoder->fd, VIDEO_SLOWMOTION, 0); + ::ioctl(videoDecoder->fd, VIDEO_PLAY); + ::ioctl(videoDecoder->fd, VIDEO_CONTINUE); + } + else return false; + + if (audioDecoder->fd >= 0) + { + ::ioctl(audioDecoder->fd, AUDIO_PLAY); + ::ioctl(audioDecoder->fd, AUDIO_CONTINUE); + } + else return false; + + playing = true; + + return true; +} + +bool cPlayback::Stop(void) +{ + hal_info("%s playing %d\n", __func__, playing); + + if (videoDecoder->fd >= 0) + { + ::ioctl(videoDecoder->fd, VIDEO_STOP); + } + if (audioDecoder->fd >= 0) + { + ::ioctl(audioDecoder->fd, AUDIO_STOP); + } + + playing = false; + return true; +} + +bool cPlayback::SetAPid(int pid, bool /* ac3 */) +{ + hal_info("%s\n", __func__); + int i = pid; + + if (pid != mAudioStream) + { + if (videoDecoder->fd >= 0) + { + struct video_command cmd = {0}; + cmd.cmd = 105; /* set audio streamid */ + cmd.raw.data[0] = pid; + ::ioctl(videoDecoder->fd, VIDEO_COMMAND, &cmd); + } + mAudioStream = pid; + } + return true; +} + +bool cPlayback::SetVPid(int /*pid*/) +{ + hal_info("%s\n", __func__); + return true; +} + +bool cPlayback::SetSubtitlePid(int pid) +{ + hal_info("%s\n", __func__); + int i = pid; + + if (pid != mSubtitleStream) + { + if (videoDecoder->fd >= 0) + { + struct video_command cmd = {0}; + cmd.cmd = 106; /* set subtitle streamid */ + cmd.raw.data[0] = i; + ::ioctl(videoDecoder->fd, VIDEO_COMMAND, &cmd); + } + mSubtitleStream = pid; + } + return true; +} + +bool cPlayback::SetTeletextPid(int pid) +{ + hal_info("%s\n", __func__); + + //int i = pid; + + if (pid != mTeletextStream) + { + mTeletextStream = pid; + } + return true; +} + +bool cPlayback::SetSpeed(int speed) +{ + hal_info("%s playing %d speed %d\n", __func__, playing, speed); + + if (!playing) + return false; + + if (videoDecoder->fd) + { + int result = 0; + nPlaybackSpeed = speed; + + if (speed > 1) + { + ::ioctl(videoDecoder->fd, VIDEO_FAST_FORWARD, speed); + ::ioctl(videoDecoder->fd, VIDEO_CONTINUE); + } + else if (speed < 0) + { + // trickseek + } + else if (speed == 0) + { + if (videoDecoder->fd >= 0) + { + ::ioctl(videoDecoder->fd, VIDEO_FREEZE); + } + if (audioDecoder->fd >= 0) + { + ::ioctl(audioDecoder->fd, AUDIO_PAUSE); + } + } + else + { + if (videoDecoder->fd >= 0) + { + ::ioctl(videoDecoder->fd, VIDEO_FAST_FORWARD, 0); + ::ioctl(videoDecoder->fd, VIDEO_SLOWMOTION, 0); + ::ioctl(videoDecoder->fd, VIDEO_CONTINUE); + } + if (audioDecoder->fd >= 0) + { + ::ioctl(audioDecoder->fd, AUDIO_CONTINUE); + } + } + + if (init_jump > -1) + { + SetPosition(init_jump); + init_jump = -1; + } + + if (result != 0) + { + printf("returning false\n"); + return false; + } + } + return true; +} + +bool cPlayback::GetSpeed(int &speed) const +{ + hal_debug("%s\n", __func__); + speed = nPlaybackSpeed; + return true; +} + +void cPlayback::GetPts(uint64_t &pts) +{ + pts = 0; + pts = videoDecoder->GetPTS(); + /* + if (videoDecoder->fd >= 0) + { + if (::ioctl(videoDecoder->fd, VIDEO_GET_PTS, &pts) >= 0) + { + return; + } + } + if (audioDecoder->fd >= 0) + { + if (::ioctl(audioDecoder->fd, AUDIO_GET_PTS, &pts) >= 0) + { + return; + } + }*/ +} + +// in milliseconds +bool cPlayback::GetPosition(int &position, int &duration) +{ + bool got_duration = false; + hal_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) + { + struct stat64 s; + if (!stat64(fn_ts.c_str(), &s)) + { + if (!playing || last_size != s.st_size) + { + last_size = s.st_size; + time_t curr_time = s.st_mtime; + if (!stat64(fn_xml.c_str(), &s)) + { + duration = (curr_time - s.st_mtime) * 1000; + if (!playing) + return true; + got_duration = true; + } + } + } + } + + if (!playing) + return false; + + int64_t vpts = 0; + //::ioctl(videoDecoder->fd, VIDEO_GET_PTS, &vpts); + vpts = videoDecoder->GetPTS(); + + if (vpts <= 0) + { + printf("ERROR: vpts==0\n"); + } + else + { + /* workaround for crazy vpts value during timeshift */ + if (!got_vpts_ts && pm == PLAYMODE_TS) + { + vpts_ts = vpts; + got_vpts_ts = true; + } + if (got_vpts_ts) + vpts -= vpts_ts; + /* end workaround */ + /* len is in nanoseconds. we have 90 000 pts per second. */ + position = vpts / 90; + } + + if (got_duration) + return true; + + int64_t length = 0; + + length = netlink_event::getInstance()->getDuration() * 1000; + + if (length <= 0) + { + duration = duration + 1000; + } + else + { + duration = length * 1000; + } + + return true; +} + +bool cPlayback::SetPosition(int position, bool absolute) +{ + hal_info("%s %d\n", __func__, position); + + if (playing && first) + { + /* the calling sequence is: + * Start() - paused + * SetPosition() - which fails if not running + * SetSpeed() - to start playing + * so let's remember the initial jump position and later jump to it + */ + init_jump = position; + first = false; + return false; + } + + int64_t pos = (position / 1000.0); + + if (!absolute) + { + uint64_t pts; + ::ioctl(videoDecoder->fd, VIDEO_GET_PTS, &pts); + pos = (pts / 90LL) + pos; + } + + if (videoDecoder->fd >= 0) + { + struct video_command cmd = {0}; + cmd.cmd = 100; /* seek */ + cmd.stop.pts = pos * 90LL; + ::ioctl(videoDecoder->fd, VIDEO_COMMAND, &cmd); + } + + + return true; +} + +void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *numpida, std::string *language) +{ + hal_info("%s\n", __func__); + int max_numpida = *numpida; + *numpida = 0; + +} + +void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::string *language) +{ + hal_info("%s\n", __func__); + + int max_numpids = *numpids; + *numpids = 0; + +} + +void cPlayback::FindAllTeletextsubtitlePids(int */*pids*/, unsigned int *numpids, std::string */*language*/, int */*mags*/, int */*pages*/) +{ + hal_info("%s\n", __func__); + //int max_numpids = *numpids; + *numpids = 0; + +} + +int cPlayback::GetTeletextPid(void) +{ + hal_info("%s\n", __func__); + int pid = -1; + + printf("teletext pid id %d (0x%x)\n", pid, pid); + return pid; +} + +void cPlayback::GetChapters(std::vector &positions, std::vector &titles) +{ + positions.clear(); + titles.clear(); +} + +void cPlayback::GetMetadata(std::vector &keys, std::vector &values) +{ + keys.clear(); + values.clear(); +} + +cPlayback::cPlayback(int num __attribute__((unused))) +{ + hal_info("%s\n", __func__); + playing = false; + first = false; +} + +cPlayback::~cPlayback() +{ + hal_info("%s\n", __func__); +} + +void cPlayback::RequestAbort() +{ + hal_info("%s\n", __func__); + Stop(); +} + +bool cPlayback::IsPlaying() +{ + return (playing == true); +} + +uint64_t cPlayback::GetReadCount() +{ + return 0; +} + +AVFormatContext *cPlayback::GetAVFormatContext() +{ + return NULL; +} + +void cPlayback::ReleaseAVFormatContext() +{ +} + +const char *cPlayback::getVidFormatStr(uint32_t format) +{ + switch (format) + { + case HI_FORMAT_VIDEO_MPEG2: + return "MPEG2"; + break; + + case HI_FORMAT_VIDEO_MPEG4: + return "MPEG4"; + break; + + case HI_FORMAT_VIDEO_AVS: + return "AVS"; + break; + + case HI_FORMAT_VIDEO_H263: + return "H263"; + break; + + case HI_FORMAT_VIDEO_H264: + return "H264"; + break; + + case HI_FORMAT_VIDEO_REAL8: + return "REAL8"; + break; + + case HI_FORMAT_VIDEO_REAL9: + return "REAL9"; + break; + + case HI_FORMAT_VIDEO_VC1: + return "VC1"; + break; + + case HI_FORMAT_VIDEO_VP6: + return "VP6"; + break; + + case HI_FORMAT_VIDEO_DIVX3: + return "DIVX3"; + break; + + case HI_FORMAT_VIDEO_RAW: + return "RAW"; + break; + + case HI_FORMAT_VIDEO_JPEG: + return "JPEG"; + break; + + case HI_FORMAT_VIDEO_MJPEG: + return "MJPEG"; + break; + case HI_FORMAT_VIDEO_MJPEGB: + return "MJPEGB"; + break; + case HI_FORMAT_VIDEO_SORENSON: + return "SORENSON"; + break; + + case HI_FORMAT_VIDEO_VP6F: + return "VP6F"; + break; + + case HI_FORMAT_VIDEO_VP6A: + return "VP6A"; + break; + + case HI_FORMAT_VIDEO_VP8: + return "VP8"; + break; + case HI_FORMAT_VIDEO_MVC: + return "MVC"; + break; + case HI_FORMAT_VIDEO_SVQ1: + return "SORENSON1"; + break; + case HI_FORMAT_VIDEO_SVQ3: + return "SORENSON3"; + break; + case HI_FORMAT_VIDEO_DV: + return "DV"; + break; + case HI_FORMAT_VIDEO_WMV1: + return "WMV1"; + break; + case HI_FORMAT_VIDEO_WMV2: + return "WMV2"; + break; + case HI_FORMAT_VIDEO_MSMPEG4V1: + return "MICROSOFT MPEG4V1"; + break; + case HI_FORMAT_VIDEO_MSMPEG4V2: + return "MICROSOFT MPEG4V2"; + break; + case HI_FORMAT_VIDEO_CINEPAK: + return "CINEPACK"; + break; + case HI_FORMAT_VIDEO_RV10: + return "RV10"; + break; + case HI_FORMAT_VIDEO_RV20: + return "RV20"; + break; + case HI_FORMAT_VIDEO_INDEO4: + return "INDEO4"; + break; + case HI_FORMAT_VIDEO_INDEO5: + return "INDEO5"; + break; + case HI_FORMAT_VIDEO_HEVC: + return "H265"; + case HI_FORMAT_VIDEO_VP9: + return "VP9"; + default: + return "UNKNOWN"; + break; + } + + return "UNKNOWN"; +} + +const char *cPlayback::getAudFormatStr(uint32_t format) +{ + switch (format) + { + case HI_FORMAT_AUDIO_MP2: + return "MPEG2"; + break; + case HI_FORMAT_AUDIO_MP3: + return "MPEG3"; + break; + case HI_FORMAT_AUDIO_AAC: + return "AAC"; + break; + case HI_FORMAT_AUDIO_AC3: + return "AC3"; + break; + case HI_FORMAT_AUDIO_DTS: + return "DTS"; + break; + case HI_FORMAT_AUDIO_VORBIS: + return "VORBIS"; + break; + case HI_FORMAT_AUDIO_DVAUDIO: + return "DVAUDIO"; + break; + case HI_FORMAT_AUDIO_WMAV1: + return "WMAV1"; + break; + case HI_FORMAT_AUDIO_WMAV2: + return "WMAV2"; + break; + case HI_FORMAT_AUDIO_MACE3: + return "MACE3"; + break; + case HI_FORMAT_AUDIO_MACE6: + return "MACE6"; + break; + case HI_FORMAT_AUDIO_VMDAUDIO: + return "VMDAUDIO"; + break; + case HI_FORMAT_AUDIO_SONIC: + return "SONIC"; + break; + case HI_FORMAT_AUDIO_SONIC_LS: + return "SONIC_LS"; + break; + case HI_FORMAT_AUDIO_FLAC: + return "FLAC"; + break; + case HI_FORMAT_AUDIO_MP3ADU: + return "MP3ADU"; + break; + case HI_FORMAT_AUDIO_MP3ON4: + return "MP3ON4"; + break; + case HI_FORMAT_AUDIO_SHORTEN: + return "SHORTEN"; + break; + case HI_FORMAT_AUDIO_ALAC: + return "ALAC"; + break; + case HI_FORMAT_AUDIO_WESTWOOD_SND1: + return "WESTWOOD_SND1"; + break; + case HI_FORMAT_AUDIO_GSM: + return "GSM"; + break; + case HI_FORMAT_AUDIO_QDM2: + return "QDM2"; + break; + case HI_FORMAT_AUDIO_COOK: + return "COOK"; + break; + case HI_FORMAT_AUDIO_TRUESPEECH: + return "TRUESPEECH"; + break; + case HI_FORMAT_AUDIO_TTA: + return "TTA"; + break; + case HI_FORMAT_AUDIO_SMACKAUDIO: + return "SMACKAUDIO"; + break; + case HI_FORMAT_AUDIO_QCELP: + return "QCELP"; + break; + case HI_FORMAT_AUDIO_WAVPACK: + return "WAVPACK"; + break; + case HI_FORMAT_AUDIO_DSICINAUDIO: + return "DSICINAUDIO"; + break; + case HI_FORMAT_AUDIO_IMC: + return "IMC"; + break; + case HI_FORMAT_AUDIO_MUSEPACK7: + return "MUSEPACK7"; + break; + case HI_FORMAT_AUDIO_MLP: + return "MLP"; + break; + case HI_FORMAT_AUDIO_GSM_MS: + return "GSM_MS"; + break; + case HI_FORMAT_AUDIO_ATRAC3: + return "ATRAC3"; + break; + case HI_FORMAT_AUDIO_VOXWARE: + return "VOXWARE"; + break; + case HI_FORMAT_AUDIO_APE: + return "APE"; + break; + case HI_FORMAT_AUDIO_NELLYMOSER: + return "NELLYMOSER"; + break; + case HI_FORMAT_AUDIO_MUSEPACK8: + return "MUSEPACK8"; + break; + case HI_FORMAT_AUDIO_SPEEX: + return "SPEEX"; + break; + case HI_FORMAT_AUDIO_WMAVOICE: + return "WMAVOICE"; + break; + case HI_FORMAT_AUDIO_WMAPRO: + return "WMAPRO"; + break; + case HI_FORMAT_AUDIO_WMALOSSLESS: + return "WMALOSSLESS"; + break; + case HI_FORMAT_AUDIO_ATRAC3P: + return "ATRAC3P"; + break; + case HI_FORMAT_AUDIO_EAC3: + return "EAC3"; + break; + case HI_FORMAT_AUDIO_SIPR: + return "SIPR"; + break; + case HI_FORMAT_AUDIO_MP1: + return "MP1"; + break; + case HI_FORMAT_AUDIO_TWINVQ: + return "TWINVQ"; + break; + case HI_FORMAT_AUDIO_TRUEHD: + return "TRUEHD"; + break; + case HI_FORMAT_AUDIO_MP4ALS: + return "MP4ALS"; + break; + case HI_FORMAT_AUDIO_ATRAC1: + return "ATRAC1"; + break; + case HI_FORMAT_AUDIO_BINKAUDIO_RDFT: + return "BINKAUDIO_RDFT"; + break; + case HI_FORMAT_AUDIO_BINKAUDIO_DCT: + return "BINKAUDIO_DCT"; + break; + case HI_FORMAT_AUDIO_DRA: + return "DRA"; + break; + + case HI_FORMAT_AUDIO_PCM: /* various PCM "codecs" */ + return "PCM"; + break; + + case HI_FORMAT_AUDIO_ADPCM: /* various ADPCM codecs */ + return "ADPCM"; + break; + + case HI_FORMAT_AUDIO_AMR_NB: /* AMR */ + return "AMR_NB"; + break; + case HI_FORMAT_AUDIO_AMR_WB: + return "AMR_WB"; + break; + case HI_FORMAT_AUDIO_AMR_AWB: + return "AMR_AWB"; + break; + + case HI_FORMAT_AUDIO_RA_144: /* RealAudio codecs*/ + return "RA_144"; + break; + case HI_FORMAT_AUDIO_RA_288: + return "RA_288"; + break; + + case HI_FORMAT_AUDIO_DPCM: /* various DPCM codecs */ + return "DPCM"; + break; + + case HI_FORMAT_AUDIO_G711: /* various G.7xx codecs */ + return "G711"; + break; + case HI_FORMAT_AUDIO_G722: + return "G722"; + break; + case HI_FORMAT_AUDIO_G7231: + return "G7231"; + break; + case HI_FORMAT_AUDIO_G726: + return "G726"; + break; + case HI_FORMAT_AUDIO_G728: + return "G728"; + break; + case HI_FORMAT_AUDIO_G729AB: + return "G729AB"; + break; + case HI_FORMAT_AUDIO_PCM_BLURAY: + return "PCM_BLURAY"; + break; + default: + break; + } + + return "UNKNOWN"; +} + +const char *cPlayback::getSubFormatStr(uint32_t format) +{ + switch (format) + { + case HI_FORMAT_SUBTITLE_ASS: + return "ASS"; + break; + case HI_FORMAT_SUBTITLE_LRC: + return "LRC"; + break; + case HI_FORMAT_SUBTITLE_SRT: + return "SRT"; + break; + case HI_FORMAT_SUBTITLE_SMI: + return "SMI"; + break; + case HI_FORMAT_SUBTITLE_SUB: + return "SUB"; + break; + case HI_FORMAT_SUBTITLE_TXT: + return "TEXT"; + break; + case HI_FORMAT_SUBTITLE_HDMV_PGS: + return "HDMV_PGS"; + break; + case HI_FORMAT_SUBTITLE_DVB_SUB: + return "DVB_SUB_BMP"; + break; + case HI_FORMAT_SUBTITLE_DVD_SUB: + return "DVD_SUB_BMP"; + break; + default: + return "UNKNOWN"; + break; + } + + return "UNKNOWN"; +} + +netlink_event * netlink_event::netlink_event_instance = NULL; + +netlink_event::netlink_event() +{ + netlink_socket = -1; +} + +netlink_event::~netlink_event() +{ + if (netlink_socket >= 0) + { + close(netlink_socket); + netlink_socket = -1; + } +} + +netlink_event* netlink_event::getInstance() +{ + if (netlink_event_instance == NULL) + { + netlink_event_instance = new netlink_event(); + hal_debug_c("[HSP] new netlink instance created \n"); + } + return netlink_event_instance; +} + +bool netlink_event::Start(cPlayback * _player) +{ + if (running) + return false; + + player = _player; + + memset(&fileinfo, 0, sizeof(fileinfo)); + memset(&streamid, 0, sizeof(streamid)); + + struct sockaddr_nl src_addr; + memset(&src_addr, 0, sizeof(src_addr)); + src_addr.nl_family = AF_NETLINK; + src_addr.nl_pid = getpid(); /* self pid */ + netlink_socket = socket(PF_NETLINK, SOCK_RAW, 30); + bind(netlink_socket, (struct sockaddr*)&src_addr, sizeof(src_addr)); + + nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD)); + + running = true; + return (OpenThreads::Thread::start() == 0); +} + +bool netlink_event::Stop() +{ + if (!running) + return false; + + running = false; + + OpenThreads::Thread::cancel(); + + if (netlink_socket >= 0) + { + close(netlink_socket); + netlink_socket = -1; + } + + return (OpenThreads::Thread::join() == 0); +} + +void netlink_event::run() +{ + OpenThreads::Thread::setCancelModeAsynchronous(); + while (running) + { + Receive(); + } +} + +int netlink_event::receive_netlink_message() +{ + struct msghdr msg; + struct iovec iov; + struct sockaddr_nl dest_addr; + memset(&dest_addr, 0, sizeof(dest_addr)); + dest_addr.nl_family = AF_NETLINK; + dest_addr.nl_pid = 0; /* For Linux Kernel */ + dest_addr.nl_groups = 0; /* unicast */ + + memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); + nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); + nlh->nlmsg_pid = getpid(); + nlh->nlmsg_flags = 0; + + iov.iov_base = (void *)nlh; + iov.iov_len = nlh->nlmsg_len; + msg.msg_name = (void *)&dest_addr; + msg.msg_namelen = sizeof(dest_addr); + msg.msg_iov = &iov; + msg.msg_iovlen = 1; + if (recvmsg(netlink_socket, &msg, 0) <= 0) + { + return 0; + } + return NLMSG_PAYLOAD(nlh, 0); +} + +void netlink_event::Receive() +{ + if (netlink_socket >= 0) + { + int readlen = receive_netlink_message(); + if (readlen > 0) + { + int decoder = *((uint32_t*)NLMSG_DATA(nlh)) >> 24; + int msgtype = *((uint32_t*)NLMSG_DATA(nlh)) & 0xffffff; + switch (msgtype) + { +#if 0 + case 2: /* subtitle data */ + if (m_currentSubtitleStream >= 0 && m_subtitle_widget && !m_paused) + { + struct subtitleheader + { + uint64_t pts; + uint32_t duration; + uint32_t datasize; + } header; + memcpy(&header, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(header)); + ePangoSubtitlePage pango_page; + gRGB rgbcol(0xD0,0xD0,0xD0); + pango_page.m_elements.push_back(ePangoSubtitlePageElement(rgbcol, (const char*)NLMSG_DATA(nlh) + sizeof(uint32_t) + sizeof(header))); + pango_page.m_show_pts = header.pts; /* ignored by widget (TODO?) */ + pango_page.m_timeout = 8000; + m_subtitle_widget->setPage(pango_page); + } + break; + case 3: /* clear subtitles */ + if (m_currentSubtitleStream >= 0 && m_subtitle_widget) + { + ePangoSubtitlePage pango_page; + pango_page.m_show_pts = 0; + pango_page.m_timeout = 0; + m_subtitle_widget->setPage(pango_page); + } + break; +#endif + case 4: /* file info */ + memcpy(&fileinfo, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(fileinfo)); + fileinfo.pastProgramInfo = (HI_FORMAT_PROGRAM_INFO_S*)malloc(fileinfo.u32ProgramNum * sizeof(HI_FORMAT_PROGRAM_INFO_S)); + fileinfo.u32ProgramNum = 0; + break; + case 5: /* program info */ + memcpy(&fileinfo.pastProgramInfo[fileinfo.u32ProgramNum], (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(HI_FORMAT_PROGRAM_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].pastVidStream = (HI_FORMAT_VID_INFO_S*)malloc(fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32VidStreamNum * sizeof(HI_FORMAT_VID_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32VidStreamNum = 0; + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].pastAudStream = (HI_FORMAT_AUD_INFO_S*)malloc(fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32AudStreamNum * sizeof(HI_FORMAT_AUD_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32AudStreamNum = 0; + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].pastSubStream = (HI_FORMAT_SUB_INFO_S*)malloc(fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32SubStreamNum * sizeof(HI_FORMAT_SUB_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum].u32SubStreamNum = 0; + fileinfo.u32ProgramNum++; + break; + case 6: /* video stream */ + memcpy(&fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].pastVidStream[fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32VidStreamNum], (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(HI_FORMAT_VID_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32VidStreamNum++; + break; + case 7: /* audio stream */ + memcpy(&fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].pastAudStream[fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32AudStreamNum], (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(HI_FORMAT_AUD_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32AudStreamNum++; + break; + case 8: /* subtitle stream */ + memcpy(&fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].pastSubStream[fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32SubStreamNum], (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(HI_FORMAT_SUB_INFO_S)); + fileinfo.pastProgramInfo[fileinfo.u32ProgramNum - 1].u32SubStreamNum++; + break; + case 9: /* stream id */ + memcpy(&streamid, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(streamid)); + hal_debug("[HSP] streamid: program %u, video %u, audio %u, subtitle %u", streamid.programid, streamid.videostreamid, streamid.audiostreamid, streamid.subtitlestreamid); + player->mAudioStream = streamid.audiostreamid; + player->mSubtitleStream = streamid.subtitlestreamid; + break; + case 10: /* player state */ + { + int32_t state; + memcpy(&state, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(state)); + hal_debug("[HSP] player state %d-->%d", m_player_state, state); + switch (state) + { + case 0: /* init */ + break; + case 1: /* deinit */ + break; + case 2: /* play */ + if (m_state != stRunning) + { + m_state = stRunning; + } + m_paused = false; + break; + case 3: /* fast forward */ + break; + case 4: /* rewind */ + break; + case 5: /* pause */ + m_paused = true; + break; + case 6: /* stop */ + m_paused = false; + break; + case 7: /* preparing */ + break; + } + m_player_state = state; + player->playing = (state < 6); + } + break; + case 11: /* error */ + { + int32_t error; + memcpy(&error, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(error)); + switch (error) + { + case 0: /* no error */ + break; + case 1: /* video playback failed */ + m_errorInfo.error_message = "video playback failed"; + break; + case 2: /* audio playback failed */ + m_errorInfo.error_message = "audio playback failed"; + break; + case 3: /* subtitle playback failed */ + m_errorInfo.error_message = "subtitle playback failed"; + break; + case 4: /* media playback failed */ + m_errorInfo.error_message = "media playback failed"; + break; + case 5: /* timeout */ + m_errorInfo.error_message = "timeout"; + break; + case 6: /* file format not supported */ + m_errorInfo.error_message = "format not supported"; + break; + case 7: /* unknown error */ + m_errorInfo.error_message = "unknown error"; + break; + case 8: /* I-frame decoding error */ + break; + } + hal_debug("[HSP] error %s (%d)", m_errorInfo.error_message.c_str(), error); + } + break; + case 12: /* buffering */ + { + struct bufferinfo + { + uint32_t status; + uint32_t percentage; + } info; + memcpy(&info, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(info)); + hal_debug("[HSP] buffering %u %u%%", info.status, info.percentage); + m_bufferpercentage = info.percentage; + switch (info.status) + { + case 0: /* empty */ + case 1: /* insufficient */ + if (!m_buffering) + { + m_buffering = true; + hal_debug("[HSP] start buffering....pause playback"); + player->SetSpeed(0); + } + break; + case 2: /* enough */ + case 3: /* full */ + if (m_buffering) + { + m_buffering = false; + hal_debug("[HSP] end buffering....continue playback"); + player->SetSpeed(1); + } + break; + default: + break; + } + } + break; + case 13: /* network info */ + { + struct networkinfo + { + uint32_t status; + int32_t errorcode; + } info; + memcpy(&info, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(info)); + switch (info.status) + { + case 0: /* network: unknown error */ + m_errorInfo.error_message = "network: error"; + break; + case 1: /* network: failed to connect */ + m_errorInfo.error_message = "network: connection failed"; + break; + case 2: /* network: timeout */ + m_errorInfo.error_message = "network: timeout"; + break; + case 3: /* network: disconnected */ + m_errorInfo.error_message = "network: disconnected"; + break; + case 4: /* network: file not found */ + m_errorInfo.error_message = "network: file not found"; + break; + case 5: /* network: status ok */ + m_errorInfo.error_message = "network: status ok"; + break; + case 6: /* network: http errorcode */ + m_errorInfo.error_message = "network: http errorcode"; + break; + case 7: /* network: bitrate adjusted */ + m_errorInfo.error_message = "network: bitrate adjusted"; + break; + } + hal_debug("[HSP] network info %s (%u) %d", m_errorInfo.error_message.c_str(), info.status, info.errorcode); + } + break; + case 14: /* event */ + { + int32_t event; + memcpy(&event, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(event)); + switch (event) + { + case 0: /* SOF */ + hal_debug("[HSP] event: SOF"); + /* reached SOF while rewinding */ + break; + case 1: /* EOF */ + hal_debug("[HSP] event: EOF"); + break; + } + } + break; + case 15: /* seekable */ + memcpy(&m_seekable, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(m_seekable)); + break; + case 16: /* download progress */ + memcpy(&m_download_progress, (unsigned char*)NLMSG_DATA(nlh) + sizeof(uint32_t), sizeof(m_download_progress)); + hal_debug("[HSP] dl progress: %d", m_download_progress); + if (m_download_progress >= 100) + { + player->SetSpeed(1); + } + break; + default: + break; + } + } + } +} + +#if 0 // for later use +void video_event::receive_video_msg() +{ + while (m_video_fd >= 0) + { + int retval; + pollfd pfd[1]; + pfd[0].fd = m_video_fd; + pfd[0].events = POLLPRI; + retval = ::poll(pfd, 1, 0); + if (retval < 0 && errno == EINTR) + continue; + if (retval <= 0) + break; + struct video_event evt; + if (::ioctl(m_video_fd, VIDEO_GET_EVENT, &evt) < 0) + { + hal_debug("[HSP] VIDEO_GET_EVENT failed: %m"); + break; + } + else + { + if (evt.type == VIDEO_EVENT_SIZE_CHANGED) + { + m_aspect = evt.u.size.aspect_ratio == 0 ? 2 : 3; // convert dvb api to etsi + m_height = evt.u.size.h; + m_width = evt.u.size.w; + hal_debug("[HSP] SIZE_CHANGED %dx%d aspect %d", m_width, m_height, m_aspect); + } + else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED) + { + m_framerate = evt.u.frame_rate; + hal_debug("[HSP] FRAME_RATE_CHANGED %d fps", m_framerate); + } + else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/) + { + m_progressive = evt.u.frame_rate; + hal_debug("[HSP] PROGRESSIVE_CHANGED %d", m_progressive); + } + else + hal_debug("[HSP] unhandled DVBAPI Video Event %d", evt.type); + } + } +} +#endif diff --git a/libarmbox/playback_hisilicon.h b/libarmbox/playback_hisilicon.h new file mode 100644 index 0000000..4103dcd --- /dev/null +++ b/libarmbox/playback_hisilicon.h @@ -0,0 +1,180 @@ +/* + Copyright (C) 2018 TangoCash + + License: GPLv2 + + 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; + + 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., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#ifndef __HAL_PLAYBACK_H +#define __HAL_PLAYBACK_H + +#include +#include + +#include +#include + +#include "hisilicon.h" + +typedef enum +{ + PLAYMODE_TS = 0, + PLAYMODE_FILE +} playmode_t; + +struct AVFormatContext; + +struct errorInfo +{ + std::string error_message; + std::string missing_codec; +}; + +class cPlayback +{ + friend class CStreamInfo2; + friend class netlink_event; + +private: + int m_video_fd; + int m_audio_fd; + bool enabled; + bool playing, first; + bool no_probe; + bool got_vpts_ts; + int nPlaybackSpeed; + int mAudioStream; + int mSubtitleStream; + int mTeletextStream; + int64_t vpts_ts; + bool Stop(void); + bool decoders_closed; + playmode_t pm; + std::string fn_ts; + std::string fn_xml; + off64_t last_size; + int init_jump; + const char *getVidFormatStr(uint32_t format); + const char *getAudFormatStr(uint32_t format); + const char *getSubFormatStr(uint32_t format); + + +public: + cPlayback(int num = 0); + ~cPlayback(); + + bool Open(playmode_t PlayMode); + void Close(void); + 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 SetSubtitlePid(int pid); + bool SetTeletextPid(int pid); + int GetAPid(void) + { + return mAudioStream; + } + int GetVPid(void) + { + return 0; + } + int GetSubtitlePid(void) + { + return mSubtitleStream; + } + int GetTeletextPid(void); + bool SetSpeed(int speed); + bool GetSpeed(int &speed) const; + bool GetPosition(int &position, int &duration); + void GetPts(uint64_t &pts); + 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 RequestAbort(void); + bool IsPlaying(void); + uint64_t GetReadCount(void); + + void GetChapters(std::vector &positions, std::vector &titles); + void GetMetadata(std::vector &keys, std::vector &values); + + AVFormatContext *GetAVFormatContext(); + void ReleaseAVFormatContext(); +}; + +class netlink_event : public OpenThreads::Thread +{ + friend class cPlayback; + +protected: + bool running; +private: + netlink_event(); + ~netlink_event(); + static netlink_event *netlink_event_instance; + cPlayback *player; + int m_player_state; + enum + { + stIdle, stRunning, stStopped, + }; + struct streamid + { + uint16_t programid; + uint16_t videostreamid; + uint16_t audiostreamid; + uint16_t subtitlestreamid; + } streamid; + int m_state; + bool m_paused; + bool m_buffering; + HI_FORMAT_FILE_INFO_S fileinfo; + struct nlmsghdr *nlh; + int m_bufferpercentage; + uint32_t m_seekable; + uint32_t m_download_progress; + int netlink_socket; + int receive_netlink_message(); + errorInfo m_errorInfo; + void run(); + void Receive(); +public: + static netlink_event* getInstance(); + uint64_t getDuration() + { + return fileinfo.s64Duration; + }; + bool Start(cPlayback *player); + bool Stop(); +}; + +#if 0 // for later use, maybe +class video_event : public OpenThreads::Thread +{ + friend class cPlayback; + +protected: + bool running; +private: + int m_video_fd; + void run(); + void Receive(); +public: + bool Start(int video_fd); + bool Stop(); +}; +#endif +#endif diff --git a/libarmbox/playback_libeplayer3.cpp b/libarmbox/playback_libeplayer3.cpp index 4e038a0..1e5c12c 100644 --- a/libarmbox/playback_libeplayer3.cpp +++ b/libarmbox/playback_libeplayer3.cpp @@ -791,10 +791,10 @@ bool cPlayback::IsPlaying() uint64_t cPlayback::GetReadCount() { - //if (player && player->playback) - //{ - // return player->playback->readCount; - //} + if (player && player->playback) + { + return player->playback->readCount; + } return 0; } diff --git a/libdvbci/dh_rsa_misc.cpp b/libdvbci/dh_rsa_misc.cpp index 921821e..5b6be9b 100644 --- a/libdvbci/dh_rsa_misc.cpp +++ b/libdvbci/dh_rsa_misc.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "misc.h" @@ -148,13 +149,25 @@ int dh_gen_exp(uint8_t *dest, int dest_len, uint8_t *dh_g, int dh_g_len, uint8_t dh = DH_new(); +#if OPENSSL_VERSION_NUMBER < 0x10100000L dh->p = BN_bin2bn(dh_p, dh_p_len, 0); dh->g = BN_bin2bn(dh_g, dh_g_len, 0); dh->flags |= DH_FLAG_NO_EXP_CONSTTIME; +#else + BIGNUM *p = BN_bin2bn(dh_p, dh_p_len, 0); + BIGNUM *g = BN_bin2bn(dh_g, dh_g_len, 0); + DH_set0_pqg(dh, p, NULL, g); +#endif DH_generate_key(dh); +#if OPENSSL_VERSION_NUMBER < 0x10100000L len = BN_num_bytes(dh->priv_key); +#else + const BIGNUM *pub_key, *priv_key; + DH_get0_key(dh, &pub_key, &priv_key); + len = BN_num_bytes(priv_key); +#endif if (len > dest_len) { printf("len > dest_len\n"); return -1; @@ -162,7 +175,12 @@ int dh_gen_exp(uint8_t *dest, int dest_len, uint8_t *dh_g, int dh_g_len, uint8_t gap = dest_len - len; memset(dest, 0, gap); + +#if OPENSSL_VERSION_NUMBER < 0x10100000L BN_bn2bin(dh->priv_key, &dest[gap]); +#else + BN_bn2bin(priv_key, &dest[gap]); +#endif DH_free(dh); diff --git a/libdvbci/dvbci_ccmgr.cpp b/libdvbci/dvbci_ccmgr.cpp index 53f3658..932e6b1 100644 --- a/libdvbci/dvbci_ccmgr.cpp +++ b/libdvbci/dvbci_ccmgr.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include "misc.h" #include "_dh_params.h" @@ -240,7 +241,11 @@ static bool certificate_validate(struct cert_ctx *ctx, X509 *cert) ret = X509_verify_cert(store_ctx); if (ret != 1) +#if OPENSSL_VERSION_NUMBER < 0x10100000L fprintf(stderr, "%s\n", X509_verify_cert_error_string(store_ctx->error)); +#else + fprintf(stderr, "%s\n", X509_verify_cert_error_string(ret)); +#endif X509_STORE_CTX_free(store_ctx); diff --git a/libeplayer3-arm/Makefile.am b/libeplayer3-arm/Makefile.am index 193f427..b29e212 100644 --- a/libeplayer3-arm/Makefile.am +++ b/libeplayer3-arm/Makefile.am @@ -51,7 +51,7 @@ SOURCE_FILES += \ output/writer/mipsel/wma.c \ output/writer/mipsel/h265.c \ output/writer/mipsel/h264.c \ - output/writer/mipsel/h263.c \ + output/writer/mipsel/mjpeg.c \ output/writer/mipsel/mpeg2.c \ output/writer/mipsel/mpeg4.c \ output/writer/mipsel/divx3.c \ diff --git a/libeplayer3-arm/container/buff_ffmpeg.c b/libeplayer3-arm/container/buff_ffmpeg.c index 506aca3..43bc82a 100644 --- a/libeplayer3-arm/container/buff_ffmpeg.c +++ b/libeplayer3-arm/container/buff_ffmpeg.c @@ -53,10 +53,10 @@ static int64_t update_max_injected_pts(int64_t pts) { if (pts > 0 && pts != INVALID_PTS_VALUE) { - //if (maxInjectedPTS == INVALID_PTS_VALUE || pts > maxInjectedPTS) - //{ + if (maxInjectedPTS == INVALID_PTS_VALUE || pts > maxInjectedPTS || 0 == PlaybackDieNow(0)) + { maxInjectedPTS = pts; - //} + } } return maxInjectedPTS; } @@ -101,7 +101,7 @@ static void update_finish_timeout() maxInjectedPts = 0; } - //printf("ret[%d] playPts[%lld] currPts[%lld] maxInjectedPts[%lld]\n", ret, playPts, currPts, maxInjectedPts); + //printf("ret[%d] playPts[%" PRId64 "] currPts[%" PRId64 "] maxInjectedPts[%" PRId64 "]\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 @@ -596,7 +596,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, if (diff > 0 && diff < rwdiff) { /* can do the seek inside the buffer */ - ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff); + ffmpeg_printf(20, "buffer-seek diff=%" PRId64 "\n", diff); if (diff > (ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read) { ffmpeg_buf_read = ffmpeg_buf + (diff - ((ffmpeg_buf + ffmpeg_buf_size) - ffmpeg_buf_read)); @@ -609,7 +609,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, else if (diff < 0 && diff * -1 < ffmpeg_buf_valid_size) { /* can do the seek inside the buffer */ - ffmpeg_printf(20, "buffer-seek diff=%lld\n", diff); + ffmpeg_printf(20, "buffer-seek diff=%" PRId64 "\n", diff); int32_t tmpdiff = diff * -1; if (tmpdiff > ffmpeg_buf_read - ffmpeg_buf) { @@ -623,7 +623,7 @@ static int64_t ffmpeg_seek(void *opaque __attribute__((unused)), int64_t offset, else { releasefillerMutex(__FILE__, __FUNCTION__, __LINE__); - ffmpeg_printf(20, "real-seek diff=%lld\n", diff); + ffmpeg_printf(20, "real-seek diff=%" PRId64 "\n", diff); ffmpeg_do_seek_ret = 0; ffmpeg_do_seek = diff; diff --git a/libeplayer3-arm/container/container.c b/libeplayer3-arm/container/container.c index 48ea13a..04ee133 100644 --- a/libeplayer3-arm/container/container.c +++ b/libeplayer3-arm/container/container.c @@ -23,28 +23,7 @@ #include #include "common.h" - -#ifdef SAM_WITH_DEBUG -#define CONTAINER_DEBUG -#else -#define CONTAINER_SILENT -#endif - -#ifdef CONTAINER_DEBUG - -static short debug_level = 0; - -#define container_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define container_printf(level, x...) -#endif - -#ifndef CONTAINER_SILENT -#define container_err(x...) do { printf(x); } while (0) -#else -#define container_err(x...) -#endif +#include "debug.h" static Container_t *AvailableContainer[] = { diff --git a/libeplayer3-arm/container/container_ffmpeg.c b/libeplayer3-arm/container/container_ffmpeg.c index 769fe56..4692b4e 100644 --- a/libeplayer3-arm/container/container_ffmpeg.c +++ b/libeplayer3-arm/container/container_ffmpeg.c @@ -25,10 +25,10 @@ /* ***************************** */ /* Includes */ /* ***************************** */ +#include "debug.h" #include #include -#include #include #include #include @@ -41,6 +41,7 @@ #include #include #include +#include #include @@ -66,30 +67,7 @@ * due to this we set own which use fopen/fread from * std library. */ -#define SAM_CUSTOM_IO - -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define FFMPEG_DEBUG -#else -#define FFMPEG_SILENT -#endif - -#ifdef FFMPEG_DEBUG - -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) -#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) -#else -#define ffmpeg_err(fmt, x...) -#endif +#define USE_CUSTOM_IO /* Error Constants */ #define cERR_CONTAINER_FFMPEG_NO_ERROR 0 @@ -122,7 +100,7 @@ static int32_t hasPlayThreadStarted = 0; 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 AVDictionary *g_avio_opts = NULL; static int64_t latestPts = 0; @@ -147,6 +125,8 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab //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); +static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts); +static int32_t container_ffmpeg_stop(Context_t *context); /* Progressive playback means that we play local file * but this local file can grows up, for example @@ -315,18 +295,20 @@ void flv2mpeg4_converter_set(const int32_t val) int32_t ffmpeg_av_dict_set(const char *key, const char *value, int32_t flags) { - return av_dict_set(&avio_opts, key, value, flags); + return av_dict_set(&g_avio_opts, key, value, flags); } 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); + ffmpeg_printf(10, "Codec ID: %d (%.8x)\n", codec_id, codec_id); switch (codec_id) { case AV_CODEC_ID_MPEG1VIDEO: return "V_MPEG1"; case AV_CODEC_ID_MPEG2VIDEO: - return "V_MPEG1"; + return "V_MPEG2"; + case AV_CODEC_ID_MJPEG: + return "V_MJPEG"; case AV_CODEC_ID_H263: case AV_CODEC_ID_H263P: case AV_CODEC_ID_H263I: @@ -462,33 +444,30 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra return "S_TEXT/SRT"; case AV_CODEC_ID_SUBRIP: return "S_TEXT/SUBRIP"; + case AV_CODEC_ID_WEBVTT: + return "D_WEBVTT/SUBTITLES"; default: - ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id); + ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id); // Default to injected-pcm for unhandled audio types. if (media_type == AVMEDIA_TYPE_AUDIO) { return "A_IPCM"; } - ffmpeg_err("Codec ID %d (%.8lx) not found\n", codec_id, codec_id); + ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id); } return NULL; } -static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) +static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts) { - if (!stream || pts == (int64_t)AV_NOPTS_VALUE) + if (time_base.den > 0) { - ffmpeg_err("stream / packet null\n"); - return INVALID_PTS_VALUE; - } - else if (stream->time_base.den > 0) - { - pts = av_rescale(pts, (int64_t)stream->time_base.num * 90000, stream->time_base.den); + pts = av_rescale(pts, (int64_t)time_base.num * 90000, time_base.den); } - if (avContextTab[avContextIdx]->start_time != AV_NOPTS_VALUE) + if (start_time != AV_NOPTS_VALUE) { - pts -= 90000 * avContextTab[avContextIdx]->start_time / AV_TIME_BASE; + pts -= 90000 * start_time / AV_TIME_BASE; } if (pts & 0x8000000000000000ull) @@ -503,6 +482,17 @@ static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) return pts; } +static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts) +{ + if (!stream || pts == (int64_t)AV_NOPTS_VALUE) + { + ffmpeg_err("stream / packet null\n"); + return INVALID_PTS_VALUE; + } + + return doCalcPts(avContextTab[avContextIdx]->start_time, stream->time_base, pts); +} + /* search for metatdata in context and stream * and map it to our metadata. */ @@ -559,6 +549,8 @@ static void FFMPEGThread(Context_t *context) int64_t lastVideoDts = -1; int64_t lastAudioDts = -1; + int64_t multiContextLastPts[IPTV_AV_CONTEXT_MAX_NUM] = {INVALID_PTS_VALUE, INVALID_PTS_VALUE}; + int64_t showtime = 0; int64_t bofcount = 0; AudioVideoOut_t avOut; @@ -573,9 +565,7 @@ static void FFMPEGThread(Context_t *context) uint32_t cAVIdx = 0; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) - Mpeg4P2Context mpeg4p2_context; - memset(&mpeg4p2_context, 0, sizeof(Mpeg4P2Context)); - AVBitStreamFilterContext *mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes"); + Mpeg4P2Context *mpeg4p2_context = mpeg4p2_context_open(); #endif #ifdef HAVE_FLV2MPEG4_CONVERTER Flv2Mpeg4Context flv2mpeg4_context; @@ -688,10 +678,11 @@ static void FFMPEGThread(Context_t *context) isWaitingForFinish = 0; if (do_seek_target_seconds) { - ffmpeg_printf(10, "seek_target_seconds[%lld]\n", seek_target_seconds); + ffmpeg_printf(10, "seek_target_seconds[%" PRId64 "]\n", seek_target_seconds); uint32_t i = 0; for (; i < IPTV_AV_CONTEXT_MAX_NUM; i += 1) { + multiContextLastPts[i] = INVALID_PTS_VALUE; if (NULL != avContextTab[i]) { if (i == 1) @@ -743,12 +734,7 @@ static void FFMPEGThread(Context_t *context) } } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) - mpeg4p2_context_reset(&mpeg4p2_context); - if (NULL != mpeg4p2_bsf_context) - { - av_bitstream_filter_close(mpeg4p2_bsf_context); - mpeg4p2_bsf_context = av_bitstream_filter_init("mpeg4_unpack_bframes"); - } + mpeg4p2_context_reset(mpeg4p2_context); #endif #ifdef HAVE_FLV2MPEG4_CONVERTER flv2mpeg4_context_reset(&flv2mpeg4_context); @@ -760,12 +746,31 @@ static void FFMPEGThread(Context_t *context) { if (NULL != avContextTab[1]) { - cAVIdx = currentVideoPts <= currentAudioPts ? 0 : 1; - if (1 == cAVIdx && prev_seek_time_sec >= 0) + if (prev_seek_time_sec >= 0) { - avformat_seek_file(avContextTab[1], -1, (currentVideoPts / 90000) * AV_TIME_BASE - AV_TIME_BASE, (currentVideoPts / 90000) * AV_TIME_BASE, (currentVideoPts / 90000) * AV_TIME_BASE + AV_TIME_BASE, 0); - prev_seek_time_sec = -1; - wrapped_avcodec_flush_buffers(1); + if (multiContextLastPts[0] != INVALID_PTS_VALUE) + { + int64_t target = av_rescale(multiContextLastPts[0], AV_TIME_BASE, 90000); + avformat_seek_file(avContextTab[1], -1, INT64_MIN, target, INT64_MAX, 0); + prev_seek_time_sec = -1; + wrapped_avcodec_flush_buffers(1); + cAVIdx = 1; + } + else + { + cAVIdx = 0; + } + } + else + { + if (multiContextLastPts[0] != INVALID_PTS_VALUE && multiContextLastPts[1] != INVALID_PTS_VALUE) + { + cAVIdx = multiContextLastPts[0] < multiContextLastPts[1] ? 0 : 1; + } + else + { + cAVIdx = !cAVIdx; + } } } else @@ -782,8 +787,13 @@ static void FFMPEGThread(Context_t *context) Track_t *audioTrack = NULL; Track_t *subtitleTrack = NULL; + context->playback->readCount += packet.size; + int32_t pid = avContextTab[cAVIdx]->streams[packet.stream_index]->id; + multiContextLastPts[cAVIdx] = calcPts(cAVIdx, avContextTab[cAVIdx]->streams[packet.stream_index], packet.pts); + ffmpeg_printf(200, "Ctx %d PTS: %"PRId64" PTS[1] %"PRId64"\n", cAVIdx, multiContextLastPts[cAVIdx], multiContextLastPts[1]); + reset_finish_timeout(); if (avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL) @@ -805,7 +815,7 @@ static void FFMPEGThread(Context_t *context) } else { - ffmpeg_printf(1, "SKIP DISCARDED PACKET stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid); + ffmpeg_printf(1, "SKIP DISCARDED PACKET packed_size[%d] 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); @@ -814,19 +824,9 @@ static void FFMPEGThread(Context_t *context) { #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) AVCodecContext *codec_context = videoTrack->avCodecCtx; - if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_bsf_context) + if (codec_context && codec_context->codec_id == AV_CODEC_ID_MPEG4 && NULL != mpeg4p2_context) { - // should never happen, if it does print error and exit immediately, so we can easily spot it - if (filter_packet(mpeg4p2_bsf_context, codec_context, &packet) < 0) - { - ffmpeg_err("cannot filter mpegp2 packet\n"); - exit(1); - } - if (mpeg4p2_write_packet(context, &mpeg4p2_context, videoTrack, cAVIdx, ¤tVideoPts, &latestPts, &packet) < 0) - { - ffmpeg_err("cannot write mpeg4p2 packet\n"); - exit(1); - } + mpeg4p2_write_packet(context, mpeg4p2_context, videoTrack, cAVIdx, ¤tVideoPts, &latestPts, &packet); update_max_injected_pts(latestPts); } else @@ -841,7 +841,7 @@ static void FFMPEGThread(Context_t *context) else #endif { - uint8_t skipPacket = 0; + bool skipPacket = false; currentVideoPts = videoTrack->pts = pts = calcPts(cAVIdx, videoTrack->stream, packet.pts); videoTrack->dts = dts = calcPts(cAVIdx, videoTrack->stream, packet.dts); @@ -863,14 +863,14 @@ static void FFMPEGThread(Context_t *context) { // skip already injected VIDEO packet ffmpeg_printf(200, "skip already injected VIDEO packet\n"); - skipPacket = 1; + skipPacket = true; } } else { // skip VIDEO packet with unknown DTS ffmpeg_printf(200, "skip VIDEO packet with unknown DTS\n"); - skipPacket = 1; + skipPacket = true; } } @@ -881,7 +881,7 @@ static void FFMPEGThread(Context_t *context) continue; } - ffmpeg_printf(200, "VideoTrack index = %d %lld\n", pid, currentVideoPts); + ffmpeg_printf(200, "VideoTrack index = %d %" PRId64 "\n", pid, currentVideoPts); avOut.data = packet.data; avOut.len = packet.size; @@ -1138,7 +1138,7 @@ static void FFMPEGThread(Context_t *context) ffmpeg_err("av_samples_alloc: %d\n", -e); continue; } - int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame), + int64_t next_in_pts = av_rescale(wrapped_frame_get_best_effort_timestamp(decoded_frame), ((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate, ((AVStream *) audioTrack->stream)->time_base.den); int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts), @@ -1184,7 +1184,7 @@ static void FFMPEGThread(Context_t *context) else if (audioTrack->have_aacheader == 1) { 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]); + ffmpeg_printf(200, "> %hhx %hhx %hhx %hhx %x %hhx %hhx\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; @@ -1344,11 +1344,7 @@ static void FFMPEGThread(Context_t *context) } #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) - mpeg4p2_context_reset(&mpeg4p2_context); - if (NULL != mpeg4p2_bsf_context) - { - av_bitstream_filter_close(mpeg4p2_bsf_context); - } + mpeg4p2_context_close(mpeg4p2_context); #endif hasPlayThreadStarted = 0; @@ -1357,6 +1353,11 @@ static void FFMPEGThread(Context_t *context) do_seek_target_seconds = 0; PlaybackDieNow(1); + if(context && context->playback) + { + container_ffmpeg_stop(context); + } + ffmpeg_printf(10, "terminating\n"); } @@ -1371,7 +1372,7 @@ static int32_t interrupt_cb(void *ctx) return p->abortRequested || PlaybackDieNow(0); } -#ifdef SAM_CUSTOM_IO +#ifdef USE_CUSTOM_IO typedef struct CustomIOCtx_t { FILE *pFile; @@ -1533,12 +1534,13 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin avContextTab[AVIdx]->interrupt_callback.callback = interrupt_cb; avContextTab[AVIdx]->interrupt_callback.opaque = context->playback; -#ifdef SAM_CUSTOM_IO +#ifdef USE_CUSTOM_IO if (0 == strstr(filename, "://") || 0 == strncmp(filename, "file://", 7)) { AVIOContext *avio_ctx = NULL; custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t)); + memset(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t)); custom_io_tab[AVIdx]->szFile = filename; @@ -1561,7 +1563,10 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin } #endif + AVDictionary *avio_opts = NULL; AVDictionary **pavio_opts = NULL; + av_dict_copy(&avio_opts, g_avio_opts, 0); + eRTMPProtoImplType rtmpProtoImplType = RTMP_NONE; uint8_t numOfRTMPImpl = 0; if (0 == strncmp(filename, "ffrtmp", 6)) @@ -1906,15 +1911,14 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) } /* initialize ffmpeg */ - avcodec_register_all(); - av_register_all(); - + wrapped_register_all(); avformat_network_init(); - // SULGE DEBUG ENABLED - // make ffmpeg silen - // av_log_set_level(AV_LOG_DEBUG); +#if FFMPEG_DEBUG_LEVEL >= 10 + av_log_set_level(AV_LOG_DEBUG); +#else av_log_set_callback(ffmpeg_silen_callback); +#endif context->playback->abortRequested = 0; int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ @@ -2097,7 +2101,8 @@ 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 */ + // do not discard any stream from second context + stream->discard = 0 == cAVIdx ? AVDISCARD_ALL : AVDISCARD_DEFAULT; /* by default we discard all video streams */ if (encoding != NULL) { @@ -2145,7 +2150,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, "bit_rate [%" PRId64 "]\n", get_codecpar(stream)->bit_rate); ffmpeg_printf(10, "time_base.den [%d]\n", stream->time_base.den); ffmpeg_printf(10, "time_base.num [%d]\n", stream->time_base.num); ffmpeg_printf(10, "width [%d]\n", get_codecpar(stream)->width); @@ -2176,7 +2181,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { track.avCodecCtx = wrapped_avcodec_get_context(cAVIdx, stream); } - ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n"); + ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track VIDEO\n", cAVIdx); if (context->manager->video->Command(context, MANAGER_ADD, &track) < 0) { /* konfetti: fixme: is this a reason to return with error? */ @@ -2199,7 +2204,8 @@ 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; + // do not discard any stream from second context + stream->discard = 0 == cAVIdx ? AVDISCARD_ALL : AVDISCARD_DEFAULT; if (encoding != NULL) { @@ -2504,9 +2510,13 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 if (context->manager->audio) { - ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n"); + ffmpeg_printf(1, "cAVIdx[%d]: MANAGER_ADD track AUDIO\n", cAVIdx); if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0) { + if(track.aacbuf){ + free(track.aacbuf); + track.aacbuf = NULL; + } /* konfetti: fixme: is this a reason to return with error? */ ffmpeg_err("failed to add track %d\n", n); } @@ -2525,7 +2535,8 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 #endif get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP && get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT && - get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT) + get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT && + get_codecpar(stream)->codec_id != AV_CODEC_ID_WEBVTT) { ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id); } @@ -2727,7 +2738,11 @@ static int32_t container_ffmpeg_stop(Context_t *context) fclose(io->pFile); if (io->pMoovFile) fclose(io->pMoovFile); - free(custom_io_tab[i]); + if(custom_io_tab[i] != NULL) + { + free(custom_io_tab[i]); + custom_io_tab[i] = NULL; + } av_freep(&(avContextTab[i]->pb->buffer)); av_freep(&(avContextTab[i]->pb)); use_custom_io[i] = 0; @@ -2741,9 +2756,9 @@ static int32_t container_ffmpeg_stop(Context_t *context) } } - if (avio_opts != NULL) + if (g_avio_opts != NULL) { - av_dict_free(&avio_opts); + av_dict_free(&g_avio_opts); } avformat_network_deinit(); @@ -2760,7 +2775,7 @@ 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); + ffmpeg_printf(20, "seeking to position %" PRId64 " (bytes)\n", pos); if (current_pos > pos) { @@ -2773,7 +2788,7 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos) return cERR_CONTAINER_FFMPEG_ERR; } - ffmpeg_printf(30, "current_pos after seek %lld\n", avio_tell(avContextTab[0]->pb)); + ffmpeg_printf(30, "current_pos after seek %" PRId64 "\n", avio_tell(avContextTab[0]->pb)); return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -2787,7 +2802,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t Track_t *current = NULL; seek_target_flag = 0; - ffmpeg_printf(10, "seeking %f sec relativ to %lld\n", sec, pos); + ffmpeg_printf(10, "seeking %" PRId64 " sec relativ to %" PRId64 "\n", sec, pos); context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); @@ -2845,7 +2860,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t return cERR_CONTAINER_FFMPEG_END_OF_FILE; } - ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %f\n", pos, sec); + ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %f\n", pos, sec); seek_target_bytes = pos; do_seek_target_bytes = 1; @@ -2862,7 +2877,7 @@ static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t 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); + ffmpeg_printf(10, "2. seeking to position %" PRId64 " 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; @@ -2884,7 +2899,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab if (!absolute) { - ffmpeg_printf(10, "seeking %lld sec\n", sec / AV_TIME_BASE); + ffmpeg_printf(10, "seeking %" PRId64 " sec\n", sec / AV_TIME_BASE); if (sec == 0) { ffmpeg_err("sec = 0 ignoring\n"); @@ -2908,7 +2923,7 @@ 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); + ffmpeg_printf(10, "goto %" PRId64 " sec\n", sec / AV_TIME_BASE); context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); @@ -2962,7 +2977,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab off_t pos = avio_tell(avContextTab[0]->pb); releaseMutex(__FILE__, __FUNCTION__, __LINE__); - ffmpeg_printf(10, "pos %lld %lld\n", pos, avContextTab[0]->bit_rate); + ffmpeg_printf(10, "pos %" PRId64 " %lld\n", pos, avContextTab[0]->bit_rate); if (avContextTab[0]->bit_rate) { @@ -2981,7 +2996,7 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab pos = 0; } - ffmpeg_printf(10, "1. seeking to position %lld bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE); + ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE); seek_target_bytes = pos / AV_TIME_BASE; do_seek_target_bytes = 1; @@ -3067,7 +3082,11 @@ static int32_t container_ffmpeg_switch_audio(Context_t *context, int32_t *arg __ int32_t i; for (i = 0; i < TrackCount; ++i) { - ((AVStream *)Tracks[i].stream)->discard = Tracks[i].Id == *arg ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + // do not discard any stream from second context + if (Tracks[i].AVIdx == 0) + { + ((AVStream *)Tracks[i].stream)->discard = Tracks[i].Id == *arg ? AVDISCARD_DEFAULT : AVDISCARD_ALL; + } } } } diff --git a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c old mode 100644 new mode 100755 index 0565912..ebcb959 --- a/libeplayer3-arm/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3-arm/container/mpeg4p2_ffmpeg.c @@ -3,108 +3,46 @@ // http://forums.openpli.org/topic/39326-gstreamer10-and-mpeg4-part2/?hl=%2Bmpeg4+%2Bpart2 // -#define MPEG4P2_MAX_B_FRAMES_COUNT 5 - +// mpeg4_unpack_bframes typedef struct { - int b_frames_count; - int first_ip_frame_written; - int64_t packet_duration; - AVPacket *b_frames[MPEG4P2_MAX_B_FRAMES_COUNT]; - AVPacket *second_ip_frame; + const AVBitStreamFilter *bsf; + AVBSFContext *ctx; } Mpeg4P2Context; - -static void set_packet(AVPacket **pkt_dest, AVPacket *pkt_src) +static Mpeg4P2Context *mpeg4p2_context_open() { - if (pkt_dest == NULL) - return; - if (*pkt_dest != NULL) + Mpeg4P2Context *context = NULL; + const AVBitStreamFilter *bsf = av_bsf_get_by_name("mpeg4_unpack_bframes"); + if (bsf) { - wrapped_packet_unref(*pkt_dest); - av_free(*pkt_dest); - } - *pkt_dest = av_malloc(sizeof(AVPacket)); - av_packet_ref(*pkt_dest, pkt_src); -} - -static int filter_packet(AVBitStreamFilterContext *bsf_ctx, AVCodecContext *enc_ctx, AVPacket *pkt) -{ - int ret; - AVPacket new_pkt = *pkt; - ret = av_bitstream_filter_filter(bsf_ctx, enc_ctx, NULL, - &new_pkt.data, &new_pkt.size, - pkt->data, pkt->size, - pkt->flags & AV_PKT_FLAG_KEY); - if (ret == 0 && new_pkt.data != pkt->data) - { - if ((ret = av_packet_ref(&new_pkt, pkt)) < 0) - return -1; - ret = 1; - } - if (ret > 0) - { - pkt->side_data = NULL; - pkt->side_data_elems = 0; - wrapped_packet_unref(pkt); - new_pkt.buf = av_buffer_create(new_pkt.data, new_pkt.size, - av_buffer_default_free, NULL, 0); - if (!new_pkt.buf) - return -1; - } - if (ret < 0) - { - ffmpeg_err("Failed to filter bitstream with filter %s for stream %d with codec %s\n", - bsf_ctx->filter->name, pkt->stream_index, - avcodec_get_name(enc_ctx->codec_id)); - return -1; - } - *pkt = new_pkt; - return 0; -} - -static void mpeg4p2_context_reset(Mpeg4P2Context *context) -{ - if (context == NULL) - return; - int i; - for (i = 0; i < MPEG4P2_MAX_B_FRAMES_COUNT; i++) - { - if (context->b_frames[i] != NULL) + context = malloc(sizeof(Mpeg4P2Context)); + if (context) { - wrapped_packet_unref(context->b_frames[i]); - av_free(context->b_frames[i]); + memset(context, 0x00, sizeof(Mpeg4P2Context)); + context->bsf = bsf; } - context->b_frames[i] = NULL; } - if (context->second_ip_frame != NULL) - { - wrapped_packet_unref(context->second_ip_frame); - 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; + return context; } -static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt) +static void mpeg4p2_write(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int64_t start_time, int64_t *currentVideoPts, int64_t *latest_Pts, AVPacket *pkt) { - *pts_current = track->pts = calcPts(avContextIdx, track->stream, pkt->pts); - if ((*pts_current > *pts_latest) && (*pts_current != INVALID_PTS_VALUE)) + *currentVideoPts = track->pts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->pts); + if ((*currentVideoPts > *latest_Pts) && (*currentVideoPts != INVALID_PTS_VALUE)) { - *pts_latest = *pts_current; + *latest_Pts = *currentVideoPts; } - track->dts = calcPts(avContextIdx, track->stream, pkt->dts); + + track->dts = doCalcPts(start_time, mpeg4p2_ctx->ctx->time_base_out, pkt->dts); AudioVideoOut_t avOut; avOut.data = pkt->data; avOut.len = pkt->size; avOut.pts = track->pts; avOut.dts = track->dts; - avOut.extradata = track->extraData; - avOut.extralen = track->extraSize; + avOut.extradata = mpeg4p2_ctx->ctx->par_out->extradata; + avOut.extralen = mpeg4p2_ctx->ctx->par_out->extradata_size; avOut.frameRate = track->frame_rate; avOut.timeScale = track->TimeScale; avOut.width = track->width; @@ -117,97 +55,90 @@ static void mpeg4p2_write(Context_t *ctx, Track_t *track, int avContextIdx, int6 } } -static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int cAVIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt) +static int mpeg4p2_context_reset(Mpeg4P2Context *context) { - uint8_t *data = pkt->data; - int data_len = pkt->size; - int pos = 0; - if (mpeg4p2_ctx->packet_duration == 0) + int ret = 0; + if (context && context->ctx) { - mpeg4p2_ctx->packet_duration = pkt->duration; - } - while (pos < data_len) - { - if (memcmp(&data[pos], "\x00\x00\x01\xb6", 4)) + // Flush + ret = av_bsf_send_packet(context->ctx, NULL); + if (ret == 0) { - pos++; - continue; - } - pos += 4; - switch ((data[pos] & 0xC0) >> 6) - { - case 0: // I-Frame - case 1: // P-Frame - if (!mpeg4p2_ctx->first_ip_frame_written) - { - mpeg4p2_ctx->first_ip_frame_written = 1; - pkt->pts = pkt->dts + mpeg4p2_ctx->packet_duration; - ffmpeg_printf(100, "Writing first I/P packet\n"); - mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, pkt); - return 0; - } - else if (!mpeg4p2_ctx->second_ip_frame) - { - set_packet(&mpeg4p2_ctx->second_ip_frame, pkt); - return 0; - } - else - { - if (!mpeg4p2_ctx->b_frames_count) - { - mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration; - ffmpeg_printf(100, "Writing second I/P packet(1)\n"); - mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame); - set_packet(&mpeg4p2_ctx->second_ip_frame, pkt); - return 0; - } - else - { - mpeg4p2_ctx->second_ip_frame->pts = mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count - 1]->dts + mpeg4p2_ctx->packet_duration; - mpeg4p2_ctx->b_frames[0]->pts = mpeg4p2_ctx->second_ip_frame->dts + mpeg4p2_ctx->packet_duration; - int i; - for (i = 1; i < mpeg4p2_ctx->b_frames_count; i++) - { - mpeg4p2_ctx->b_frames[i]->pts = mpeg4p2_ctx->b_frames[i - 1]->dts + mpeg4p2_ctx->packet_duration; - } - ffmpeg_printf(100, "Writing second I/P packet(2)\n"); - mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->second_ip_frame); - set_packet(&mpeg4p2_ctx->second_ip_frame, pkt); - for (i = 0; i < mpeg4p2_ctx->b_frames_count; i++) - { - ffmpeg_printf(100, "Writing B-frame[%d]\n", i); - mpeg4p2_write(ctx, track, cAVIdx, pts_current, pts_latest, mpeg4p2_ctx->b_frames[i]); - } - mpeg4p2_ctx->b_frames_count = 0; - return 0; - } - } - break; - case 3: // S-Frame - break; - case 2: // B-Frame - if (!mpeg4p2_ctx->second_ip_frame) - { - ffmpeg_err("Cannot predict B-Frame without surrounding I/P-Frames, dropping..."); - return 0; - } - if (mpeg4p2_ctx->b_frames_count == MPEG4P2_MAX_B_FRAMES_COUNT) - { - ffmpeg_err("Oops max B-Frames count = %d, reached", MPEG4P2_MAX_B_FRAMES_COUNT); - // not recoverable, to fix just increase MPEG4P2_MAX_B_FRAMES_COUNT - return -1; - } - else - { - ffmpeg_printf(100, "Storing B-Frame\n"); - set_packet(&mpeg4p2_ctx->b_frames[mpeg4p2_ctx->b_frames_count++], pkt); - return 0; - } - case 4: - default: - break; + AVPacket *pkt = NULL; + while ((ret = av_bsf_receive_packet(context->ctx, pkt)) == 0) + { + wrapped_frame_unref(pkt); + } } + av_bsf_free(&context->ctx); + } + + return ret; +} + +static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Track_t *track, int cAVIdx, int64_t *pts_current, int64_t *pts_latest, AVPacket *pkt) +{ + int ret = 0; + if (mpeg4p2_ctx) + { + // Setup is needed + if (!mpeg4p2_ctx->ctx) + { + ret = av_bsf_alloc(mpeg4p2_ctx->bsf, &mpeg4p2_ctx->ctx); + if (ret == 0) + { + AVStream *in = track->stream; + ret = avcodec_parameters_copy(mpeg4p2_ctx->ctx->par_in, in->codecpar); + if (ret == 0) + { + mpeg4p2_ctx->ctx->time_base_in = in->time_base; + ret = av_bsf_init(mpeg4p2_ctx->ctx); + } + } + } + + if (ret == 0) + { + ret = av_bsf_send_packet(mpeg4p2_ctx->ctx, pkt); + if (ret == 0) + { + while ((ret = av_bsf_receive_packet(mpeg4p2_ctx->ctx, pkt)) == 0) + { + mpeg4p2_write(ctx, mpeg4p2_ctx, track, avContextTab[cAVIdx]->start_time, pts_current, pts_latest, pkt); + } + + if (ret == AVERROR(EAGAIN)) + { + return 0; + } + + if (ret < 0) + { + ffmpeg_err("av_bsf_receive_packet failed error 0x%x\n", ret); + mpeg4p2_context_reset(mpeg4p2_ctx); + } + } + } + else + { + ffmpeg_err("bsf setup failed error 0x%x\n", ret); + } + + } + else + { + ret = -1; + } + return ret; +} + +static void mpeg4p2_context_close(Mpeg4P2Context *context) +{ + if (context) + { + mpeg4p2_context_reset(context); + free(context); + return; } - return 0; } diff --git a/libeplayer3-arm/container/wrapped_ffmpeg.c b/libeplayer3-arm/container/wrapped_ffmpeg.c index 2bf6bb7..b86e61f 100644 --- a/libeplayer3-arm/container/wrapped_ffmpeg.c +++ b/libeplayer3-arm/container/wrapped_ffmpeg.c @@ -153,8 +153,11 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st avcodec_free_context(&avCodecCtx); return NULL; } +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) av_codec_set_pkt_timebase(avCodecCtx, stream->time_base); - +#else + avCodecCtx->pkt_timebase = stream->time_base; +#endif store_avcodec_context(avCodecCtx, cAVIdx, stream->id); } @@ -187,3 +190,22 @@ static void wrapped_avcodec_flush_buffers(uint32_t cAVIdx) } #endif } + +static void wrapped_register_all(void) +{ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) + avcodec_register_all(); + av_register_all(); +#endif +} + +static int64_t wrapped_frame_get_best_effort_timestamp(const AVFrame *frame) +{ +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(58, 9, 100) + return av_frame_get_best_effort_timestamp(frame); +#else + return frame->best_effort_timestamp; +#endif +} + + diff --git a/libeplayer3-arm/external/ffmpeg/src/latmenc.c b/libeplayer3-arm/external/ffmpeg/src/latmenc.c index 9c13c32..2711bc6 100644 --- a/libeplayer3-arm/external/ffmpeg/src/latmenc.c +++ b/libeplayer3-arm/external/ffmpeg/src/latmenc.c @@ -26,18 +26,11 @@ #include #include #include +#include "debug.h" /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -//#define LATMENC_SILENT - -#ifndef LATMENC_SILENT -#define latmenc_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define latmenc_err(fmt, x...) -#endif - int latmenc_decode_extradata(LATMContext *ctx, uint8_t *buf, int size) { diff --git a/libeplayer3-arm/include/bcm_ioctls.h b/libeplayer3-arm/include/bcm_ioctls.h index d52f298..f67fd31 100644 --- a/libeplayer3-arm/include/bcm_ioctls.h +++ b/libeplayer3-arm/include/bcm_ioctls.h @@ -55,6 +55,7 @@ typedef enum STREAMTYPE_DIVX5 = 15, STREAMTYPE_VB6 = 18, STREAMTYPE_SPARK = 21, + STREAMTYPE_MJPEG = 30, } video_stream_type_t; @@ -75,7 +76,7 @@ typedef enum AUDIOTYPE_WMA_PRO = 0x21, AUDIOTYPE_AC3_PLUS = 0x22, AUDIOTYPE_AMR = 0x23, - AUDIOTYPE_RAW = 0xf + AUDIOTYPE_RAW = 0x30 } audio_stream_type_t; diff --git a/libeplayer3-arm/include/debug.h b/libeplayer3-arm/include/debug.h index 1740868..4365add 100644 --- a/libeplayer3-arm/include/debug.h +++ b/libeplayer3-arm/include/debug.h @@ -1,21 +1,548 @@ -#ifndef debug_123 -#define debug_123 - #include -#include +#include -static inline void Hexdump(unsigned char *Data, int length) -{ +#define __FILENAME__ (strrchr(__FILE__, '/') ? strrchr(__FILE__, '/') + 1 : __FILE__) - int k; - for (k = 0; k < length; k++) - { - printf("%02x ", Data[k]); - if (((k + 1) & 31) == 0) - printf("\n"); - } - printf("\n"); +#define log_error(fmt, x...) do { printf("[%s:%s] " fmt, __FILENAME__, __FUNCTION__, ## x); } while (0) +#define log_printf(maxlevel, level, fmt, x...) do { if (maxlevel >= level) printf("[%s:%s] " fmt, __FILENAME__, __FUNCTION__, ## x); } while (0) -} +/******************************************* + * ffmpeg + *******************************************/ +#define FFMPEG_DEBUG_LEVEL 0 +#define FFMPEG_SILENT + +#if FFMPEG_DEBUG_LEVEL +#define ffmpeg_printf(...) log_printf(FFMPEG_DEBUG_LEVEL, __VA_ARGS__) +#else +#define ffmpeg_printf(...) #endif + +#ifndef FFMPEG_SILENT +#define ffmpeg_err(...) log_error(__VA_ARGS__) +#else +#define ffmpeg_err(...) +#endif + +/******************************************* + * container + *******************************************/ +#define CONTAINER_DEBUG_LEVEL 0 +#define CONTAINER_SILENT + +#if CONTAINER_DEBUG_LEVEL +#define container_printf(...) log_printf(CONTAINER_DEBUG_LEVEL, __VA_ARGS__) +#else +#define container_printf(...) +#endif + +#ifndef CONTAINER_SILENT +#define container_err(...) log_error(__VA_ARGS__) +#else +#define container_err(...) +#endif + +/******************************************* + * latmenc + *******************************************/ +#define LATMENC_DEBUG_LEVEL 0 +#define LATMENC_SILENT + +#if LATMENC_DEBUG_LEVEL +#define latmenc_printf(...) log_printf(LATMENC_DEBUG_LEVEL, __VA_ARGS__) +#else +#define latmenc_printf(...) +#endif + +#ifndef LATMENC_SILENT +#define latmenc_err(...) log_error(__VA_ARGS__) +#else +#define latmenc_err(...) +#endif + +/******************************************* + * audio_mgr + *******************************************/ +#define AUDIO_MGR_DEBUG_LEVEL 0 +#define AUDIO_MGR_SILENT + +#if AUDIO_MGR_DEBUG_LEVEL +#define audio_mgr_printf(...) log_printf(AUDIO_MGR_DEBUG_LEVEL, __VA_ARGS__) +#else +#define audio_mgr_printf(...) +#endif + +#ifndef AUDIO_MGR_SILENT +#define audio_mgr_err(...) log_error(__VA_ARGS__) +#else +#define audio_mgr_err(...) +#endif + +/******************************************* + * subtitle_mgr + *******************************************/ +#define SUBTITLE_MGR_DEBUG_LEVEL 0 +#define SUBTITLE_MGR_SILENT + +#if SUBTITLE_MGR_DEBUG_LEVEL +#define subtitle_mgr_printf(...) log_printf(SUBTITLE_MGR_DEBUG_LEVEL, __VA_ARGS__) +#else +#define subtitle_mgr_printf(...) +#endif + +#ifndef SUBTITLE_MGR_SILENT +#define subtitle_mgr_err(...) log_error(__VA_ARGS__) +#else +#define subtitle_mgr_err(...) +#endif + +/******************************************* + * video_mgr + *******************************************/ +#define VIDEO_MGR_DEBUG_LEVEL 0 +#define VIDEO_MGR_SILENT + +#if VIDEO_MGR_DEBUG_LEVEL +#define video_mgr_printf(...) log_printf(VIDEO_MGR_DEBUG_LEVEL, __VA_ARGS__) +#else +#define video_mgr_printf(...) +#endif + +#ifndef VIDEO_MGR_SILENT +#define video_mgr_err(...) log_error(__VA_ARGS__) +#else +#define video_mgr_err(...) +#endif + +/******************************************* + * linuxdvb + *******************************************/ +#define LINUXDVB_DEBUG_LEVEL 0 +#define LINUXDVB_SILENT + +#if LINUXDVB_DEBUG_LEVEL +#define linuxdvb_printf(...) log_printf(LINUXDVB_DEBUG_LEVEL, __VA_ARGS__) +#else +#define linuxdvb_printf(...) +#endif + +#ifndef LINUXDVB_SILENT +#define linuxdvb_err(...) log_error(__VA_ARGS__) +#else +#define linuxdvb_err(...) +#endif + +/******************************************* + * buff + *******************************************/ +#define BUFF_DEBUG_LEVEL 0 +#define BUFF_SILENT + +#if BUFF_DEBUG_LEVEL +#define buff_printf(...) log_printf(BUFF_DEBUG_LEVEL, __VA_ARGS__) +#else +#define buff_printf(...) +#endif + +#ifndef BUFF_SILENT +#define buff_err(...) log_error(__VA_ARGS__) +#else +#define buff_err(...) +#endif + +/******************************************* + * output + *******************************************/ +#define OUTPUT_DEBUG_LEVEL 0 +#define OUTPUT_SILENT + +#if OUTPUT_DEBUG_LEVEL +#define output_printf(...) log_printf(OUTPUT_DEBUG_LEVEL, __VA_ARGS__) +#else +#define output_printf(...) +#endif + +#ifndef OUTPUT_SILENT +#define output_err(...) log_error(__VA_ARGS__) +#else +#define output_err(...) +#endif + +/******************************************* + * subtitle + *******************************************/ +#define SUBTITLE_DEBUG_LEVEL 0 +#define SUBTITLE_SILENT + +#if SUBTITLE_DEBUG_LEVEL +#define subtitle_printf(...) log_printf(SUBTITLE_DEBUG_LEVEL, __VA_ARGS__) +#else +#define subtitle_printf(...) +#endif + +#ifndef SUBTITLE_SILENT +#define subtitle_err(...) log_error(__VA_ARGS__) +#else +#define subtitle_err(...) +#endif + +/******************************************* + * writer + *******************************************/ +#define WRITER_DEBUG_LEVEL 0 +#define WRITER_SILENT + +#if WRITER_DEBUG_LEVEL +#define writer_printf(...) log_printf(WRITER_DEBUG_LEVEL, __VA_ARGS__) +#else +#define writer_printf(...) +#endif + +#ifndef WRITER_SILENT +#define writer_err(...) log_error(__VA_ARGS__) +#else +#define writer_err(...) +#endif + +/******************************************* + * playback + *******************************************/ +#define PLAYBACK_DEBUG_LEVEL 0 +#define PLAYBACK_SILENT + +#if PLAYBACK_DEBUG_LEVEL +#define playback_printf(...) log_printf(PLAYBACK_DEBUG_LEVEL, __VA_ARGS__) +#else +#define playback_printf(...) +#endif + +#ifndef PLAYBACK_SILENT +#define playback_err(...) log_error(__VA_ARGS__) +#else +#define playback_err(...) +#endif + +/******************************************* + * aac + *******************************************/ +#define AAC_DEBUG_LEVEL 0 +#define AAC_SILENT + +#if AAC_DEBUG_LEVEL +#define aac_printf(...) log_printf(AAC_DEBUG_LEVEL, __VA_ARGS__) +#else +#define aac_printf(...) +#endif + +#ifndef AAC_SILENT +#define aac_err(...) log_error(__VA_ARGS__) +#else +#define aac_err(...) +#endif + +/******************************************* + * ac3 + *******************************************/ +#define AC3_DEBUG_LEVEL 0 +#define AC3_SILENT + +#if AC3_DEBUG_LEVEL +#define ac3_printf(...) log_printf(AC3_DEBUG_LEVEL, __VA_ARGS__) +#else +#define ac3_printf(...) +#endif + +#ifndef AC3_SILENT +#define ac3_err(...) log_error(__VA_ARGS__) +#else +#define ac3_err(...) +#endif + +/******************************************* + * amr + *******************************************/ +#define AMR_DEBUG_LEVEL 0 +#define AMR_SILENT + +#if AMR_DEBUG_LEVEL +#define amr_printf(...) log_printf(AMR_DEBUG_LEVEL, __VA_ARGS__) +#else +#define amr_printf(...) +#endif + +#ifndef AMR_SILENT +#define amr_err(...) log_error(__VA_ARGS__) +#else +#define amr_err(...) +#endif + +/******************************************* + * divx + *******************************************/ +#define DIVX_DEBUG_LEVEL 0 +#define DIVX_SILENT + +#if DIVX_DEBUG_LEVEL +#define divx_printf(...) log_printf(DIVX_DEBUG_LEVEL, __VA_ARGS__) +#else +#define divx_printf(...) +#endif + +#ifndef DIVX_SILENT +#define divx_err(...) log_error(__VA_ARGS__) +#else +#define divx_err(...) +#endif + +/******************************************* + * dts + *******************************************/ +#define DTS_DEBUG_LEVEL 0 +#define DTS_SILENT + +#if DTS_DEBUG_LEVEL +#define dts_printf(...) log_printf(DTS_DEBUG_LEVEL, __VA_ARGS__) +#else +#define dts_printf(...) +#endif + +#ifndef DTS_SILENT +#define dts_err(...) log_error(__VA_ARGS__) +#else +#define dts_err(...) +#endif + +/******************************************* + * h263 + *******************************************/ +#define H263_DEBUG_LEVEL 0 +#define H263_SILENT + +#if H263_DEBUG_LEVEL +#define h263_printf(...) log_printf(H263_DEBUG_LEVEL, __VA_ARGS__) +#else +#define h263_printf(...) +#endif + +#ifndef H263_SILENT +#define h263_err(...) log_error(__VA_ARGS__) +#else +#define h263_err(...) +#endif + +/******************************************* + * h264 + *******************************************/ +#define H264_DEBUG_LEVEL 0 +#define H264_SILENT + +#if H264_DEBUG_LEVEL +#define h264_printf(...) log_printf(H264_DEBUG_LEVEL, __VA_ARGS__) +#else +#define h264_printf(...) +#endif + +#ifndef H264_SILENT +#define h264_err(...) log_error(__VA_ARGS__) +#else +#define h264_err(...) +#endif + +/******************************************* + * h265 + *******************************************/ +#define H265_DEBUG_LEVEL 0 +#define H265_SILENT + +#if H265_DEBUG_LEVEL +#define h265_printf(...) log_printf(H265_DEBUG_LEVEL, __VA_ARGS__) +#else +#define h265_printf(...) +#endif + +#ifndef H265_SILENT +#define h265_err(...) log_error(__VA_ARGS__) +#else +#define h265_err(...) +#endif + +/******************************************* + * lpcm + *******************************************/ +#define LPCM_DEBUG_LEVEL 0 +#define LPCM_SILENT + +#if LPCM_DEBUG_LEVEL +#define lpcm_printf(...) log_printf(LPCM_DEBUG_LEVEL, __VA_ARGS__) +#else +#define lpcm_printf(...) +#endif + +#ifndef LPCM_SILENT +#define lpcm_err(...) log_error(__VA_ARGS__) +#else +#define lpcm_err(...) +#endif + +/******************************************* + * mp3 + *******************************************/ +#define MP3_DEBUG_LEVEL 0 +#define MP3_SILENT + +#if MP3_DEBUG_LEVEL +#define mp3_printf(...) log_printf(MP3_DEBUG_LEVEL, __VA_ARGS__) +#else +#define mp3_printf(...) +#endif + +#ifndef MP3_SILENT +#define mp3_err(...) log_error(__VA_ARGS__) +#else +#define mp3_err(...) +#endif + +/******************************************* + * mpeg2 + *******************************************/ +#define MPEG2_DEBUG_LEVEL 0 +#define MPEG2_SILENT + +#if MPEG2_DEBUG_LEVEL +#define mpeg2_printf(...) log_printf(MPEG2_DEBUG_LEVEL, __VA_ARGS__) +#else +#define mpeg2_printf(...) +#endif + +#ifndef MPEG2_SILENT +#define mpeg2_err(...) log_error(__VA_ARGS__) +#else +#define mpeg2_err(...) +#endif + +/******************************************* + * mpeg4 + *******************************************/ +#define MPEG4_DEBUG_LEVEL 0 +#define MPEG4_SILENT + +#if MPEG4_DEBUG_LEVEL +#define mpeg4_printf(...) log_printf(MPEG4_DEBUG_LEVEL, __VA_ARGS__) +#else +#define mpeg4_printf(...) +#endif + +#ifndef MPEG4_SILENT +#define mpeg4_err(...) log_error(__VA_ARGS__) +#else +#define mpeg4_err(...) +#endif + +/******************************************* + * pcm + *******************************************/ +#define PCM_DEBUG_LEVEL 0 +#define PCM_SILENT + +#if PCM_DEBUG_LEVEL +#define pcm_printf(...) log_printf(PCM_DEBUG_LEVEL, __VA_ARGS__) +#else +#define pcm_printf(...) +#endif + +#ifndef PCM_SILENT +#define pcm_err(...) log_error(__VA_ARGS__) +#else +#define pcm_err(...) +#endif + +/******************************************* + * vc1 + *******************************************/ +#define VC1_DEBUG_LEVEL 0 +#define VC1_SILENT + +#if VC1_DEBUG_LEVEL +#define vc1_printf(...) log_printf(VC1_DEBUG_LEVEL, __VA_ARGS__) +#else +#define vc1_printf(...) +#endif + +#ifndef VC1_SILENT +#define vc1_err(...) log_error(__VA_ARGS__) +#else +#define vc1_err(...) +#endif + +/******************************************* + * vp + *******************************************/ +#define VP_DEBUG_LEVEL 0 +#define VP_SILENT + +#if VP_DEBUG_LEVEL +#define vp_printf(...) log_printf(VP_DEBUG_LEVEL, __VA_ARGS__) +#else +#define vp_printf(...) +#endif + +#ifndef VP_SILENT +#define vp_err(...) log_error(__VA_ARGS__) +#else +#define vp_err(...) +#endif + +/******************************************* + * wma + *******************************************/ +#define WMA_DEBUG_LEVEL 0 +#define WMA_SILENT + +#if WMA_DEBUG_LEVEL +#define wma_printf(...) log_printf(WMA_DEBUG_LEVEL, __VA_ARGS__) +#else +#define wma_printf(...) +#endif + +#ifndef WMA_SILENT +#define wma_err(...) log_error(__VA_ARGS__) +#else +#define wma_err(...) +#endif + +/******************************************* + * wmv + *******************************************/ +#define WMV_DEBUG_LEVEL 0 +#define WMV_SILENT + +#if WMV_DEBUG_LEVEL +#define wmv_printf(...) log_printf(WMV_DEBUG_LEVEL, __VA_ARGS__) +#else +#define wmv_printf(...) +#endif + +#ifndef WMV_SILENT +#define wmv_err(...) log_error(__VA_ARGS__) +#else +#define wmv_err(...) +#endif + +/******************************************* + * mjpeg + *******************************************/ +#define MJPEG_DEBUG_LEVEL 0 +#define MJPEG_SILENT + +#if MJPEG_DEBUG_LEVEL +#define mjpeg_printf(...) log_printf(MJPEG_DEBUG_LEVEL, __VA_ARGS__) +#else +#define mjpeg_printf(...) +#endif + +#ifndef MJPEG_SILENT +#define mjpeg_err(...) log_error(__VA_ARGS__) +#else +#define mjpeg_err(...) +#endif \ No newline at end of file diff --git a/libeplayer3-arm/include/misc.h b/libeplayer3-arm/include/misc.h index f1114b4..7bf2ed4 100644 --- a/libeplayer3-arm/include/misc.h +++ b/libeplayer3-arm/include/misc.h @@ -1,5 +1,5 @@ -#ifndef misc_123 -#define misc_123 +#ifndef _exteplayer3_misc_ +#define _exteplayer3_misc_ #include #include @@ -20,6 +20,15 @@ typedef struct BitPacker_s int32_t Remaining; /* number of remaining in the shifter */ } BitPacker_t; +typedef enum +{ + STB_UNKNOWN, + STB_DREAMBOX, + STB_VUPLUS, + STB_HISILICON, + STB_OTHER = 999, +} stb_type_t; + /* ***************************** */ /* Makros/Constants */ /* ***************************** */ @@ -33,6 +42,7 @@ typedef struct BitPacker_s void PutBits(BitPacker_t *ld, uint32_t code, uint32_t length); void FlushBits(BitPacker_t *ld); int8_t PlaybackDieNow(int8_t val); +stb_type_t GetSTBType(); /* ***************************** */ /* MISC Functions */ @@ -51,54 +61,6 @@ static inline char *getExtension(char *name) return NULL; } -/* the function returns the base name */ -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; -} - -/* the function returns the directry name */ -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] == '/') - { - pos = i; - } - path[i] = name[i]; - i++; - } - - path[i] = 0; - path[pos] = 0; - - return path; -} - -static inline int32_t IsDreambox() -{ - struct stat buffer; - return (stat("/proc/stb/tpm/0/serial", &buffer) == 0); -} - static inline uint32_t ReadUint32(uint8_t *buffer) { uint32_t num = (uint32_t)buffer[0] << 24 | @@ -115,4 +77,4 @@ static inline uint16_t ReadUInt16(uint8_t *buffer) return num; } -#endif +#endif // _exteplayer3_misc_ diff --git a/libeplayer3-arm/include/pes.h b/libeplayer3-arm/include/pes.h index 1b2d019..cca5ee7 100644 --- a/libeplayer3-arm/include/pes.h +++ b/libeplayer3-arm/include/pes.h @@ -28,5 +28,6 @@ int32_t InsertPesHeader(uint8_t *data, int32_t size, uint8_t stream_id, uint64_t pts, int32_t pic_start_code); int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size); +void UpdatePesHeaderPayloadSize(uint8_t *data, int32_t size); #endif diff --git a/libeplayer3-arm/include/playback.h b/libeplayer3-arm/include/playback.h index b6d9b63..cbb9941 100644 --- a/libeplayer3-arm/include/playback.h +++ b/libeplayer3-arm/include/playback.h @@ -51,6 +51,7 @@ typedef struct PlaybackHandler_s int32_t BackWard; int32_t SlowMotion; int32_t Speed; + uint64_t readCount; int32_t AVSync; uint8_t isVideo; diff --git a/libeplayer3-arm/include/writer.h b/libeplayer3-arm/include/writer.h index 9b7b7b5..fddb15b 100644 --- a/libeplayer3-arm/include/writer.h +++ b/libeplayer3-arm/include/writer.h @@ -7,6 +7,7 @@ #include "common.h" typedef enum { eNone, eAudio, eVideo} eWriterType_t; +typedef ssize_t (* WriteV_t)(int, const struct iovec *, int); typedef struct { @@ -23,7 +24,7 @@ typedef struct unsigned int Height; unsigned char Version; unsigned int InfoFlags; - ssize_t (* WriteV) (int, const struct iovec *, int); + WriteV_t WriteV; } WriterAVCallData_t; @@ -80,7 +81,7 @@ extern Writer_t WriterVideoVC1; extern Writer_t WriterVideoVP6; extern Writer_t WriterVideoVP8; extern Writer_t WriterVideoVP9; -extern Writer_t WriterVideoSPARK; +extern Writer_t WriterVideoMJPEG; extern Writer_t WriterFramebuffer; extern Writer_t WriterPipe; @@ -91,6 +92,8 @@ Writer_t *getDefaultAudioWriter(); ssize_t write_with_retry(int fd, const void *buf, int size); ssize_t writev_with_retry(int fd, const struct iovec *iov, int ic); -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size); +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size); void FlushPipe(int pipefd); + +ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size); #endif diff --git a/libeplayer3-arm/main/exteplayer.c b/libeplayer3-arm/main/exteplayer.c index 8ebce36..4c00c00 100644 --- a/libeplayer3-arm/main/exteplayer.c +++ b/libeplayer3-arm/main/exteplayer.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include @@ -40,6 +41,8 @@ #include "common.h" #include "misc.h" +#include "debug.h" + #define DUMP_BOOL(x) 0 == x ? "false" : "true" #define IPTV_MAX_FILE_PATH 1024 @@ -90,7 +93,11 @@ static pthread_mutex_t playbackStartMtx; static void TerminateWakeUp() { - write(g_pfd[1], "x", 1); + int ret = write(g_pfd[1], "x", 1); + if (ret != 1) + { + printf("TerminateWakeUp write return %d\n", ret); + } } static void *TermThreadFun(void *arg __attribute__((unused))) @@ -692,7 +699,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", 49); + fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 55); PlayFiles_t playbackFiles; memset(&playbackFiles, 0x00, sizeof(playbackFiles)); @@ -939,7 +946,7 @@ int main(int argc, char *argv[]) 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); + fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); lengthInt = (int32_t)length; if (10 <= lengthInt || force) @@ -951,7 +958,7 @@ int main(int argc, char *argv[]) } commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK_ABS, (void *)&sec); - fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal); + fprintf(stderr, "{\"PLAYBACK_SEEK_ABS\":{\"sec\":%" PRId64 ", \"sts\":%d}}\n", sec, commandRetVal); } } break; @@ -973,13 +980,13 @@ int main(int argc, char *argv[]) if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); + fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 "}}\n", pts / 90); } if (0 == commandRetVal || force) { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); - fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); + fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); lengthInt = (int32_t)length; if (10 <= lengthInt || force) @@ -1003,7 +1010,7 @@ int main(int argc, char *argv[]) } } commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK, (void *)&sec); - fprintf(stderr, "{\"PLAYBACK_SEEK\":{\"sec\":%lld, \"sts\":%d}}\n", sec, commandRetVal); + fprintf(stderr, "{\"PLAYBACK_SEEK\":{\"sec\":%" PRId64 ", \"sts\":%d}}\n", sec, commandRetVal); } break; } @@ -1011,7 +1018,7 @@ int main(int argc, char *argv[]) { int64_t length = 0; commandRetVal = g_player->playback->Command(g_player, PLAYBACK_LENGTH, (void *)&length); - fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%lld, \"sts\":%d}}\n", length, commandRetVal); + fprintf(stderr, "{\"PLAYBACK_LENGTH\":{\"length\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); break; } case 'j': @@ -1030,11 +1037,11 @@ int main(int argc, char *argv[]) if (0 == commandRetVal && lastPts != INVALID_PTS_VALUE) { - fprintf(stderr, "{\"J\":{\"ms\":%lld,\"lms\":%lld}}\n", pts / 90, lastPts / 90); + fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 ",\"lms\":%" PRId64 "}}\n", pts / 90, lastPts / 90); } else { - fprintf(stderr, "{\"J\":{\"ms\":%lld}}\n", pts / 90); + fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 "}}\n", pts / 90); } } break; diff --git a/libeplayer3-arm/manager/audio.c b/libeplayer3-arm/manager/audio.c index 9e029e8..d2240a0 100644 --- a/libeplayer3-arm/manager/audio.c +++ b/libeplayer3-arm/manager/audio.c @@ -27,6 +27,7 @@ #include #include "manager.h" #include "common.h" +#include "debug.h" /* ***************************** */ /* Makros/Constants */ @@ -34,29 +35,6 @@ #define TRACKWRAP 20 -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define AUDIO_MGR_DEBUG -#else -#define AUDIO_MGR_SILENT -#endif - -#ifdef AUDIO_MGR_DEBUG - -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) -#else -#define audio_mgr_printf(level, x...) -#endif - -#ifndef AUDIO_MGR_SILENT -#define audio_mgr_err(x...) do { printf(x); } while (0) -#else -#define audio_mgr_err(x...) -#endif - /* Error Constants */ #define cERR_AUDIO_MGR_NO_ERROR 0 #define cERR_AUDIO_MGR_ERROR -1 @@ -107,6 +85,10 @@ static int ManagerAdd(Context_t *context, Track_t track) if (Tracks[i].Id == track.Id) { Tracks[i].pending = 0; + if(track.aacbuf){ + free(track.aacbuf); + track.aacbuf = NULL; + } return cERR_AUDIO_MGR_NO_ERROR; } } diff --git a/libeplayer3-arm/manager/subtitle.c b/libeplayer3-arm/manager/subtitle.c index 5386bde..1e26e30 100644 --- a/libeplayer3-arm/manager/subtitle.c +++ b/libeplayer3-arm/manager/subtitle.c @@ -26,6 +26,7 @@ #include "manager.h" #include "common.h" +#include "debug.h" /* ***************************** */ /* Makros/Constants */ @@ -33,30 +34,6 @@ #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; - -#define subtitle_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define subtitle_mgr_printf(level, x...) -#endif - -#ifndef SUBTITLE_MGR_SILENT -#define subtitle_mgr_err(x...) do { printf(x); } while (0) -#else -#define subtitle_mgr_err(x...) -#endif - /* Error Constants */ #define cERR_SUBTITLE_MGR_NO_ERROR 0 #define cERR_SUBTITLE_MGR_ERROR -1 diff --git a/libeplayer3-arm/manager/video.c b/libeplayer3-arm/manager/video.c index 93b7073..35a8181 100644 --- a/libeplayer3-arm/manager/video.c +++ b/libeplayer3-arm/manager/video.c @@ -26,6 +26,7 @@ #include "manager.h" #include "common.h" +#include "debug.h" /* ***************************** */ /* Makros/Constants */ @@ -33,28 +34,6 @@ #define TRACKWRAP 4 -#ifdef SAM_WITH_DEBUG -#define VIDEO_MGR_DEBUG -#else -#define VIDEO_MGR_SILENT -#endif - -#ifdef VIDEO_MGR_DEBUG - -static short debug_level = 0; - -#define video_mgr_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define video_mgr_printf(level, x...) -#endif - -#ifndef VIDEO_MGR_SILENT -#define video_mgr_err(x...) do { printf(x); } while (0) -#else -#define video_mgr_err(x...) -#endif - /* Error Constants */ #define cERR_VIDEO_MGR_NO_ERROR 0 #define cERR_VIDEO_MGR_ERROR -1 @@ -83,7 +62,7 @@ static void (* updatedTrackInfoFnc)(void) = NULL; static int ManagerAdd(Context_t *context, Track_t track) { - video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + video_mgr_printf(10, "\n"); if (Tracks == NULL) { @@ -97,7 +76,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("malloc failed\n"); return cERR_VIDEO_MGR_ERROR; } @@ -118,7 +97,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("TrackCount out if range %d - %d\n", TrackCount, TRACKWRAP); return cERR_VIDEO_MGR_ERROR; } @@ -127,7 +106,7 @@ static int ManagerAdd(Context_t *context, Track_t track) context->playback->isVideo = 1; } - video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + video_mgr_printf(10, "\n"); return cERR_VIDEO_MGR_NO_ERROR; } @@ -137,7 +116,7 @@ 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__); + video_mgr_printf(10, "\n"); if (Tracks != NULL) { @@ -145,7 +124,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("malloc failed\n"); return NULL; } @@ -164,7 +143,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); + video_mgr_printf(10, "return %p (%d - %d)\n", tracklist, j, TrackCount); return tracklist; } @@ -173,7 +152,7 @@ static int ManagerDel(Context_t *context) { int i = 0; - video_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); + video_mgr_printf(10, "\n"); if (Tracks != NULL) { @@ -186,7 +165,7 @@ static int ManagerDel(Context_t *context) } else { - video_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); + video_mgr_err("nothing to delete!\n"); return cERR_VIDEO_MGR_ERROR; } @@ -194,7 +173,7 @@ static int ManagerDel(Context_t *context) CurrentTrack = 0; context->playback->isVideo = 0; - video_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__); + video_mgr_printf(10, "return no error\n"); return cERR_VIDEO_MGR_NO_ERROR; } @@ -202,7 +181,7 @@ 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__); + video_mgr_printf(10, "\n"); switch (command) { @@ -258,7 +237,7 @@ 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__); + video_mgr_printf(20, "MANAGER_GET_TRACK\n"); if ((TrackCount > 0) && (CurrentTrack >= 0)) { @@ -308,7 +287,7 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) if (i == TrackCount) { - video_mgr_err("%s::%s track id %d unknown\n", __FILE__, __FUNCTION__, *((int *)argument)); + video_mgr_err("track id %d unknown\n", *((int *)argument)); ret = cERR_VIDEO_MGR_ERROR; } break; @@ -339,12 +318,12 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) break; } default: - video_mgr_err("%s::%s ContainerCmd %d not supported!\n", __FILE__, __FUNCTION__, command); + video_mgr_err("ContainerCmd %d not supported!\n", command); ret = cERR_VIDEO_MGR_ERROR; break; } - video_mgr_printf(10, "%s::%s returning %d\n", __FILE__, __FUNCTION__, ret); + video_mgr_printf(10, "returning %d\n", ret); return ret; } diff --git a/libeplayer3-arm/output/linuxdvb_buffering.c b/libeplayer3-arm/output/linuxdvb_buffering.c index 1df9028..cfe53d5 100644 --- a/libeplayer3-arm/output/linuxdvb_buffering.c +++ b/libeplayer3-arm/output/linuxdvb_buffering.c @@ -36,6 +36,7 @@ #include #include "common.h" +#include "debug.h" #include "misc.h" #include "writer.h" @@ -62,29 +63,6 @@ typedef struct BufferingNode_s #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 - /* ***************************** */ /* Variables */ /* ***************************** */ @@ -105,6 +83,8 @@ static int videofd = -1; static int audiofd = -1; static int g_pfd[2] = {-1, -1}; +static pthread_mutex_t *g_pDVBMtx = NULL; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -115,7 +95,11 @@ static int g_pfd[2] = {-1, -1}; static void WriteWakeUp() { - write(g_pfd[1], "x", 1); + int ret = write(g_pfd[1], "x", 1); + if (ret != 1) + { + buff_printf(20, "WriteWakeUp write return %d\n", ret); + } } /* ***************************** */ @@ -211,7 +195,7 @@ 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 != WriteWithRetry(context, g_pfd[0], fd, dataPtr, nodePtr->dataSize)) + if (0 != WriteWithRetry(context, g_pfd[0], fd, g_pDVBMtx, dataPtr, nodePtr->dataSize)) { buff_err("Something is WRONG\n"); } @@ -242,7 +226,7 @@ uint32_t LinuxDvbBuffGetSize() return maxBufferingDataSize; } -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx) { int32_t error = 0; int32_t ret = cERR_LINUX_DVB_BUFFERING_NO_ERROR; @@ -255,6 +239,8 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd) pthread_attr_init(&attr); pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + g_pDVBMtx = mtx; + if ((error = pthread_create(&bufferingThread, &attr, (void *)&LinuxDvbBuffThread, context)) != 0) { buff_printf(10, "Creating thread, error:%d:%s\n", error, strerror(error)); diff --git a/libeplayer3-arm/output/linuxdvb_fake.c b/libeplayer3-arm/output/linuxdvb_fake.c new file mode 100644 index 0000000..cb4070c --- /dev/null +++ b/libeplayer3-arm/output/linuxdvb_fake.c @@ -0,0 +1,529 @@ +/* + * LinuxDVB Output handling. + * + * 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 +#include +#include +#include +#include +#include +#include + +#include "common.h" +#include "debug.h" +#include "output.h" +#include "writer.h" +#include "misc.h" +#include "pes.h" + +/* ***************************** */ +/* Makros/Constants */ +/* ***************************** */ + +#define cERR_LINUXDVB_NO_ERROR 0 +#define cERR_LINUXDVB_ERROR -1 + +static const char VIDEODEV[] = "/tmp/e2i_video0"; +static const char AUDIODEV[] = "/tmp/e2i_audio0"; + +static int videofd = -1; +static int audiofd = -1; + +struct DVBApiVideoInfo_s +{ + int aspect_ratio; + int progressive; + int frame_rate; + int width, height; +}; +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); +int32_t LinuxDvbBuffResume(Context_t *context); + +ssize_t BufferingWriteV(int fd, const struct iovec *iov, int ic); +int32_t LinuxDvbBuffSetSize(const uint32_t bufferSize); +uint32_t LinuxDvbBuffGetSize(); + +int LinuxDvbStop(Context_t *context, char *type); + +/* ***************************** */ +/* MISC Functions */ +/* ***************************** */ + +#define getLinuxDVBMutex() pthread_mutex_lock(&LinuxDVBmutex) +#define releaseLinuxDVBMutex() pthread_mutex_unlock(&LinuxDVBmutex) + + +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_CREAT | O_TRUNC | O_WRONLY | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0666); + } + + if (audio && audiofd < 0) + { + audiofd = open(AUDIODEV, O_CREAT | O_TRUNC | O_WRONLY | S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH, 0666); + } + + return 0; +} + +int LinuxDvbClose(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbPlay(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +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 (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) + { + linuxdvb_err("AUDIO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + } + + if (isBufferedOutput) + LinuxDvbBuffResume(context); + + linuxdvb_printf(10, "exiting\n"); + + return ret; +} + +int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbSlowMotion(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + return 0; +} + +int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) +{ + *((unsigned long long int *)pts) = (unsigned long long int)0; + return 0; +} + +int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned long long int *frameCount __attribute__((unused))) +{ + return cERR_LINUXDVB_NO_ERROR; +} + +int LinuxDvbSwitch(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) +{ + + 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; + 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=%"PRIu64" FrameRate=%d\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); + ret = cERR_LINUXDVB_ERROR; + } + else + { + struct pollfd pfd[1]; + pfd[0].fd = videofd; + pfd[0].events = POLLPRI; + int pollret = poll(pfd, 1, 0); + if (pollret > 0 && pfd[0].revents & POLLPRI) + { + struct video_event evt; + if (ioctl(videofd, VIDEO_GET_EVENT, &evt) == -1) + { + linuxdvb_err("ioctl failed with errno %d\n", errno); + linuxdvb_err("VIDEO_GET_EVENT: %s\n", strerror(errno)); + } + else + { + if (evt.type == VIDEO_EVENT_SIZE_CHANGED) + { + linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED type: 0x%x\n", evt.type); + linuxdvb_printf(10, "width : %d\n", evt.u.size.w); + linuxdvb_printf(10, "height : %d\n", evt.u.size.h); + linuxdvb_printf(10, "aspect : %d\n", evt.u.size.aspect_ratio); + videoInfo.width = evt.u.size.w; + videoInfo.height = evt.u.size.h; + videoInfo.aspect_ratio = evt.u.size.aspect_ratio; + } + else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED) + { + linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED type: 0x%x\n", evt.type); + linuxdvb_printf(10, "framerate : %d\n", evt.u.frame_rate); + videoInfo.frame_rate = evt.u.frame_rate; + } + else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/) + { + linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED type: 0x%x\n", evt.type); + linuxdvb_printf(10, "progressive : %d\n", evt.u.frame_rate); + videoInfo.progressive = evt.u.frame_rate; + context->manager->video->Command(context, MANAGER_UPDATED_TRACK_INFO, NULL); + } + else + { + linuxdvb_err("unhandled DVBAPI Video Event %d\n", evt.type); + } + } + } + + call.fd = videofd; + call.data = out->data; + call.len = out->len; + call.Pts = out->pts; + call.Dts = out->dts; + call.private_data = out->extradata; + call.private_size = out->extralen; + call.FrameRate = out->frameRate; + call.FrameScale = out->timeScale; + call.Width = out->width; + call.Height = out->height; + call.InfoFlags = out->infoFlags; + call.Version = 0; + 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); + linuxdvb_err("%s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + } + + free(Encoding); + } + else if (audio) + { + char *Encoding = NULL; + context->manager->audio->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 = getDefaultAudioWriter(); + } + + if (writer == NULL) + { + linuxdvb_err("unknown audio codec %s and no default writer\n", Encoding); + ret = cERR_LINUXDVB_ERROR; + } + else + { + call.fd = audiofd; + call.data = out->data; + call.len = out->len; + call.Pts = out->pts; + call.Dts = out->dts; + call.private_data = out->extradata; + call.private_size = out->extralen; + call.FrameRate = out->frameRate; + call.FrameScale = out->timeScale; + call.InfoFlags = out->infoFlags; + call.Version = 0; + 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); + linuxdvb_err("%s\n", strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + } + + free(Encoding); + } + + return ret; +} + +static int reset(Context_t *context __attribute__((unused))) +{ + return 0; +} + +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: + { + ret = LinuxDvbOpen(context, (char *)argument); + break; + } + case OUTPUT_CLOSE: + { + ret = LinuxDvbClose(context, (char *)argument); + reset(context); + sCURRENT_PTS = 0; + break; + } + case OUTPUT_PLAY: // 4 + { + sCURRENT_PTS = 0; + ret = LinuxDvbPlay(context, (char *)argument); + break; + } + case OUTPUT_STOP: + { + reset(context); + ret = LinuxDvbStop(context, (char *)argument); + sCURRENT_PTS = 0; + break; + } + case OUTPUT_FLUSH: + { + ret = LinuxDvbFlush(context, (char *)argument); + reset(context); + sCURRENT_PTS = 0; + break; + } + case OUTPUT_PAUSE: + { + ret = LinuxDvbPause(context, (char *)argument); + break; + } + case OUTPUT_CONTINUE: + { + ret = LinuxDvbContinue(context, (char *)argument); + break; + } + case OUTPUT_AVSYNC: + { + ret = LinuxDvbAVSync(context, (char *)argument); + break; + } + case OUTPUT_CLEAR: + { + ret = LinuxDvbClear(context, (char *)argument); + reset(context); + sCURRENT_PTS = 0; + break; + } + case OUTPUT_PTS: + { + unsigned long long int pts = 0; + ret = LinuxDvbPts(context, &pts); + *((unsigned long long int *)argument) = (unsigned long long int)pts; + break; + } + case OUTPUT_SWITCH: + { + ret = LinuxDvbSwitch(context, (char *)argument); + break; + } + case OUTPUT_SLOWMOTION: + { + return LinuxDvbSlowMotion(context, (char *)argument); + break; + } + case OUTPUT_AUDIOMUTE: + { + return LinuxDvbAudioMute(context, (char *)argument); + break; + } + case OUTPUT_GET_FRAME_COUNT: + { + unsigned long long int frameCount = 0; + ret = LinuxDvbGetFrameCount(context, &frameCount); + *((unsigned long long int *)argument) = (unsigned long long int)frameCount; + break; + } + case OUTPUT_GET_PROGRESSIVE: + { + ret = cERR_LINUXDVB_NO_ERROR; + *((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) + { + LinuxDvbBuffSetSize(bufferSize); + isBufferedOutput = true; + } + } + break; + } + case OUTPUT_GET_BUFFER_SIZE: + { + ret = cERR_LINUXDVB_NO_ERROR; + *((uint32_t *)argument) = LinuxDvbBuffGetSize(); + break; + } + default: + linuxdvb_err("ContainerCmd %d not supported!\n", command); + ret = cERR_LINUXDVB_ERROR; + break; + } + + linuxdvb_printf(50, "exiting with value %d\n", ret); + + return ret; +} + +static char *LinuxDvbCapabilities[] = { "audio", "video", NULL }; + +struct Output_s LinuxDvbOutput = +{ + "LinuxDvb", + &Command, + &Write, + LinuxDvbCapabilities +}; diff --git a/libeplayer3-arm/output/linuxdvb_mipsel.c b/libeplayer3-arm/output/linuxdvb_mipsel.c index 455fc8e..13d647c 100644 --- a/libeplayer3-arm/output/linuxdvb_mipsel.c +++ b/libeplayer3-arm/output/linuxdvb_mipsel.c @@ -22,6 +22,7 @@ /* ***************************** */ #include +#include #include #include #include @@ -41,6 +42,7 @@ #include "bcm_ioctls.h" #include "common.h" +#include "debug.h" #include "output.h" #include "writer.h" #include "misc.h" @@ -50,29 +52,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define LINUXDVB_DEBUG -static unsigned short debug_level = 20; -#else -#define LINUXDVB_SILENT -#endif - -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) -#else -#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(x...) -#endif - #define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_ERROR -1 @@ -99,7 +78,7 @@ pthread_mutex_t LinuxDVBmutex; /* ***************************** */ /* Prototypes */ /* ***************************** */ -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx); int32_t LinuxDvbBuffClose(Context_t *context); int32_t LinuxDvbBuffFlush(Context_t *context); int32_t LinuxDvbBuffResume(Context_t *context); @@ -114,25 +93,68 @@ int LinuxDvbStop(Context_t *context, char *type); /* MISC Functions */ /* ***************************** */ -void getLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) -{ - pthread_mutex_lock(&LinuxDVBmutex); -} +#define getLinuxDVBMutex() pthread_mutex_lock(&LinuxDVBmutex) +#define releaseLinuxDVBMutex() pthread_mutex_unlock(&LinuxDVBmutex) -void releaseLinuxDVBMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int line __attribute__((unused))) +static int LinuxDvbMapBypassMode(int bypass, bool primary) { - pthread_mutex_unlock(&LinuxDVBmutex); -} - -static int LinuxDvbMapBypassMode(int bypass) -{ - if (0x30 == bypass && IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { - return 0x0f; + primary = !primary; } + + switch (bypass) + { + case AUDIOTYPE_RAW: + bypass = primary ? 0x30 : 0xf; + break; + case AUDIOTYPE_AC3_PLUS: + bypass = primary ? 0x22 : 7; + break; + case AUDIOTYPE_WMA: + bypass = primary ? 0x20 : 0xd; + break; + case AUDIOTYPE_WMA_PRO: + bypass = primary ? 0x21 : 0xe; + break; + default: + break; + }; + return bypass; } +static int LinuxDvbMapStreamType(int streamtype, bool primary) +{ + if (STB_DREAMBOX == GetSTBType()) + { + primary = !primary; + } + + switch (streamtype) + { + case STREAMTYPE_MPEG4_H265: + streamtype = primary ? 7 : 22; + break; + case STREAMTYPE_VC1: + streamtype = primary ? 3 : 16; + break; + case STREAMTYPE_VC1_SM: + streamtype = primary ? 5 : 17; + break; + case STREAMTYPE_VB8: + streamtype = primary ? 8 : 20; + break; + case STREAMTYPE_VB9: + streamtype = primary ? 9 : 23; + break; + default: + break; + }; + + return streamtype; +} + int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) { uint8_t video = !strcmp("video", type); @@ -167,7 +189,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, videofd); + LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex); } if (audio && audiofd < 0) { @@ -195,7 +217,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, audiofd); + LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex); } return cERR_LINUXDVB_NO_ERROR; @@ -214,7 +236,7 @@ int LinuxDvbClose(Context_t *context, char *type) */ LinuxDvbStop(context, type); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (isBufferedOutput) LinuxDvbBuffClose(context); @@ -230,7 +252,7 @@ int LinuxDvbClose(Context_t *context, char *type) audiofd = -1; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return cERR_LINUXDVB_NO_ERROR; } @@ -261,7 +283,9 @@ int LinuxDvbPlay(Context_t *context, char *type) else { 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) + ret = ioctl(videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, true)); + if (ret < 0) ret = ioctl(videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, false)); + if (ret < 0) { linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; @@ -302,7 +326,9 @@ int LinuxDvbPlay(Context_t *context, char *type) else { 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) + ret = ioctl(audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, true)); + if (ret < 0) ret = ioctl(audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, false)); + if (ret < 0) { linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; @@ -335,7 +361,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -370,7 +396,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) ioctl(audiofd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_DEMUX); } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return ret; } @@ -383,7 +409,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -403,7 +429,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return ret; } @@ -457,17 +483,17 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) { if (*flag == '1') { - if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) + if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1) { - linuxdvb_err("AUDIO_STOP: ERROR %d, %s\n", errno, strerror(errno)); + linuxdvb_err("AUDIO_SET_MUTE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } else { - if (ioctl(audiofd, AUDIO_PLAY) == -1) + if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1) { - linuxdvb_err("AUDIO_PLAY: ERROR %d, %s\n", errno, strerror(errno)); + linuxdvb_err("AUDIO_SET_MUTE: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } } @@ -495,14 +521,20 @@ int LinuxDvbFastForward(Context_t *context, char *type) if (video && videofd != -1) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); // konfetti comment: speed is a value given in skipped frames if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == -1) { linuxdvb_err("VIDEO_FAST_FORWARD: ERROR %d, %s\n", errno, strerror(errno)); ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + + if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) + { + linuxdvb_err("VIDEO_CONTINUE: ERROR %d, %s\n", errno, strerror(errno)); + ret = cERR_LINUXDVB_ERROR; + } + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -520,7 +552,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -531,7 +563,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -550,7 +582,7 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr */ if (audiofd != -1) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1) { @@ -558,7 +590,7 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } return ret; @@ -574,7 +606,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -593,7 +625,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting\n"); @@ -649,12 +681,13 @@ int LinuxDvbSwitch(Context_t *context, char *type) uint8_t audio = !strcmp("audio", type); uint8_t video = !strcmp("video", type); Writer_t *writer; + int ret = 0; linuxdvb_printf(10, "v%d a%d\n", video, audio); if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (audio && audiofd != -1) { @@ -684,7 +717,9 @@ int LinuxDvbSwitch(Context_t *context, char *type) 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) + ret = ioctl(audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, true)); + if (ret < 0) ret = ioctl(audiofd, AUDIO_SET_BYPASS_MODE, LinuxDvbMapBypassMode(writer->caps->dvbStreamType, false)); + if (ret < 0) { linuxdvb_err("AUDIO_SET_BYPASS_MODE: ERROR %d, %s\n", errno, strerror(errno)); } @@ -730,7 +765,9 @@ int LinuxDvbSwitch(Context_t *context, char *type) 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) + ret = ioctl(videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, true)); + if (ret < 0) ret = ioctl(videofd, VIDEO_SET_STREAMTYPE, LinuxDvbMapStreamType(writer->caps->dvbStreamType, false)); + if (ret < 0) { linuxdvb_err("VIDEO_SET_STREAMTYPE: ERROR %d, %s\n", errno, strerror(errno)); } @@ -751,7 +788,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } @@ -779,7 +816,7 @@ static int Write(Context_t *context, void *_out) video = !strcmp("video", out->type); audio = !strcmp("audio", out->type); - linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", + linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%" PRIu64 " FrameRate=%d\n", out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); @@ -821,7 +858,7 @@ static int Write(Context_t *context, void *_out) { if (evt.type == VIDEO_EVENT_SIZE_CHANGED) { - linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED\n", evt.type); + linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED type: 0x%x\n", evt.type); linuxdvb_printf(10, "width : %d\n", evt.u.size.w); linuxdvb_printf(10, "height : %d\n", evt.u.size.h); linuxdvb_printf(10, "aspect : %d\n", evt.u.size.aspect_ratio); @@ -831,13 +868,13 @@ static int Write(Context_t *context, void *_out) } else if (evt.type == VIDEO_EVENT_FRAME_RATE_CHANGED) { - linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED\n", evt.type); + linuxdvb_printf(10, "VIDEO_EVENT_FRAME_RATE_CHANGED type: 0x%x\n", evt.type); linuxdvb_printf(10, "framerate : %d\n", evt.u.frame_rate); videoInfo.frame_rate = evt.u.frame_rate; } else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/) { - linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED\n", evt.type); + linuxdvb_printf(10, "VIDEO_EVENT_PROGRESSIVE_CHANGED type: 0x%x\n", evt.type); linuxdvb_printf(10, "progressive : %d\n", evt.u.frame_rate); videoInfo.progressive = evt.u.frame_rate; context->manager->video->Command(context, MANAGER_UPDATED_TRACK_INFO, NULL); @@ -884,7 +921,7 @@ static int Write(Context_t *context, void *_out) char *Encoding = NULL; context->manager->audio->Command(context, MANAGER_GETENCODING, &Encoding); - linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, __FUNCTION__, Encoding); + linuxdvb_printf(20, "Encoding = %s\n", Encoding); writer = getWriter(Encoding); diff --git a/libeplayer3-arm/output/linuxdvb_sh4.c b/libeplayer3-arm/output/linuxdvb_sh4.c index be04aa7..dedc77f 100644 --- a/libeplayer3-arm/output/linuxdvb_sh4.c +++ b/libeplayer3-arm/output/linuxdvb_sh4.c @@ -31,7 +31,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +39,10 @@ #include #include "bcm_ioctls.h" +#include "stm_ioctls.h" #include "common.h" +#include "debug.h" #include "output.h" #include "writer.h" #include "misc.h" @@ -51,27 +52,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define LINUXDVB_DEBUG -#define LINUXDVB_SILENT - -static unsigned short debug_level = 0; - -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) -#else -#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(x...) -#endif - - #define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_ERROR -1 @@ -98,7 +78,7 @@ pthread_mutex_t LinuxDVBmutex; /* ***************************** */ /* Prototypes */ /* ***************************** */ -int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd); +int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx); int32_t LinuxDvbBuffClose(Context_t *context); int32_t LinuxDvbBuffFlush(Context_t *context); int32_t LinuxDvbBuffResume(Context_t *context); @@ -113,23 +93,8 @@ int LinuxDvbStop(Context_t *context, char *type); /* 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"); - -} +#define getLinuxDVBMutex() pthread_mutex_lock(&LinuxDVBmutex) +#define releaseLinuxDVBMutex() pthread_mutex_unlock(&LinuxDVBmutex) int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) { @@ -174,7 +139,7 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) } if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, videofd); + LinuxDvbBuffOpen(context, type, videofd, &LinuxDVBmutex); } if (audio && audiofd < 0) { @@ -206,15 +171,15 @@ int LinuxDvbOpen(Context_t *context __attribute__((unused)), char *type) linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno)); } - + if (isBufferedOutput) - LinuxDvbBuffOpen(context, type, audiofd); + LinuxDvbBuffOpen(context, type, audiofd, &LinuxDVBmutex); } return cERR_LINUXDVB_NO_ERROR; } -int LinuxDvbClose(Context_t *context, char *type) +int LinuxDvbClose(Context_t *context, char *type) { uint8_t video = !strcmp("video", type); uint8_t audio = !strcmp("audio", type); @@ -227,7 +192,7 @@ int LinuxDvbClose(Context_t *context, char *type) */ LinuxDvbStop(context, type); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (isBufferedOutput) LinuxDvbBuffClose(context); @@ -237,13 +202,14 @@ int LinuxDvbClose(Context_t *context, char *type) close(videofd); videofd = -1; } + if (audio && audiofd != -1) { close(audiofd); audiofd = -1; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return cERR_LINUXDVB_NO_ERROR; } @@ -269,7 +235,7 @@ int LinuxDvbPlay(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_ENCODING, (void *) VIDEO_ENCODING_AUTO) == -1) + if (ioctl(videofd, VIDEO_SET_ENCODING, VIDEO_ENCODING_AUTO) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); @@ -279,7 +245,7 @@ int LinuxDvbPlay(Context_t *context, char *type) else { linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); - if (ioctl(videofd, VIDEO_SET_ENCODING, (void *) writer->caps->dvbEncoding) == -1) + if (ioctl(videofd, VIDEO_SET_ENCODING, writer->caps->dvbEncoding) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); @@ -295,6 +261,7 @@ int LinuxDvbPlay(Context_t *context, char *type) } free(Encoding); } + if (audio && audiofd != -1) { char *Encoding = NULL; @@ -317,7 +284,7 @@ int LinuxDvbPlay(Context_t *context, char *type) else { linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); - if (ioctl(audiofd, AUDIO_SET_ENCODING, (void *) writer->caps->dvbEncoding) == -1) + if (ioctl(audiofd, AUDIO_SET_ENCODING, writer->caps->dvbEncoding) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); @@ -345,7 +312,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -368,6 +335,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } + if (audio && audiofd != -1) { if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) @@ -390,7 +358,7 @@ int LinuxDvbStop(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return ret; } @@ -403,7 +371,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -424,7 +392,7 @@ int LinuxDvbPause(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return ret; } @@ -455,7 +423,7 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) ret = cERR_LINUXDVB_ERROR; } } - + if (isBufferedOutput) LinuxDvbBuffResume(context); @@ -472,7 +440,7 @@ int LinuxDvbReverseDiscontinuity(Context_t *context __attribute__((unused)), int linuxdvb_printf(50, "\n"); - if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) + if (ioctl(videofd, VIDEO_DISCONTINUITY, dis_type) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); @@ -532,7 +500,7 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -552,7 +520,7 @@ int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting\n"); @@ -572,8 +540,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) if (video && videofd != -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); /* konfetti comment: speed is a value given in skipped frames */ @@ -584,7 +551,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -612,8 +579,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) if (video && videofd != -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); @@ -626,13 +592,12 @@ int LinuxDvbFastForward(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } if (audio && audiofd != -1) { - - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); @@ -645,7 +610,7 @@ int LinuxDvbFastForward(Context_t *context, char *type) ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -672,7 +637,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -684,7 +649,7 @@ int LinuxDvbSlowMotion(Context_t *context, char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting with value %d\n", ret); @@ -703,7 +668,7 @@ int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused))) */ if (audiofd != -1) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (ioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync) == -1) { @@ -712,7 +677,7 @@ int LinuxDvbAVSync(Context_t *context, char *type __attribute__((unused))) ret = cERR_LINUXDVB_ERROR; } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } return ret; @@ -728,7 +693,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (video && videofd != -1) { @@ -749,7 +714,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } linuxdvb_printf(10, "exiting\n"); @@ -764,7 +729,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i linuxdvb_printf(50, "\n"); // pts is a non writting requests and can be done in parallel to other requests - //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); + //getLinuxDVBMutex(); if (videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *)&sCURRENT_PTS)) { @@ -794,7 +759,7 @@ int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long i *((unsigned long long int *)pts) = (unsigned long long int)sCURRENT_PTS; - //releaseLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); + //releaseLinuxDVBMutex(); return ret; } @@ -806,7 +771,7 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l linuxdvb_printf(50, "\n"); - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (videofd != -1) { @@ -836,7 +801,7 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l if (ret == cERR_LINUXDVB_NO_ERROR) *((unsigned long long int *)frameCount) = playInfo.frame_count; - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); return ret; } @@ -851,7 +816,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + getLinuxDVBMutex(); if (audio && audiofd != -1) { @@ -881,7 +846,7 @@ 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_ENCODING, (void *) AUDIO_ENCODING_MP3) == -1) + if (ioctl(audiofd, AUDIO_SET_ENCODING, AUDIO_ENCODING_MP3) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); @@ -890,7 +855,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) else { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); - if (ioctl(audiofd, AUDIO_SET_ENCODING, (void *) writer->caps->dvbEncoding) == -1) + if (ioctl(audiofd, AUDIO_SET_ENCODING, writer->caps->dvbEncoding) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); @@ -945,7 +910,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) else { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); - if (ioctl(videofd, VIDEO_SET_ENCODING, (void *) writer->caps->dvbEncoding) == -1) + if (ioctl(videofd, VIDEO_SET_ENCODING, writer->caps->dvbEncoding) == -1) { linuxdvb_err("ioctl failed with errno %d\n", errno); linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); @@ -968,7 +933,7 @@ int LinuxDvbSwitch(Context_t *context, char *type) } } - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); + releaseLinuxDVBMutex(); } @@ -1188,7 +1153,7 @@ static int reset(Context_t *context) } free(Encoding); - + if (isBufferedOutput) LinuxDvbBuffFlush(context); @@ -1313,7 +1278,7 @@ static int Command(void *_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) { @@ -1326,7 +1291,7 @@ static int Command(void *_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 c1b3ce4..89ebd5b 100644 --- a/libeplayer3-arm/output/output.c +++ b/libeplayer3-arm/output/output.c @@ -24,6 +24,7 @@ #include #include +#include "debug.h" #include "common.h" #include "output.h" @@ -31,28 +32,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define OUTPUT_DEBUG -#else -#define OUTPUT_SILENT -#endif - -#ifdef OUTPUT_DEBUG - -static short debug_level = 0; - -#define output_printf(level, x...) do { \ -if (debug_level >= level) fprintf(stderr, x); } while (0) -#else -#define output_printf(level, x...) -#endif - -#ifndef OUTPUT_SILENT -#define output_err(x...) do { printf(x); } while (0) -#else -#define output_err(x...) -#endif - /* Error Constants */ #define cERR_OUTPUT_NO_ERROR 0 #define cERR_OUTPUT_INTERNAL_ERROR -1 diff --git a/libeplayer3-arm/output/output_subtitle.c b/libeplayer3-arm/output/output_subtitle.c index 5810440..22a6257 100644 --- a/libeplayer3-arm/output/output_subtitle.c +++ b/libeplayer3-arm/output/output_subtitle.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -34,36 +35,13 @@ #include #include "common.h" +#include "debug.h" #include "output.h" /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -//SULGE DEBUG ENABLED -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define SUBTITLE_DEBUG -#else -#define SUBTITLE_SILENT -#endif - -#ifdef SUBTITLE_DEBUG - -static short debug_level = 0; - -#define subtitle_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define subtitle_printf(level, fmt, x...) -#endif - -#ifndef SUBTITLE_SILENT -#define subtitle_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define subtitle_err(fmt, x...) -#endif - /* Error Constants */ #define cERR_SUBTITLE_NO_ERROR 0 #define cERR_SUBTITLE_ERROR -1 @@ -226,11 +204,15 @@ static int Write(Context_t *context, void *data) 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)); + fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%" PRId64 ",\"e\":%" PRId64 ",\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data)); } else if (!strncmp("S_TEXT/ASS", Encoding, 10)) { - fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%lld,\"e\":%lld,\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, ass_get_text((char *)out->data)); + fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%" PRId64 ",\"e\":%" PRId64 ",\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, ass_get_text((char *)out->data)); + } + else if (!strncmp("D_WEBVTT/SUBTITLES", Encoding, 18)) + { + fprintf(stderr, "{\"s_a\":{\"id\":%d,\"s\":%" PRId64 ",\"e\":%" PRId64 ",\"t\":\"%s\"}}\n", out->trackId, out->pts / 90, out->pts / 90 + out->durationMS, json_string_escape((char *)out->data)); } else { diff --git a/libeplayer3-arm/output/writer/common/misc.c b/libeplayer3-arm/output/writer/common/misc.c index 71c5ec1..bb4d42a 100644 --- a/libeplayer3-arm/output/writer/common/misc.c +++ b/libeplayer3-arm/output/writer/common/misc.c @@ -126,3 +126,34 @@ void FlushBits(BitPacker_t *ld) ld->Remaining = 32; ld->BitBuffer = 0; } + +stb_type_t GetSTBType() +{ + static stb_type_t type = STB_UNKNOWN; + if (type == STB_UNKNOWN) + { +// struct stat buffer; + if (access("/proc/stb/tpm/0/serial", F_OK) != -1) + { + type = STB_DREAMBOX; + } + else if (access("/proc/stb/info/vumodel", F_OK) != -1 && + access("/proc/stb/info/boxtype", F_OK) == -1) + { + // some STB like Octagon SF4008 has also /proc/stb/info/vumodel + // but VU PLUS does not have /proc/stb/info/boxtype + // please see: https://gitlab.com/e2i/e2iplayer/issues/282 + type = STB_VUPLUS; + } + else if (access("/sys/firmware/devicetree/base/soc/hisilicon_clock/name", F_OK) != -1) + { + type = STB_HISILICON; + } + else + { + type = STB_OTHER; + } + } + + return type; +} diff --git a/libeplayer3-arm/output/writer/common/pes.c b/libeplayer3-arm/output/writer/common/pes.c index e4788c5..f91be82 100644 --- a/libeplayer3-arm/output/writer/common/pes.c +++ b/libeplayer3-arm/output/writer/common/pes.c @@ -88,31 +88,38 @@ int32_t InsertVideoPrivateDataHeader(uint8_t *data, int32_t payload_size) FlushBits(&ld2); return PES_PRIVATE_DATA_LENGTH + 1; +} +void UpdatePesHeaderPayloadSize(uint8_t *data, int32_t size) +{ + if (size > MAX_PES_PACKET_SIZE || size < 0) + size = 0; + data[4] = size >> 8; + data[5] = size & 0xFF; } 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)) + PutBits(&ld2, 0x0, 8); + PutBits(&ld2, 0x0, 8); + PutBits(&ld2, 0x1, 8); // Start Code + PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream + + if (size > 0) { - size = -1; // unbounded + size += 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0); + } + + if (size > MAX_PES_PACKET_SIZE || size < 0) + { + size = 0; // unbounded } - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x1, 8); // Start Code - PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream //4 - if (-1 == size) - { - PutBits(&ld2, 0x0, 16); - } - else - { - PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length - } + PutBits(&ld2, size, 16); // PES_packet_length + //6 = 4+2 PutBits(&ld2, 0x2, 2); // 10 PutBits(&ld2, 0x0, 2); // PES_Scrambling_control diff --git a/libeplayer3-arm/output/writer/common/writer.c b/libeplayer3-arm/output/writer/common/writer.c index 0ad4b3e..63fcb19 100644 --- a/libeplayer3-arm/output/writer/common/writer.c +++ b/libeplayer3-arm/output/writer/common/writer.c @@ -28,30 +28,13 @@ #include "misc.h" #include "writer.h" +#include "debug.h" #include "common.h" /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -//#define WRITER_DEBUG - -#ifdef WRITER_DEBUG - -static short debug_level = 0; - -#define writer_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define writer_printf(level, x...) -#endif - -#ifndef WRITER_SILENT -#define writer_err(x...) do { printf(x); } while (0) -#else -#define writer_err(x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -72,3 +55,11 @@ void FlushPipe(int pipefd) char tmp; while (1 == read(pipefd, &tmp, 1)); } + +ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size) +{ + struct iovec iov[1]; + iov[0].iov_base = data; + iov[0].iov_len = size; + return _call(fd, iov, 1); +} diff --git a/libeplayer3-arm/output/writer/mipsel/aac.c b/libeplayer3-arm/output/writer/mipsel/aac.c index e75556c..c808927 100644 --- a/libeplayer3-arm/output/writer/mipsel/aac.c +++ b/libeplayer3-arm/output/writer/mipsel/aac.c @@ -45,6 +45,7 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -57,30 +58,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - -#ifdef SAM_WITH_DEBUG -#define AAC_DEBUG -#else -#define AAC_SILENT -#endif - -#ifdef AAC_DEBUG - -static short debug_level = 0; - -#define aac_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define aac_printf(level, fmt, x...) -#endif - -#ifndef AAC_SILENT -#define aac_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define aac_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -180,7 +157,7 @@ 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)) { diff --git a/libeplayer3-arm/output/writer/mipsel/ac3.c b/libeplayer3-arm/output/writer/mipsel/ac3.c index 12ade9a..c1e2f57 100644 --- a/libeplayer3-arm/output/writer/mipsel/ac3.c +++ b/libeplayer3-arm/output/writer/mipsel/ac3.c @@ -42,6 +42,7 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -54,24 +55,6 @@ /* ***************************** */ #define AC3_HEADER_LENGTH 7 -#define AC3_DEBUG - -#ifdef AC3_DEBUG - -static short debug_level = 0; - -#define ac3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_printf(level, fmt, x...) -#endif - -#ifndef AC3_SILENT -#define ac3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -124,7 +107,7 @@ static int writeData(WriterAVCallData_t *call) 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) + 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; @@ -135,7 +118,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); + ac3_printf(40, "PES HEADER LEN %d\n", (int)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 98cc1a4..381e0f8 100644 --- a/libeplayer3-arm/output/writer/mipsel/amr.c +++ b/libeplayer3-arm/output/writer/mipsel/amr.c @@ -39,9 +39,10 @@ #include #include -#include "stm_ioctls.h" +//#include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -52,28 +53,6 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define AMR_DEBUG -#else -#define AMR_SILENT -#endif - -#ifdef AMR_DEBUG - -static short debug_level = 0; - -#define amr_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define amr_printf(level, fmt, x...) -#endif - -#ifndef AMR_SILENT -#define amr_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define amr_err(fmt, x...) -#endif /* ***************************** */ /* Types */ diff --git a/libeplayer3-arm/output/writer/mipsel/divx3.c b/libeplayer3-arm/output/writer/mipsel/divx3.c index d4de31f..40256a0 100644 --- a/libeplayer3-arm/output/writer/mipsel/divx3.c +++ b/libeplayer3-arm/output/writer/mipsel/divx3.c @@ -42,6 +42,7 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -56,28 +57,6 @@ #define B_GET_BITS(w,e,b) (((w)>>(b))&(((unsigned)(-1))>>((sizeof(unsigned))*8-(e+1-b)))) #define B_SET_BITS(name,v,e,b) (((unsigned)(v))<<(b)) -#ifdef SAM_WITH_DEBUG -#define DIVX_DEBUG -#else -#define DIVX_SILENT -#endif - -#ifdef DIVX_DEBUG - -static short debug_level = 0; - -#define divx_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_printf(level, fmt, x...) -#endif - -#ifndef DIVX_SILENT -#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/dts.c b/libeplayer3-arm/output/writer/mipsel/dts.c index 7e1ea7a..a9acd96 100644 --- a/libeplayer3-arm/output/writer/mipsel/dts.c +++ b/libeplayer3-arm/output/writer/mipsel/dts.c @@ -42,6 +42,7 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -58,28 +59,6 @@ #define PES_AUDIO_PACKET_SIZE 2028 #define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples. -#ifdef SAM_WITH_DEBUG -#define DTS_DEBUG -#else -#define DTS_SILENT -#endif - -#ifdef DTS_DEBUG - -static int16_t debug_level = 0; - -#define dts_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_printf(level, fmt, x...) -#endif - -#ifndef DTS_SILENT -#define dts_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/h264.c b/libeplayer3-arm/output/writer/mipsel/h264.c index b5b37da..1b01c5c 100644 --- a/libeplayer3-arm/output/writer/mipsel/h264.c +++ b/libeplayer3-arm/output/writer/mipsel/h264.c @@ -45,6 +45,7 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" +#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -55,23 +56,6 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define H264_SILENT -//#define H264_DEBUG -#ifdef H264_DEBUG - -static short debug_level = 0; - -#define h264_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_printf(level, fmt, x...) -#endif - -#ifndef H264_SILENT -#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_err(fmt, x...) -#endif #define IOVEC_SIZE 128 @@ -299,6 +283,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { *NalLength = 0; } + return ret; } diff --git a/libeplayer3-arm/output/writer/mipsel/h265.c b/libeplayer3-arm/output/writer/mipsel/h265.c index 1e61411..8555cb0 100644 --- a/libeplayer3-arm/output/writer/mipsel/h265.c +++ b/libeplayer3-arm/output/writer/mipsel/h265.c @@ -55,23 +55,6 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define H264_SILENT -//#define H265_DEBUG -#ifdef H265_DEBUG - -static short debug_level = 10; - -#define h264_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_printf(level, fmt, x...) -#endif - -#ifndef H265_SILENT -#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_err(fmt, x...) -#endif #define IOVEC_SIZE 128 @@ -99,14 +82,14 @@ static unsigned int CodecDataLen = 0; static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigned int *NalLength) { - h264_printf(10, "H265 check codec data..!\n"); + h265_printf(10, "H265 check codec data..!\n"); int32_t ret = -100; if (data) { unsigned char tmp[2048]; unsigned int tmp_len = 0; - h264_printf(10, "H265 have codec data..!"); + h265_printf(10, "H265 have codec data..!"); if (cd_len > 3 && (data[0] || data[1] || data[2] > 1)) { @@ -115,7 +98,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne int i; if (data[0] != 0) { - h264_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]); + h265_printf(10, "Unsupported extra data version %d, decoding may fail", (int)data[0]); } *NalLength = (data[21] & 3) + 1; @@ -126,7 +109,7 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne int j; if (pos + 3 > cd_len) { - h264_printf(10, "Buffer underrun in extra header (%d >= %u)", pos + 3, cd_len); + h265_printf(10, "Buffer underrun in extra header (%d >= %u)", pos + 3, cd_len); break; } // ignore flags + NAL type (1 byte) @@ -136,14 +119,14 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne { if (pos + 2 > cd_len) { - h264_printf(10, "Buffer underrun in extra nal header (%d >= %u)", pos + 2, cd_len); + h265_printf(10, "Buffer underrun in extra nal header (%d >= %u)", pos + 2, cd_len); break; } int nal_size = data[pos] << 8 | data[pos + 1]; pos += 2; if (pos + nal_size > cd_len) { - h264_printf(10, "Buffer underrun in extra nal (%d >= %u)", pos + 2 + nal_size, cd_len); + h265_printf(10, "Buffer underrun in extra nal (%d >= %u)", pos + 2 + nal_size, cd_len); break; } memcpy(tmp + tmp_len, "\x00\x00\x00\x01", 4); @@ -183,7 +166,7 @@ static int writeData(WriterAVCallData_t *call) unsigned int len = 0; int ic = 0; struct iovec iov[IOVEC_SIZE]; - h264_printf(20, "\n"); + h265_printf(20, "\n"); if (call == NULL) { @@ -198,7 +181,7 @@ static int writeData(WriterAVCallData_t *call) if (TimeScale) {} VideoPts = call->Pts; - h264_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); + h265_printf(20, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); if ((call->data == NULL) || (call->len <= 0)) { @@ -212,9 +195,9 @@ static int writeData(WriterAVCallData_t *call) return 0; } - if (call->InfoFlags & 0x1) // TS container + if (call->InfoFlags & 0x1) // TS container { - h264_printf(10, "H265 simple inject method!\n"); + h265_printf(10, "H265 simple inject method!\n"); uint32_t PacketLength = 0; uint32_t FakeStartCode = (call->Version << 8) | PES_VERSION_FAKE_START_CODE; @@ -304,7 +287,7 @@ static int writeData(WriterAVCallData_t *call) } while ((pos + NalLengthBytes) < call->len); - h264_printf(10, "<<<< PacketLength [%d]\n", PacketLength); + h265_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); @@ -315,7 +298,7 @@ static int writeData(WriterAVCallData_t *call) } } - h264_printf(10, "< len %d\n", len); + h265_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 cf099a2..f8c1abc 100644 --- a/libeplayer3-arm/output/writer/mipsel/lpcm.c +++ b/libeplayer3-arm/output/writer/mipsel/lpcm.c @@ -58,29 +58,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define LPCM_DEBUG -#else -#define LPCM_SILENT -#endif - -#ifdef LPCM_DEBUG - -static uint16_t debug_level = 1; - -#define lpcm_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define lpcm_printf(level, fmt, x...) -#endif - -#ifndef LPCM_SILENT -#define lpcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define lpcm_err(fmt, x...) -#endif - #define LLPCM_VOB_HEADER_LEN (6) /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/mipsel/h263.c b/libeplayer3-arm/output/writer/mipsel/mjpeg.c old mode 100644 new mode 100755 similarity index 54% rename from libeplayer3-arm/output/writer/mipsel/h263.c rename to libeplayer3-arm/output/writer/mipsel/mjpeg.c index 1d8b0e5..afd522f --- a/libeplayer3-arm/output/writer/mipsel/h263.c +++ b/libeplayer3-arm/output/writer/mipsel/mjpeg.c @@ -1,7 +1,7 @@ /* * linuxdvb output/writer handling. * - * crow 2010 + * konfetti 2010 based on linuxdvb.c code from libeplayer2 * * 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 @@ -31,13 +31,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include "stm_ioctls.h" #include "bcm_ioctls.h" @@ -52,23 +52,6 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -//#define H263_DEBUG - -#ifdef H263_DEBUG - -static short debug_level = 0; - -#define h263_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h263_printf(level, fmt, x...) -#endif - -#ifndef H263_SILENT -#define h263_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h263_err(fmt, x...) -#endif /* ***************************** */ /* Types */ @@ -78,6 +61,8 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); /* Variables */ /* ***************************** */ +static bool must_send_header = true; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -86,93 +71,54 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); /* MISC Functions */ /* ***************************** */ -static int32_t reset() +static int reset() { + must_send_header = true; return 0; } static int writeData(WriterAVCallData_t *call) { - uint8_t PesHeader[PES_MAX_HEADER_SIZE]; - int32_t len = 0; + static uint8_t PesHeader[PES_MAX_HEADER_SIZE]; - h263_printf(10, "\n"); + mjpeg_printf(10, "\n"); if (call == NULL) { - h263_err("call data is NULL...\n"); + mjpeg_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; + mjpeg_printf(10, "VideoPts %lld\n", call->Pts); struct iovec iov[2]; + iov[0].iov_base = PesHeader; - iov[0].iov_len = HeaderLength; + iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + 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; + return call->WriteV(call->fd, iov, 2);; } /* ***************************** */ /* Writer Definition */ /* ***************************** */ -static WriterCaps_t caps_h263 = +static WriterCaps_t caps = { - "h263", + "mjpeg", eVideo, - "V_H263", - VIDEO_ENCODING_H263, - STREAMTYPE_H263, - CT_MPEG4_PART2 + "V_MJPEG", + VIDEO_ENCODING_AUTO, + STREAMTYPE_MJPEG, + -1 }; -struct Writer_s WriterVideoH263 = +struct Writer_s WriterVideoMJPEG = { &reset, &writeData, - &caps_h263 -}; - -static WriterCaps_t caps_flv = -{ - "FLV", - eVideo, - "V_FLV", - VIDEO_ENCODING_FLV1, - STREAMTYPE_H263, - CT_MPEG4_PART2 -}; - -struct Writer_s WriterVideoFLV = -{ - &reset, - &writeData, - &caps_flv + &caps }; diff --git a/libeplayer3-arm/output/writer/mipsel/mp3.c b/libeplayer3-arm/output/writer/mipsel/mp3.c index 9eb9f5c..fa225fd 100644 --- a/libeplayer3-arm/output/writer/mipsel/mp3.c +++ b/libeplayer3-arm/output/writer/mipsel/mp3.c @@ -52,23 +52,6 @@ /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define MP3_DEBUG - -#ifdef MP3_DEBUG - -static short debug_level = 0; - -#define mp3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_printf(level, fmt, x...) -#endif - -#ifndef MP3_SILENT -#define mp3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_err(fmt, x...) -#endif /* ***************************** */ /* Types */ diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg2.c b/libeplayer3-arm/output/writer/mipsel/mpeg2.c index aecc701..26746f3 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg2.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg2.c @@ -53,24 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -#define MPEG2_DEBUG - -#ifdef MPEG2_DEBUG - -static short debug_level = 0; - -#define mpeg2_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_printf(level, fmt, x...) -#endif - -#ifndef MPEG2_SILENT -#define mpeg2_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -79,6 +61,11 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); /* Variables */ /* ***************************** */ +static bool must_send_header = true; +static uint8_t *private_data = NULL; +static uint32_t private_size = 0; + + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -89,15 +76,13 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); static int reset() { + must_send_header = true; return 0; } static int writeData(WriterAVCallData_t *call) { - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - - int len = 0; - unsigned int Position = 0; + static uint8_t PesHeader[PES_MAX_HEADER_SIZE]; mpeg2_printf(10, "\n"); @@ -121,35 +106,143 @@ static int writeData(WriterAVCallData_t *call) return 0; } - while (Position < call->len) + uint8_t *data = call->data; + uint32_t data_len = call->len; + + if (!private_data && !call->private_data && data_len > 3 && !memcmp(data, "\x00\x00\x01\xb3", 4)) { - 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) + bool ok = true; + uint32_t pos = 4; + uint32_t sheader_data_len = 0; + while (pos < data_len && ok) { - len = l; + if (pos >= data_len) break; + pos += 7; + if (pos >= data_len) break; + sheader_data_len = 12; + if (data[pos] & 2) + { + // intra matrix + pos += 64; + if (pos >= data_len) break; + sheader_data_len += 64; + } + if (data[pos] & 1) + { + // non intra matrix + pos += 64; + if (pos >= data_len) break; + sheader_data_len += 64; + } + pos += 1; + if (pos + 3 >= data_len) break; + if (!memcmp(&data[pos], "\x00\x00\x01\xb5", 4)) + { + // extended start code + pos += 3; + sheader_data_len += 3; + do + { + pos += 1; + ++sheader_data_len; + if (pos + 2 > data_len) + { + ok = false; + break; + } + } + while (memcmp(&data[pos], "\x00\x00\x01", 3)); + if (!ok) break; + } + if (pos + 3 >= data_len) break; + if (!memcmp(&data[pos], "\x00\x00\x01\xb2", 4)) + { + // private data + pos += 3; + sheader_data_len += 3; + do + { + pos += 1; + ++sheader_data_len; + if (pos + 2 > data_len) + { + ok = false; + break; + } + } + while (memcmp(&data[pos], "\x00\x00\x01", 3)); + if (!ok) break; + } + + free(private_data); + private_data = malloc(sheader_data_len); + if (private_data) + { + private_size = sheader_data_len; + memcpy(private_data, data + pos - sheader_data_len, sheader_data_len); + } + must_send_header = false; break; } - len += l; + } + else if ((private_data || call->private_data) && must_send_header) + { + uint8_t *codec_data = NULL; + uint32_t codec_data_size = 0; + int pos = 0; - Position += PacketLength; - call->Pts = INVALID_PTS_VALUE; + if (private_data) + { + codec_data = private_data; + codec_data_size = private_size; + } + else + { + codec_data = call->private_data; + codec_data_size = call->private_size; + } + + while ((unsigned)pos <= data_len - 4) + { + if (memcmp(&data[pos], "\x00\x00\x01\xb8", 4)) /* find group start code */ + { + pos++; + continue; + } + + struct iovec iov[4]; + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, call->len + codec_data_size, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + + iov[1].iov_base = data; + iov[1].iov_len = pos; + + iov[2].iov_base = codec_data; + iov[2].iov_len = codec_data_size; + + iov[3].iov_base = data + pos; + iov[3].iov_len = data_len - pos; + + must_send_header = false; + return call->WriteV(call->fd, iov, 4); + } } - mpeg2_printf(10, "< len %d\n", len); - return len; + struct iovec iov[2]; + + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + + iov[1].iov_base = data; + iov[1].iov_len = data_len; + + PesHeader[6] = 0x81; + + UpdatePesHeaderPayloadSize(PesHeader, data_len + iov[0].iov_len - 6); + if (iov[0].iov_len != (unsigned)WriteExt(call->WriteV, call->fd, iov[0].iov_base, iov[0].iov_len)) return -1; + if (iov[1].iov_len != (unsigned)WriteExt(call->WriteV, call->fd, iov[1].iov_base, iov[1].iov_len)) return -1; + + return 1; } /* ***************************** */ @@ -162,7 +255,7 @@ static WriterCaps_t caps = "V_MPEG2", VIDEO_ENCODING_AUTO, STREAMTYPE_MPEG2, - CT_MPEG2 + -1 }; struct Writer_s WriterVideoMPEG2 = @@ -177,9 +270,9 @@ static WriterCaps_t mpg1_caps = "mpge1", eVideo, "V_MPEG1", - VIDEO_ENCODING_H264, + VIDEO_ENCODING_AUTO, STREAMTYPE_MPEG1, - CT_MPEG1 + -1 }; struct Writer_s WriterVideoMPEG1 = diff --git a/libeplayer3-arm/output/writer/mipsel/mpeg4.c b/libeplayer3-arm/output/writer/mipsel/mpeg4.c index 0086992..326739d 100644 --- a/libeplayer3-arm/output/writer/mipsel/mpeg4.c +++ b/libeplayer3-arm/output/writer/mipsel/mpeg4.c @@ -53,29 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define MPEG4_DEBUG -#else -#define MPEG4_SILENT -#endif - -#ifdef MPEG4_DEBUG - -static short debug_level = 0; - -#define mpeg4_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg4_printf(level, fmt, x...) -#endif - -#ifndef MPEG4_SILENT -#define mpeg4_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg4_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -173,3 +150,20 @@ struct Writer_s WriterVideoMPEG4 = &writeData, &mpeg4p2_caps }; + +static WriterCaps_t caps_h263 = +{ + "h263", + eVideo, + "V_H263", + VIDEO_ENCODING_H263, + STREAMTYPE_H263, + -1 +}; + +struct Writer_s WriterVideoH263 = +{ + &reset, + &writeData, + &caps_h263 +}; diff --git a/libeplayer3-arm/output/writer/mipsel/pcm.c b/libeplayer3-arm/output/writer/mipsel/pcm.c index f50ab64..d24b4e2 100644 --- a/libeplayer3-arm/output/writer/mipsel/pcm.c +++ b/libeplayer3-arm/output/writer/mipsel/pcm.c @@ -56,28 +56,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define PCM_DEBUG -#else -#define PCM_SILENT -#endif - -#ifdef PCM_DEBUG - -static uint16_t debug_level = 0; - -#define pcm_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_printf(level, fmt, x...) -#endif - -#ifndef PCM_SILENT -#define pcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -139,17 +117,6 @@ static int writeData(WriterAVCallData_t *call) if (pcmPrivateData->bResampling || NULL == fixed_buffer) { - if (0) - { - printf("ioctl %d", ioctl(call->fd, AUDIO_SELECT_SOURCE, AUDIO_SOURCE_MEMORY)); - printf("ioctl %d", ioctl(call->fd, AUDIO_PAUSE)); - printf("ioctl %d", ioctl(call->fd, AUDIO_SET_BYPASS_MODE, 0x30)); - 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; @@ -193,6 +160,7 @@ static int writeData(WriterAVCallData_t *call) } uint8_t *data = codec_data; + uint16_t format = LE ? 0x0001 : 0x0100; byterate = channels * rate * width / 8; block_align = channels * width / 8; @@ -237,7 +205,7 @@ static int writeData(WriterAVCallData_t *call) fixed_bufferfilled = 0; /* avoid compiler warning */ if (LE) {} - //printf("PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE":"BE"); + pcm_printf(40, "PCM fixed_buffersize [%u] [%s]\n", fixed_buffersize, LE ? "LE" : "BE"); } while (size > 0) @@ -256,12 +224,12 @@ static int writeData(WriterAVCallData_t *call) size -= cpSize; uint32_t addHeaderSize = 0; - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { addHeaderSize = 4; } uint32_t headerSize = InsertPesHeader(PesHeader, fixed_buffersize + 4 + addHeaderSize + sizeof(codec_data), MPEG_AUDIO_PES_START_CODE, fixed_buffertimestamp, 0); - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { PesHeader[headerSize++] = 0x42; // B PesHeader[headerSize++] = 0x43; // C @@ -286,11 +254,6 @@ 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); - 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 0cdb63b..79635fd 100644 --- a/libeplayer3-arm/output/writer/mipsel/vc1.c +++ b/libeplayer3-arm/output/writer/mipsel/vc1.c @@ -56,30 +56,6 @@ #define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80 #define VC1_FRAME_START_CODE 0x0d -#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define VC1_DEBUG -#else -#define VC1_SILENT -#endif - -#ifdef VC1_DEBUG - -static short debug_level = 10; - -#define vc1_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_printf(level, fmt, x...) -#endif - -#ifndef VC1_SILENT -#define vc1_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_err(fmt, x...) -#endif - - /* ***************************** */ /* Types */ /* ***************************** */ @@ -153,7 +129,7 @@ static int writeData(WriterAVCallData_t *call) videocodecdata.data = malloc(videocodecdata.length); memset(videocodecdata.data, 0, videocodecdata.length); memcpy(videocodecdata.data + 8, call->private_data, call->private_size); - if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) + if (STB_DREAMBOX == GetSTBType() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) { iov[ic].iov_base = videocodecdata.data; iov[ic++].iov_len = videocodecdata.length; diff --git a/libeplayer3-arm/output/writer/mipsel/vp.c b/libeplayer3-arm/output/writer/mipsel/vp.c index a9f75aa..fe348b1 100644 --- a/libeplayer3-arm/output/writer/mipsel/vp.c +++ b/libeplayer3-arm/output/writer/mipsel/vp.c @@ -53,30 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define VP_DEBUG -#else -#define VP_SILENT -#endif - -#ifdef VP_DEBUG - -static short debug_level = 10; - -#define vp_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vp_printf(level, fmt, x...) -#endif - -#ifndef VP_SILENT -#define vp_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vp_err(fmt, x...) -#endif - - /* ***************************** */ /* Types */ /* ***************************** */ @@ -98,7 +74,8 @@ static int reset() return 0; } -static int writeData(WriterAVCallData_t *call, int is_vp6) +static uint8_t PesHeader[256]; +static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) { vp_printf(10, "\n"); @@ -123,14 +100,21 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) 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]; + uint64_t pts = is_vp9 && STB_VUPLUS == GetSTBType() ? 0 : call->Pts; iov[0].iov_base = PesHeader; - uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, pts, 0); uint32_t len = call->len + 4 + 6; memcpy(PesHeader + pes_header_len, "BCMV", 4); pes_header_len += 4; + + if (is_vp9 && STB_VUPLUS == GetSTBType()) + { + uint32_t vp9_pts = (call->Pts == INVALID_PTS_VALUE ? call->Dts : call->Pts) / 2; + memcpy(&PesHeader[9], &vp9_pts, sizeof(vp9_pts)); + } + if (is_vp6) ++len; PesHeader[pes_header_len++] = (len & 0xFF000000) >> 24; @@ -138,24 +122,114 @@ static int writeData(WriterAVCallData_t *call, int is_vp6) PesHeader[pes_header_len++] = (len & 0x0000FF00) >> 8; PesHeader[pes_header_len++] = (len & 0x000000FF) >> 0; PesHeader[pes_header_len++] = 0; - PesHeader[pes_header_len++] = 0; + PesHeader[pes_header_len++] = STB_VUPLUS != GetSTBType() && is_vp9 ? 1 : 0; if (is_vp6) PesHeader[pes_header_len++] = 0; 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); + int32_t payload_len = call->len + pes_header_len - 6; + + if (!is_vp9 || STB_VUPLUS == GetSTBType() || STB_HISILICON == GetSTBType() || STB_DREAMBOX == GetSTBType()) + { + UpdatePesHeaderPayloadSize(PesHeader, payload_len); + // it looks like for VUPLUS drivers PES header must be written separately + int ret = call->WriteV(call->fd, iov, 1); + if (iov[0].iov_len != (unsigned)ret) + return ret; + ret = call->WriteV(call->fd, iov + 1, 1); + return iov[0].iov_len + ret; + } + else + { + if (payload_len > 0x8008) + payload_len = 0x8008; + + int offs = 0; + int bytes = payload_len - 10 - 8; + UpdatePesHeaderPayloadSize(PesHeader, payload_len); + // pes header + if (pes_header_len != (unsigned)WriteExt(call->WriteV, call->fd, PesHeader, pes_header_len)) return -1; + if (bytes != WriteExt(call->WriteV, call->fd, call->data, bytes)) return -1; + + offs += bytes; + + while ((unsigned)bytes < call->len) + { + int left = call->len - bytes; + int wr = 0x8000; + if (wr > left) + wr = left; + + //gst_buffer_unmap(self->pesheader_buffer, &pesheadermap); + //gst_buffer_map(self->pesheader_buffer, &pesheadermap, GST_MAP_WRITE); + //pes_header = pesheadermap.data; + + //PesHeader[0] = 0x00; + //PesHeader[1] = 0x00; + //PesHeader[2] = 0x01; + //PesHeader[3] = 0xE0; + PesHeader[6] = 0x81; + PesHeader[7] = 0x00; + PesHeader[8] = 0x00; + pes_header_len = 9; + + UpdatePesHeaderPayloadSize(PesHeader, wr + 3); + + if (pes_header_len != (unsigned)WriteExt(call->WriteV, call->fd, PesHeader, pes_header_len)) return -1; + if (wr != WriteExt(call->WriteV, call->fd, call->data + offs, wr)) return -1; + + bytes += wr; + offs += wr; + } + + //gst_buffer_unmap(self->pesheader_buffer, &pesheadermap); + //gst_buffer_map(self->pesheader_buffer, &pesheadermap, GST_MAP_WRITE); + //pes_header = pesheadermap.data; + + //PesHeader[0] = 0x00; + //PesHeader[1] = 0x00; + //PesHeader[2] = 0x01; + //PesHeader[3] = 0xE0; + PesHeader[4] = 0x00; + PesHeader[5] = 0xB2; + PesHeader[6] = 0x81; + PesHeader[7] = 0x01; + PesHeader[8] = 0x14; + PesHeader[9] = 0x80; + PesHeader[10] = 'B'; + PesHeader[11] = 'R'; + PesHeader[12] = 'C'; + PesHeader[13] = 'M'; + memset(PesHeader + 14, 0, 170); + PesHeader[26] = 0xFF; + PesHeader[27] = 0xFF; + PesHeader[28] = 0xFF; + PesHeader[29] = 0xFF; + PesHeader[33] = 0x85; + + if (pes_header_len != (unsigned)WriteExt(call->WriteV, call->fd, PesHeader, 184)) return -1; + + return 1; + } + + //return call->WriteV(call->fd, iov, 2); } static int writeDataVP6(WriterAVCallData_t *call) { - return writeData(call, 1); + return writeData(call, true, false); } -static int writeDataVP89(WriterAVCallData_t *call) +static int writeDataVP8(WriterAVCallData_t *call) { - return writeData(call, 0); + return writeData(call, false, false); +} + +static int writeDataVP9(WriterAVCallData_t *call) +{ + return writeData(call, false, true); } /* ***************************** */ @@ -192,7 +266,7 @@ static WriterCaps_t capsVP8 = struct Writer_s WriterVideoVP8 = { &reset, - &writeDataVP89, + &writeDataVP8, &capsVP8 }; @@ -209,23 +283,23 @@ static WriterCaps_t capsVP9 = struct Writer_s WriterVideoVP9 = { &reset, - &writeDataVP89, + &writeDataVP9, &capsVP9 }; -static WriterCaps_t capsSPARK = +static WriterCaps_t capsFLV = { - "spark", + "flv1", eVideo, - "V_SPARK", + "V_FLV", VIDEO_ENCODING_VC1, STREAMTYPE_SPARK, CT_SPARK }; -struct Writer_s WriterVideoSPARK = +struct Writer_s WriterVideoFLV = { &reset, - &writeDataVP89, - &capsSPARK + &writeDataVP8, + &capsFLV }; diff --git a/libeplayer3-arm/output/writer/mipsel/wma.c b/libeplayer3-arm/output/writer/mipsel/wma.c index e953ed8..ae69d12 100644 --- a/libeplayer3-arm/output/writer/mipsel/wma.c +++ b/libeplayer3-arm/output/writer/mipsel/wma.c @@ -53,28 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define WMA_DEBUG -#else -#define WMA_SILENT -#endif - -#ifdef WMA_DEBUG - -static short debug_level = 0; - -#define wma_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wma_printf(level, fmt, x...) -#endif - -#ifndef WMA_SILENT -#define wma_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wma_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -129,7 +107,7 @@ static int writeData(WriterAVCallData_t *call) uint32_t packetLength = 4 + call->private_size + call->len; - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { packetLength += 4; } @@ -145,7 +123,7 @@ static int writeData(WriterAVCallData_t *call) } uint32_t headerSize = InsertPesHeader(PesHeader, packetLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); - if (IsDreambox()) + if (STB_DREAMBOX == GetSTBType()) { PesHeader[headerSize++] = 0x42; // B PesHeader[headerSize++] = 0x43; // C diff --git a/libeplayer3-arm/output/writer/mipsel/wmv.c b/libeplayer3-arm/output/writer/mipsel/wmv.c index 13934c7..24e1567 100644 --- a/libeplayer3-arm/output/writer/mipsel/wmv.c +++ b/libeplayer3-arm/output/writer/mipsel/wmv.c @@ -55,29 +55,6 @@ #define WMV_FRAME_START_CODE 0x0d -//#define SAM_WITH_DEBUG -#ifdef SAM_WITH_DEBUG -#define WMV_DEBUG -#else -#define WMV_SILENT -#endif - -#ifdef WMV_DEBUG - -static short debug_level = 10; - -#define wmv_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_printf(level, fmt, x...) -#endif - -#ifndef WMV_SILENT -#define wmv_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -159,7 +136,7 @@ static int writeData(WriterAVCallData_t *call) *(data++) = (call->Height >> 8) & 0xff; *(data++) = call->Height & 0xff; if (call->private_data && codec_size) memcpy(data, call->private_data, codec_size); - if (IsDreambox() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) + if (STB_DREAMBOX == GetSTBType() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) { iov[ic].iov_base = videocodecdata.data; iov[ic++].iov_len = videocodecdata.length; diff --git a/libeplayer3-arm/output/writer/mipsel/writer.c b/libeplayer3-arm/output/writer/mipsel/writer.c index c5ccb35..f8853a0 100644 --- a/libeplayer3-arm/output/writer/mipsel/writer.c +++ b/libeplayer3-arm/output/writer/mipsel/writer.c @@ -26,37 +26,32 @@ #include #include #include +#include #include "misc.h" #include "writer.h" #include "common.h" +#include "debug.h" /* ***************************** */ /* Makros/Constants */ /* ***************************** */ -#define WRITER_DEBUG - -#ifdef WRITER_DEBUG - -static short debug_level = 0; - -#define writer_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define writer_printf(level, x...) -#endif - -#ifndef WRITER_SILENT -#define writer_err(x...) do { printf(x); } while (0) -#else -#define writer_err(x...) -#endif +#define getDVBMutex(pmtx) do { if (pmtx) pthread_mutex_lock(pmtx);} while(false); +#define releaseDVBMutex(pmtx) do { if (pmtx) pthread_mutex_unlock(pmtx);} while(false); /* ***************************** */ /* Types */ /* ***************************** */ +typedef enum +{ + DVB_STS_UNKNOWN, + DVB_STS_SEEK, + DVB_STS_PAUSE, + DVB_STS_EXIT +} DVBState_t; + /* ***************************** */ /* Variables */ /* ***************************** */ @@ -88,8 +83,9 @@ static Writer_t *AvailableWriter[] = &WriterVideoVP6, &WriterVideoVP8, &WriterVideoVP9, - &WriterVideoSPARK, + &WriterVideoFLV, &WriterVideoWMV, + &WriterVideoMJPEG, NULL }; @@ -101,7 +97,7 @@ static Writer_t *AvailableWriter[] = /* Functions */ /* ***************************** */ -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size) +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx __attribute__((unused)), const void *buf, int size) { fd_set rfds; fd_set wfds; @@ -110,8 +106,17 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int retval = -1; int maxFd = pipefd > fd ? pipefd : fd; struct timeval tv; - - while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) + + static bool first = true; + if (first && STB_HISILICON == GetSTBType()) + { + // workaround: playback of some files does not start + // if injection of the frist frame is to fast + usleep(100000); + } + first = false; + + while (size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) { FD_ZERO(&rfds); FD_ZERO(&wfds); @@ -119,15 +124,15 @@ 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 continue to be filled. Unfortunately, in such case after resume - * select() will never return with fd set - bug in DVB drivers? - * There are to workarounds possible: - * 1. write to pipe at resume to return from select() immediately - * 2. make timeout select(), limit max time spend in the select() - * to for example 0,1s - * (at now first workaround is used) - */ + /* When we PAUSE LINUX DVB outputs buffers, then audio/video buffers + * will continue to be filled. Unfortunately, in such case after resume + * select() will never return with fd set - bug in DVB drivers? + * There are to workarounds possible: + * 1. write to pipe at resume to return from select() immediately + * 2. make timeout select(), limit max time spend in the select() + * to for example 0,1s + * (at now first workaround is used) + */ //tv.tv_sec = 0; //tv.tv_usec = 100000; // 100ms @@ -143,19 +148,19 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, // continue; //} - if(FD_ISSET(pipefd, &rfds)) + if (FD_ISSET(pipefd, &rfds)) { FlushPipe(pipefd); //printf("RETURN FROM SELECT DUE TO pipefd SET\n"); continue; } - if(FD_ISSET(fd, &wfds)) + if (FD_ISSET(fd, &wfds)) { ret = write(fd, buf, size); if (ret < 0) { - switch(errno) + switch (errno) { case EINTR: case EAGAIN: diff --git a/libeplayer3-arm/output/writer/sh4/aac.c b/libeplayer3-arm/output/writer/sh4/aac.c index 62978e5..4d36753 100644 --- a/libeplayer3-arm/output/writer/sh4/aac.c +++ b/libeplayer3-arm/output/writer/sh4/aac.c @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -42,7 +41,7 @@ #include #include "ffmpeg/latmenc.h" - +#include "stm_ioctls.h" #include "common.h" #include "output.h" @@ -56,30 +55,6 @@ /* Makros/Constants */ /* ***************************** */ -//#define SAM_WITH_DEBUG - -#ifdef SAM_WITH_DEBUG -#define AAC_DEBUG -#else -#define AAC_SILENT -#endif - -#ifdef AAC_DEBUG - -static short debug_level = 0; - -#define aac_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define aac_printf(level, fmt, x...) -#endif - -#ifndef AAC_SILENT -#define aac_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define aac_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -181,7 +156,7 @@ 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)) { diff --git a/libeplayer3-arm/output/writer/sh4/ac3.c b/libeplayer3-arm/output/writer/sh4/ac3.c index cba2445..8fa881f 100644 --- a/libeplayer3-arm/output/writer/sh4/ac3.c +++ b/libeplayer3-arm/output/writer/sh4/ac3.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -52,28 +52,6 @@ /* ***************************** */ #define AC3_HEADER_LENGTH 7 -#ifdef SAM_WITH_DEBUG -#define AC3_DEBUG -#else -#define AC3_SILENT -#endif - -#ifdef AC3_DEBUG - -static short debug_level = 0; - -#define ac3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_printf(level, fmt, x...) -#endif - -#ifndef AC3_SILENT -#define ac3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/divx.c b/libeplayer3-arm/output/writer/sh4/divx.c index c1b97c7..ee184ef 100644 --- a/libeplayer3-arm/output/writer/sh4/divx.c +++ b/libeplayer3-arm/output/writer/sh4/divx.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define DIVX_DEBUG -#else -#define DIVX_SILENT -#endif - -#ifdef DIVX_DEBUG - -static short debug_level = 0; - -#define divx_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_printf(level, fmt, x...) -#endif - -#ifndef DIVX_SILENT -#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/divx2.c b/libeplayer3-arm/output/writer/sh4/divx2.c index fc80917..044d2e0 100644 --- a/libeplayer3-arm/output/writer/sh4/divx2.c +++ b/libeplayer3-arm/output/writer/sh4/divx2.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define DIVX_DEBUG -#else -#define DIVX_SILENT -#endif - -#ifdef DIVX_DEBUG - -static short debug_level = 0; - -#define divx_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_printf(level, fmt, x...) -#endif - -#ifndef DIVX_SILENT -#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/dts.c b/libeplayer3-arm/output/writer/sh4/dts.c index f6cc94c..d631231 100644 --- a/libeplayer3-arm/output/writer/sh4/dts.c +++ b/libeplayer3-arm/output/writer/sh4/dts.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -56,28 +56,6 @@ #define PES_AUDIO_PACKET_SIZE 2028 #define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples. -#ifdef SAM_WITH_DEBUG -#define DTS_DEBUG -#else -#define DTS_SILENT -#endif - -#ifdef DTS_DEBUG - -static short debug_level = 0; - -#define dts_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_printf(level, fmt, x...) -#endif - -#ifndef DTS_SILENT -#define dts_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/h263.c b/libeplayer3-arm/output/writer/sh4/h263.c index c29309b..c1b95fa 100644 --- a/libeplayer3-arm/output/writer/sh4/h263.c +++ b/libeplayer3-arm/output/writer/sh4/h263.c @@ -33,13 +33,13 @@ #include #include #include -#include #include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define H263_DEBUG -#else -#define H263_SILENT -#endif - -#ifdef H263_DEBUG -static short debug_level = 0; -static const char *FILENAME = "h263.c"; - -#define h263_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0) -#else -#define h263_printf(level, fmt, x...) -#endif - -#ifndef H263_SILENT -#define h263_err(fmt, x...) do { printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0) -#else -#define h263_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/h264.c b/libeplayer3-arm/output/writer/sh4/h264.c index b749139..a81b535 100644 --- a/libeplayer3-arm/output/writer/sh4/h264.c +++ b/libeplayer3-arm/output/writer/sh4/h264.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -42,6 +41,7 @@ #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -53,28 +53,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define H264_DEBUG -#else -#define H264_SILENT -#endif - -#ifdef H264_DEBUG - -static short debug_level = 0; - -#define h264_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_printf(level, fmt, x...) -#endif - -#ifndef H264_SILENT -#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_err(fmt, x...) -#endif - #define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24 #define CONTAINER_PARAMETERS_VERSION 0x00 @@ -267,7 +245,7 @@ static int32_t writeData(void *_call) iov[ic++].iov_base = PesHeader; initialHeader = 0; - if (initialHeader) + if (initialHeader) { initialHeader = 0; iov[ic].iov_base = call->private_data; diff --git a/libeplayer3-arm/output/writer/sh4/mp3.c b/libeplayer3-arm/output/writer/sh4/mp3.c index 72b0aa5..962c640 100644 --- a/libeplayer3-arm/output/writer/sh4/mp3.c +++ b/libeplayer3-arm/output/writer/sh4/mp3.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define MP3_DEBUG -#else -#define MP3_SILENT -#endif - -#ifdef MP3_DEBUG - -static short debug_level = 0; - -#define mp3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_printf(level, fmt, x...) -#endif - -#ifndef MP3_SILENT -#define mp3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ @@ -182,3 +160,4 @@ struct Writer_s WriterAudioVORBIS = &writeData, &caps_vorbis }; + diff --git a/libeplayer3-arm/output/writer/sh4/mpeg2.c b/libeplayer3-arm/output/writer/sh4/mpeg2.c index 5dae349..d7fb298 100644 --- a/libeplayer3-arm/output/writer/sh4/mpeg2.c +++ b/libeplayer3-arm/output/writer/sh4/mpeg2.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define MPEG2_DEBUG -#else -#define MPEG2_SILENT -#endif - -#ifdef MPEG2_DEBUG - -static short debug_level = 0; - -#define mpeg2_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_printf(level, fmt, x...) -#endif - -#ifndef MPEG2_SILENT -#define mpeg2_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/pcm.c b/libeplayer3-arm/output/writer/sh4/pcm.c index e9bef07..43e1709 100644 --- a/libeplayer3-arm/output/writer/sh4/pcm.c +++ b/libeplayer3-arm/output/writer/sh4/pcm.c @@ -34,7 +34,6 @@ #include #include #include -#include #include #include #include @@ -42,6 +41,7 @@ #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -54,28 +54,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define PCM_DEBUG -#else -#define PCM_SILENT -#endif - -#ifdef PCM_DEBUG - -static short debug_level = 0; - -#define pcm_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_printf(level, fmt, x...) -#endif - -#ifndef PCM_SILENT -#define pcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/pes.c b/libeplayer3-arm/output/writer/sh4/pes.c index 12a7bd6..5ce53aa 100644 --- a/libeplayer3-arm/output/writer/sh4/pes.c +++ b/libeplayer3-arm/output/writer/sh4/pes.c @@ -33,12 +33,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" diff --git a/libeplayer3-arm/output/writer/sh4/vc1.c b/libeplayer3-arm/output/writer/sh4/vc1.c index 8545eba..f9fba12 100644 --- a/libeplayer3-arm/output/writer/sh4/vc1.c +++ b/libeplayer3-arm/output/writer/sh4/vc1.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -61,28 +61,6 @@ #define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80 #define VC1_FRAME_START_CODE 0x0d -#ifdef SAM_WITH_DEBUG -#define VC1_DEBUG -#else -#define VC1_SILENT -#endif - -#ifdef VC1_DEBUG - -static short debug_level = 0; - -#define vc1_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_printf(level, fmt, x...) -#endif - -#ifndef VC1_SILENT -#define vc1_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/vorbis.c b/libeplayer3-arm/output/writer/sh4/vorbis.c index 3ed1cb2..e51513e 100644 --- a/libeplayer3-arm/output/writer/sh4/vorbis.c +++ b/libeplayer3-arm/output/writer/sh4/vorbis.c @@ -38,10 +38,10 @@ #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" -#include "stm_ioctls.h" #include "misc.h" #include "pes.h" #include "writer.h" @@ -50,28 +50,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define VORBIS_DEBUG -#else -#define VORBIS_SILENT -#endif - -#ifdef VORBIS_DEBUG - -static short debug_level = 1; - -#define vorbis_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vorbis_printf(level, fmt, x...) -#endif - -#ifndef VORBIS_SILENT -#define vorbis_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vorbis_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/wma.c b/libeplayer3-arm/output/writer/sh4/wma.c index 35408df..4a52055 100644 --- a/libeplayer3-arm/output/writer/sh4/wma.c +++ b/libeplayer3-arm/output/writer/sh4/wma.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -51,28 +51,6 @@ /* Makros/Constants */ /* ***************************** */ -#ifdef SAM_WITH_DEBUG -#define WMA_DEBUG -#else -#define WMA_SILENT -#endif - -#ifdef WMA_DEBUG - -static short debug_level = 0; - -#define wma_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wma_printf(level, fmt, x...) -#endif - -#ifndef WMA_SILENT -#define wma_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wma_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/wmv.c b/libeplayer3-arm/output/writer/sh4/wmv.c index 9a644d9..2204195 100644 --- a/libeplayer3-arm/output/writer/sh4/wmv.c +++ b/libeplayer3-arm/output/writer/sh4/wmv.c @@ -34,12 +34,12 @@ #include #include #include -#include #include #include #include #include +#include "stm_ioctls.h" #include "common.h" #include "output.h" #include "debug.h" @@ -58,28 +58,6 @@ #define METADATA_STRUCT_B_FRAMERATE_START 32 #define METADATA_STRUCT_C_START 8 -#ifdef SAM_WITH_DEBUG -#define WMV_DEBUG -#else -#define WMV_SILENT -#endif - -#ifdef WMV_DEBUG - -static short debug_level = 0; - -#define wmv_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_printf(level, fmt, x...) -#endif - -#ifndef WMV_SILENT -#define wmv_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_err(fmt, x...) -#endif - /* ***************************** */ /* Types */ /* ***************************** */ diff --git a/libeplayer3-arm/output/writer/sh4/writer.c b/libeplayer3-arm/output/writer/sh4/writer.c index 71aa862..f1bd83e 100644 --- a/libeplayer3-arm/output/writer/sh4/writer.c +++ b/libeplayer3-arm/output/writer/sh4/writer.c @@ -97,50 +97,50 @@ static Writer_t *AvailableWriter[] = /* ***************************** */ /* Functions */ /* ***************************** */ -ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, const void *buf, int size) +ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, const void *buf, int size) { fd_set rfds; - + ssize_t ret; int retval = -1; struct timeval tv; - - while(size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) + + while (size > 0 && 0 == PlaybackDieNow(0) && !context->playback->isSeeking) { if (context->playback->isPaused) { FD_ZERO(&rfds); FD_SET(pipefd, &rfds); - + tv.tv_sec = 0; tv.tv_usec = 500000; // 500ms - + retval = select(pipefd + 1, &rfds, 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)) + + if (FD_ISSET(pipefd, &rfds)) { FlushPipe(pipefd); //printf("RETURN FROM SELECT DUE TO pipefd SET\n"); continue; } } - + //printf(">> Before Write fd [%d]\n", fd); ret = write(fd, buf, size); //printf(">> After Write ret[%d] size[%d]\n", (int)ret, size); if (ret == size) ret = 0; // no error - + break; } return ret; @@ -199,3 +199,4 @@ Writer_t *getDefaultAudioWriter() return NULL; } + diff --git a/libeplayer3-arm/playback/playback.c b/libeplayer3-arm/playback/playback.c index 781bf4f..280faa1 100644 --- a/libeplayer3-arm/playback/playback.c +++ b/libeplayer3-arm/playback/playback.c @@ -8,6 +8,7 @@ /* ***************************** */ #include +#include #include #include #include @@ -21,6 +22,7 @@ #include #include "playback.h" +#include "debug.h" #include "common.h" #include "misc.h" @@ -28,29 +30,6 @@ /* Makros/Constants */ /* ***************************** */ -// SULGE DEBUG -//#define SAM_WITH_DEBUG - -#ifdef SAM_WITH_DEBUG -#define PLAYBACK_DEBUG -static short debug_level = 20; -#else -#define PLAYBACK_SILENT -#endif - -#ifdef PLAYBACK_DEBUG -#define playback_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define playback_printf(level, fmt, x...) -#endif - -#ifndef PLAYBACK_SILENT -#define playback_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define playback_err(fmt, x...) -#endif - #define cERR_PLAYBACK_NO_ERROR 0 #define cERR_PLAYBACK_ERROR -1 @@ -71,6 +50,7 @@ static int hasThreadStarted = 0; /* ***************************** */ static int32_t PlaybackTerminate(Context_t *context); + static int8_t dieNow = 0; static PlaybackDieNowCallback playbackDieNowCallbacks[MAX_PLAYBACK_DIE_NOW_CALLBACKS] = {NULL}; @@ -540,7 +520,6 @@ static int PlaybackFastForward(Context_t *context, int *speed) playback_printf(20, "Speed: %d x {%d}\n", *speed, context->playback->Speed); context->output->Command(context, OUTPUT_FASTFORWARD, NULL); context->output->Command(context, OUTPUT_AUDIOMUTE, "1"); - context->output->Command(context, OUTPUT_CONTINUE, NULL); } else { @@ -652,7 +631,7 @@ 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); + playback_printf(10, "pos: %" PRIu64 "\n", *pos); if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused) { @@ -1007,6 +986,7 @@ PlaybackHandler_t PlaybackHandler = 0, //BackWard 0, //SlowMotion 0, //Speed + 0, //readCount 0, //AVSync 0, //isVideo 0, //isAudio