diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index 402e575..d39313d 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -18,6 +18,7 @@ SOURCE_FILES += manager/audio.c SOURCE_FILES += manager/video.c SOURCE_FILES += manager/chapter.c SOURCE_FILES += manager/subtitle.c +SOURCE_FILES += output/graphic_subtitle.c SOURCE_FILES += output/output_subtitle.c SOURCE_FILES += output/output.c SOURCE_FILES += output/writer/common/pes.c @@ -28,6 +29,8 @@ SOURCE_FILES += playback/playback.c SOURCE_FILES += external/ffmpeg/src/bitstream.c SOURCE_FILES += external/ffmpeg/src/latmenc.c SOURCE_FILES += external/ffmpeg/src/mpeg4audio.c +SOURCE_FILES += external/ffmpeg/src/xiph.c +SOURCE_FILES += external/plugins/src/png.c if ENABLE_FLV2MPEG4 AM_CFLAGS += -DHAVE_FLV2MPEG4_CONVERTER @@ -43,12 +46,12 @@ SOURCE_FILES += \ output/writer/mipsel/writer.c \ output/writer/mipsel/aac.c \ output/writer/mipsel/ac3.c \ + output/writer/mipsel/bcma.c \ output/writer/mipsel/mp3.c \ output/writer/mipsel/pcm.c \ output/writer/mipsel/lpcm.c \ output/writer/mipsel/dts.c \ output/writer/mipsel/amr.c \ - output/writer/mipsel/wma.c \ output/writer/mipsel/h265.c \ output/writer/mipsel/h264.c \ output/writer/mipsel/mjpeg.c \ @@ -61,9 +64,9 @@ SOURCE_FILES += \ libeplayer3_la_SOURCES = $(SOURCE_FILES) -LIBEPLAYER3_LIBS = libeplayer3.la -lpthread -lavformat -lavcodec -lavutil -lswresample +LIBEPLAYER3_LIBS = libeplayer3.la -lswscale -ldl -lpthread -lavformat -lavcodec -lavutil -lswresample -#bin_PROGRAMS = eplayer3 -#eplayer3_SOURCES = main/exteplayer.c -#eplayer3_LDADD = $(LIBEPLAYER3_LIBS) -#eplayer3_DEPENDENCIES = libeplayer3.la +bin_PROGRAMS = eplayer3 +eplayer3_SOURCES = main/exteplayer.c +eplayer3_LDADD = $(LIBEPLAYER3_LIBS) +eplayer3_DEPENDENCIES = libeplayer3.la diff --git a/libeplayer3/container/buff_ffmpeg.c b/libeplayer3/container/buff_ffmpeg.c index 7fbb23e..32cf0c2 100644 --- a/libeplayer3/container/buff_ffmpeg.c +++ b/libeplayer3/container/buff_ffmpeg.c @@ -107,7 +107,7 @@ static void update_finish_timeout() * this is the reason for additional validation when we what to close immediately */ if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts && - ((currPts - maxInjectedPts) / 90000) < 2) + ((currPts - maxInjectedPts) / 90000) < 2) { /* close immediately */ @@ -271,7 +271,7 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 } while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) || - (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF)) + (flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF)) { if (0 == PlaybackDieNow(0)) { @@ -335,9 +335,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3 if (size > 0) { - if (flag == 1 && hasfillerThreadStarted[id] == 2) break; + if (flag == 1 && hasfillerThreadStarted[id] == 2) + break; + len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size); - if (flag == 1 && hasfillerThreadStarted[id] == 2) break; + + if (flag == 1 && hasfillerThreadStarted[id] == 2) + break; ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len); diff --git a/libeplayer3/container/container.c b/libeplayer3/container/container.c index 04ee133..a18790f 100644 --- a/libeplayer3/container/container.c +++ b/libeplayer3/container/container.c @@ -85,7 +85,6 @@ static int32_t selectContainer(Context_t *context, char *extension) return ret; } - static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused))) { int ret = 0; @@ -117,7 +116,6 @@ static int Command(Context_t *context, ContainerCmd_t command, void *argument __ return ret; } - ContainerHandler_t ContainerHandler = { "Output", diff --git a/libeplayer3/container/container_ffmpeg.c b/libeplayer3/container/container_ffmpeg.c index 221a41b..435b292 100644 --- a/libeplayer3/container/container_ffmpeg.c +++ b/libeplayer3/container/container_ffmpeg.c @@ -56,12 +56,6 @@ /* Makros/Constants */ /* ***************************** */ -#if (LIBAVFORMAT_VERSION_MAJOR > 56) -#define TS_BYTES_SEEKING 0 -#else -#define TS_BYTES_SEEKING 1 -#endif - /* Some STB with old kernels have problem with default * read/write functions in ffmpeg which use open/read * due to this we set own which use fopen/fread from @@ -122,12 +116,37 @@ static int32_t mutexInitialized = 0; /* ***************************** */ static int32_t container_ffmpeg_seek_bytes(off_t pos); static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute); -//static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec); static int32_t container_ffmpeg_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); +void LinuxDvbBuffSetStamp(void *stamp); static int32_t container_ffmpeg_stop(Context_t *context); +static char *g_graphic_sub_path; + +const char *GetGraphicSubPath() +{ + return g_graphic_sub_path; +} + +void E2iSendMsg(const char *format, ...) +{ + va_list args; + va_start(args, format); + vfprintf(stderr, format, args); + va_end(args); +} + +void E2iStartMsg(void) +{ + flockfile(stderr); +} + +void E2iEndMsg(void) +{ + funlockfile(stderr); +} + /* Progressive playback means that we play local file * but this local file can grows up, for example * we start playback before download was finished @@ -179,7 +198,6 @@ static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData, i return ret; } - #include "buff_ffmpeg.c" #include "wrapped_ffmpeg.c" #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) @@ -205,6 +223,10 @@ static int32_t aac_latm_software_decode = 0; static int32_t ac3_software_decode = 0; static int32_t eac3_software_decode = 0; static int32_t dts_software_decode = 0; +static int32_t amr_software_decode = 1; +static int32_t vorbis_software_decode = 1; +static int32_t opus_software_decode = 1; + static int32_t pcm_resampling = 1; static int32_t stereo_software_decoder = 0; static int32_t insert_pcm_as_lpcm = 0; @@ -263,6 +285,21 @@ void dts_software_decoder_set(const int32_t val) dts_software_decode = val; } +void amr_software_decoder_set(const int32_t val) +{ + amr_software_decode = val; +} + +void vorbis_software_decoder_set(const int32_t val) +{ + vorbis_software_decode = val; +} + +void opus_software_decoder_set(const int32_t val) +{ + opus_software_decode = val; +} + void stereo_software_decoder_set(const int32_t val) { stereo_software_decoder = val; @@ -327,7 +364,15 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra #endif case AV_CODEC_ID_RV10: case AV_CODEC_ID_RV20: - return "V_RMV"; + return "V_RV20"; + case AV_CODEC_ID_RV30: + return "V_RV30"; + case AV_CODEC_ID_RV40: + return "V_RV40"; +#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 21, 100) + case AV_CODEC_ID_AVS2: + return "V_AVS2"; +#endif case AV_CODEC_ID_MPEG4: return "V_MPEG4"; #if LIBAVCODEC_VERSION_MAJOR < 53 @@ -336,7 +381,7 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra case AV_CODEC_ID_MSMPEG4V1: case AV_CODEC_ID_MSMPEG4V2: case AV_CODEC_ID_MSMPEG4V3: - return "V_DIVX3"; + return "V_MPEG4"; //"V_DIVX3"; case AV_CODEC_ID_WMV1: *version = 1; return "V_WMV"; @@ -370,10 +415,17 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra MPEG4AudioConfig m4ac; int off = avpriv_mpeg4audio_get_config(&m4ac, extradata, extradata_size * 8, 1); ffmpeg_printf(1, "aac [%d] off[%d]\n", m4ac.object_type, off); - if (off < 0 || 2 != m4ac.object_type) + if (off < 0) { return "A_IPCM"; } + else if (0 == m4ac.chan_config && STB_HISILICON != GetSTBType()) + { + // according to https://wiki.multimedia.cx/index.php/ADTS + // "MPEG-4 Channel Configuration - in the case of 0, the channel configuration is sent via an inband PCE" + // we already have AAC_LATM formatter which will include PCE + return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM"; + } } return (aac_software_decode) ? "A_IPCM" : "A_AAC"; case AV_CODEC_ID_AAC_LATM: @@ -385,6 +437,7 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra case AV_CODEC_ID_DTS: return (dts_software_decode) ? "A_IPCM" : "A_DTS"; case AV_CODEC_ID_WMAV1: + return "A_IPCM"; case AV_CODEC_ID_WMAV2: return (wma_software_decode) ? "A_IPCM" : "A_WMA"; case AV_CODEC_ID_WMAPRO: @@ -397,8 +450,6 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra return "A_IPCM"; case AV_CODEC_ID_RA_288: return "A_IPCM"; - case AV_CODEC_ID_VORBIS: - return "A_IPCM"; case AV_CODEC_ID_FLAC: return "A_IPCM"; case AV_CODEC_ID_PCM_S8: @@ -417,8 +468,12 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra case AV_CODEC_ID_PCM_U32BE: return pcm_resampling ? "A_IPCM" : "A_PCM"; case AV_CODEC_ID_AMR_NB: - return "A_IPCM";//return "A_AMR"; - + case AV_CODEC_ID_AMR_WB: + return amr_software_decode ? "A_IPCM" : "A_AMR"; + case AV_CODEC_ID_VORBIS: + return vorbis_software_decode ? "A_IPCM" : "A_VORBIS"; + case AV_CODEC_ID_OPUS : + return opus_software_decode ? "A_IPCM" : "A_OPUS"; /* In exteplayer3 embedded text subtitle simple printed * to output like other data. Maybe worth to consider is to use * linux socket or pipe to put @@ -431,8 +486,6 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra #endif return "S_TEXT/ASS"; /* Hellmaster1024: seems to be ASS instead of SSA */ case AV_CODEC_ID_DVD_SUBTITLE: - case AV_CODEC_ID_DVB_SUBTITLE: - case AV_CODEC_ID_XSUB: case AV_CODEC_ID_MOV_TEXT: case AV_CODEC_ID_DVB_TELETEXT: // case CODEC_ID_DVB_TELETEXT: @@ -447,6 +500,10 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra return "S_TEXT/WEBVTT"; case AV_CODEC_ID_HDMV_PGS_SUBTITLE: return "S_GRAPHIC/PGS"; + case AV_CODEC_ID_DVB_SUBTITLE: + return "S_GRAPHIC/DVB"; + case AV_CODEC_ID_XSUB: + return "S_GRAPHIC/XSUB"; default: ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id); // Default to injected-pcm for unhandled audio types. @@ -477,7 +534,7 @@ static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t } else { - pts &= 0x01FFFFFFFF; // PES header can handle only 33 bit PTS + pts &= 0x01FFFFFFFFull; // PES header can handle only 33 bit PTS } return pts; @@ -564,10 +621,15 @@ static void FFMPEGThread(Context_t *context) int32_t out_channels = 2; uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO; uint32_t cAVIdx = 0; + void *stamp = 0; #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100) +#ifdef __sh__ + Mpeg4P2Context *mpeg4p2_context = NULL; +#else Mpeg4P2Context *mpeg4p2_context = mpeg4p2_context_open(); #endif +#endif #ifdef HAVE_FLV2MPEG4_CONVERTER Flv2Mpeg4Context flv2mpeg4_context; memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context)); @@ -581,11 +643,9 @@ static void FFMPEGThread(Context_t *context) } ffmpeg_printf(10, "Running!\n"); -#ifdef __sh__ uint32_t bufferSize = 0; context->output->Command(context, OUTPUT_GET_BUFFER_SIZE, &bufferSize); ffmpeg_printf(10, "bufferSize [%u]\n", bufferSize); -#endif int8_t isWaitingForFinish = 0; @@ -595,11 +655,11 @@ static void FFMPEGThread(Context_t *context) * we will not wait here because we can still fill * DVB drivers buffers at PAUSE time * - * In the future we can add buffering queue before injection in to - * AUDIO, VIDEO decoders, so we can not wait here */ #ifdef __sh__ - //IF MOVIE IS PAUSED, WAIT + /* ST DVB drivers skip data if they are written during pause + * so, we must wait here if there is not buffering queue + */ if (0 == bufferSize && context->playback->isPaused) { ffmpeg_printf(20, "paused\n"); @@ -704,6 +764,12 @@ static void FFMPEGThread(Context_t *context) } } reset_finish_timeout(); + /* + if (bufferSize > 0) + { + context->output->Command(context, OUTPUT_CLEAR, NULL); + } + */ } else { @@ -846,7 +912,7 @@ static void FFMPEGThread(Context_t *context) #endif #ifdef HAVE_FLV2MPEG4_CONVERTER if (get_codecpar(avContextTab[cAVIdx]->streams[packet.stream_index])->codec_id == AV_CODEC_ID_FLV1 && - 0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7)) + 0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7)) { flv2mpeg4_write_packet(context, &flv2mpeg4_context, videoTrack, cAVIdx, ¤tVideoPts, &latestPts, &packet); update_max_injected_pts(latestPts); @@ -967,7 +1033,9 @@ static void FFMPEGThread(Context_t *context) pcmExtradata.bits_per_coded_sample = get_codecpar(audioTrack->stream)->bits_per_coded_sample; pcmExtradata.sample_rate = get_codecpar(audioTrack->stream)->sample_rate; pcmExtradata.bit_rate = get_codecpar(audioTrack->stream)->bit_rate; - pcmExtradata.ffmpeg_codec_id = get_codecpar(audioTrack->stream)->codec_id; + pcmExtradata.block_align = get_codecpar(audioTrack->stream)->block_align; + pcmExtradata.frame_size = get_codecpar(audioTrack->stream)->frame_size; + pcmExtradata.codec_id = get_codecpar(audioTrack->stream)->codec_id; pcmExtradata.bResampling = restart_audio_resampling; uint8_t *pAudioExtradata = get_codecpar(audioTrack->stream)->extradata; @@ -1136,7 +1204,7 @@ static void FFMPEGThread(Context_t *context) if (e < 0) { ffmpeg_err("swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n", - -e, (int32_t)c->channel_layout, (int32_t)out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16); + -e, (int32_t)c->channel_layout, (int32_t)out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16); swr_free(&swr); swr = NULL; } @@ -1152,11 +1220,11 @@ static void FFMPEGThread(Context_t *context) continue; } 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); + ((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), - ((AVStream *) audioTrack->stream)->time_base.den, - ((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate); + ((AVStream *) audioTrack->stream)->time_base.den, + ((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate); currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, next_out_pts); out_samples = swr_convert(swr, &output[0], out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples); @@ -1168,9 +1236,9 @@ static void FFMPEGThread(Context_t *context) pcmExtradata.sample_rate = out_sample_rate; // The data described by the sample format is always in native-endian order #ifdef WORDS_BIGENDIAN - pcmExtradata.ffmpeg_codec_id = AV_CODEC_ID_PCM_S16BE; + pcmExtradata.codec_id = AV_CODEC_ID_PCM_S16BE; #else - pcmExtradata.ffmpeg_codec_id = AV_CODEC_ID_PCM_S16LE; + pcmExtradata.codec_id = AV_CODEC_ID_PCM_S16LE; #endif ////////////////////////////////////////////////////////////////////// @@ -1215,6 +1283,27 @@ static void FFMPEGThread(Context_t *context) ffmpeg_err("(aac) writing data to audio device failed\n"); } } + else if (pcmExtradata.codec_id == AV_CODEC_ID_VORBIS || pcmExtradata.codec_id == AV_CODEC_ID_OPUS || + pcmExtradata.codec_id == AV_CODEC_ID_WMAV1 || pcmExtradata.codec_id == AV_CODEC_ID_WMAV2 || + pcmExtradata.codec_id == AV_CODEC_ID_WMAPRO || pcmExtradata.codec_id == AV_CODEC_ID_WMALOSSLESS) + { + avOut.data = packet.data; + avOut.len = packet.size; + avOut.pts = pts; + avOut.extradata = (uint8_t *) &pcmExtradata; + avOut.extralen = sizeof(pcmExtradata); + avOut.frameRate = 0; + avOut.timeScale = 0; + avOut.width = 0; + avOut.height = 0; + avOut.type = "audio"; + pcmExtradata.private_data = pAudioExtradata; + pcmExtradata.private_size = audioExtradataSize; + if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) + { + ffmpeg_err("writing data to audio device failed\n"); + } + } else { avOut.data = packet.data; @@ -1250,15 +1339,19 @@ static void FFMPEGThread(Context_t *context) // duration in milliseconds duration = (int64_t)av_rescale(get_packet_duration(&packet), (int64_t)stream->time_base.num * 1000, stream->time_base.den); } - - if (duration > 0) + if (duration > 0 || duration == -1) { SubtitleOut_t subOut; memset(&subOut, 0, sizeof(subOut)); - subOut.trackId = pid; - subOut.data = (uint8_t *)packet.data; - subOut.pts = pts; + subOut.trackId = pid; + subOut.data = (uint8_t *)packet.data; + subOut.len = packet.size; + subOut.pts = pts; subOut.durationMS = duration; + subOut.extradata = get_codecpar(stream)->extradata; + subOut.extralen = get_codecpar(stream)->extradata_size; + subOut.width = get_codecpar(stream)->width;; + subOut.height = get_codecpar(stream)->height;; if (Write(context->output->subtitle->Write, context, &subOut, pts) < 0) { ffmpeg_err("writing data to teletext fifo failed\n"); @@ -1281,7 +1374,7 @@ static void FFMPEGThread(Context_t *context) /* if(ffmpegStatus == AVERROR(EAGAIN)) { - continue; + continue; } */ ffmpegStatus = 0; @@ -1309,18 +1402,8 @@ static void FFMPEGThread(Context_t *context) int64_t tmpLength = 0; if (0 == container_ffmpeg_get_length(context, &tmpLength) && tmpLength > 0 && get_play_pts() > 0) { -#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING - if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) - { - seek_target_bytes = 0; - do_seek_target_bytes = 1; - } - else -#endif - { - seek_target_seconds = 0; - do_seek_target_seconds = 1; - } + seek_target_seconds = 0; + do_seek_target_seconds = 1; bEndProcess = 0; context->output->Command(context, OUTPUT_CLEAR, NULL); context->output->Command(context, OUTPUT_PLAY, NULL); @@ -1556,7 +1639,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin } #ifdef USE_CUSTOM_IO if (0 == strstr(filename, "://") || - 0 == strncmp(filename, "file://", 7)) + 0 == strncmp(filename, "file://", 7)) { AVIOContext *avio_ctx = NULL; custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t)); @@ -1608,11 +1691,11 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin } if (0 == strncmp(filename, "rtmp://", 7) || - 0 == strncmp(filename, "rtmpe://", 8) || - 0 == strncmp(filename, "rtmps://", 8) || - 0 == strncmp(filename, "rtmpt://", 8) || - 0 == strncmp(filename, "rtmpte://", 9) || - 0 == strncmp(filename, "rtmpts://", 9)) + 0 == strncmp(filename, "rtmpe://", 8) || + 0 == strncmp(filename, "rtmps://", 8) || + 0 == strncmp(filename, "rtmpt://", 8) || + 0 == strncmp(filename, "rtmpte://", 9) || + 0 == strncmp(filename, "rtmpts://", 9)) { /* At first we need to check which protocol * implementations we have @@ -1652,7 +1735,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin * only by librtmp */ if (strstr(filename, " token=") || - strstr(filename, " jtv=")) + strstr(filename, " jtv=")) { rtmpProtoImplType = RTMP_LIBRTMP; } @@ -1802,7 +1885,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin } } else if (0 == strncmp(filename, "http://", 7) || - 0 == strncmp(filename, "https://", 8)) + 0 == strncmp(filename, "https://", 8)) { char num[16]; @@ -1822,8 +1905,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin if (avContextTab[AVIdx] != NULL && ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0)) { if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN && - rtmpProtoImplType == RTMP_NATIVE && - numOfRTMPImpl > 1) + rtmpProtoImplType == RTMP_NATIVE && + numOfRTMPImpl > 1) { // retry with librtmp err = avformat_open_input(&avContextTab[AVIdx], filename + 2, fmt, pavio_opts); @@ -1836,7 +1919,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename); av_strerror(err, error, 512); - fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err); + E2iSendMsg("{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err); if (avio_opts != NULL) { @@ -1848,7 +1931,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin } if (avContextTab[AVIdx] != NULL) { -#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100) +#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 100) avContextTab[AVIdx]->iformat->flags |= AVFMT_SEEK_TO_PTS; #endif avContextTab[AVIdx]->flags = AVFMT_FLAG_GENPTS; @@ -1961,7 +2044,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) context->playback->abortRequested = 0; int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ - playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); + playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); if (0 != res) { @@ -1971,7 +2054,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames) if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0') { res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \ - playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); + playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); } if (0 != res) @@ -2029,7 +2112,6 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 if ((avContextTab[0] != NULL) && (FFMPEG_DEBUG_LEVEL > 0)) av_dump_format(avContextTab[0], 0, filename, 0); - uint32_t cAVIdx = 0; for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1) @@ -2142,9 +2224,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 } encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \ - (uint8_t *)get_codecpar(stream)->extradata, \ - (int)get_codecpar(stream)->extradata_size, \ - (int)get_codecpar(stream)->profile, &version); + (uint8_t *)get_codecpar(stream)->extradata, \ + (int)get_codecpar(stream)->extradata_size, \ + (int)get_codecpar(stream)->profile, &version); if (encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm) { @@ -2348,7 +2430,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC) { if (0 == strncmp(avContext->iformat->name, "mpegts", 6) || - 0 == strncmp(avContext->iformat->name, "hls,", 4)) + 0 == strncmp(avContext->iformat->name, "hls,", 4)) { const char marker[] = "ADTS"; track.aacbuflen = sizeof(marker) / sizeof(char); @@ -2381,15 +2463,16 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 int32_t object_type = 2; // LC int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate); - int32_t chan_config = get_codecpar(stream)->channels - 1; + int32_t chan_config = get_chan_config(get_codecpar(stream)->channels); ffmpeg_printf(1, "aac object_type %d\n", object_type); ffmpeg_printf(1, "aac sample_index %d\n", sample_index); ffmpeg_printf(1, "aac chan_config %d\n", chan_config); + int off = -1; if (get_codecpar(stream)->extradata_size >= 2) { MPEG4AudioConfig m4ac; - int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1); + off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1); if (off >= 0) { object_type = m4ac.object_type; @@ -2406,12 +2489,26 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_printf(1, "aac sample_index %d\n", sample_index); ffmpeg_printf(1, "aac chan_config %d\n", chan_config); + if (off >= 0 && chan_config == 0) // channel config must be send in the inband PCE + { + track.aacbuf = malloc(AAC_HEADER_LENGTH + MAX_PCE_SIZE); + GetBitContext gb; + PutBitContext pb; + init_put_bits(&pb, track.aacbuf + AAC_HEADER_LENGTH, MAX_PCE_SIZE); + init_get_bits8(&gb, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size); + skip_bits_long(&gb, off + 3); + put_bits(&pb, 3, 5); //ID_PCE + track.aacbuflen = AAC_HEADER_LENGTH + (avpriv_copy_pce_data(&pb, &gb) + 3) / 8; + flush_put_bits(&pb); + } + else + { + track.aacbuflen = AAC_HEADER_LENGTH; + track.aacbuf = malloc(AAC_HEADER_LENGTH + 1); + } // https://wiki.multimedia.cx/index.php/ADTS object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1 - - track.aacbuflen = AAC_HEADER_LENGTH; - track.aacbuf = malloc(8); track.aacbuf[0] = 0xFF; track.aacbuf[1] = 0xF1; //track.aacbuf[1] |=0x8; @@ -2432,46 +2529,34 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_err("AV_CODEC_ID_AAC extradata not available\n"); } */ - } +#ifdef __sh__ else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1 || - get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2 || - get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO || - get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0) + get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2 || + get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO || + get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0) { ffmpeg_printf(10, "Create WMA ExtraData\n"); - uint16_t channels = get_codecpar(stream)->channels; - uint32_t rate = get_codecpar(stream)->sample_rate; - uint32_t bitrate = get_codecpar(stream)->bit_rate; - uint16_t block_align = get_codecpar(stream)->block_align; - uint16_t depth = get_codecpar(stream)->bits_per_coded_sample; - uint32_t codec_data_size = get_codecpar(stream)->extradata_size; - uint8_t *codec_data_pointer = get_codecpar(stream)->extradata; - // type_specific_data -#define WMA_VERSION_1 0x160 -#define WMA_VERSION_2_9 0x161 -#define WMA_VERSION_9_PRO 0x162 -#define WMA_LOSSLESS 0x163 uint16_t codec_id = 0; switch (get_codecpar(stream)->codec_id) { //TODO: What code for lossless ? case AV_CODEC_ID_WMALOSSLESS: - codec_id = WMA_LOSSLESS; + codec_id = 0x163; // WMA_LOSSLESS break; case AV_CODEC_ID_WMAPRO: - codec_id = WMA_VERSION_9_PRO; + codec_id = 0x162; // WMA_VERSION_9_PRO break; case AV_CODEC_ID_WMAV2: - codec_id = WMA_VERSION_2_9 ; + codec_id = 0x161; // WMA_VERSION_2_9 break; case AV_CODEC_ID_WMAV1: default: - codec_id = WMA_VERSION_1; + codec_id = 0x160; // WMA_VERSION_1 break; } -#ifdef __sh__ + track.aacbuflen = 104 + get_codecpar(stream)->extradata_size; track.aacbuf = malloc(track.aacbuflen); memset(track.aacbuf, 0, track.aacbuflen); @@ -2539,48 +2624,10 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size); -#else - track.aacbuflen = 18 + get_codecpar(stream)->extradata_size; - track.aacbuf = malloc(track.aacbuflen); - memset(track.aacbuf, 0, track.aacbuflen); - - uint8_t *data = track.aacbuf; - /* codec tag */ - *(data++) = codec_id & 0xff; - *(data++) = (codec_id >> 8) & 0xff; - /* channels */ - *(data++) = channels & 0xff; - *(data++) = (channels >> 8) & 0xff; - /* sample rate */ - *(data++) = rate & 0xff; - *(data++) = (rate >> 8) & 0xff; - *(data++) = (rate >> 16) & 0xff; - *(data++) = (rate >> 24) & 0xff; - /* byte rate */ - bitrate /= 8; - *(data++) = bitrate & 0xff; - *(data++) = (bitrate >> 8) & 0xff; - *(data++) = (bitrate >> 16) & 0xff; - *(data++) = (bitrate >> 24) & 0xff; - /* block align */ - *(data++) = block_align & 0xff; - *(data++) = (block_align >> 8) & 0xff; - /* word size */ - *(data++) = depth & 0xff; - *(data++) = (depth >> 8) & 0xff; - /* codec data size */ - *(data++) = codec_data_size & 0xff; - *(data++) = (codec_data_size >> 8) & 0xff; - memcpy(data, codec_data_pointer, codec_data_size); -#endif ffmpeg_printf(1, "aacbuf:\n"); - //Hexdump(track.aacbuf, track.aacbuflen); - - //ffmpeg_printf(1, "priv_data:\n"); - //Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen); - track.have_aacheader = 1; } +#endif if (context->manager->audio) { @@ -2606,12 +2653,16 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 { if (get_codecpar(stream)->codec_id != AV_CODEC_ID_SSA && #if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100) - get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS && + get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS && #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_WEBVTT) + 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_WEBVTT && + ((get_codecpar(stream)->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE && + get_codecpar(stream)->codec_id != AV_CODEC_ID_DVB_SUBTITLE && + get_codecpar(stream)->codec_id != AV_CODEC_ID_XSUB) || + !GetGraphicSubPath() || !GetGraphicSubPath()[0])) { ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id); } @@ -2638,10 +2689,6 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32 ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n"); track.duration = (int64_t) avContext->duration / 1000; } - - track.extraData = get_codecpar(stream)->extradata; - track.extraSize = get_codecpar(stream)->extradata_size; - ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id); ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width); ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height); @@ -2868,101 +2915,6 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos) return cERR_CONTAINER_FFMPEG_NO_ERROR; } -#if 0 //unused -/* seeking relative to a given byteposition N seconds ->for reverse playback needed */ -static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec) -{ - Track_t *videoTrack = NULL; - Track_t *audioTrack = NULL; - Track_t *current = NULL; - seek_target_flag = 0; - - 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); - - if (videoTrack != NULL) - { - current = videoTrack; - } - else if (audioTrack != NULL) - { - current = audioTrack; - } - - if (current == NULL) - { - ffmpeg_err("no track avaibale to seek\n"); - return cERR_CONTAINER_FFMPEG_ERR; - } - - if (pos == -1) - { - pos = avio_tell(avContextTab[0]->pb); - } - - if (pts == -1) - { - pts = current->pts; - } - - if (sec < 0) - { - seek_target_flag |= AVSEEK_FLAG_BACKWARD; - } - - ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags); -#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING - if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) - { - if (avContextTab[0]->bit_rate) - { - sec *= avContextTab[0]->bit_rate / 8; - ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate); - } - else - { - sec *= 180000; - } - - pos += sec; - - if (pos < 0) - { - ffmpeg_err("end of file reached\n"); - releaseMutex(__FILE__, __FUNCTION__, __LINE__); - return cERR_CONTAINER_FFMPEG_END_OF_FILE; - } - - ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %f\n", pos, sec); - - seek_target_bytes = pos; - do_seek_target_bytes = 1; - - return pos; - } - else -#endif - { - sec += pts / 90000; - - if (sec < 0) - { - sec = 0; - } - - ffmpeg_printf(10, "2. seeking to position %" 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; - } - - releaseMutex(__FILE__, __FUNCTION__, __LINE__); - return cERR_CONTAINER_FFMPEG_NO_ERROR; -} -#endif - static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute) { Track_t *videoTrack = NULL; @@ -3038,50 +2990,8 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags); -#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING - if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT) - { - /* konfetti: for ts streams seeking frame per seconds does not work (why?). - * I take this algo partly from ffplay.c. - * - * seeking per HTTP does still not work very good. forward seeks everytime - * about 10 seconds, backward does not work. - */ - - getMutex(__FILE__, __FUNCTION__, __LINE__); - off_t pos = avio_tell(avContextTab[0]->pb); - releaseMutex(__FILE__, __FUNCTION__, __LINE__); - - ffmpeg_printf(10, "pos %" PRId64 " %lld\n", pos, avContextTab[0]->bit_rate); - - if (avContextTab[0]->bit_rate) - { - sec *= avContextTab[0]->bit_rate / 8; - ffmpeg_printf(10, "bit_rate %lld\n", avContextTab[0]->bit_rate); - } - else - { - sec *= 180000; - } - - pos = sec; - - if (pos < 0) - { - pos = 0; - } - - 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; - } - else -#endif - { - seek_target_seconds = sec; - do_seek_target_seconds = 1; - } + seek_target_seconds = sec; + do_seek_target_seconds = 1; return cERR_CONTAINER_FFMPEG_NO_ERROR; } @@ -3374,11 +3284,11 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen ffmpeg_printf(50, "Command %d\n", command); if (command != CONTAINER_SET_BUFFER_SEEK_TIME && - command != CONTAINER_SET_BUFFER_SIZE && - command != CONTAINER_GET_BUFFER_SIZE && - command != CONTAINER_GET_BUFFER_STATUS && - command != CONTAINER_STOP_BUFFER && - command != CONTAINER_INIT && !avContextTab[0]) + command != CONTAINER_SET_BUFFER_SIZE && + command != CONTAINER_GET_BUFFER_SIZE && + command != CONTAINER_GET_BUFFER_STATUS && + command != CONTAINER_STOP_BUFFER && + command != CONTAINER_INIT && !avContextTab[0]) { return cERR_CONTAINER_FFMPEG_ERR; } @@ -3476,7 +3386,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen return ret; } -static char *FFMPEG_Capabilities[] = {"aac", "avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv", "wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "ra", "ram", "rm", "3gp", "amr", "webm", "m3u8", "mpd", NULL }; +static char *FFMPEG_Capabilities[] = {"aac", "avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv", "wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "jpeg", "ra", "ram", "rm", "3gp", "amr", "rmvb", "rm", "webm", "opus", "m3u8", "mpd", NULL }; Container_t FFMPEGContainer = { diff --git a/libeplayer3/container/flv2mpeg4_ffmpeg.c b/libeplayer3/container/flv2mpeg4_ffmpeg.c index 51408fe..1a56b33 100644 --- a/libeplayer3/container/flv2mpeg4_ffmpeg.c +++ b/libeplayer3/container/flv2mpeg4_ffmpeg.c @@ -5,7 +5,6 @@ #include "flv2mpeg4/flv2mpeg4.h" - typedef struct { flv2mpeg4_CTX *ctx; @@ -16,7 +15,6 @@ typedef struct Track_t *track; } Flv2Mpeg4Context; - static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe __attribute__((unused)), int pts __attribute__((unused)), const uint8_t *buf, int size) { Flv2Mpeg4Context *ctx = usr_data; @@ -26,7 +24,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe __attr } AudioVideoOut_t avOut; - avOut.data = (char *)buf; + avOut.data = (unsigned char *)buf; avOut.len = size; avOut.pts = ctx->track->pts; avOut.dts = ctx->track->dts; diff --git a/libeplayer3/container/mpeg4p2_ffmpeg.c b/libeplayer3/container/mpeg4p2_ffmpeg.c index 0743f26..5f00493 100755 --- a/libeplayer3/container/mpeg4p2_ffmpeg.c +++ b/libeplayer3/container/mpeg4p2_ffmpeg.c @@ -126,7 +126,6 @@ static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Tra { ffmpeg_err("bsf setup failed error 0x%x\n", ret); } - } else { diff --git a/libeplayer3/container/wrapped_ffmpeg.c b/libeplayer3/container/wrapped_ffmpeg.c index 79ddc2c..1284b19 100644 --- a/libeplayer3/container/wrapped_ffmpeg.c +++ b/libeplayer3/container/wrapped_ffmpeg.c @@ -145,13 +145,13 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st avCodecCtx = avcodec_alloc_context3(NULL); if (!avCodecCtx) { - fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id); + ffmpeg_err("context3 alloc for stream %d failed\n", (int)stream->id); return NULL; } if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0) { - fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id); + ffmpeg_err("parameters to context for stream %d failed\n", (int)stream->id); avcodec_free_context(&avCodecCtx); return NULL; } diff --git a/libeplayer3/external/ffmpeg/get_bits.h b/libeplayer3/external/ffmpeg/get_bits.h index 61b476b..7f718e4 100644 --- a/libeplayer3/external/ffmpeg/get_bits.h +++ b/libeplayer3/external/ffmpeg/get_bits.h @@ -91,58 +91,54 @@ typedef struct GetBitContext */ #ifdef LONG_BITSTREAM_READER -# define MIN_CACHE_BITS 32 +#define MIN_CACHE_BITS 32 #else -# define MIN_CACHE_BITS 25 +#define MIN_CACHE_BITS 25 #endif #define OPEN_READER_NOSIZE(name, gb) \ unsigned int name ## _index = (gb)->index; \ unsigned int av_unused name ## _cache - #define OPEN_READER(name, gb) OPEN_READER_NOSIZE(name, gb) #define BITS_AVAILABLE(name, gb) 1 - #define CLOSE_READER(name, gb) (gb)->index = name ## _index # ifdef LONG_BITSTREAM_READER # define UPDATE_CACHE_LE(name, gb) name ## _cache = \ - AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + AV_RL64((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) # define UPDATE_CACHE_BE(name, gb) name ## _cache = \ - AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7)) + AV_RB64((gb)->buffer + (name ## _index >> 3)) >> (32 - (name ## _index & 7)) #else # define UPDATE_CACHE_LE(name, gb) name ## _cache = \ - AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) + AV_RL32((gb)->buffer + (name ## _index >> 3)) >> (name ## _index & 7) # define UPDATE_CACHE_BE(name, gb) name ## _cache = \ - AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7) + AV_RB32((gb)->buffer + (name ## _index >> 3)) << (name ## _index & 7) #endif - #ifdef BITSTREAM_READER_LE -# define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) +#define UPDATE_CACHE(name, gb) UPDATE_CACHE_LE(name, gb) -# define SKIP_CACHE(name, gb, num) name ## _cache >>= (num) +#define SKIP_CACHE(name, gb, num) name ## _cache >>= (num) #else -# define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb) +#define UPDATE_CACHE(name, gb) UPDATE_CACHE_BE(name, gb) -# define SKIP_CACHE(name, gb, num) name ## _cache <<= (num) +#define SKIP_CACHE(name, gb, num) name ## _cache <<= (num) #endif #define SKIP_COUNTER(name, gb, num) name ## _index += (num) - #define BITS_LEFT(name, gb) ((int)((gb)->size_in_bits - name ## _index)) #define SKIP_BITS(name, gb, num) \ @@ -160,11 +156,11 @@ typedef struct GetBitContext #define SHOW_SBITS_BE(name, gb, num) NEG_SSR32(name ## _cache, num) #ifdef BITSTREAM_READER_LE -# define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num) -# define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num) +#define SHOW_UBITS(name, gb, num) SHOW_UBITS_LE(name, gb, num) +#define SHOW_SBITS(name, gb, num) SHOW_SBITS_LE(name, gb, num) #else -# define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num) -# define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num) +#define SHOW_UBITS(name, gb, num) SHOW_UBITS_BE(name, gb, num) +#define SHOW_SBITS(name, gb, num) SHOW_SBITS_BE(name, gb, num) #endif #define GET_CACHE(name, gb) ((uint32_t) name ## _cache) @@ -388,8 +384,7 @@ static inline int check_marker(void *logctx __attribute__((unused)), GetBitConte * @param bit_size the size of the buffer in bits * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. */ -static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, - int bit_size) +static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, int bit_size) { int buffer_size; int ret = 0; @@ -420,8 +415,7 @@ static inline int init_get_bits(GetBitContext *s, const uint8_t *buffer, * @param byte_size the size of the buffer in bytes * @return 0 on success, AVERROR_INVALIDDATA if the buffer_size would overflow. */ -static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer, - int byte_size) +static inline int init_get_bits8(GetBitContext *s, const uint8_t *buffer, int byte_size) { if (byte_size > INT_MAX / 8 || byte_size < 0) byte_size = -1; @@ -474,7 +468,7 @@ static inline const uint8_t *align_get_bits(GetBitContext *s) } while (0) #define GET_RL_VLC(level, run, name, gb, table, bits, \ - max_depth, need_update) \ + max_depth, need_update) \ do { \ int n, nb_bits; \ unsigned int index; \ @@ -510,7 +504,6 @@ do { \ SKIP_BITS(name, gb, n); \ } while (0) - static inline int decode012(GetBitContext *gb) { int n; diff --git a/libeplayer3/external/ffmpeg/mathops.h b/libeplayer3/external/ffmpeg/mathops.h index d558e34..62909e5 100644 --- a/libeplayer3/external/ffmpeg/mathops.h +++ b/libeplayer3/external/ffmpeg/mathops.h @@ -26,11 +26,11 @@ #include #ifndef NEG_USR32 -# define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) +#define NEG_USR32(a,s) (((uint32_t)(a))>>(32-(s))) #endif #ifndef NEG_SSR32 -# define NEG_SSR32(a,s) (((int32_t)(a))>>(32-(s))) +#define NEG_SSR32(a,s) (((int32_t)(a))>>(32-(s))) #endif #ifndef sign_extend diff --git a/libeplayer3/external/ffmpeg/mpeg4audio.h b/libeplayer3/external/ffmpeg/mpeg4audio.h index cc617df..0f55ab0 100644 --- a/libeplayer3/external/ffmpeg/mpeg4audio.h +++ b/libeplayer3/external/ffmpeg/mpeg4audio.h @@ -53,8 +53,7 @@ extern const uint8_t ff_mpeg4audio_channels[8]; * @param[in] sync_extension look for a sync extension after config if true. * @return On error -1 is returned, on success AudioSpecificConfig bit index in extradata. */ -int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, - int bit_size, int sync_extension); +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int bit_size, int sync_extension); enum AudioObjectType { @@ -108,5 +107,6 @@ enum AudioObjectType /// s->size_in_bits); @@ -139,8 +137,7 @@ void avpriv_align_put_bits(PutBitContext *s); * * @param terminate_string 0-terminates the written string if value is 1 */ -void avpriv_put_string(PutBitContext *pb, const char *string, - int terminate_string); +void avpriv_put_string(PutBitContext *pb, const char *string, int terminate_string); /** * Copy the content of src to the bitstream. diff --git a/libeplayer3/external/ffmpeg/src/bitstream.c b/libeplayer3/external/ffmpeg/src/bitstream.c index b9c5b43..8cd922a 100644 --- a/libeplayer3/external/ffmpeg/src/bitstream.c +++ b/libeplayer3/external/ffmpeg/src/bitstream.c @@ -32,7 +32,6 @@ #include #include - void avpriv_align_put_bits(PutBitContext *s) { put_bits(s, s->bit_left & 7, 0); diff --git a/libeplayer3/external/ffmpeg/src/mpeg4audio.c b/libeplayer3/external/ffmpeg/src/mpeg4audio.c index 4ba0257..ad144c6 100644 --- a/libeplayer3/external/ffmpeg/src/mpeg4audio.c +++ b/libeplayer3/external/ffmpeg/src/mpeg4audio.c @@ -79,8 +79,22 @@ static inline int get_sample_rate(GetBitContext *gb, int *index) return *index == 0x0f ? (int)get_bits(gb, 24) : avpriv_mpeg4audio_sample_rates[*index]; } -int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, - int bit_size, int sync_extension) +uint8_t get_chan_config(int channels) +{ + uint8_t chan_config = 0; + unsigned int i; + for (i = 0; i < FF_ARRAY_ELEMS(ff_mpeg4audio_channels); i++) + { + if (channels == ff_mpeg4audio_channels[i]) + { + chan_config = i; + break; + } + } + return chan_config; +} + +int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, int bit_size, int sync_extension) { GetBitContext gb; int specific_config_bitindex, ret; @@ -100,8 +114,8 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, c->sbr = -1; c->ps = -1; if (c->object_type == AOT_SBR || (c->object_type == AOT_PS && - // check for W6132 Annex YYYY draft MP3onMP4 - !(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F)))) + // check for W6132 Annex YYYY draft MP3onMP4 + !(show_bits(&gb, 3) & 0x03 && !(show_bits(&gb, 9) & 0x3F)))) { if (c->object_type == AOT_PS) c->ps = 1; @@ -164,9 +178,7 @@ int avpriv_mpeg4audio_get_config(MPEG4AudioConfig *c, const uint8_t *buf, return specific_config_bitindex; } -static av_always_inline unsigned int copy_bits(PutBitContext *pb, - GetBitContext *gb, - int bits) +static av_always_inline unsigned int copy_bits(PutBitContext *pb, GetBitContext *gb, int bits) { unsigned int el = get_bits(gb, bits); put_bits(pb, bits, el); diff --git a/libeplayer3/external/flv2mpeg4/src/bitreader.h b/libeplayer3/external/flv2mpeg4/src/bitreader.h index 19799e0..5ae6e99 100644 --- a/libeplayer3/external/flv2mpeg4/src/bitreader.h +++ b/libeplayer3/external/flv2mpeg4/src/bitreader.h @@ -38,7 +38,7 @@ typedef struct _BR } BR; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -static void init_br(BR *p, const uint8 *buf, uint32 size) +static inline void init_br(BR *p, const uint8 *buf, uint32 size) { p->buf = buf; p->size = size; @@ -51,7 +51,7 @@ static uint8 get_u8(BR *p) return p->buf[p->read++]; } -static uint32 get_u24(BR *p) +static inline uint32 get_u24(BR *p) { uint32 a = get_u8(p); uint32 b = get_u8(p); @@ -60,7 +60,7 @@ static uint32 get_u24(BR *p) return (a << 16) | (b << 8) | c; } -static uint32 get_u32(BR *p) +static inline uint32 get_u32(BR *p) { uint32 a = get_u8(p); uint32 b = get_u8(p); @@ -70,12 +70,12 @@ static uint32 get_u32(BR *p) return (a << 24) | (b << 16) | (c << 8) | d; } -static int is_eob(BR *p) +static inline int is_eob(BR *p) { return p->read >= p->size; } -static void skip(BR *p, uint32 skip) +static inline void skip(BR *p, uint32 skip) { p->read += skip; } @@ -93,7 +93,7 @@ static uint32 show_bits(BR *p, uint32 bits) return tmp; } -static int32 show_sbits(BR *p, uint32 bits) +static inline int32 show_sbits(BR *p, uint32 bits) { const uint8 *pp; int32 tmp; @@ -106,7 +106,7 @@ static int32 show_sbits(BR *p, uint32 bits) return tmp; } -static void flash_bits(BR *p, uint32 bits) +static inline void flash_bits(BR *p, uint32 bits) { if (bits > 0) { @@ -116,21 +116,21 @@ static void flash_bits(BR *p, uint32 bits) } } -static uint32 get_bits(BR *p, uint32 bits) +static inline uint32 get_bits(BR *p, uint32 bits) { uint32 tmp = show_bits(p, bits); flash_bits(p, bits); return tmp; } -static int32 get_sbits(BR *p, uint32 bits) +static inline int32 get_sbits(BR *p, uint32 bits) { int32 tmp = show_sbits(p, bits); flash_bits(p, bits); return tmp; } -static void align_bits(BR *p) +static inline void align_bits(BR *p) { if (p->bitoffset > 0) { diff --git a/libeplayer3/external/flv2mpeg4/src/bitwriter.h b/libeplayer3/external/flv2mpeg4/src/bitwriter.h index 29f15a8..a11281f 100644 --- a/libeplayer3/external/flv2mpeg4/src/bitwriter.h +++ b/libeplayer3/external/flv2mpeg4/src/bitwriter.h @@ -144,7 +144,9 @@ static inline void m4v_stuffing(BW *p) put_bits(p, 1, 0); length = (- p->bitoffset) & 7; - if (length) put_bits(p, length, (1 << length) - 1); + + if (length) + put_bits(p, length, (1 << length) - 1); } #endif // BITWRITER_H diff --git a/libeplayer3/external/flv2mpeg4/src/dcprediction.c b/libeplayer3/external/flv2mpeg4/src/dcprediction.c index d2cf74d..98e1705 100644 --- a/libeplayer3/external/flv2mpeg4/src/dcprediction.c +++ b/libeplayer3/external/flv2mpeg4/src/dcprediction.c @@ -25,7 +25,6 @@ #include "dcprediction.h" - // M4V ADDED static const uint8 mpeg4_y_dc_scale_table[32] = { @@ -103,8 +102,10 @@ static inline int get_scale(M4V_DCPRED *pred, int n) ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// void dcpred_set_qscale(M4V_DCPRED *pred, int qscale) { - if (qscale < 0) qscale = 0; - if (qscale > 31) qscale = 31; + if (qscale < 0) + qscale = 0; + if (qscale > 31) + qscale = 31; pred->y_dc_scale = mpeg4_y_dc_scale_table[qscale]; pred->c_dc_scale = mpeg4_c_dc_scale_table[qscale]; } diff --git a/libeplayer3/external/flv2mpeg4/src/dcprediction.h b/libeplayer3/external/flv2mpeg4/src/dcprediction.h index 936b741..0384ae3 100644 --- a/libeplayer3/external/flv2mpeg4/src/dcprediction.h +++ b/libeplayer3/external/flv2mpeg4/src/dcprediction.h @@ -39,8 +39,6 @@ typedef struct _M4V_DCPRED int y_dc_scale; int c_dc_scale; - - } M4V_DCPRED; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// diff --git a/libeplayer3/external/flv2mpeg4/src/flv.h b/libeplayer3/external/flv2mpeg4/src/flv.h index e2f08ce..22874b3 100644 --- a/libeplayer3/external/flv2mpeg4/src/flv.h +++ b/libeplayer3/external/flv2mpeg4/src/flv.h @@ -65,7 +65,6 @@ typedef struct _PICTURE int width; int height; - #define FLV_I_TYPE 0 #define FLV_P_TYPE 1 @@ -157,5 +156,4 @@ static const int8 rl_inter_run[102] = static const int rl_inter_n = 102; static const int rl_inter_last = 58; - #endif // FLV_H diff --git a/libeplayer3/external/flv2mpeg4/src/flv2mpeg4.c b/libeplayer3/external/flv2mpeg4/src/flv2mpeg4.c index d35d4ab..86efac0 100644 --- a/libeplayer3/external/flv2mpeg4/src/flv2mpeg4.c +++ b/libeplayer3/external/flv2mpeg4/src/flv2mpeg4.c @@ -41,7 +41,6 @@ typedef struct _CONVCTX M4V_VOL vol; } CONVCTX; - typedef struct { uint8 *out_buf; @@ -65,7 +64,6 @@ static const uint8 ff_mpeg4_c_dc_scale_table[32] = 0, 8, 8, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 16, 17, 17, 18, 18, 19, 20, 21, 22, 23, 24, 25 }; - static void copy_vol(PICTURE *flv_pic, M4V_VOL *vol) { vol->width = flv_pic->width; @@ -122,7 +120,7 @@ static void copy_microblock(MICROBLOCK *flv_mb, M4V_MICROBLOCK *m4v_mb) } } -static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw, uint32 time) +static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw, int time) { // if any timecode padding is needed, then pad. while (c->frame * 1000 / 30 < time) @@ -139,10 +137,10 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw // write frame if (pub_ctx->write_packet_cb(pub_ctx->usr_data, - 0, - 0,//c->frame, - bw->buf, - bw->pos) < 0) + 0, + 0,//c->frame, + bw->buf, + bw->pos) < 0) { return -1; } @@ -156,7 +154,7 @@ static int write_pad_not_coded_frames(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BW *bw return 0; } -static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, PICTURE *flvpic, uint32 time) +static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, PICTURE *flvpic, uint32 time __attribute__((unused))) { MICROBLOCK mb; M4V_VOP vop; @@ -181,7 +179,8 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B if (vop.picture_type == M4V_I_TYPE) { mb.intra = 1; - if (decode_I_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) return -1; + if (decode_I_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) + return -1; m4v_mb.qscale = vop.qscale; copy_microblock(&mb, &m4v_mb); m4v_encode_I_dcpred(&m4v_mb, &c->vol.dcpred, x, y); @@ -189,7 +188,8 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B } else { - if (decode_P_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) return -1; + if (decode_P_mb(br, &mb, flvpic->escape_type, flvpic->qscale) < 0) + return -1; m4v_mb.qscale = vop.qscale; copy_microblock(&mb, &m4v_mb); m4v_encode_I_dcpred(&m4v_mb, &c->vol.dcpred, x, y); @@ -203,10 +203,10 @@ static int write_m4v_picture_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, B // write frame if (pub_ctx->write_packet_cb(pub_ctx->usr_data, - vop.picture_type == M4V_I_TYPE, - 0,//c->frame, - bw->buf, - bw->pos) < 0) + vop.picture_type == M4V_I_TYPE, + 0,//c->frame, + bw->buf, + bw->pos) < 0) { return -1; } @@ -223,10 +223,10 @@ static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, u memset(&picture, 0, sizeof(picture)); init_dcpred(&c->vol.dcpred); - - if (decode_picture_header(br, &picture) < 0) return -1; - if (c->width != picture.width || c->height != picture.height) return -1; //size changed.. - + if (decode_picture_header(br, &picture) < 0) + return -1; + if (c->width != picture.width || c->height != picture.height) + return -1; //size changed.. copy_vol(&picture, &c->vol); if (picture.picture_type == FLV_I_TYPE) @@ -235,7 +235,8 @@ static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, u } else { - if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) return -1; + if (write_pad_not_coded_frames(pub_ctx, c, bw, time) < 0) + return -1; } if (write_m4v_picture_frame(pub_ctx, c, br, bw, &picture, time) < 0) @@ -246,7 +247,7 @@ static int write_m4v_frame(flv2mpeg4_CTX *pub_ctx, CONVCTX *c, BR *br, BW *bw, u return 0; } -int flv2mpeg4_process_flv_packet(flv2mpeg4_CTX *ctx, uint8 picture_type, const uint8 *buf, uint32 size, uint32 time) +int flv2mpeg4_process_flv_packet(flv2mpeg4_CTX *ctx, uint8 picture_type __attribute__((unused)), const uint8 *buf, uint32 size, uint32 time) { CTX *p = ctx->priv; BR br; @@ -320,5 +321,3 @@ void flv2mpeg4_release_ctx(flv2mpeg4_CTX **pub_ctx) *pub_ctx = NULL; } - - diff --git a/libeplayer3/external/flv2mpeg4/src/flvdecoder.c b/libeplayer3/external/flv2mpeg4/src/flvdecoder.c index 3f5eeb2..2a3cb9b 100644 --- a/libeplayer3/external/flv2mpeg4/src/flvdecoder.c +++ b/libeplayer3/external/flv2mpeg4/src/flvdecoder.c @@ -38,7 +38,6 @@ static const uint8 zig_zag_scan[64] = 58, 59, 52, 45, 38, 31, 39, 46, 53, 60, 61, 54, 47, 55, 62, 63 }; - static const VLCtab vlc_table_intra_MCBPC[] = //: table_size=72 table_allocated=128 bits=6 { {64, -3}, @@ -128,7 +127,6 @@ static const VLCtab vlc_table_rl_inter[] = //: table_size=554 table_allocated=10 {100, 3}, {101, 3}, {8, 1}, {7, 1} }; - static const VLCtab vlc_table_mv[] = //mv_vlc: table_size=538 table_allocated=1024 bits=9 { {512, -3}, {520, -2}, {524, -1}, {526, -1}, {528, -1}, {530, -1}, {532, -1}, {534, -1}, {536, -1}, {10, 9}, @@ -182,7 +180,9 @@ static inline int decode_DC(BR *p) printf("illigal dc\n"); return -1; } - if (level == 255) level = 128; + + if (level == 255) + level = 128; // printf("DC: %d\n", level); return level; @@ -225,7 +225,9 @@ static inline int decode_AC(BR *p, BLOCK *block, int escape_type, int i) run = get_bits(p, 6); level = get_bits(p, 8); sign = level >= 128; - if (sign) level = 256 - level; + + if (sign) + level = 256 - level; } } else @@ -235,7 +237,9 @@ static inline int decode_AC(BR *p, BLOCK *block, int escape_type, int i) last = code >= rl_inter_last; sign = get_bits(p, 1); - if (sign) level = -level; + + if (sign) + level = -level; } i += run; @@ -245,7 +249,9 @@ static inline int decode_AC(BR *p, BLOCK *block, int escape_type, int i) return -1; } block->block[zig_zag_scan[i]] = level; - if (last) break; + + if (last) + break; i++; } @@ -270,7 +276,9 @@ static inline int decode_intra_block(BR *p, BLOCK *block, int escape_type, int c return 0; } - if (decode_AC(p, block, escape_type, 1) < 0) return -1; + if (decode_AC(p, block, escape_type, 1) < 0) + return -1; + return 0; } @@ -283,7 +291,9 @@ static inline int decode_inter_block(BR *p, BLOCK *block, int escape_type, int c return 0; } - if (decode_AC(p, block, escape_type, 0) < 0) return -1; + if (decode_AC(p, block, escape_type, 0) < 0) + return -1; + return 0; } @@ -293,7 +303,8 @@ static inline int get_intra_MCBPC(BR *br) do { cbpc = get_vlc(br, vlc_table_intra_MCBPC, 6, 2); - if (cbpc < 0) return -1; + if (cbpc < 0) + return -1; } while (cbpc == 8); return cbpc; @@ -309,7 +320,8 @@ static inline int get_inter_MCBPC(BR *br) return -2; } cbpc = get_vlc(br, vlc_table_inter_MCBPC, 7, 2); - if (cbpc < 0) return -1; + if (cbpc < 0) + return -1; } while (cbpc == 20); @@ -375,7 +387,8 @@ static inline int decode_intra_mb_internal(BR *p, MICROBLOCK *mb, int escape_typ for (i = 0; i < 6; i++) { - if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; + if (decode_intra_block(p, &mb->block[i], escape_type, cbp & 32) != 0) + return -1; cbp += cbp; } @@ -423,7 +436,8 @@ static inline int decode_inter_mb_internal(BR *p, MICROBLOCK *mb, int escape_typ for (i = 0; i < 6; i++) { - if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) return -1; + if (decode_inter_block(p, &mb->block[i], escape_type, cbp & 32) != 0) + return -1; cbp += cbp; } @@ -496,14 +510,12 @@ int decode_picture_header(BR *p, PICTURE *picture) if (get_bits(p, 17) != 1) { - fprintf(stderr, "start code error\n"); return -1; } tmp = get_bits(p, 5); if (tmp != 0 && tmp != 1) { - fprintf(stderr, "picture format error\n"); return -1; } @@ -537,7 +549,6 @@ int decode_picture_header(BR *p, PICTURE *picture) width = 160, height = 120; break; default: - fprintf(stderr, "size error\n"); return -1; } diff --git a/libeplayer3/external/flv2mpeg4/src/m4v.h b/libeplayer3/external/flv2mpeg4/src/m4v.h index df5fd2e..73369fc 100644 --- a/libeplayer3/external/flv2mpeg4/src/m4v.h +++ b/libeplayer3/external/flv2mpeg4/src/m4v.h @@ -134,6 +134,5 @@ static const uint8 alternate_vertical_scan[64] = 38, 46, 54, 62, 39, 47, 55, 63, }; - #endif // M4V_H diff --git a/libeplayer3/external/flv2mpeg4/src/m4vencode.c b/libeplayer3/external/flv2mpeg4/src/m4vencode.c index 234669e..7dcfb85 100644 --- a/libeplayer3/external/flv2mpeg4/src/m4vencode.c +++ b/libeplayer3/external/flv2mpeg4/src/m4vencode.c @@ -62,8 +62,8 @@ static const uint32 vlce_inter_MCBPC_bits[28] = ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// static inline void encode_DC(BW *p, int level, int n) { - if (level < -255 || level > 255) printf("dc overflow\n"); - + if (level < -255 || level > 255) + printf("dc overflow\n"); #if 1 level += 256; if (n < 4) @@ -75,7 +75,6 @@ static inline void encode_DC(BW *p, int level, int n) put_bits(p, uni_DCtab_chrom_len[level], uni_DCtab_chrom_bits[level]); } #else - int size, v; /* find number of bits */ size = 0; @@ -106,17 +105,15 @@ static inline void encode_DC(BW *p, int level, int n) if (size > 8) put_bits(p, 1, 1); } - #endif - } static inline void encode_escape_3(BW *p, int last, int run, int level) { #if 0 put_bits(p, - 7 + 2 + 1 + 6 + 1 + 12 + 1, //30bit - (3 << 23) + (3 << 21) + (last << 20) + (run << 14) + (1 << 13) + (((level - 64) & 0xfff) << 1) + 1); + 7 + 2 + 1 + 6 + 1 + 12 + 1, //30bit + (3 << 23) + (3 << 21) + (last << 20) + (run << 14) + (1 << 13) + (((level - 64) & 0xfff) << 1) + 1); #else put_bits(p, 7, 3); // escape put_bits(p, 2, 3); // escape3 @@ -271,10 +268,7 @@ esc3: last_non_zero = i; } } - #endif - - } static inline void encode_intra_block(BW *bw, M4V_BLOCK *block, int n) @@ -312,7 +306,6 @@ static inline void encode_inter_8x8_MCBPC(BW *bw, int cbpc) put_bits(bw, vlce_inter_MCBPC_bits[cbpc + 16], vlce_inter_MCBPC_code[cbpc + 16]); } - // same as H.263 static inline void encode_cbpy(BW *bw, int cbpy) { @@ -340,7 +333,6 @@ static inline void encode_motion(BW *bw, VLCDEC *mv_x, VLCDEC *mv_y) { put_bits(bw, mv_x->bits_ex - 1, mv_x->value_ex >> 1); } - } put_vlcdec(bw, mv_y); if (mv_y->bits_ex) @@ -371,7 +363,8 @@ static inline void encode_mb_inter_internal(BW *bw, M4V_MICROBLOCK *mb) cbpy = cbp >> 2; cbpy ^= 0xF; - if (mb->dquant) cbpc += 8; + if (mb->dquant) + cbpc += 8; switch (mb->mv_type) { @@ -414,12 +407,16 @@ static inline void encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int ifra cbpc = cbp & 3; if (iframe) { - if (mb->dquant) cbpc += 4; + if (mb->dquant) + cbpc += 4; + encode_intra_I_MCBPC(bw, cbpc); } else { - if (mb->dquant) cbpc += 8; + if (mb->dquant) + cbpc += 8; + encode_intra_P_MCBPC(bw, cbpc); } @@ -430,7 +427,6 @@ static inline void encode_mb_intra_internal(BW *bw, M4V_MICROBLOCK *mb, int ifra encode_cbpy(bw, cbpy); encode_dquant(bw, mb->dquant); - for (i = 0; i < 6; i++) { encode_intra_block(bw, &mb->block[i], i); @@ -482,7 +478,9 @@ static inline int encode_vol_header(BW *p, M4V_VOL *vol) put_bits(p, 2, 0); // shape_type put_bits(p, 1, 1); // marker - if (vol->time_bits != 5) return -1; // for vop_time_increment_resolution = 30 + if (vol->time_bits != 5) + return -1; // for vop_time_increment_resolution = 30 + put_bits(p, 16, 30); // *** vop_time_increment_resolution = 30 put_bits(p, 1, 1); // marker @@ -520,7 +518,6 @@ static inline int encode_vop_header(BW *p, M4V_VOP *vop, int time_bits, int vop_ put_bits(p, 2, vop->picture_type); - // printf("not_code:%d vop_time: %d\n", vop_not_coded, vop->time); // printf("pic:%d icount:%d vop_time: %d\n", vop->picture_type, time_incr, vop->time); @@ -619,7 +616,7 @@ static inline int encode_user_header(BW *p) } ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// -void m4v_encode_m4v_header(BW *bw, M4V_VOL *vol, uint32 time) +void m4v_encode_m4v_header(BW *bw, M4V_VOL *vol, uint32 time __attribute__((unused))) { encode_vo_header(bw); encode_vol_header(bw, vol); diff --git a/libeplayer3/include/aac.h b/libeplayer3/include/aac.h index 33f32fd..e045862 100644 --- a/libeplayer3/include/aac.h +++ b/libeplayer3/include/aac.h @@ -25,7 +25,7 @@ static inline int HasADTSHeader(uint8_t *data, int size) { if (size >= AAC_HEADER_LENGTH && 0xFF == data[0] && 0xF0 == (0xF0 & data[1]) && - size == ((data[3] & 0x3) << 11 | data[4] << 3 | data[5] >> 5)) + size == ((data[3] & 0x3) << 11 | data[4] << 3 | data[5] >> 5)) { return 1; } diff --git a/libeplayer3/include/bcm_ioctls.h b/libeplayer3/include/bcm_ioctls.h index af7b38b..33052af 100644 --- a/libeplayer3/include/bcm_ioctls.h +++ b/libeplayer3/include/bcm_ioctls.h @@ -52,9 +52,12 @@ typedef enum STREAMTYPE_DIVX311 = 13, STREAMTYPE_DIVX4 = 14, STREAMTYPE_DIVX5 = 15, - STREAMTYPE_VB6 = 18, + STREAMTYPE_VB6 = 18, /* 17 is also valid for ZGEMMA STBs*/ STREAMTYPE_SPARK = 21, - STREAMTYPE_MJPEG = 30 + STREAMTYPE_MJPEG = 30, + STREAMTYPE_RV30 = 31, /* rv30: RealVideo 8, suspected to based largely on an early draft of H.264 (included with RealPlayer 8)*/ + STREAMTYPE_RV40 = 32, /* RealVideo 9, RealVideo 10*/ + STREAMTYPE_AVS2 = 40 } video_stream_type_t; typedef enum @@ -73,6 +76,8 @@ typedef enum AUDIOTYPE_WMA_PRO = 0x21, AUDIOTYPE_AC3_PLUS = 0x22, AUDIOTYPE_AMR = 0x23, + AUDIOTYPE_OPUS = 0x24, + AUDIOTYPE_VORBIS = 0x25, AUDIOTYPE_RAW = 0x30 } audio_stream_type_t; diff --git a/libeplayer3/include/common.h b/libeplayer3/include/common.h index 993f5b6..cae5873 100644 --- a/libeplayer3/include/common.h +++ b/libeplayer3/include/common.h @@ -31,4 +31,12 @@ typedef struct Context_s int container_ffmpeg_update_tracks(Context_t *context, char *filename, int initial); +const char *GetGraphicSubPath(); +int32_t GetGraphicWindowWidth(); +int32_t GetGraphicWindowHeight(); + +void E2iSendMsg(const char *format, ...); +void E2iStartMsg(void); +void E2iEndMsg(void); + #endif diff --git a/libeplayer3/include/debug.h b/libeplayer3/include/debug.h index 191ef27..89e7f56 100644 --- a/libeplayer3/include/debug.h +++ b/libeplayer3/include/debug.h @@ -545,3 +545,39 @@ #else #define mjpeg_err(...) #endif + +/******************************************* + * bcma + *******************************************/ +#define BCMA_DEBUG_LEVEL 0 +#define BCMA_SILENT + +#if BCMA_DEBUG_LEVEL +#define bcma_printf(...) log_printf(BCMA_DEBUG_LEVEL, __VA_ARGS__) +#else +#define bcma_printf(...) +#endif + +#ifndef BCMA_SILENT +#define bcma_err(...) log_error(__VA_ARGS__) +#else +#define bcma_err(...) +#endif + +/******************************************* + * plugin + *******************************************/ +#define PLUGIN_DEBUG_LEVEL 0 +#define PLUGIN_SILENT + +#if PLUGIN_DEBUG_LEVEL +#define plugin_printf(...) log_printf(PLUGIN_DEBUG_LEVEL, __VA_ARGS__) +#else +#define plugin_printf(...) +#endif + +#ifndef PLUGIN_SILENT +#define plugin_err(...) log_error(__VA_ARGS__) +#else +#define plugin_err(...) +#endif diff --git a/libeplayer3/include/misc.h b/libeplayer3/include/misc.h index 5611ce2..ffce79d 100644 --- a/libeplayer3/include/misc.h +++ b/libeplayer3/include/misc.h @@ -64,16 +64,15 @@ static inline char *getExtension(char *name) static inline uint32_t ReadUint32(uint8_t *buffer) { uint32_t num = (uint32_t)buffer[0] << 24 | - (uint32_t)buffer[1] << 16 | - (uint32_t)buffer[2] << 8 | - (uint32_t)buffer[3]; + (uint32_t)buffer[1] << 16 | + (uint32_t)buffer[2] << 8 | + (uint32_t)buffer[3]; return num; } static inline uint16_t ReadUInt16(uint8_t *buffer) { - uint16_t num = (uint16_t)buffer[0] << 8 | - (uint16_t)buffer[1]; + uint16_t num = (uint16_t)buffer[0] << 8 | (uint16_t)buffer[1]; return num; } diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index f825bc4..88992fc 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -60,9 +60,16 @@ typedef struct uint8_t *data; uint32_t len; + uint8_t *extradata; + uint32_t extralen; + int64_t pts; + int64_t dts; int64_t durationMS; // duration in miliseconds + uint32_t width; + uint32_t height; + char *type; } SubtitleOut_t; diff --git a/libeplayer3/include/pcm.h b/libeplayer3/include/pcm.h index 96d98d7..b9f8698 100644 --- a/libeplayer3/include/pcm.h +++ b/libeplayer3/include/pcm.h @@ -31,6 +31,14 @@ typedef struct pcmPrivateData_s int32_t bits_per_coded_sample; int32_t sample_rate; int32_t bit_rate; - int32_t ffmpeg_codec_id; + + int32_t block_align; + int32_t frame_size; + + int32_t codec_id; + + uint8_t *private_data; + uint32_t private_size; } pcmPrivateData_t; + #endif diff --git a/libeplayer3/include/pes.h b/libeplayer3/include/pes.h index 5a6d149..5045b65 100644 --- a/libeplayer3/include/pes.h +++ b/libeplayer3/include/pes.h @@ -1,7 +1,7 @@ #ifndef pes_123 #define pes_123 -#define PES_HEADER_SIZE 9 ///< size of pes header +#define PES_HEADER_SIZE 9 ///< size of pes header #define PES_MAX_HEADER_SIZE (PES_HEADER_SIZE + 256) ///< maximal header size #define PES_PRIVATE_DATA_FLAG 0x80 #define PES_PRIVATE_DATA_LENGTH 8 @@ -13,10 +13,8 @@ #define PES_START_CODE_RESERVED_4 0xfd #define PES_VERSION_FAKE_START_CODE 0x31 - #define MAX_PES_PACKET_SIZE (65535) - /* start codes */ #define PCM_PES_START_CODE 0xbd #define PRIVATE_STREAM_1_PES_START_CODE 0xbd diff --git a/libeplayer3/include/stm_ioctls.h b/libeplayer3/include/stm_ioctls.h index 6212053..d6b0c6a 100644 --- a/libeplayer3/include/stm_ioctls.h +++ b/libeplayer3/include/stm_ioctls.h @@ -92,7 +92,6 @@ typedef enum VIDEO_ENCODING_PRIVATE } video_encoding_t; - /* * List of possible audio encodings - used to select frame parser and codec. */ @@ -199,93 +198,91 @@ typedef struct dvb_play_info_s typedef dvb_play_info_t video_play_info_t; typedef dvb_play_info_t audio_play_info_t; - typedef enum { -#define DVB_OPTION_VALUE_DISABLE 0 -#define DVB_OPTION_VALUE_ENABLE 1 +#define DVB_OPTION_VALUE_DISABLE 0 +#define DVB_OPTION_VALUE_ENABLE 1 - DVB_OPTION_TRICK_MODE_AUDIO = 0, - DVB_OPTION_PLAY_24FPS_VIDEO_AT_25FPS = 1, + DVB_OPTION_TRICK_MODE_AUDIO = 0, + DVB_OPTION_PLAY_24FPS_VIDEO_AT_25FPS = 1, -#define DVB_OPTION_VALUE_VIDEO_CLOCK_MASTER 0 -#define DVB_OPTION_VALUE_AUDIO_CLOCK_MASTER 1 -#define DVB_OPTION_VALUE_SYSTEM_CLOCK_MASTER 2 - DVB_OPTION_MASTER_CLOCK = 2, +#define DVB_OPTION_VALUE_VIDEO_CLOCK_MASTER 0 +#define DVB_OPTION_VALUE_AUDIO_CLOCK_MASTER 1 +#define DVB_OPTION_VALUE_SYSTEM_CLOCK_MASTER 2 + DVB_OPTION_MASTER_CLOCK = 2, - DVB_OPTION_EXTERNAL_TIME_MAPPING = 3, - DVB_OPTION_EXTERNAL_TIME_MAPPING_VSYNC_LOCKED = 31, - DVB_OPTION_AV_SYNC = 4, - DVB_OPTION_DISPLAY_FIRST_FRAME_EARLY = 5, - DVB_OPTION_VIDEO_BLANK = 6, - DVB_OPTION_STREAM_ONLY_KEY_FRAMES = 7, - DVB_OPTION_STREAM_SINGLE_GROUP_BETWEEN_DISCONTINUITIES = 8, - DVB_OPTION_CLAMP_PLAYBACK_INTERVAL_ON_PLAYBACK_DIRECTION_CHANGE = 9, + DVB_OPTION_EXTERNAL_TIME_MAPPING = 3, + DVB_OPTION_EXTERNAL_TIME_MAPPING_VSYNC_LOCKED = 31, + DVB_OPTION_AV_SYNC = 4, + DVB_OPTION_DISPLAY_FIRST_FRAME_EARLY = 5, + DVB_OPTION_VIDEO_BLANK = 6, + DVB_OPTION_STREAM_ONLY_KEY_FRAMES = 7, + DVB_OPTION_STREAM_SINGLE_GROUP_BETWEEN_DISCONTINUITIES = 8, + DVB_OPTION_CLAMP_PLAYBACK_INTERVAL_ON_PLAYBACK_DIRECTION_CHANGE = 9, -#define DVB_OPTION_VALUE_PLAYOUT 0 -#define DVB_OPTION_VALUE_DISCARD 1 - DVB_OPTION_PLAYOUT_ON_TERMINATE = 10, - DVB_OPTION_PLAYOUT_ON_SWITCH = 11, - DVB_OPTION_PLAYOUT_ON_DRAIN = 12, +#define DVB_OPTION_VALUE_PLAYOUT 0 +#define DVB_OPTION_VALUE_DISCARD 1 + DVB_OPTION_PLAYOUT_ON_TERMINATE = 10, + DVB_OPTION_PLAYOUT_ON_SWITCH = 11, + DVB_OPTION_PLAYOUT_ON_DRAIN = 12, - DVB_OPTION_VIDEO_ASPECT_RATIO = 13, - DVB_OPTION_VIDEO_DISPLAY_FORMAT = 14, + DVB_OPTION_VIDEO_ASPECT_RATIO = 13, + DVB_OPTION_VIDEO_DISPLAY_FORMAT = 14, -#define DVB_OPTION_VALUE_TRICK_MODE_AUTO 0 -#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_ALL 1 -#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_ALL_DEGRADE_NON_REFERENCE_FRAMES 2 -#define DVB_OPTION_VALUE_TRICK_MODE_START_DISCARDING_NON_REFERENCE_FRAMES 3 -#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_REFERENCE_FRAMES_DEGRADE_NON_KEY_FRAMES 4 -#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_KEY_FRAMES 5 -#define DVB_OPTION_VALUE_TRICK_MODE_DISCONTINUOUS_KEY_FRAMES 6 - DVB_OPTION_TRICK_MODE_DOMAIN = 15, +#define DVB_OPTION_VALUE_TRICK_MODE_AUTO 0 +#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_ALL 1 +#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_ALL_DEGRADE_NON_REFERENCE_FRAMES 2 +#define DVB_OPTION_VALUE_TRICK_MODE_START_DISCARDING_NON_REFERENCE_FRAMES 3 +#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_REFERENCE_FRAMES_DEGRADE_NON_KEY_FRAMES 4 +#define DVB_OPTION_VALUE_TRICK_MODE_DECODE_KEY_FRAMES 5 +#define DVB_OPTION_VALUE_TRICK_MODE_DISCONTINUOUS_KEY_FRAMES 6 + DVB_OPTION_TRICK_MODE_DOMAIN = 15, -#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_NEVER 0 -#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_ALWAYS 1 -#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_AFTER_SYNCHRONIZE 2 - DVB_OPTION_DISCARD_LATE_FRAMES = 16, - DVB_OPTION_VIDEO_START_IMMEDIATE = 17, - DVB_OPTION_REBASE_ON_DATA_DELIVERY_LATE = 18, - DVB_OPTION_REBASE_ON_FRAME_DECODE_LATE = 19, - DVB_OPTION_LOWER_CODEC_DECODE_LIMITS_ON_FRAME_DECODE_LATE = 20, - DVB_OPTION_H264_ALLOW_NON_IDR_RESYNCHRONIZATION = 21, - DVB_OPTION_MPEG2_IGNORE_PROGESSIVE_FRAME_FLAG = 22, - DVB_OPTION_AUDIO_SPDIF_SOURCE = 23, +#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_NEVER 0 +#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_ALWAYS 1 +#define DVB_OPTION_VALUE_DISCARD_LATE_FRAMES_AFTER_SYNCHRONIZE 2 + DVB_OPTION_DISCARD_LATE_FRAMES = 16, + DVB_OPTION_VIDEO_START_IMMEDIATE = 17, + DVB_OPTION_REBASE_ON_DATA_DELIVERY_LATE = 18, + DVB_OPTION_REBASE_ON_FRAME_DECODE_LATE = 19, + DVB_OPTION_LOWER_CODEC_DECODE_LIMITS_ON_FRAME_DECODE_LATE = 20, + DVB_OPTION_H264_ALLOW_NON_IDR_RESYNCHRONIZATION = 21, + DVB_OPTION_MPEG2_IGNORE_PROGESSIVE_FRAME_FLAG = 22, + DVB_OPTION_AUDIO_SPDIF_SOURCE = 23, - DVB_OPTION_H264_ALLOW_BAD_PREPROCESSED_FRAMES = 24, - DVB_OPTION_CLOCK_RATE_ADJUSTMENT_LIMIT_2_TO_THE_N_PARTS_PER_MILLION = 25, /* Value = N */ - DVB_OPTION_LIMIT_INPUT_INJECT_AHEAD = 26, + DVB_OPTION_H264_ALLOW_BAD_PREPROCESSED_FRAMES = 24, + DVB_OPTION_CLOCK_RATE_ADJUSTMENT_LIMIT_2_TO_THE_N_PARTS_PER_MILLION = 25, /* Value = N */ + DVB_OPTION_LIMIT_INPUT_INJECT_AHEAD = 26, -#define DVB_OPTION_VALUE_MPEG2_APPLICATION_MPEG2 0 -#define DVB_OPTION_VALUE_MPEG2_APPLICATION_ATSC 1 -#define DVB_OPTION_VALUE_MPEG2_APPLICATION_DVB 2 - DVB_OPTION_MPEG2_APPLICATION_TYPE = 27, +#define DVB_OPTION_VALUE_MPEG2_APPLICATION_MPEG2 0 +#define DVB_OPTION_VALUE_MPEG2_APPLICATION_ATSC 1 +#define DVB_OPTION_VALUE_MPEG2_APPLICATION_DVB 2 + DVB_OPTION_MPEG2_APPLICATION_TYPE = 27, -#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_DISABLED 0 -#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_HALF 1 -#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_QUARTER 2 - DVB_OPTION_DECIMATE_DECODER_OUTPUT = 28, +#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_DISABLED 0 +#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_HALF 1 +#define DVB_OPTION_VALUE_DECIMATE_DECODER_OUTPUT_QUARTER 2 + DVB_OPTION_DECIMATE_DECODER_OUTPUT = 28, - DVB_OPTION_PTS_FORWARD_JUMP_DETECTION_THRESHOLD = 29, - DVB_OPTION_H264_TREAT_DUPLICATE_DPB_AS_NON_REFERENCE_FRAME_FIRST = 30, + DVB_OPTION_PTS_FORWARD_JUMP_DETECTION_THRESHOLD = 29, + DVB_OPTION_H264_TREAT_DUPLICATE_DPB_AS_NON_REFERENCE_FRAME_FIRST = 30, - DVB_OPTION_PIXEL_ASPECT_RATIO_CORRECTION = 32, + DVB_OPTION_PIXEL_ASPECT_RATIO_CORRECTION = 32, DVB_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING = 33, - DVB_OPTION_PTS_SYMMETRIC_JUMP_DETECTION = 34, + DVB_OPTION_PTS_SYMMETRIC_JUMP_DETECTION = 34, - DVB_OPTION_ALLOW_FRAME_DISCARD_AT_NORMAL_SPEED = 35, + DVB_OPTION_ALLOW_FRAME_DISCARD_AT_NORMAL_SPEED = 35, /* OPTION_MAX must always be one greater than largest option - currently DVB_OPTION_ALLOW_FRAME_DISCARD_AT_NORMAL_SPEED */ - DVB_OPTION_MAX = 35 + DVB_OPTION_MAX = 35 } dvb_option_t; // Legacy typo correction #define DVP_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING DVB_OPTION_H264_FORCE_PIC_ORDER_CNT_IGNORE_DPB_DISPLAY_FRAME_ORDERING - typedef dvb_option_t video_option_t; /* Decoder commands */ @@ -296,7 +293,6 @@ typedef dvb_option_t video_option_t; #define VIDEO_CMD_SET_OPTION (4) #define VIDEO_CMD_GET_OPTION (5) - /* Flags for VIDEO_CMD_FREEZE */ #define VIDEO_CMD_FREEZE_TO_BLACK (1 << 0) diff --git a/libeplayer3/include/writer.h b/libeplayer3/include/writer.h index fddb15b..3eaf853 100644 --- a/libeplayer3/include/writer.h +++ b/libeplayer3/include/writer.h @@ -27,8 +27,6 @@ typedef struct WriteV_t WriteV; } WriterAVCallData_t; - - typedef struct WriterCaps_s { char *name; @@ -61,8 +59,9 @@ extern Writer_t WriterAudioDTS; extern Writer_t WriterAudioWMA; extern Writer_t WriterAudioWMAPRO; extern Writer_t WriterAudioFLAC; -extern Writer_t WriterAudioVORBIS; extern Writer_t WriterAudioAMR; +extern Writer_t WriterAudioVORBIS; +extern Writer_t WriterAudioOPUS; extern Writer_t WriterVideoMPEG1; extern Writer_t WriterVideoMPEG2; @@ -84,6 +83,9 @@ extern Writer_t WriterVideoVP9; extern Writer_t WriterVideoMJPEG; extern Writer_t WriterFramebuffer; extern Writer_t WriterPipe; +extern Writer_t WriterVideoRV30; +extern Writer_t WriterVideoRV40; +extern Writer_t WriterVideoAVS2; Writer_t *getWriter(char *encoding); @@ -96,4 +98,45 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx, co void FlushPipe(int pipefd); ssize_t WriteExt(WriteV_t _call, int fd, void *data, size_t size); + +// Subtitles + +typedef enum +{ + SUBTITLE_CODEC_ID_UNKNOWN, + SUBTITLE_CODEC_ID_SUBRIP, + SUBTITLE_CODEC_ID_ASS, + SUBTITLE_CODEC_ID_WEBVTT, + SUBTITLE_CODEC_ID_PGS, + SUBTITLE_CODEC_ID_DVB, + SUBTITLE_CODEC_ID_XSUB +} SubtitleCodecId_t; + +typedef struct +{ + SubtitleCodecId_t codecId; + uint32_t trackId; + uint8_t *data; + uint32_t len; + int64_t pts; + int64_t dts; + uint8_t *private_data; + uint32_t private_size; + + int64_t durationMS; // duration in miliseconds + + int width; + int height; +} WriterSubCallData_t; + +typedef struct SubWriter_s +{ + int32_t (* open)(SubtitleCodecId_t codecId, uint8_t *extradata, int extradata_size); + int32_t (* close)(); + int32_t (* reset)(); + int32_t (* write)(WriterSubCallData_t *); +} SubWriter_t; + +extern SubWriter_t WriterSubPGS; + #endif diff --git a/libeplayer3/main/exteplayer.c b/libeplayer3/main/exteplayer.c index 7067cfd..5699819 100644 --- a/libeplayer3/main/exteplayer.c +++ b/libeplayer3/main/exteplayer.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -54,6 +55,10 @@ extern void wma_software_decoder_set(const int32_t val); extern void ac3_software_decoder_set(const int32_t val); extern void eac3_software_decoder_set(const int32_t val); extern void mp3_software_decoder_set(const int32_t val); +extern void amr_software_decoder_set(const int32_t val); +extern void vorbis_software_decoder_set(const int32_t val); +extern void opus_software_decoder_set(const int32_t val); + extern void rtmp_proto_impl_set(const int32_t val); extern void flv2mpeg4_converter_set(const int32_t val); extern void sel_program_id_set(const int32_t val); @@ -91,6 +96,20 @@ static int g_pfd[2] = {-1, -1}; /* Used to wake terminate thread and kbhit */ static int isPlaybackStarted = 0; static pthread_mutex_t playbackStartMtx; +static int32_t g_windows_width = 1280; +static int32_t g_windows_height = 720; +static char *g_graphic_sub_path; + +int32_t GetGraphicWindowWidth() +{ + return g_windows_width; +} + +int32_t GetGraphicWindowHeight() +{ + return g_windows_height; +} + static void TerminateWakeUp() { int ret = write(g_pfd[1], "x", 1); @@ -102,7 +121,7 @@ static void TerminateWakeUp() static void *TermThreadFun(void *arg __attribute__((unused))) { - const char *socket_path = "/tmp/iptvplayer_extplayer_term_fd"; + const char *socket_path = "/tmp/.exteplayerterm.socket"; struct sockaddr_un addr; int fd = -1; int cl = -1; @@ -159,7 +178,6 @@ finish: close(cl); close(fd); pthread_exit(NULL); - } static void map_inter_file_path(char *filename) @@ -263,7 +281,8 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac int Id = -1; char *pch; char Name[] = " "; - fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]); + E2iStartMsg(); + E2iSendMsg("{\"%c_%c\": [", argvBuff[0], argvBuff[1]); for (i = 0; TrackList[i] != NULL; i += 2) { pch = strtok(TrackList[i], " "); @@ -278,19 +297,20 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac } if (0 < i) { - fprintf(stderr, ", "); + E2iSendMsg(", "); } - fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", Id, TrackList[i + 1], Name); + E2iSendMsg("{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", Id, TrackList[i + 1], Name); free(TrackList[i]); free(TrackList[i + 1]); } - fprintf(stderr, "]}\n"); + E2iSendMsg("]}\n"); + E2iEndMsg(); free(TrackList); } else { // not tracks - fprintf(stderr, "{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]); + E2iSendMsg("{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]); } break; } @@ -302,12 +322,12 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac { if ('a' == argvBuff[0] || 's' == argvBuff[0]) { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name); + E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name); } else // video { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \ - argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den); + E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \ + argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den); } free(track->Encoding); free(track->Name); @@ -318,11 +338,11 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac // no tracks if ('a' == argvBuff[0] || 's' == argvBuff[0]) { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", ""); + E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", ""); } else // video { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1); + E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1); } } break; @@ -373,7 +393,7 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac if (id >= 0 || (1 == ok && id == -1)) { commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal); + E2iSendMsg("{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal); } } break; @@ -383,132 +403,6 @@ static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbac return commandRetVal; } -#if 0 -static int HandleTracks(const Manager_t *ptrManager, const PlaybackCmd_t playbackSwitchCmd, const char *argvBuff) -{ - int commandRetVal = 0; - if (NULL == ptrManager || NULL == argvBuff || 2 != strnlen(argvBuff, 2)) - { - return -1; - } - switch (argvBuff[1]) - { - case 'l': - { - TrackDescription_t *TrackList = NULL; - ptrManager->Command(g_player, MANAGER_LIST, &TrackList); - if (NULL != TrackList) - { - int i = 0; - fprintf(stderr, "{\"%c_%c\": [", argvBuff[0], argvBuff[1]); - for (i = 0; TrackList[i].Id >= 0; ++i) - { - if (0 < i) - { - fprintf(stderr, ", "); - } - fprintf(stderr, "{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}", TrackList[i].Id, TrackList[i].Encoding, TrackList[i].Name); - free(TrackList[i].Encoding); - free(TrackList[i].Name); - } - fprintf(stderr, "]}\n"); - free(TrackList); - } - else - { - // not tracks - fprintf(stderr, "{\"%c_%c\": []}\n", argvBuff[0], argvBuff[1]); - } - break; - } - case 'c': - { - - TrackDescription_t *track = NULL; - ptrManager->Command(g_player, MANAGER_GET_TRACK_DESC, &track); - if (NULL != track) - { - if ('a' == argvBuff[0] || 's' == argvBuff[0]) - { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name); - } - else // video - { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d,\"an\":%d,\"ad\":%d}}\n", \ - argvBuff[0], argvBuff[1], track->Id, track->Encoding, track->Name, track->width, track->height, track->frame_rate, track->progressive, track->aspect_ratio_num, track->aspect_ratio_den); - } - free(track->Encoding); - free(track->Name); - free(track); - } - else - { - // no tracks - if ('a' == argvBuff[0] || 's' == argvBuff[0]) - { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\"}}\n", argvBuff[0], argvBuff[1], -1, "", ""); - } - else // video - { - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"e\":\"%s\",\"n\":\"%s\",\"w\":%d,\"h\":%d,\"f\":%u,\"p\":%d}}\n", argvBuff[0], argvBuff[1], -1, "", "", -1, -1, 0, -1); - } - } - break; - } - default: - { - /* switch command available only for audio and subtitle tracks */ - if ('a' == argvBuff[0] || 's' == argvBuff[0]) - { - int ok = 0; - int id = -1; - if ('i' == argvBuff[1]) - { - int idx = -1; - ok = sscanf(argvBuff + 2, "%d", &idx); - if (idx >= 0) - { - TrackDescription_t *TrackList = NULL; - ptrManager->Command(g_player, MANAGER_LIST, &TrackList); - if (NULL != TrackList) - { - int i = 0; - for (i = 0; TrackList[i].Id >= 0; ++i) - { - if (idx == i) - { - id = TrackList[i].Id; - } - free(TrackList[i].Encoding); - free(TrackList[i].Name); - } - free(TrackList); - } - } - else - { - id = idx; - } - } - else - { - ok = sscanf(argvBuff + 1, "%d", &id); - } - - if (id >= 0 || (1 == ok && id == -1)) - { - commandRetVal = g_player->playback->Command(g_player, playbackSwitchCmd, (void *)&id); - fprintf(stderr, "{\"%c_%c\":{\"id\":%d,\"sts\":%d}}\n", argvBuff[0], 's', id, commandRetVal); - } - } - break; - } - } - - return commandRetVal; -} -#endif - static void UpdateVideoTrack() { HandleTracks(g_player->manager->video, (PlaybackCmd_t) -1, "vc"); @@ -522,6 +416,23 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * { switch (c) { + case 'G': + g_graphic_sub_path = optarg; + break; + case 'W': + { + int val = atoi(optarg); + if (val) + g_windows_width = val; + break; + } + case 'H': + { + int val = atoi(optarg); + if (val) + g_windows_height = val; + break; + } case 'a': { int flag = atoi(optarg); @@ -534,6 +445,18 @@ static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int * printf("Software decoder will be used for EAC3 codec\n"); eac3_software_decoder_set(1); break; + case 'A': + printf("Software decoder will be used for AMR codec\n"); + amr_software_decoder_set(atoi(optarg)); + break; + case 'V': + printf("Software decoder will be used for VORBIS codec\n"); + vorbis_software_decoder_set(atoi(optarg)); + break; + case 'U': + printf("Software decoder will be used for OPUS codec\n"); + vorbis_software_decoder_set(atoi(optarg)); + break; case '3': printf("Software decoder will be used for AC3 codec\n"); ac3_software_decoder_set(1); @@ -704,7 +627,7 @@ int main(int argc, char *argv[]) int commandRetVal = -1; /* inform client that we can handle additional commands */ - fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 55); + E2iSendMsg("{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 68); PlayFiles_t playbackFiles; memset(&playbackFiles, 0x00, sizeof(playbackFiles)); @@ -718,7 +641,10 @@ int main(int argc, char *argv[]) printf("[-3] AC3 software decoding\n"); printf("[-d] DTS software decoding\n"); printf("[-m] MP3 software decoding\n"); - printf("[-w] WMA1, WMA2, WMA/PRO software decoding\n"); + printf("[-A 0|1] disable|enable AMR software decoding\n"); + printf("[-V 0|1] disable|enable VORBIS software decoding\n"); + printf("[-U 0|1] disable|enable AMR software decoding\n"); + printf("[-w] WMA2, WMA/PRO software decoding\n"); printf("[-l] software decoder use LPCM for injection (otherwise wav PCM will be used)\n"); printf("[-s] software decoding as stereo [downmix]\n"); #ifdef HAVE_FLV2MPEG4_CONVERTER @@ -742,6 +668,9 @@ int main(int argc, char *argv[]) printf("[-F path to additional file with moov atom data (used for mp4 playback in progressive download mode)\n"); printf("[-O moov atom offset in the original file (used for mp4 playback in progressive download mode)\n"); printf("[-S remote file size (used for mp4 playback in progressive download mode)\n"); + printf("[-G path (directory where graphic subtitles frames will be saved)\n"); + printf("[-W osd window width (width of the window used to scale graphic subtitle frame)\n"); + printf("[-H osd window height (height of the window used to scale graphic subtitle frame)\n"); exit(1); } @@ -808,7 +737,7 @@ int main(int argc, char *argv[]) } commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles); - fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, playbackFiles.szFirstFile, commandRetVal); + E2iSendMsg("{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, playbackFiles.szFirstFile, commandRetVal); if (commandRetVal < 0) { if (NULL != g_player) @@ -824,9 +753,9 @@ int main(int argc, char *argv[]) pthread_mutex_unlock(&playbackStartMtx); commandRetVal = g_player->output->Command(g_player, OUTPUT_OPEN, NULL); - fprintf(stderr, "{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal); + E2iSendMsg("{\"OUTPUT_OPEN\":{\"sts\":%d}}\n", commandRetVal); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PLAY, NULL); - fprintf(stderr, "{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal); + E2iSendMsg("{\"PLAYBACK_PLAY\":{\"sts\":%d}}\n", commandRetVal); if (g_player->playback->isPlaying) { @@ -887,19 +816,19 @@ int main(int argc, char *argv[]) case 'q': { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_STOP, NULL); - fprintf(stderr, "{\"PLAYBACK_STOP\":{\"sts\":%d}}\n", commandRetVal); + E2iSendMsg("{\"PLAYBACK_STOP\":{\"sts\":%d}}\n", commandRetVal); break; } case 'c': { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_CONTINUE, NULL); - fprintf(stderr, "{\"PLAYBACK_CONTINUE\":{\"sts\":%d}}\n", commandRetVal); + E2iSendMsg("{\"PLAYBACK_CONTINUE\":{\"sts\":%d}}\n", commandRetVal); break; } case 'p': { commandRetVal = g_player->playback->Command(g_player, PLAYBACK_PAUSE, NULL); - fprintf(stderr, "{\"PLAYBACK_PAUSE\":{\"sts\":%d}}\n", commandRetVal); + E2iSendMsg("{\"PLAYBACK_PAUSE\":{\"sts\":%d}}\n", commandRetVal); break; } case 'm': @@ -908,7 +837,7 @@ int main(int argc, char *argv[]) sscanf(argvBuff + 1, "%d", &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SLOWMOTION, &speed); - fprintf(stderr, "{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); + E2iSendMsg("{\"PLAYBACK_SLOWMOTION\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; } case 'o': @@ -917,7 +846,7 @@ int main(int argc, char *argv[]) if (1 == sscanf(argvBuff + 1, "%d", &flags)) { progressive_playback_set(flags); - fprintf(stderr, "{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags); + E2iSendMsg("{\"PROGRESSIVE_DOWNLOAD\":{\"flags\":%d, \"sts\":0}}\n", flags); } break; } @@ -927,7 +856,7 @@ int main(int argc, char *argv[]) sscanf(argvBuff + 1, "%d", &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTFORWARD, &speed); - fprintf(stderr, "{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); + E2iSendMsg("{\"PLAYBACK_FASTFORWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; } case 'b': @@ -936,7 +865,7 @@ int main(int argc, char *argv[]) sscanf(argvBuff + 1, "%d", &speed); commandRetVal = g_player->playback->Command(g_player, PLAYBACK_FASTBACKWARD, &speed); - fprintf(stderr, "{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); + E2iSendMsg("{\"PLAYBACK_FASTBACKWARD\":{\"speed\":%d, \"sts\":%d}}\n", speed, commandRetVal); break; } case 'g': @@ -951,8 +880,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\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); - + E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal); lengthInt = (int32_t)length; if (10 <= lengthInt || force) { @@ -963,7 +891,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\":%" PRId64 ", \"sts\":%d}}\n", sec, commandRetVal); + E2iSendMsg("{\"PLAYBACK_SEEK_ABS\":{\"sec\":%"PRId64", \"sts\":%d}}\n", sec, commandRetVal); } } break; @@ -985,13 +913,13 @@ int main(int argc, char *argv[]) if (0 == commandRetVal) { - fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 "}}\n", pts / 90); + E2iSendMsg("{\"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\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); + E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal); lengthInt = (int32_t)length; if (10 <= lengthInt || force) @@ -1015,7 +943,7 @@ int main(int argc, char *argv[]) } } commandRetVal = g_player->playback->Command(g_player, PLAYBACK_SEEK, (void *)&sec); - fprintf(stderr, "{\"PLAYBACK_SEEK\":{\"sec\":%" PRId64 ", \"sts\":%d}}\n", sec, commandRetVal); + E2iSendMsg("{\"PLAYBACK_SEEK\":{\"sec\":%"PRId64", \"sts\":%d}}\n", sec, commandRetVal); } break; } @@ -1023,7 +951,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\":%" PRId64 ", \"sts\":%d}}\n", length, commandRetVal); + E2iSendMsg("{\"PLAYBACK_LENGTH\":{\"length\":%"PRId64", \"sts\":%d}}\n", length, commandRetVal); break; } case 'j': @@ -1042,11 +970,11 @@ int main(int argc, char *argv[]) if (0 == commandRetVal && lastPts != INVALID_PTS_VALUE) { - fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 ",\"lms\":%" PRId64 "}}\n", pts / 90, lastPts / 90); + E2iSendMsg("{\"J\":{\"ms\":%"PRId64",\"lms\":%"PRId64"}}\n", pts / 90, lastPts / 90); } else { - fprintf(stderr, "{\"J\":{\"ms\":%" PRId64 "}}\n", pts / 90); + E2iSendMsg("{\"J\":{\"ms\":%"PRId64"}}\n", pts / 90); } } break; @@ -1056,11 +984,11 @@ int main(int argc, char *argv[]) PlaybackHandler_t *ptrP = g_player->playback; if (ptrP) { - fprintf(stderr, "{\"PLAYBACK_INFO\":{ \"isPlaying\":%s, \"isPaused\":%s, \"isForwarding\":%s, \"isSeeking\":%s, \"isCreationPhase\":%s,", \ - DUMP_BOOL(ptrP->isPlaying), DUMP_BOOL(ptrP->isPaused), DUMP_BOOL(ptrP->isForwarding), DUMP_BOOL(ptrP->isSeeking), DUMP_BOOL(ptrP->isCreationPhase)); - fprintf(stderr, "\"BackWard\":%d, \"SlowMotion\":%d, \"Speed\":%d, \"AVSync\":%d,", ptrP->BackWard, ptrP->SlowMotion, ptrP->Speed, ptrP->AVSync); - fprintf(stderr, " \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \ - DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested)); + E2iSendMsg("{\"PLAYBACK_INFO\":{ \"isPlaying\":%s, \"isPaused\":%s, \"isForwarding\":%s, \"isSeeking\":%s, \"isCreationPhase\":%s,", \ + DUMP_BOOL(ptrP->isPlaying), DUMP_BOOL(ptrP->isPaused), DUMP_BOOL(ptrP->isForwarding), DUMP_BOOL(ptrP->isSeeking), DUMP_BOOL(ptrP->isCreationPhase)); + E2iSendMsg("\"BackWard\":%d, \"SlowMotion\":%d, \"Speed\":%d, \"AVSync\":%d,", ptrP->BackWard, ptrP->SlowMotion, ptrP->Speed, ptrP->AVSync); + E2iSendMsg(" \"isVideo\":%s, \"isAudio\":%s, \"isSubtitle\":%s, \"isDvbSubtitle\":%s, \"isTeletext\":%s, \"mayWriteToFramebuffer\":%s, \"abortRequested\":%s }}\n", \ + DUMP_BOOL(ptrP->isVideo), DUMP_BOOL(ptrP->isAudio), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(0), DUMP_BOOL(ptrP->abortRequested)); } break; @@ -1074,12 +1002,11 @@ int main(int argc, char *argv[]) if (ptrP) { ptrP->isLoopMode = '1' == argvBuff[1] ? 1 : 0; - fprintf(stderr, "{\"N\":{ \"isLoop\":%s }}\n", DUMP_BOOL(ptrP->isLoopMode)); + E2iSendMsg("{\"N\":{ \"isLoop\":%s }}\n", DUMP_BOOL(ptrP->isLoopMode)); } } break; } - default: { break; diff --git a/libeplayer3/manager/audio.c b/libeplayer3/manager/audio.c index 5867982..ad2a376 100644 --- a/libeplayer3/manager/audio.c +++ b/libeplayer3/manager/audio.c @@ -153,45 +153,6 @@ static char **ManagerList(Context_t *context __attribute__((unused))) return tracklist; } -#if 0 -static TrackDescription_t *ManagerList(Context_t *context __attribute__((unused))) -{ - int i = 0; - TrackDescription_t *tracklist = NULL; - - audio_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); - if (Tracks != NULL) - { - tracklist = malloc(sizeof(TrackDescription_t) * ((TrackCount) + 1)); - - if (tracklist == NULL) - { - audio_mgr_err("%s::%s malloc failed\n", __FILE__, __FUNCTION__); - return NULL; - } - - int j = 0; - for (i = 0; i < TrackCount; ++i) - { - if (Tracks[i].pending || Tracks[i].Id < 0) - { - continue; - } - - tracklist[j].Id = Tracks[i].Id; - tracklist[j].Name = strdup(Tracks[i].Name); - tracklist[j].Encoding = strdup(Tracks[i].Encoding); - ++j; - } - - tracklist[j].Id = -1; - } - //audio_mgr_printf(10, "%s::%s return %p (%d - %d)\n", __FILE__, __FUNCTION__, tracklist, j, TrackCount); - - return tracklist; -} -#endif - static int ManagerDel(Context_t *context) { int i = 0; @@ -372,7 +333,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) return ret; } - struct Manager_s AudioManager = { "Audio", diff --git a/libeplayer3/manager/chapter.c b/libeplayer3/manager/chapter.c index 4fb1bdb..3dc181d 100644 --- a/libeplayer3/manager/chapter.c +++ b/libeplayer3/manager/chapter.c @@ -151,8 +151,7 @@ static char **ManagerList(Context_t *context __attribute__((unused))) tracklist[j] = NULL; } - chapter_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, - __FUNCTION__, tracklist, j, TrackCount); + chapter_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, __FUNCTION__, tracklist, j, TrackCount); return tracklist; } diff --git a/libeplayer3/manager/subtitle.c b/libeplayer3/manager/subtitle.c index be88eb6..85b3f39 100644 --- a/libeplayer3/manager/subtitle.c +++ b/libeplayer3/manager/subtitle.c @@ -23,6 +23,7 @@ #include #include +#include #include "manager.h" #include "common.h" @@ -32,7 +33,7 @@ /* Makros/Constants */ /* ***************************** */ -#define TRACKWRAP 20 +#define TRACKWRAP 10 /* Error Constants */ #define cERR_SUBTITLE_MGR_NO_ERROR 0 @@ -47,6 +48,7 @@ /* ***************************** */ static Track_t *Tracks = NULL; +static int TrackSlotCount = 0; static int TrackCount = 0; static int CurrentTrack = -1; //no as default. @@ -60,15 +62,26 @@ static int CurrentTrack = -1; //no as default. static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) { + int i = 0; subtitle_mgr_printf(10, "%s::%s %s %s %d\n", __FILE__, __FUNCTION__, track.Name, track.Encoding, track.Id); - if (Tracks == NULL) + if (TrackCount == TrackSlotCount) { - Tracks = malloc(sizeof(Track_t) * TRACKWRAP); - int i; - for (i = 0; i < TRACKWRAP; i++) + static Track_t *t; + t = realloc(Tracks, (TrackSlotCount + TRACKWRAP) * sizeof(Track_t)); + if (t) { - Tracks[i].Id = -1; + Tracks = t; + TrackSlotCount += TRACKWRAP; + for (i = TrackCount; i < TrackSlotCount; ++i) + { + Tracks[i].Id = -1; + } + } + else + { + subtitle_mgr_err("%s:%s realloc failed\n", __FILE__, __FUNCTION__); + return cERR_SUBTITLE_MGR_ERROR; } } @@ -78,8 +91,7 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) return cERR_SUBTITLE_MGR_ERROR; } - int i; - for (i = 0; i < TRACKWRAP; i++) + for (i = 0; i < TrackSlotCount; i++) { if (Tracks[i].Id == track.Id) { @@ -88,14 +100,14 @@ static int ManagerAdd(Context_t *context __attribute__((unused)), Track_t track) } } - if (TrackCount < TRACKWRAP) + if (TrackCount < TrackSlotCount) { copyTrack(&Tracks[TrackCount], &track); TrackCount++; } else { - subtitle_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TRACKWRAP); + subtitle_mgr_err("%s::%s TrackCount out if range %d - %d\n", __FILE__, __FUNCTION__, TrackCount, TrackSlotCount); return cERR_SUBTITLE_MGR_ERROR; } @@ -147,32 +159,33 @@ static char **ManagerList(Context_t *context __attribute__((unused))) return tracklist; } -static int ManagerDel(Context_t *context __attribute__((unused))) +static int ManagerDel(Context_t *context __attribute__((unused)), int32_t onlycurrent) { int i = 0; - subtitle_mgr_printf(10, "%s::%s\n", __FILE__, __FUNCTION__); - if (Tracks != NULL) + if (onlycurrent == 0) { - for (i = 0; i < TrackCount; i++) + if (Tracks != NULL) { - freeTrack(&Tracks[i]); + for (i = 0; i < TrackCount; i++) + { + freeTrack(&Tracks[i]); + } + free(Tracks); + Tracks = NULL; } - - free(Tracks); - Tracks = NULL; - } - else - { - subtitle_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); - return cERR_SUBTITLE_MGR_ERROR; + else + { + subtitle_mgr_err("%s::%s nothing to delete!\n", __FILE__, __FUNCTION__); + return cERR_SUBTITLE_MGR_ERROR; + } + TrackCount = 0; + TrackSlotCount = 0; + context->playback->isSubtitle = 0; } - TrackCount = 0; CurrentTrack = -1; -// context->playback->isSubtitle = 0; - subtitle_mgr_printf(10, "%s::%s return no error\n", __FILE__, __FUNCTION__); return cERR_SUBTITLE_MGR_NO_ERROR; @@ -272,19 +285,21 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } case MANAGER_SET: { - int i; + int i = 0; + int32_t requestedTrackId = *((int *)argument); subtitle_mgr_printf(20, "%s::%s MANAGER_SET id=%d\n", __FILE__, __FUNCTION__, *((int *)argument)); - if (*((int *)argument) < 0) + if (requestedTrackId == -1) { + // track id -1 mean disable subtitle CurrentTrack = -1; break; } for (i = 0; i < TrackCount; i++) { - if (Tracks[i].Id == *((int *)argument)) + if (Tracks[i].Id == requestedTrackId) { CurrentTrack = i; break; @@ -300,7 +315,14 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) } case MANAGER_DEL: { - ret = ManagerDel(context); + if (argument == NULL) + { + ret = ManagerDel(context, 0); + } + else + { + ret = ManagerDel(context, *((int *)argument)); + } break; } case MANAGER_INIT_UPDATE: diff --git a/libeplayer3/manager/video.c b/libeplayer3/manager/video.c index 4a21233..5bbf2ff 100644 --- a/libeplayer3/manager/video.c +++ b/libeplayer3/manager/video.c @@ -328,7 +328,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) return ret; } - struct Manager_s VideoManager = { "Video", diff --git a/libeplayer3/output/linuxdvb_buffering.c b/libeplayer3/output/linuxdvb_buffering.c index cfe53d5..426f7b6 100644 --- a/libeplayer3/output/linuxdvb_buffering.c +++ b/libeplayer3/output/linuxdvb_buffering.c @@ -54,6 +54,7 @@ typedef struct BufferingNode_s { uint32_t dataSize; OutputType_t dataType; + void *stamp; struct BufferingNode_s *next; } BufferingNode_t; @@ -71,6 +72,7 @@ static pthread_t bufferingThread; static pthread_mutex_t bufferingMtx; static pthread_cond_t bufferingExitCond; static pthread_cond_t bufferingDataConsumedCond; +static pthread_cond_t bufferingWriteFinishedCond; static pthread_cond_t bufferingdDataAddedCond; static bool hasBufferingThreadStarted = false; static BufferingNode_t *bufferingQueueHead = NULL; @@ -85,6 +87,11 @@ static int g_pfd[2] = {-1, -1}; static pthread_mutex_t *g_pDVBMtx = NULL; +static bool g_bDuringWrite = false; +static bool g_bSignalWriteFinish = false; + +static void *g_pWriteStamp = NULL; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -147,6 +154,12 @@ static void LinuxDvbBuffThread(Context_t *context) while (0 == PlaybackDieNow(0)) { pthread_mutex_lock(&bufferingMtx); + g_bDuringWrite = false; + if (g_bSignalWriteFinish) + { + pthread_cond_signal(&bufferingWriteFinishedCond); + g_bSignalWriteFinish = false; + } if (nodePtr) { free(nodePtr); @@ -183,23 +196,28 @@ static void LinuxDvbBuffThread(Context_t *context) bufferingDataSize = 0; } } - pthread_mutex_unlock(&bufferingMtx); /* We will write data without mutex * this have some disadvantage because we can * write some portion of data after LinuxDvbBuffFlush, - * for example after seek, this will be fixed later + * for example after seek. */ - if (nodePtr && !context->playback->isSeeking) + if (nodePtr && !context->playback->isSeeking && context->playback->stamp == nodePtr->stamp) { /* Write data to valid output */ uint8_t *dataPtr = (uint8_t *)nodePtr + sizeof(BufferingNode_t); int fd = nodePtr->dataType == OUTPUT_VIDEO ? videofd : audiofd; + g_bDuringWrite = true; + pthread_mutex_unlock(&bufferingMtx); if (0 != WriteWithRetry(context, g_pfd[0], fd, g_pDVBMtx, dataPtr, nodePtr->dataSize)) { buff_err("Something is WRONG\n"); } } + else + { + pthread_mutex_unlock(&bufferingMtx); + } } pthread_mutex_lock(&bufferingMtx); @@ -258,6 +276,7 @@ int32_t LinuxDvbBuffOpen(Context_t *context, char *type, int outfd, void *mtx) pthread_cond_init(&bufferingExitCond, NULL); pthread_cond_init(&bufferingDataConsumedCond, NULL); + pthread_cond_init(&bufferingWriteFinishedCond, NULL); pthread_cond_init(&bufferingdDataAddedCond, NULL); } } @@ -321,6 +340,7 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused))) /* pthread_mutex_destroy(&bufferingMtx); pthread_cond_destroy(&bufferingDataConsumedCond); + pthread_cond_destroy(&bufferingWriteFinishedCond); pthread_cond_destroy(&bufferingdDataAddedCond); */ } @@ -356,6 +376,12 @@ int32_t LinuxDvbBuffFlush(Context_t *context __attribute__((unused))) /* signal that queue is empty */ pthread_cond_signal(&bufferingDataConsumedCond); + + while (g_bDuringWrite && !PlaybackDieNow(0)) + { + g_bSignalWriteFinish = true; + pthread_cond_wait(&bufferingWriteFinishedCond, &bufferingMtx); + } pthread_mutex_unlock(&bufferingMtx); buff_printf(40, "EXIT\n"); @@ -372,6 +398,11 @@ int32_t LinuxDvbBuffResume(Context_t *context __attribute__((unused))) return 0; } +void LinuxDvbBuffSetStamp(void *stamp) +{ + g_pWriteStamp = stamp; +} + ssize_t BufferingWriteV(int fd, const struct iovec *iov, int ic) { OutputType_t dataType = OUTPUT_UNK; @@ -445,6 +476,7 @@ ssize_t BufferingWriteV(int fd, const struct iovec *iov, int ic) chunkSize -= sizeof(BufferingNode_t); nodePtr->dataSize = chunkSize; nodePtr->dataType = dataType; + nodePtr->stamp = g_pWriteStamp; nodePtr->next = NULL; /* signal that we added some data to queue */ diff --git a/libeplayer3/output/linuxdvb_fake.c b/libeplayer3/output/linuxdvb_fake.c index 88312d5..eac27a2 100644 --- a/libeplayer3/output/linuxdvb_fake.c +++ b/libeplayer3/output/linuxdvb_fake.c @@ -73,6 +73,8 @@ bool isBufferedOutput = false; pthread_mutex_t LinuxDVBmutex; +static int64_t last_pts = 0; + /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -94,7 +96,6 @@ int LinuxDvbStop(Context_t *context, char *type); #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); @@ -196,7 +197,7 @@ int LinuxDvbClear(Context_t *context __attribute__((unused)), char *type __attri int LinuxDvbPts(Context_t *context __attribute__((unused)), unsigned long long int *pts) { - *((unsigned long long int *)pts) = (unsigned long long int)0; + *((unsigned long long int *)pts) = (unsigned long long int)last_pts; return 0; } @@ -207,7 +208,6 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l int LinuxDvbSwitch(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { - return cERR_LINUXDVB_NO_ERROR; } @@ -231,7 +231,7 @@ static int Write(Context_t *context, void *_out) 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); + out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); if (video) @@ -300,6 +300,16 @@ static int Write(Context_t *context, void *_out) } } + if (out->pts != INVALID_PTS_VALUE) + { + if (out->pts > last_pts) + { + usleep((out->pts - last_pts) / 90 * 900); + //usleep((out->pts - last_pts) / 90 * 500); + } + last_pts = out->pts; + } + call.fd = videofd; call.data = out->data; call.len = out->len; diff --git a/libeplayer3/output/linuxdvb_mipsel.c b/libeplayer3/output/linuxdvb_mipsel.c index d8db1a8..11f64f1 100644 --- a/libeplayer3/output/linuxdvb_mipsel.c +++ b/libeplayer3/output/linuxdvb_mipsel.c @@ -288,7 +288,10 @@ int LinuxDvbPlay(Context_t *context, char *type) { linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); 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) + 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)); @@ -331,7 +334,10 @@ int LinuxDvbPlay(Context_t *context, char *type) { linuxdvb_printf(20, "found writer %s for encoding %s\n", writer->caps->name, Encoding); 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) + 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)); @@ -587,7 +593,6 @@ int LinuxDvbAVSync(Context_t *context __attribute__((unused)), char *type __attr if (audiofd != -1) { getLinuxDVBMutex(); - if (ioctl(audiofd, AUDIO_SET_AV_SYNC, 0) == -1) //context->playback->AVSync) == -1) { linuxdvb_err("AUDIO_SET_AV_SYNC: ERROR %d, %s\n", errno, strerror(errno)); @@ -722,7 +727,10 @@ int LinuxDvbSwitch(Context_t *context, char *type) { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); 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) + 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)); @@ -770,7 +778,10 @@ int LinuxDvbSwitch(Context_t *context, char *type) { linuxdvb_printf(10, "found writer %s for encoding %s\n", writer->caps->name, Encoding); 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) + 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)); @@ -821,7 +832,7 @@ static int Write(Context_t *context, void *_out) 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); + out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); if (video) @@ -862,6 +873,7 @@ static int Write(Context_t *context, void *_out) } else { + bool changed = false; if (evt.type == VIDEO_EVENT_SIZE_CHANGED) { linuxdvb_printf(10, "VIDEO_EVENT_SIZE_CHANGED type: 0x%x\n", evt.type); @@ -871,12 +883,14 @@ static int Write(Context_t *context, void *_out) videoInfo.width = evt.u.size.w; videoInfo.height = evt.u.size.h; videoInfo.aspect_ratio = evt.u.size.aspect_ratio; + changed = true; } 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; + changed = true; } else if (evt.type == 16 /*VIDEO_EVENT_PROGRESSIVE_CHANGED*/) { @@ -884,11 +898,23 @@ static int Write(Context_t *context, void *_out) 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); + changed = true; } else { linuxdvb_err("unhandled DVBAPI Video Event %d\n", evt.type); } + + if (changed && + videoInfo.width != -1 && + videoInfo.height != -1 && + videoInfo.aspect_ratio != -1 && + videoInfo.frame_rate != -1 && + videoInfo.progressive != -1) + { + E2iSendMsg("{\"v_e\":{\"w\":%d,\"h\":%d,\"a\":%d,\"f\":%d,\"p\":%d}}\n", + videoInfo.width, videoInfo.height, videoInfo.aspect_ratio, videoInfo.frame_rate, videoInfo.progressive); + } } } @@ -1028,7 +1054,6 @@ static int reset(Context_t *context) if (isBufferedOutput) LinuxDvbBuffFlush(context); - return ret; } @@ -1094,6 +1119,7 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument) } case OUTPUT_CLEAR: { + reset(context); ret = LinuxDvbClear(context, (char *)argument); reset(context); sCURRENT_PTS = 0; diff --git a/libeplayer3/output/linuxdvb_sh4.c b/libeplayer3/output/linuxdvb_sh4.c index 42194ad..bdb2ef1 100644 --- a/libeplayer3/output/linuxdvb_sh4.c +++ b/libeplayer3/output/linuxdvb_sh4.c @@ -429,7 +429,6 @@ int LinuxDvbContinue(Context_t *context __attribute__((unused)), char *type) linuxdvb_printf(10, "exiting\n"); - return ret; } @@ -490,7 +489,6 @@ int LinuxDvbAudioMute(Context_t *context __attribute__((unused)), char *flag) return ret; } - int LinuxDvbFlush(Context_t *context __attribute__((unused)), char *type) { unsigned char video = !strcmp("video", type); @@ -619,7 +617,6 @@ int LinuxDvbFastForward(Context_t *context, char *type) } #endif - int LinuxDvbReverse(Context_t *context __attribute__((unused)), char *type __attribute__((unused))) { int ret = cERR_LINUXDVB_NO_ERROR; @@ -781,7 +778,8 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l linuxdvb_err("VIDEO_GET_PLAY_INFO: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } - else linuxdvb_err("V: %llu\n", playInfo.frame_count); + else + linuxdvb_err("V: %llu\n", playInfo.frame_count); } else if (audiofd != -1) { @@ -791,7 +789,8 @@ int LinuxDvbGetFrameCount(Context_t *context __attribute__((unused)), unsigned l linuxdvb_err("AUDIO_GET_PLAY_INFO: %s\n", strerror(errno)); ret = cERR_LINUXDVB_ERROR; } - else linuxdvb_err("A: %llu\n", playInfo.frame_count); + else + linuxdvb_err("A: %llu\n", playInfo.frame_count); } else { @@ -934,7 +933,6 @@ int LinuxDvbSwitch(Context_t *context, char *type) } releaseLinuxDVBMutex(); - } linuxdvb_printf(10, "exiting\n"); @@ -963,7 +961,7 @@ static int Write(void *_context, void *_out) audio = !strcmp("audio", out->type); linuxdvb_printf(20, "DataLength=%u PrivateLength=%u Pts=%llu FrameRate=%f\n", - out->len, out->extralen, out->pts, out->frameRate); + out->len, out->extralen, out->pts, out->frameRate); linuxdvb_printf(20, "v%d a%d\n", video, audio); if (video) @@ -1228,6 +1226,7 @@ static int Command(void *_context, OutputCmd_t command, void *argument) } case OUTPUT_CLEAR: { + reset(context); ret = LinuxDvbClear(context, (char *)argument); reset(context); sCURRENT_PTS = 0; diff --git a/libeplayer3/output/output_subtitle.c b/libeplayer3/output/output_subtitle.c index 22a6257..e9a07b5 100644 --- a/libeplayer3/output/output_subtitle.c +++ b/libeplayer3/output/output_subtitle.c @@ -37,6 +37,7 @@ #include "common.h" #include "debug.h" #include "output.h" +#include "writer.h" /* ***************************** */ /* Makros/Constants */ @@ -60,13 +61,13 @@ Number, Style, Name,, MarginL, MarginR, MarginV, Effect,, Text /* Types */ /* ***************************** */ - /* ***************************** */ /* Variables */ /* ***************************** */ static pthread_mutex_t mutex; static int isSubtitleOpened = 0; +static SubWriter_t *g_subWriter; /* ***************************** */ /* Prototypes */ @@ -158,7 +159,6 @@ static char *json_string_escape(char *str) *ptr1++ = *ptr2; break; } - ++ptr2; } *ptr1 = '\0'; @@ -167,7 +167,10 @@ static char *json_string_escape(char *str) static int Flush() { - fprintf(stderr, "{\"s_f\":{\"r\":0}}\n"); + if (g_subWriter) + g_subWriter->reset(); + + E2iSendMsg("{\"s_f\":{\"r\":0}}\n"); return cERR_SUBTITLE_NO_ERROR; } @@ -190,6 +193,11 @@ static int Write(Context_t *context, void *data) context->manager->subtitle->Command(context, MANAGER_GET, &curtrackid); if (curtrackid != (int32_t)out->trackId) { + if (g_subWriter) + { + g_subWriter = NULL; + g_subWriter->close(); + } Flush(); } context->manager->subtitle->Command(context, MANAGER_GETENCODING, &Encoding); @@ -201,25 +209,60 @@ static int Write(Context_t *context, void *data) } subtitle_printf(20, "Encoding:%s Text:%s Len:%d\n", Encoding, (const char *) out->data, out->len); + SubtitleCodecId_t subCodecId = SUBTITLE_CODEC_ID_UNKNOWN; if (!strncmp("S_TEXT/SUBRIP", Encoding, 13)) - { - 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)); - } + subCodecId = SUBTITLE_CODEC_ID_SUBRIP; else if (!strncmp("S_TEXT/ASS", Encoding, 10)) - { - 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 - { - subtitle_err("unknown encoding %s\n", Encoding); - return cERR_SUBTITLE_ERROR; - } + subCodecId = SUBTITLE_CODEC_ID_ASS; + else if (!strncmp("S_TEXT/WEBVTT", Encoding, 18)) + subCodecId = SUBTITLE_CODEC_ID_WEBVTT; + else if (!strncmp("S_GRAPHIC/PGS", Encoding, 13)) + subCodecId = SUBTITLE_CODEC_ID_PGS; + else if (!strncmp("S_GRAPHIC/DVB", Encoding, 13)) + subCodecId = SUBTITLE_CODEC_ID_DVB; + else if (!strncmp("S_GRAPHIC/XSUB", Encoding, 14)) + subCodecId = SUBTITLE_CODEC_ID_XSUB; + switch (subCodecId) + { + case SUBTITLE_CODEC_ID_SUBRIP: + case SUBTITLE_CODEC_ID_WEBVTT: + E2iSendMsg("{\"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)); + break; + case SUBTITLE_CODEC_ID_ASS: + E2iSendMsg("{\"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)); + break; + case SUBTITLE_CODEC_ID_PGS: + case SUBTITLE_CODEC_ID_DVB: + case SUBTITLE_CODEC_ID_XSUB: + { + if (!g_subWriter) + { + g_subWriter = &WriterSubPGS; + //g_subWriter->open(subCodecId, out->extradata, out->extralen); + } + + WriterSubCallData_t subPacket; + memset(&subPacket, 0x00, sizeof(subPacket)); + subPacket.codecId = subCodecId; + subPacket.trackId = out->trackId; + subPacket.data = out->data; + subPacket.len = out->len; + subPacket.pts = out->pts; + subPacket.dts = out->dts; + subPacket.private_data = out->extradata; + subPacket.private_size = out->extralen; + subPacket.durationMS = out->durationMS; + subPacket.width = out->width; + subPacket.height = out->height; + g_subWriter->write(&subPacket); + } + break; + default: + subtitle_err("unknown encoding %s\n", Encoding); + return cERR_SUBTITLE_ERROR; + } subtitle_printf(10, "<\n"); return cERR_SUBTITLE_NO_ERROR; } @@ -252,8 +295,13 @@ static int32_t subtitle_Close(Context_t *context __attribute__((unused))) getMutex(__LINE__); - isSubtitleOpened = 0; + if (g_subWriter) + { + g_subWriter->close(); + g_subWriter = NULL; + } + isSubtitleOpened = 0; releaseMutex(__LINE__); subtitle_printf(10, "<\n"); @@ -325,7 +373,6 @@ static int Command(Context_t *context, OutputCmd_t command, void *argument __att return ret; } - static char *SubtitleCapabilitis[] = { "subtitle", NULL }; Output_t SubtitleOutput = diff --git a/libeplayer3/output/writer/common/misc.c b/libeplayer3/output/writer/common/misc.c index 696934b..e8913a6 100644 --- a/libeplayer3/output/writer/common/misc.c +++ b/libeplayer3/output/writer/common/misc.c @@ -138,7 +138,7 @@ stb_type_t GetSTBType() type = STB_DREAMBOX; } else if (access("/proc/stb/info/vumodel", F_OK) != -1 && - access("/proc/stb/info/boxtype", 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 diff --git a/libeplayer3/output/writer/common/pes.c b/libeplayer3/output/writer/common/pes.c index f91be82..383c433 100644 --- a/libeplayer3/output/writer/common/pes.c +++ b/libeplayer3/output/writer/common/pes.c @@ -57,7 +57,6 @@ /* Types */ /* ***************************** */ - /* ***************************** */ /* Varaibles */ /* ***************************** */ diff --git a/libeplayer3/output/writer/mipsel/aac.c b/libeplayer3/output/writer/mipsel/aac.c index 655a3b9..b9f666f 100644 --- a/libeplayer3/output/writer/mipsel/aac.c +++ b/libeplayer3/output/writer/mipsel/aac.c @@ -41,6 +41,7 @@ #include #include "ffmpeg/latmenc.h" +#include "ffmpeg/mpeg4audio.h" #include "stm_ioctls.h" #include "bcm_ioctls.h" @@ -66,6 +67,8 @@ /* Variables */ /* ***************************** */ +static bool needInitHeader = true; + /// ** AAC ADTS format ** /// /// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM @@ -130,6 +133,7 @@ static int reset() free(pLATMCtx); pLATMCtx = NULL; } + needInitHeader = true; return 0; } @@ -169,7 +173,7 @@ static int _writeData(WriterAVCallData_t *call, int type) else // check LOAS header { if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe && - ((uint32_t)(AV_RB16(call->data + 1) & 0x1FFF) + 3) == call->len)) + ((uint32_t)(AV_RB16(call->data + 1) & 0x1FFF) + 3) == call->len)) { aac_err("parsing Data with wrong latm header. ignoring...\n"); return 0; @@ -194,35 +198,25 @@ static int writeDataADTS(WriterAVCallData_t *call) { aac_printf(10, "\n"); - if (call == NULL) + if (call == NULL || call->data == NULL || call->len <= 0 || call->fd < 0) { aac_err("call data is NULL...\n"); return 0; } - if ((call->data == NULL) || (call->len <= 0)) - { - aac_err("parsing NULL Data. ignoring...\n"); - return 0; - } - - if (call->fd < 0) - { - aac_err("file pointer < 0. ignoring ...\n"); - return 0; - } - if ((call->private_data && 0 == strncmp("ADTS", (const char *)call->private_data, call->private_size)) || - HasADTSHeader(call->data, call->len)) + HasADTSHeader(call->data, call->len)) { //printf("%hhx %hhx %hhx %hhx %hhx %hhx %hhx %hhx\n", call->data[0], call->data[1], call->data[2], call->data[3], call->data[4], call->data[5], call->data[6], call->data[7]); return _writeData(call, 0); } - uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; - uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; + uint32_t adtsHeaderSize = (call->private_data == NULL || needInitHeader == false) ? AAC_HEADER_LENGTH : call->private_size; + uint32_t PacketLength = call->len + adtsHeaderSize; + uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH + MAX_PCE_SIZE]; uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint8_t *pExtraData = &PesHeader[headerSize]; + needInitHeader = false; aac_printf(10, "AudioPts %lld\n", call->Pts); if (call->private_data == NULL) @@ -232,7 +226,7 @@ static int writeDataADTS(WriterAVCallData_t *call) } else { - memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); + memcpy(pExtraData, call->private_data, adtsHeaderSize); } pExtraData[3] &= 0xC0; @@ -252,7 +246,7 @@ static int writeDataADTS(WriterAVCallData_t *call) struct iovec iov[2]; iov[0].iov_base = PesHeader; - iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; + iov[0].iov_len = headerSize + adtsHeaderSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; diff --git a/libeplayer3/output/writer/mipsel/amr.c b/libeplayer3/output/writer/mipsel/amr.c index 381e0f8..0526d48 100644 --- a/libeplayer3/output/writer/mipsel/amr.c +++ b/libeplayer3/output/writer/mipsel/amr.c @@ -77,37 +77,26 @@ static int reset() static int writeData(WriterAVCallData_t *call) { - unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; + uint8_t PesHeader[PES_MAX_HEADER_SIZE + 4 + 9]; amr_printf(10, "\n"); - if (call == NULL) + if (call == NULL || call->data == NULL || call->len <= 0 || call->fd < 0) { - amr_err("call data is NULL...\n"); + amr_err("call error wrong data call: %p, data: %p, len: %d, fd: %d\n", call, call->data, call->len, call->fd); return 0; } amr_printf(10, "AudioPts %lld\n", call->Pts); + size_t payload_len = call->len; + bool hasCodecData = true; - if ((call->data == NULL) || (call->len <= 0)) - { - amr_err("parsing NULL Data. ignoring...\n"); - return 0; - } - - if (call->fd < 0) - { - amr_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - uint8_t hasCodecData = 1; if (NULL != call->private_data && call->private_size >= 17) { amr_err("wrong private_data. ignoring ...\n"); - hasCodecData = 1; + hasCodecData = false; } - size_t payload_len = call->len; + if (hasCodecData) { payload_len += 9; @@ -122,10 +111,7 @@ static int writeData(WriterAVCallData_t *call) if (hasCodecData) { - uint8_t tmp[] = {0x45, 0x4d, 0x50, 0x20, 0x00, 0x00, 0x80, 0x00, 0x01}; - memcpy(&PesHeader[headerSize], tmp, 9); - //memcpy(&PesHeader[headerSize], call->private_data + 8, 9); - //memset(&PesHeader[headerSize], 0, 9); + memcpy(&PesHeader[headerSize], call->private_data + 8, 9); } struct iovec iov[2]; diff --git a/libeplayer3/output/writer/mipsel/divx3.c b/libeplayer3/output/writer/mipsel/divx3.c index 71206d6..b57d41c 100644 --- a/libeplayer3/output/writer/mipsel/divx3.c +++ b/libeplayer3/output/writer/mipsel/divx3.c @@ -95,9 +95,6 @@ static int reset() static int writeData(WriterAVCallData_t *call) { unsigned char PesHeader[PES_MAX_HEADER_SIZE + 4]; -// unsigned char Version = 5; -// unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; - divx_printf(10, "\n"); if (call == NULL) @@ -132,11 +129,11 @@ static int writeData(WriterAVCallData_t *call) data += 38; data[0] = B_GET_BITS(width, 11, 4); data[1] = B_SET_BITS("width [3..0]", B_GET_BITS(width, 3, 0), 7, 4) | - B_SET_BITS("'10'", 0x02, 3, 2) | - B_SET_BITS("height [11..10]", B_GET_BITS(height, 11, 10), 1, 0); + B_SET_BITS("'10'", 0x02, 3, 2) | + B_SET_BITS("height [11..10]", B_GET_BITS(height, 11, 10), 1, 0); data[2] = B_GET_BITS(height, 9, 2); data[3] = B_SET_BITS("height [1.0]", B_GET_BITS(height, 1, 0), 7, 6) | - B_SET_BITS("'100000'", 0x20, 5, 0); + B_SET_BITS("'100000'", 0x20, 5, 0); iov[ic].iov_base = brcm_divx311_sequence_header; iov[ic++].iov_len = sizeof(brcm_divx311_sequence_header); @@ -145,7 +142,7 @@ static int writeData(WriterAVCallData_t *call) iov[ic].iov_base = PesHeader; uint32_t headerSize = 0; - if (memcmp(call->data, "\x00\x00\x01\xb6", 4)) + if (0 != memcmp(call->data, "\x00\x00\x01\xb6", 4)) { headerSize = InsertPesHeader(PesHeader, call->len + 4, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); memcpy(PesHeader + headerSize, "\x00\x00\x01\xb6", 4); @@ -176,7 +173,7 @@ static WriterCaps_t divix3_caps = "divix3", eVideo, "V_DIVX3", - VIDEO_ENCODING_MPEG4P2, + -1, STREAMTYPE_DIVX311, -1 }; diff --git a/libeplayer3/output/writer/mipsel/dts.c b/libeplayer3/output/writer/mipsel/dts.c index a9acd96..ef15e94 100644 --- a/libeplayer3/output/writer/mipsel/dts.c +++ b/libeplayer3/output/writer/mipsel/dts.c @@ -146,7 +146,7 @@ static int writeData(WriterAVCallData_t *call) } /* ***************************** */ -/* Writer Definition */ +/* Writer Definition */ /* ***************************** */ static WriterCaps_t caps = diff --git a/libeplayer3/output/writer/mipsel/h264.c b/libeplayer3/output/writer/mipsel/h264.c index bcf91a5..c65bca8 100644 --- a/libeplayer3/output/writer/mipsel/h264.c +++ b/libeplayer3/output/writer/mipsel/h264.c @@ -335,8 +335,8 @@ static int writeData(WriterAVCallData_t *call) /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || - ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) + ((call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))) { uint32_t i = 0; uint8_t InsertPrivData = !sps_pps_in_stream; diff --git a/libeplayer3/output/writer/mipsel/h265.c b/libeplayer3/output/writer/mipsel/h265.c index 67fb79a..8fd4c06 100644 --- a/libeplayer3/output/writer/mipsel/h265.c +++ b/libeplayer3/output/writer/mipsel/h265.c @@ -113,26 +113,36 @@ static int32_t PreparCodecData(unsigned char *data, unsigned int cd_len, unsigne break; } // ignore flags + NAL type (1 byte) + int nal_type = data[pos] & 0x3f; int nal_count = data[pos + 1] << 8 | data[pos + 2]; pos += 3; for (j = 0; j < nal_count; j++) { if (pos + 2 > cd_len) { - h265_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)\n", pos + 2, cd_len); break; } int nal_size = data[pos] << 8 | data[pos + 1]; pos += 2; + if (pos + nal_size > cd_len) { - h265_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)\n", pos + 2 + nal_size, cd_len); break; } - memcpy(tmp + tmp_len, "\x00\x00\x00\x01", 4); - tmp_len += 4; - memcpy(tmp + tmp_len, data + pos, nal_size); - tmp_len += nal_size; + + if ((nal_type == 0x20 || nal_type == 0x21 || nal_type == 0x22) && ((tmp_len + 4 + nal_size) < sizeof(tmp))) // use only VPS, SPS, PPS nals + { + memcpy(tmp + tmp_len, "\x00\x00\x00\x01", 4); + tmp_len += 4; + memcpy(tmp + tmp_len, data + pos, nal_size); + tmp_len += nal_size; + } + else if ((tmp_len + 4 + nal_size) >= sizeof(tmp)) + { + h264_err("Ignoring nal as tmp buffer is too small tmp_len + nal = %d\n", tmp_len + 4 + nal_size); + } pos += nal_size; } } @@ -195,7 +205,7 @@ static int writeData(WriterAVCallData_t *call) return 0; } - if (call->InfoFlags & 0x1) // TS container + if (call->InfoFlags & 0x1) // TS container { h265_printf(10, "H265 simple inject method!\n"); uint32_t PacketLength = 0; @@ -258,6 +268,7 @@ static int writeData(WriterAVCallData_t *call) if (ic >= IOVEC_SIZE) { h264_err(">> Drop data due to ic overflow\n"); + exit(-1); break; } diff --git a/libeplayer3/output/writer/mipsel/mjpeg.c b/libeplayer3/output/writer/mipsel/mjpeg.c index 2bd2765..0762e92 100755 --- a/libeplayer3/output/writer/mipsel/mjpeg.c +++ b/libeplayer3/output/writer/mipsel/mjpeg.c @@ -42,7 +42,6 @@ #include "stm_ioctls.h" #include "bcm_ioctls.h" -#include "debug.h" #include "common.h" #include "output.h" #include "debug.h" @@ -62,7 +61,7 @@ /* Variables */ /* ***************************** */ -static bool must_send_header = true; +static bool must_send_header = false; /* ***************************** */ /* Prototypes */ @@ -74,14 +73,78 @@ static bool must_send_header = true; static int reset() { - must_send_header = true; + must_send_header = false; return 0; } +static int writeDataSimple(WriterAVCallData_t *call) +{ + uint8_t PesHeader[PES_MAX_HEADER_SIZE]; + 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 = call->data; + iov[1].iov_len = call->len; + return call->WriteV(call->fd, iov, 2);; +} + +static int writeDataBCMV(WriterAVCallData_t *call) +{ + uint8_t PesHeader[PES_MAX_HEADER_SIZE]; + uint32_t pes_header_len = InsertPesHeader(PesHeader, call->len, MPEG_VIDEO_PES_START_CODE, call->Pts, 0); + uint32_t len = call->len + 4 + 4 + 2; + memcpy(PesHeader + pes_header_len, "BCMV", 4); + pes_header_len += 4; + PesHeader[pes_header_len++] = (len & 0xFF000000) >> 24; + PesHeader[pes_header_len++] = (len & 0x00FF0000) >> 16; + PesHeader[pes_header_len++] = (len & 0x0000FF00) >> 8; + PesHeader[pes_header_len++] = (len & 0x000000FF) >> 0; + PesHeader[pes_header_len++] = 0; + PesHeader[pes_header_len++] = 1; + int32_t payload_len = call->len + pes_header_len - 6; + + 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; + //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; + } + return 1; +} + static int writeData(WriterAVCallData_t *call) { - static uint8_t PesHeader[PES_MAX_HEADER_SIZE]; - mjpeg_printf(10, "\n"); if (call == NULL) @@ -92,15 +155,12 @@ static int writeData(WriterAVCallData_t *call) mjpeg_printf(10, "VideoPts %lld\n", call->Pts); - struct iovec iov[2]; + if (STB_HISILICON == GetSTBType()) + { + return writeDataSimple(call); + } - 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 = call->data; - iov[1].iov_len = call->len; - - return call->WriteV(call->fd, iov, 2);; + return writeDataBCMV(call); } /* ***************************** */ @@ -123,3 +183,54 @@ struct Writer_s WriterVideoMJPEG = &writeData, &caps }; + +static WriterCaps_t capsRV30 = +{ + "rv30", + eVideo, + "V_RV30", + VIDEO_ENCODING_AUTO, + STREAMTYPE_RV30, + -1 +}; + +struct Writer_s WriterVideoRV30 = +{ + &reset, + &writeData, + &capsRV30 +}; + +static WriterCaps_t capsRV40 = +{ + "rv40", + eVideo, + "V_RV40", + VIDEO_ENCODING_AUTO, + STREAMTYPE_RV40, + -1 +}; + +struct Writer_s WriterVideoRV40 = +{ + &reset, + &writeData, + &capsRV40 +}; + +static WriterCaps_t capsAVS2 = +{ + "avs2", + eVideo, + "V_AVS2", + VIDEO_ENCODING_AUTO, + STREAMTYPE_AVS2, + -1 +}; + +struct Writer_s WriterVideoAVS2 = +{ + &reset, + &writeData, + &capsAVS2 +}; diff --git a/libeplayer3/output/writer/mipsel/mp3.c b/libeplayer3/output/writer/mipsel/mp3.c index fa225fd..234a7bc 100644 --- a/libeplayer3/output/writer/mipsel/mp3.c +++ b/libeplayer3/output/writer/mipsel/mp3.c @@ -80,26 +80,13 @@ static int writeData(WriterAVCallData_t *call) mp3_printf(10, "\n"); - if (call == NULL) + if (call == NULL || call->data == NULL || call->len <= 0 || call->fd < 0) { - mp3_err("call data is NULL...\n"); + mp3_err("Wrong input call: %p, data: %p, len: %d, fd: %d\n", call, call->data, call->len, call->fd); return 0; } mp3_printf(10, "AudioPts %lld\n", call->Pts); - - if ((call->data == NULL) || (call->len <= 0)) - { - mp3_err("parsing NULL Data. ignoring...\n"); - return 0; - } - - if (call->fd < 0) - { - mp3_err("file pointer < 0. ignoring ...\n"); - return 0; - } - call->private_size = 0; uint32_t headerSize = InsertPesHeader(PesHeader, call->len + call->private_size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); @@ -157,20 +144,3 @@ struct Writer_s WriterAudioMPEGL3 = &writeData, &caps_mpegl3 }; - -static WriterCaps_t caps_vorbis = -{ - "vorbis", - eAudio, - "A_VORBIS", - AUDIO_ENCODING_VORBIS, - AUDIO_ENCODING_MP3, - -1 -}; - -struct Writer_s WriterAudioVORBIS = -{ - &reset, - &writeData, - &caps_vorbis -}; diff --git a/libeplayer3/output/writer/mipsel/mpeg2.c b/libeplayer3/output/writer/mipsel/mpeg2.c index 26746f3..48fc35b 100644 --- a/libeplayer3/output/writer/mipsel/mpeg2.c +++ b/libeplayer3/output/writer/mipsel/mpeg2.c @@ -65,7 +65,6 @@ static bool must_send_header = true; static uint8_t *private_data = NULL; static uint32_t private_size = 0; - /* ***************************** */ /* Prototypes */ /* ***************************** */ @@ -116,26 +115,40 @@ static int writeData(WriterAVCallData_t *call) uint32_t sheader_data_len = 0; while (pos < data_len && ok) { - if (pos >= data_len) break; + if (pos >= data_len) + break; + pos += 7; - if (pos >= data_len) break; + + if (pos >= data_len) + break; + sheader_data_len = 12; + if (data[pos] & 2) { // intra matrix pos += 64; - if (pos >= data_len) break; + + if (pos >= data_len) + break; sheader_data_len += 64; } + if (data[pos] & 1) { // non intra matrix pos += 64; - if (pos >= data_len) break; + + if (pos >= data_len) + break; sheader_data_len += 64; } pos += 1; - if (pos + 3 >= data_len) break; + + if (pos + 3 >= data_len) + break; + if (!memcmp(&data[pos], "\x00\x00\x01\xb5", 4)) { // extended start code @@ -152,9 +165,14 @@ static int writeData(WriterAVCallData_t *call) } } while (memcmp(&data[pos], "\x00\x00\x01", 3)); - if (!ok) break; + + if (!ok) + break; } - if (pos + 3 >= data_len) break; + + if (pos + 3 >= data_len) + break; + if (!memcmp(&data[pos], "\x00\x00\x01\xb2", 4)) { // private data @@ -171,7 +189,9 @@ static int writeData(WriterAVCallData_t *call) } } while (memcmp(&data[pos], "\x00\x00\x01", 3)); - if (!ok) break; + + if (!ok) + break; } free(private_data); @@ -239,9 +259,11 @@ static int writeData(WriterAVCallData_t *call) 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; + 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; } diff --git a/libeplayer3/output/writer/mipsel/pcm.c b/libeplayer3/output/writer/mipsel/pcm.c index d3cfb6f..acd23c8 100644 --- a/libeplayer3/output/writer/mipsel/pcm.c +++ b/libeplayer3/output/writer/mipsel/pcm.c @@ -124,7 +124,7 @@ static int writeData(WriterAVCallData_t *call) int32_t block_align = 0; int32_t byterate = 0; - uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; + uint32_t codecID = (uint32_t)pcmPrivateData->codec_id; //uint8_t dataPrecision = 0; uint8_t LE = 0; @@ -271,7 +271,7 @@ static WriterCaps_t caps_pcm = "pcm", eAudio, "A_PCM", - AUDIO_ENCODING_LPCMA, + -1, 0x30, -1 }; @@ -288,7 +288,7 @@ static WriterCaps_t caps_ipcm = "ipcm", eAudio, "A_IPCM", - AUDIO_ENCODING_LPCMA, + -1, 0x30, -1 }; diff --git a/libeplayer3/output/writer/mipsel/vc1.c b/libeplayer3/output/writer/mipsel/vc1.c index 79635fd..3766db9 100644 --- a/libeplayer3/output/writer/mipsel/vc1.c +++ b/libeplayer3/output/writer/mipsel/vc1.c @@ -139,7 +139,7 @@ static int writeData(WriterAVCallData_t *call) uint8_t needFrameStartCode = 0; if (sizeof(Vc1FrameStartCode) >= call->len || - memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) + memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) { needFrameStartCode = 1; PacketLength += sizeof(Vc1FrameStartCode); diff --git a/libeplayer3/output/writer/mipsel/vp.c b/libeplayer3/output/writer/mipsel/vp.c index fe348b1..6a1c3be 100644 --- a/libeplayer3/output/writer/mipsel/vp.c +++ b/libeplayer3/output/writer/mipsel/vp.c @@ -150,8 +150,11 @@ static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) 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; + 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; @@ -161,11 +164,6 @@ static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) 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; @@ -177,17 +175,15 @@ static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) 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; + 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; @@ -209,11 +205,11 @@ static int writeData(WriterAVCallData_t *call, bool is_vp6, bool is_vp9) PesHeader[29] = 0xFF; PesHeader[33] = 0x85; - if (pes_header_len != (unsigned)WriteExt(call->WriteV, call->fd, PesHeader, 184)) return -1; + if (pes_header_len != (unsigned)WriteExt(call->WriteV, call->fd, PesHeader, 184)) + return -1; return 1; } - //return call->WriteV(call->fd, iov, 2); } diff --git a/libeplayer3/output/writer/mipsel/wmv.c b/libeplayer3/output/writer/mipsel/wmv.c index 24e1567..99394a5 100644 --- a/libeplayer3/output/writer/mipsel/wmv.c +++ b/libeplayer3/output/writer/mipsel/wmv.c @@ -123,7 +123,9 @@ static int writeData(WriterAVCallData_t *call) } unsigned int codec_size = call->private_size; - if (codec_size > 4) codec_size = 4; + + if (codec_size > 4) + codec_size = 4; videocodecdata.length = 33; uint8_t *data = videocodecdata.data = malloc(videocodecdata.length); @@ -135,7 +137,10 @@ static int writeData(WriterAVCallData_t *call) /* height */ *(data++) = (call->Height >> 8) & 0xff; *(data++) = call->Height & 0xff; - if (call->private_data && codec_size) memcpy(data, call->private_data, codec_size); + + if (call->private_data && codec_size) + memcpy(data, call->private_data, codec_size); + if (STB_DREAMBOX == GetSTBType() || 0 != ioctl(call->fd, VIDEO_SET_CODEC_DATA, &videocodecdata)) { iov[ic].iov_base = videocodecdata.data; @@ -146,7 +151,7 @@ static int writeData(WriterAVCallData_t *call) uint8_t needFrameStartCode = 0; if (sizeof(Vc1FrameStartCode) >= call->len || - memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) + memcmp(call->data, Vc1FrameStartCode, sizeof(Vc1FrameStartCode)) != 0) { needFrameStartCode = 1; PacketLength += sizeof(Vc1FrameStartCode); diff --git a/libeplayer3/output/writer/mipsel/writer.c b/libeplayer3/output/writer/mipsel/writer.c index a24da31..4344eca 100644 --- a/libeplayer3/output/writer/mipsel/writer.c +++ b/libeplayer3/output/writer/mipsel/writer.c @@ -71,6 +71,8 @@ static Writer_t *AvailableWriter[] = &WriterAudioDTS, &WriterAudioWMA, &WriterAudioWMAPRO, + &WriterAudioOPUS, + &WriterAudioVORBIS, &WriterVideoH264, &WriterVideoH265, @@ -86,6 +88,9 @@ static Writer_t *AvailableWriter[] = &WriterVideoFLV, &WriterVideoWMV, &WriterVideoMJPEG, + &WriterVideoRV40, + &WriterVideoRV30, + &WriterVideoAVS2, NULL }; @@ -106,16 +111,6 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx __a int retval = -1; int maxFd = pipefd > fd ? pipefd : fd; struct timeval tv; - - 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); @@ -144,8 +139,8 @@ ssize_t WriteWithRetry(Context_t *context, int pipefd, int fd, void *pDVBMtx __a //if (retval == 0) //{ - // //printf("RETURN FROM SELECT DUE TO TIMEOUT\n"); - // continue; + // //printf("RETURN FROM SELECT DUE TO TIMEOUT\n"); + // continue; //} if (FD_ISSET(pipefd, &rfds)) diff --git a/libeplayer3/output/writer/sh4/aac.c b/libeplayer3/output/writer/sh4/aac.c index 6f57379..bdfc3cf 100644 --- a/libeplayer3/output/writer/sh4/aac.c +++ b/libeplayer3/output/writer/sh4/aac.c @@ -41,6 +41,7 @@ #include #include "ffmpeg/latmenc.h" +#include "ffmpeg/mpeg4audio.h" #include "stm_ioctls.h" #include "common.h" @@ -63,6 +64,8 @@ /* Variables */ /* ***************************** */ +static bool needInitHeader = true; + /// ** AAC ADTS format ** /// /// AAAAAAAA AAAABCCD EEFFFFGH HHIJKLMM @@ -127,6 +130,7 @@ static int reset() free(pLATMCtx); pLATMCtx = NULL; } + needInitHeader = true; return 0; } @@ -168,7 +172,7 @@ static int _writeData(void *_call, int type) else // check LOAS header { if (!(call->len > 2 && call->data[0] == 0x56 && (call->data[1] >> 4) == 0xe && - (AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len)) + (AV_RB16(call->data + 1) & 0x1FFF) + 3 == call->len)) { aac_err("parsing Data with wrong latm header. ignoring...\n"); return 0; @@ -214,15 +218,17 @@ static int writeDataADTS(void *_call) } if ((call->private_data && 0 == strncmp("ADTS", call->private_data, call->private_size)) || - HasADTSHeader(call->data, call->len)) + HasADTSHeader(call->data, call->len)) { return _writeData(_call, 0); } - uint32_t PacketLength = call->len + AAC_HEADER_LENGTH; - uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH]; + uint32_t adtsHeaderSize = (call->private_data == NULL || needInitHeader == false) ? AAC_HEADER_LENGTH : call->private_size; + uint32_t PacketLength = call->len + adtsHeaderSize; + uint8_t PesHeader[PES_MAX_HEADER_SIZE + AAC_HEADER_LENGTH + MAX_PCE_SIZE]; uint32_t headerSize = InsertPesHeader(PesHeader, PacketLength, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); uint8_t *pExtraData = &PesHeader[headerSize]; + needInitHeader = false; aac_printf(10, "AudioPts %lld\n", call->Pts); if (call->private_data == NULL) @@ -232,7 +238,7 @@ static int writeDataADTS(void *_call) } else { - memcpy(pExtraData, call->private_data, AAC_HEADER_LENGTH); + memcpy(pExtraData, call->private_data, adtsHeaderSize); } pExtraData[3] &= 0xC0; @@ -250,7 +256,7 @@ static int writeDataADTS(void *_call) struct iovec iov[2]; iov[0].iov_base = PesHeader; - iov[0].iov_len = headerSize + AAC_HEADER_LENGTH; + iov[0].iov_len = headerSize + adtsHeaderSize; iov[1].iov_base = call->data; iov[1].iov_len = call->len; diff --git a/libeplayer3/output/writer/sh4/h264.c b/libeplayer3/output/writer/sh4/h264.c index 5c18d5f..85e9e44 100644 --- a/libeplayer3/output/writer/sh4/h264.c +++ b/libeplayer3/output/writer/sh4/h264.c @@ -237,14 +237,15 @@ static int32_t writeData(void *_call) /* AnnexA */ if (!avc3 && ((1 < call->private_size && 0 == call->private_data[0]) || - (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || - (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) + (call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) || + (call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff)))) { uint32_t PacketLength = 0; uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE; iov[ic++].iov_base = PesHeader; initialHeader = 0; + if (initialHeader) { initialHeader = 0; @@ -440,7 +441,7 @@ static int32_t writeData(void *_call) if (NalStart + NalLength > SampleSize) { h264_printf(20, "nal length past end of buffer - size %u frame offset %u left %u\n", - NalLength, NalStart, SampleSize - NalStart); + NalLength, NalStart, SampleSize - NalStart); NalStart = SampleSize; } diff --git a/libeplayer3/output/writer/sh4/mpeg2.c b/libeplayer3/output/writer/sh4/mpeg2.c index 602ce7d..21d01c6 100644 --- a/libeplayer3/output/writer/sh4/mpeg2.c +++ b/libeplayer3/output/writer/sh4/mpeg2.c @@ -106,7 +106,7 @@ static int writeData(void *_call) while (Position < call->len) { int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? - (call->len - Position) : MAX_PES_PACKET_SIZE; + (call->len - Position) : MAX_PES_PACKET_SIZE; int32_t Remaining = call->len - Position - PacketLength; diff --git a/libeplayer3/output/writer/sh4/pcm.c b/libeplayer3/output/writer/sh4/pcm.c index 201c70f..551e910 100644 --- a/libeplayer3/output/writer/sh4/pcm.c +++ b/libeplayer3/output/writer/sh4/pcm.c @@ -97,10 +97,10 @@ static uint32_t breakBufferFillSize = 0; static int32_t prepareClipPlay(int32_t uNoOfChannels, int32_t uSampleRate, int32_t uBitsPerSample, uint8_t bLittleEndian __attribute__((unused))) { printf("rate: %d ch: %d bits: %d (%d bps)\n", - uSampleRate/*Format->dwSamplesPerSec*/, - uNoOfChannels/*Format->wChannels*/, - uBitsPerSample/*Format->wBitsPerSample*/, - (uBitsPerSample/*Format->wBitsPerSample*/ / 8) + uSampleRate/*Format->dwSamplesPerSec*/, + uNoOfChannels/*Format->wChannels*/, + uBitsPerSample/*Format->wBitsPerSample*/, + (uBitsPerSample/*Format->wBitsPerSample*/ / 8) ); SubFrameLen = 0; @@ -203,7 +203,7 @@ static int32_t writeData(void *_call) if (initialHeader) { - uint32_t codecID = (uint32_t)pcmPrivateData->ffmpeg_codec_id; + uint32_t codecID = (uint32_t)pcmPrivateData->codec_id; uint8_t LE = 0; switch (codecID) { diff --git a/libeplayer3/output/writer/sh4/vc1.c b/libeplayer3/output/writer/sh4/vc1.c index 9aa35a0..918fdb5 100644 --- a/libeplayer3/output/writer/sh4/vc1.c +++ b/libeplayer3/output/writer/sh4/vc1.c @@ -197,7 +197,7 @@ static int writeData(void *_call) while (Position < call->len) { int32_t PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? - (call->len - Position) : MAX_PES_PACKET_SIZE; + (call->len - Position) : MAX_PES_PACKET_SIZE; int32_t Remaining = call->len - Position - PacketLength; diff --git a/libeplayer3/output/writer/sh4/wmv.c b/libeplayer3/output/writer/sh4/wmv.c index c72a6c2..a674f9e 100644 --- a/libeplayer3/output/writer/sh4/wmv.c +++ b/libeplayer3/output/writer/sh4/wmv.c @@ -134,7 +134,7 @@ static int writeData(void *_call) wmv_printf(10, "Got Private Size %d\n", call->private_size); memcpy(private_data.privateData, call->private_data, - call->private_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->private_size); + call->private_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->private_size); private_data.width = call->Width; private_data.height = call->Height; @@ -196,7 +196,7 @@ static int writeData(void *_call) while (Position < call->len) { int PacketLength = (call->len - Position) <= MAX_PES_PACKET_SIZE ? - (call->len - Position) : MAX_PES_PACKET_SIZE; + (call->len - Position) : MAX_PES_PACKET_SIZE; int Remaining = call->len - Position - PacketLength; @@ -213,8 +213,7 @@ static int writeData(void *_call) unsigned int PrivateHeaderLength; PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->len); /* Update PesLength */ - PesLength = PesHeader[PES_LENGTH_BYTE_0] + - (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + 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; diff --git a/libeplayer3/playback/playback.c b/libeplayer3/playback/playback.c index 9e0b075..9a5b9e3 100644 --- a/libeplayer3/playback/playback.c +++ b/libeplayer3/playback/playback.c @@ -215,8 +215,8 @@ static int PlaybackOpen(Context_t *context, PlayFiles_t *pFiles) pFiles->szFirstFile = context->playback->uri; if ((context->container->Command(context, CONTAINER_ADD, extension) < 0) || - (!context->container->selectedContainer) || - (context->container->selectedContainer->Command(context, CONTAINER_INIT, pFiles) < 0)) + (!context->container->selectedContainer) || + (context->container->selectedContainer->Command(context, CONTAINER_INIT, pFiles) < 0)) { playback_err("CONTAINER_ADD failed\n"); if (context->playback->uri) @@ -385,8 +385,8 @@ static int32_t PlaybackContinue(Context_t *context) playback_printf(10, "\n"); if (context->playback->isPlaying && - (context->playback->isPaused || context->playback->isForwarding || - context->playback->BackWard || context->playback->SlowMotion)) + (context->playback->isPaused || context->playback->isForwarding || + context->playback->BackWard || context->playback->SlowMotion)) { if (context->playback->SlowMotion || context->playback->isForwarding || context->playback->BackWard) context->output->Command(context, OUTPUT_CLEAR, NULL); @@ -423,6 +423,8 @@ static int32_t PlaybackStop(Context_t *context) PlaybackDieNow(1); + context->playback->stamp = (void *) -1; + if (context && context->playback && context->playback->isPlaying) { context->playback->isPaused = 0; @@ -559,7 +561,7 @@ static int PlaybackFastBackward(Context_t *context, int *speed) /* Audio only reverse play not supported */ if (context->playback->isVideo && !context->playback->isForwarding && - (!context->playback->isPaused || context->playback->isPlaying)) + (!context->playback->isPaused || context->playback->isPlaying)) { if ((*speed > 0) || (*speed < cMaxSpeed_fr)) { @@ -649,12 +651,20 @@ static int32_t PlaybackSlowMotion(Context_t *context, int *speed) static int32_t PlaybackSeek(Context_t *context, int64_t *pos, uint8_t absolute) { int32_t ret = cERR_PLAYBACK_NO_ERROR; + static uint32_t stamp = 0; playback_printf(10, "pos: %" PRIu64 "\n", *pos); if (context->playback->isPlaying && !context->playback->isForwarding && !context->playback->BackWard && !context->playback->SlowMotion && !context->playback->isPaused) { context->playback->isSeeking = 1; + /* We changing current stamp, so all frames with old stamps will be skipped + * Without this there could be situation when the ffmpeg thread is + * in the av_read_frame(), so, even if we flushed data, still + * data from the old position were written + */ + stamp += 1; + context->playback->stamp = (void *)stamp; context->output->Command(context, OUTPUT_CLEAR, NULL); if (absolute) {