diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index 2442b5c..8c30568 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -44,14 +44,12 @@ struct Track { std::string title; int pid; - int64_t duration; - AVFormatContext *avfc; AVStream *stream; bool inactive; bool is_static; int ac3flags; int type, mag, page; // for teletext - Track() : pid(-1), duration(-1), avfc(NULL), stream(NULL), inactive(0), is_static(0), ac3flags(0) {} + Track() : pid(-1), stream(NULL), inactive(0), is_static(0), ac3flags(0) {} }; class Manager diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index fd84d04..7090703 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -74,7 +74,7 @@ class Output bool GetFrameCount(int64_t &framecount); bool SwitchAudio(AVStream *stream); bool SwitchVideo(AVStream *stream); - bool Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t Pts); + bool Write(AVStream *stream, AVPacket *packet, int64_t Pts); }; #endif diff --git a/libeplayer3/include/writer.h b/libeplayer3/include/writer.h index 7de9f3e..bd699ff 100644 --- a/libeplayer3/include/writer.h +++ b/libeplayer3/include/writer.h @@ -39,6 +39,8 @@ extern "C" { class Writer { + protected: + int fd; public: static void Register(Writer *w, enum AVCodecID id, video_encoding_t encoding); static void Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding); @@ -46,7 +48,7 @@ class Writer static audio_encoding_t GetAudioEncoding(enum AVCodecID id); static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type); - virtual void Init(void) { } - virtual bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + virtual void Init(int _fd, AVStream * /*stream*/ ) { fd = _fd; } + virtual bool Write(AVPacket *packet, int64_t pts); }; #endif diff --git a/libeplayer3/input.cpp b/libeplayer3/input.cpp index 501cf88..c243d30 100644 --- a/libeplayer3/input.cpp +++ b/libeplayer3/input.cpp @@ -88,6 +88,10 @@ bool Input::Play() int warnAudioWrite = 0; int warnVideoWrite = 0; + // HACK: Drop all video frames until the first audio frame was seen to keep player2 from stuttering. + // This seems to be necessary for network streaming only ... + bool audioSeen = !audioTrack || !player->isHttp; + while (player->isPlaying && !player->abortRequested) { //IF MOVIE IS PAUSED, WAIT @@ -149,9 +153,8 @@ bool Input::Play() seek_target = INT64_MIN; restart_audio_resampling = true; - // flush streams - unsigned int i; - for (i = 0; i < avfc->nb_streams; i++) + // clear streams + for (unsigned int i = 0; i < avfc->nb_streams; i++) if (avfc->streams[i]->codec && avfc->streams[i]->codec->codec) avcodec_flush_buffers(avfc->streams[i]->codec); player->output.ClearAudio(); @@ -179,7 +182,7 @@ bool Input::Play() if (_videoTrack && (_videoTrack->stream == stream)) { int64_t pts = calcPts(stream, packet.pts); - if (!player->output.Write(avfc, stream, &packet, pts)) { + if (audioSeen && !player->output.Write(stream, &packet, pts)) { if (warnVideoWrite) warnVideoWrite--; else { @@ -190,11 +193,11 @@ bool Input::Play() } else if (_audioTrack && (_audioTrack->stream == stream)) { if (restart_audio_resampling) { restart_audio_resampling = false; - player->output.Write(avfc, stream, NULL, 0); + player->output.Write(stream, NULL, 0); } if (!player->isBackWard) { int64_t pts = calcPts(stream, packet.pts); - if (!player->output.Write(avfc, stream, &packet, _videoTrack ? pts : 0)) { + if (!player->output.Write(stream, &packet, _videoTrack ? pts : 0)) { if (warnAudioWrite) warnAudioWrite--; else { @@ -203,6 +206,7 @@ bool Input::Play() } } } + audioSeen = true; } else if (_subtitleTrack && (_subtitleTrack->stream == stream)) { if (stream->codec->codec) { AVSubtitle sub; @@ -239,17 +243,8 @@ bool Input::Play() if (player->abortRequested) player->output.Clear(); - else { - Track *_audioTrack = audioTrack; - if (_audioTrack) { - // flush audio decoder - AVPacket packet; - av_init_packet(&packet); - packet.size = 0; - player->output.Write(avfc, _audioTrack->stream, &packet, 0); - } + else player->output.Flush(); - } dvbsub_ass_clear(); abortPlayback = true; @@ -278,7 +273,7 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) const char *lastDot = strrchr(filename, '.'); if (!lastDot) return false; - char *subfile = (char *) alloca(strlen(filename) + strlen(format)); + char subfile[strlen(filename) + strlen(format)]; strcpy(subfile, filename); strcpy(subfile + (lastDot + 1 - filename), format); @@ -314,9 +309,6 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) AVPacket packet; av_init_packet(&packet); - if (c->subtitle_header) - fprintf(stderr, "%s\n", c->subtitle_header); - while (av_read_frame(subavfc, &packet) > -1) { AVSubtitle sub; memset(&sub, 0, sizeof(sub)); @@ -326,6 +318,7 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) dvbsub_ass_write(c, &sub, pid); av_free_packet(&packet); } + avcodec_close(c); avformat_close_input(&subavfc); avformat_free_context(subavfc); @@ -441,15 +434,10 @@ bool Input::UpdateTracks() stream->id = n + 1; Track track; - track.avfc = avfc; track.stream = stream; AVDictionaryEntry *lang = av_dict_get(stream->metadata, "language", NULL, 0); track.title = lang ? lang->value : ""; track.pid = stream->id; - if (stream->duration == AV_NOPTS_VALUE) - track.duration = avfc->duration; - else - track.duration = av_rescale(stream->time_base.num * AV_TIME_BASE, stream->duration, stream->time_base.den); switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { @@ -531,8 +519,11 @@ bool Input::Stop() while (hasPlayThreadStarted != 0) usleep(100000); - if (avfc) + if (avfc) { + for (unsigned int i = 0; i < avfc->nb_streams; i++) + avcodec_close(avfc->streams[i]->codec); avformat_close_input(&avfc); + } avformat_network_deinit(); @@ -550,23 +541,11 @@ bool Input::Seek(int64_t avts, bool absolute) bool Input::GetDuration(int64_t &duration) { + if (avfc) { + duration = avfc->duration; + return true; + } duration = 0; - - Track *track = videoTrack; - if (track && track->duration) { - duration = track->duration; - return true; - } - track = audioTrack; - if (track && track->duration) { - duration = track->duration; - return true; - } - track = subtitleTrack; - if (track && track->duration) { - duration = track->duration; - return true; - } return false; } @@ -574,7 +553,7 @@ bool Input::SwitchAudio(Track *track) { audioTrack = track; player->output.SwitchAudio(track ? track->stream : NULL); - player->Seek(-5000, false); + // player->Seek(-5000, false); return true; } @@ -593,6 +572,7 @@ bool Input::SwitchTeletext(Track *track) bool Input::SwitchVideo(Track *track) { videoTrack = track; + player->output.SwitchVideo(track ? track->stream : NULL); return true; } diff --git a/libeplayer3/output.cpp b/libeplayer3/output.cpp index 9792a46..105095f 100644 --- a/libeplayer3/output.cpp +++ b/libeplayer3/output.cpp @@ -129,18 +129,20 @@ bool Output::Play() OpenThreads::ScopedLock v_lock(videoMutex); OpenThreads::ScopedLock a_lock(audioMutex); - if (videoStream && videofd > -1) { - videoWriter = Writer::GetWriter(videoStream->codec->codec_id, videoStream->codec->codec_type); - videoWriter->Init(); - if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(videoStream->codec->codec_id)) + AVCodecContext *avcc; + + if (videoStream && videofd > -1 && (avcc = videoStream->codec)) { + videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type); + videoWriter->Init(videofd, videoStream); + if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(avcc->codec_id)) || dioctl(videofd, VIDEO_PLAY, NULL)) ret = false; } - if (audioStream && audiofd > -1) { - audioWriter = Writer::GetWriter(audioStream->codec->codec_id, audioStream->codec->codec_type); - audioWriter->Init(); - if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(audioStream->codec->codec_id)) + if (audioStream && audiofd > -1 && (avcc = audioStream->codec)) { + audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type); + audioWriter->Init(audiofd, audioStream); + if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(avcc->codec_id)) || dioctl(audiofd, AUDIO_PLAY, NULL)) ret = false; } @@ -227,8 +229,16 @@ bool Output::Flush() if (videofd > -1 && ioctl(videofd, VIDEO_FLUSH, NULL)) ret = false; - if (audiofd > -1 && ioctl(audiofd, AUDIO_FLUSH, NULL)) - ret = false; + if (audiofd > -1 && audioWriter) { + // flush audio decoder + AVPacket packet; + packet.data = NULL; + packet.size = 0; + audioWriter->Write(&packet, 0); + + if (ioctl(audiofd, AUDIO_FLUSH, NULL)) + ret = false; + } return ret; } @@ -300,10 +310,13 @@ bool Output::SwitchAudio(AVStream *stream) } audioStream = stream; if (stream) { - audioWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); - audioWriter->Init(); + AVCodecContext *avcc = stream->codec; + if (!avcc) + return false; + audioWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type); + audioWriter->Init(audiofd, audioStream); if (audiofd > -1) { - dioctl (audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(stream->codec->codec_id)); + dioctl(audiofd, AUDIO_SET_ENCODING, Writer::GetAudioEncoding(avcc->codec_id)); dioctl(audiofd, AUDIO_PLAY, NULL); } } @@ -321,26 +334,29 @@ bool Output::SwitchVideo(AVStream *stream) } videoStream = stream; if (stream) { - videoWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); - videoWriter->Init(); + AVCodecContext *avcc = stream->codec; + if (!avcc) + return false; + videoWriter = Writer::GetWriter(avcc->codec_id, avcc->codec_type); + videoWriter->Init(videofd, videoStream); if (videofd > -1) { - dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(stream->codec->codec_id)); + dioctl(videofd, VIDEO_SET_ENCODING, Writer::GetVideoEncoding(avcc->codec_id)); dioctl(videofd, VIDEO_PLAY, NULL); } } return true; } -bool Output::Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts) +bool Output::Write(AVStream *stream, AVPacket *packet, int64_t pts) { switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { OpenThreads::ScopedLock v_lock(videoMutex); - return videofd > -1 && videoWriter && videoWriter->Write(videofd, avfc, stream, packet, pts); + return videofd > -1 && videoWriter && videoWriter->Write(packet, pts); } case AVMEDIA_TYPE_AUDIO: { OpenThreads::ScopedLock a_lock(audioMutex); - return audiofd > -1 && audioWriter && audioWriter->Write(audiofd, avfc, stream, packet, pts); + return audiofd > -1 && audioWriter && audioWriter->Write(packet, pts); } default: return false; diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index 48f4d2c..a9390eb 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -78,6 +78,7 @@ bool Player::Open(const char *Url, bool _noprobe) isHttp = true; } else if (strstr(Url, "://")) { url = Url; + isHttp = strncmp("file://", Url, 7); } else { fprintf(stderr, "%s %s %d: Unknown stream (%s)\n", __FILE__, __func__, __LINE__, Url); return false; diff --git a/libeplayer3/writer/ac3.cpp b/libeplayer3/writer/ac3.cpp index dac0664..d1a32ba 100644 --- a/libeplayer3/writer/ac3.cpp +++ b/libeplayer3/writer/ac3.cpp @@ -35,13 +35,13 @@ class WriterAC3 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); WriterAC3(); }; -bool WriterAC3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) +bool WriterAC3::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; diff --git a/libeplayer3/writer/divx.cpp b/libeplayer3/writer/divx.cpp index 12af898..185665c 100644 --- a/libeplayer3/writer/divx.cpp +++ b/libeplayer3/writer/divx.cpp @@ -37,20 +37,23 @@ class WriterDIVX : public Writer { private: bool initialHeader; + AVStream *stream; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); - void Init(); + bool Write(AVPacket *packet, int64_t pts); + void Init(int fd, AVStream *_stream); WriterDIVX(); }; -void WriterDIVX::Init() +void WriterDIVX::Init(int _fd, AVStream *_stream) { + fd = _fd; + stream = _stream; initialHeader = true; } -bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) +bool WriterDIVX::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; @@ -101,7 +104,6 @@ WriterDIVX::WriterDIVX() Register(this, AV_CODEC_ID_MSMPEG4V1, VIDEO_ENCODING_MPEG4P2); Register(this, AV_CODEC_ID_MSMPEG4V2, VIDEO_ENCODING_MPEG4P2); Register(this, AV_CODEC_ID_MSMPEG4V3, VIDEO_ENCODING_MPEG4P2); - Init(); } static WriterDIVX writer_divx __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/dts.cpp b/libeplayer3/writer/dts.cpp index 356bb95..11125bb 100644 --- a/libeplayer3/writer/dts.cpp +++ b/libeplayer3/writer/dts.cpp @@ -36,13 +36,13 @@ class WriterDTS : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); WriterDTS(); }; -bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) +bool WriterDTS::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_AUDIO_HEADER_SIZE]; diff --git a/libeplayer3/writer/h263.cpp b/libeplayer3/writer/h263.cpp index 1924506..7243e6c 100644 --- a/libeplayer3/writer/h263.cpp +++ b/libeplayer3/writer/h263.cpp @@ -32,13 +32,13 @@ class WriterH263 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); WriterH263(); }; -bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) +bool WriterH263::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; diff --git a/libeplayer3/writer/h264.cpp b/libeplayer3/writer/h264.cpp index ecaefc3..ebf1825 100644 --- a/libeplayer3/writer/h264.cpp +++ b/libeplayer3/writer/h264.cpp @@ -52,21 +52,24 @@ class WriterH264 : public Writer private: bool initialHeader; unsigned int NalLengthBytes; + AVStream *stream; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); - void Init(); + bool Write(AVPacket *packet, int64_t pts); + void Init(int _fd, AVStream *_stream); WriterH264(); }; -void WriterH264::Init(void) +void WriterH264::Init(int _fd, AVStream *_stream) { + fd = _fd; + stream = _stream; initialHeader = true; NalLengthBytes = 1; } -bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) +bool WriterH264::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; unsigned int TimeDelta; @@ -249,7 +252,6 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A WriterH264::WriterH264() { Register(this, AV_CODEC_ID_H264, VIDEO_ENCODING_H264); - Init(); } static WriterH264 writerh264 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/mp3.cpp b/libeplayer3/writer/mp3.cpp index cb9f99b..c71af94 100644 --- a/libeplayer3/writer/mp3.cpp +++ b/libeplayer3/writer/mp3.cpp @@ -35,13 +35,13 @@ class WriterMP3 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); WriterMP3(); }; -bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) +bool WriterMP3::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; diff --git a/libeplayer3/writer/mpeg2.cpp b/libeplayer3/writer/mpeg2.cpp index 4577807..f7cbb8f 100644 --- a/libeplayer3/writer/mpeg2.cpp +++ b/libeplayer3/writer/mpeg2.cpp @@ -35,13 +35,13 @@ class WriterMPEG2 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); WriterMPEG2(); }; -bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) +bool WriterMPEG2::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; diff --git a/libeplayer3/writer/pcm.cpp b/libeplayer3/writer/pcm.cpp index bbc56d3..12872e7 100644 --- a/libeplayer3/writer/pcm.cpp +++ b/libeplayer3/writer/pcm.cpp @@ -71,6 +71,7 @@ class WriterPCM : public Writer int uSampleRate; int uBitsPerSample; + AVStream *stream; SwrContext *swr; AVFrame *decoded_frame; int out_sample_rate; @@ -80,10 +81,10 @@ class WriterPCM : public Writer bool restart_audio_resampling; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); + bool Write(AVPacket *packet, int64_t pts); bool prepareClipPlay(); - bool writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size); - void Init(); + bool writePCM(int64_t Pts, uint8_t *data, unsigned int size); + void Init(int _fd, AVStream *_stream); WriterPCM(); }; @@ -128,8 +129,7 @@ bool WriterPCM::prepareClipPlay() SubFrameLen *= uBitsPerSample / 8; //rewrite PES size to have as many complete subframes per PES as we can - // FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14. - SubFramesPerPES = ((sizeof(injectBuffer) - 18) - sizeof(lpcm_prv)) / SubFrameLen; + SubFramesPerPES = ((sizeof(injectBuffer) - 14) - sizeof(lpcm_prv)) / SubFrameLen; SubFrameLen *= SubFramesPerPES; //set number of channels @@ -148,7 +148,7 @@ bool WriterPCM::prepareClipPlay() return true; } -bool WriterPCM::writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) +bool WriterPCM::writePCM(int64_t Pts, uint8_t *data, unsigned int size) { bool res = true; uint8_t PesHeader[PES_MAX_HEADER_SIZE]; @@ -219,17 +219,16 @@ bool WriterPCM::writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) return res; } -void WriterPCM::Init() +void WriterPCM::Init(int _fd, AVStream *_stream) { + fd = _fd; + stream = _stream; initialHeader = true; restart_audio_resampling = true; } -bool WriterPCM::Write(int fd, AVFormatContext * /*avfc*/, AVStream *stream, AVPacket *packet, int64_t pts) +bool WriterPCM::Write(AVPacket *packet, int64_t pts) { - if (fd < 0) - return false; - if (!packet) { restart_audio_resampling = true; return true; @@ -248,6 +247,7 @@ bool WriterPCM::Write(int fd, AVFormatContext * /*avfc*/, AVStream *stream, AVPa fprintf(stderr, "%s %d: avcodec_find_decoder(%llx)\n", __func__, __LINE__, (unsigned long long) c->codec_id); return false; } + avcodec_close(c); if (avcodec_open2(c, codec, NULL)) { fprintf(stderr, "%s %d: avcodec_open2 failed\n", __func__, __LINE__); return false; @@ -292,7 +292,7 @@ bool WriterPCM::Write(int fd, AVFormatContext * /*avfc*/, AVStream *stream, AVPa int e = swr_init(swr); if (e < 0) { - fprintf(stderr, "swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n", + fprintf(stderr, "swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d)\n", -e, (int) c->channel_layout, (int) out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16); restart_audio_resampling = true; @@ -332,7 +332,7 @@ bool WriterPCM::Write(int fd, AVFormatContext * /*avfc*/, AVStream *stream, AVPa out_samples = swr_convert(swr, &output, out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples); - if (!writePCM(fd, pts, output, out_samples * sizeof(short) * out_channels)) { + if (!writePCM(pts, output, out_samples * sizeof(short) * out_channels)) { restart_audio_resampling = true; break; } @@ -353,7 +353,6 @@ WriterPCM::WriterPCM() decoded_frame = av_frame_alloc(); Register(this, AV_CODEC_ID_INJECTPCM, AUDIO_ENCODING_LPCMA); - Init(); } static WriterPCM writer_pcm __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/pes.cpp b/libeplayer3/writer/pes.cpp index f32da30..0a1265b 100644 --- a/libeplayer3/writer/pes.cpp +++ b/libeplayer3/writer/pes.cpp @@ -107,7 +107,7 @@ int InsertPesHeader(uint8_t *data, int size, uint8_t stream_id, int64_t pts, int PutBits(&ld2, 0x1, 8); // Start Code PutBits(&ld2, pic_start_code & 0xff, 8); // 00, for picture start PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code) - //14 + 4 = 18 + //14 + 5 = 19 } FlushBits(&ld2); diff --git a/libeplayer3/writer/vc1.cpp b/libeplayer3/writer/vc1.cpp index d3ce02a..b0fd743 100644 --- a/libeplayer3/writer/vc1.cpp +++ b/libeplayer3/writer/vc1.cpp @@ -50,20 +50,23 @@ class WriterVC1 : public Writer private: bool initialHeader; uint8_t FrameHeaderSeen; + AVStream *stream; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); - void Init(); + bool Write(AVPacket *packet, int64_t pts); + void Init(int _fd, AVStream *_stream); WriterVC1(); }; -void WriterVC1::Init() +void WriterVC1::Init(int _fd, AVStream *_stream) { + fd = _fd; + stream = _stream; initialHeader = true; } -bool WriterVC1::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) +bool WriterVC1::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; if (initialHeader) { @@ -181,7 +184,6 @@ bool WriterVC1::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV WriterVC1::WriterVC1() { Register(this, AV_CODEC_ID_VC1, VIDEO_ENCODING_VC1); - Init(); } static WriterVC1 writer_vc1 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/wmv.cpp b/libeplayer3/writer/wmv.cpp index 10220d1..22dea64 100644 --- a/libeplayer3/writer/wmv.cpp +++ b/libeplayer3/writer/wmv.cpp @@ -57,20 +57,23 @@ class WriterWMV : public Writer { private: bool initialHeader; + AVStream *stream; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); - void Init(); + bool Write(AVPacket *packet, int64_t pts); + void Init(int _fd, AVStream *_stream); WriterWMV(); }; -void WriterWMV::Init() +void WriterWMV::Init(int _fd, AVStream *_stream) { + fd = _fd; + stream = _stream; initialHeader = true; } -bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) +bool WriterWMV::Write(AVPacket *packet, int64_t pts) { - if (fd < 0 || !packet || !packet->data) + if (!packet || !packet->data) return false; if (initialHeader) { @@ -164,7 +167,6 @@ WriterWMV::WriterWMV() Register(this, AV_CODEC_ID_WMV1, VIDEO_ENCODING_WMV); Register(this, AV_CODEC_ID_WMV2, VIDEO_ENCODING_WMV); Register(this, AV_CODEC_ID_WMV3, VIDEO_ENCODING_WMV); - Init(); } static WriterWMV writer_wmv __attribute__ ((init_priority (300))); diff --git a/libeplayer3/writer/writer.cpp b/libeplayer3/writer/writer.cpp index 82f199c..00443ca 100644 --- a/libeplayer3/writer/writer.cpp +++ b/libeplayer3/writer/writer.cpp @@ -58,7 +58,7 @@ void Writer::Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding) aencoding[id] = encoding; } -bool Writer::Write(int /* fd */, AVFormatContext * /* avfc */, AVStream * /*stream*/, AVPacket * /* packet */, int64_t /* pts */) +bool Writer::Write(AVPacket * /* packet */, int64_t /* pts */) { return false; } diff --git a/libspark/hardware_caps.c b/libspark/hardware_caps.c index 73cbde8..0a2693f 100644 --- a/libspark/hardware_caps.c +++ b/libspark/hardware_caps.c @@ -35,6 +35,7 @@ hw_caps_t *get_hwcaps(void) caps.can_shutdown = 1; caps.display_type = HW_DISPLAY_LED_NUM; caps.has_HDMI = 1; + caps.has_SCART = 1; caps.display_xres = 4; strcpy(caps.boxvendor, "SPARK"); const char *tmp; @@ -65,89 +66,83 @@ hw_caps_t *get_hwcaps(void) switch (sys_id) { case 0x090003: tmp = "Truman Premier 1+"; - caps.has_SCART = 1; break; case 0x090007: tmp = "GoldenMedia GM990"; - caps.has_SCART = 1; break; case 0x090008: tmp = "Edision Pingulux"; - caps.has_SCART = 1; // RCA qualifies ... --martii if (caps.display_type == HW_DISPLAY_LINE_TEXT) tmp = "Edision Pingulux Plus"; break; case 0x09000a: tmp = "Amiko Alien SDH8900"; - caps.has_SCART = 1; break; case 0x09000b: tmp = "GalaxyInnovations S8120"; - caps.has_SCART = 1; break; case 0x09000d: tmp = "Dynavision Spark"; - caps.has_SCART = 1; break; case 0x09000e: tmp = "SAB Unix F+ Solo (S902)"; - caps.has_SCART = 1; break; case 0x090015: tmp = "Superbox S 750 HD"; - caps.has_SCART = 1; break; case 0x09001d: tmp = "Fulan Spark I+"; - caps.has_SCART = 1; break; case 0x090020: tmp = "SAMSAT LINUX 1"; - caps.has_SCART = 1; break; case 0x090021: tmp = "Visionnet Hammer 5400"; // or Startrack SRT 2020 HD, or Visionnet Fireball 101 - caps.has_SCART = 1; + break; + case 0x090043: + tmp = "Sogno Spark Revolution"; break; case 0x0c0003: tmp = "Truman Top Box 2"; - caps.has_SCART = 1; + break; + case 0x0c0004: + tmp = "Delta"; break; case 0x0c0007: tmp = "GoldenMedia Triplex"; - caps.has_SCART = 1; break; case 0x0c000a: tmp = "Amiko Alien 2"; - caps.has_SCART = 1; break; case 0x0c000b: tmp = "GalaxyInnovations Avatar 3 (8820)"; - caps.has_SCART = 1; break; case 0x0c000d: tmp = "Dynavision 7162"; - caps.has_SCART = 1; break; case 0x0c000e: tmp = "SAB Unix Triple HD (S903)"; - caps.has_SCART = 1; + break; + case 0x0c0015: + tmp = "Superbox Z500"; break; case 0x0c001d: tmp = "Satcom 7162"; - caps.has_SCART = 1; break; case 0x0c0020: tmp = "Samsat 7162"; - caps.has_SCART = 1; break; case 0x0c0021: tmp = "Visionnet Falcon"; - caps.has_SCART = 1; break; - case 0x0c002b00: + case 0x0c002b: tmp = "Icecrypt S3700 CHD"; - caps.has_SCART = 1; + break; + case 0x0c0043: + tmp = "Sogno Spark Triple"; + break; + case 0x0c0045: + tmp = "Interstar"; break; default: tmp = p;