From cb3db6256cb52c4197feaba96c16031c7dbad23b Mon Sep 17 00:00:00 2001 From: martii Date: Tue, 8 Apr 2014 20:02:07 +0200 Subject: [PATCH] libeplayer3: continue refresh --- libeplayer3/Makefile.am | 5 +- libeplayer3/README | 6 + libeplayer3/include/input.h | 22 +++ libeplayer3/include/manager.h | 33 +++- libeplayer3/include/output.h | 22 ++- libeplayer3/include/pes.h | 2 +- libeplayer3/include/player.h | 52 ++++-- libeplayer3/include/writer.h | 22 ++- libeplayer3/input.cpp | 259 +++++++++++---------------- libeplayer3/manager.cpp | 124 +++++-------- libeplayer3/output.cpp | 60 ++----- libeplayer3/player.cpp | 323 +++++++++++++--------------------- libeplayer3/writer/ac3.cpp | 20 +-- libeplayer3/writer/divx.cpp | 27 ++- libeplayer3/writer/dts.cpp | 20 +-- libeplayer3/writer/flac.cpp | 20 +-- libeplayer3/writer/h263.cpp | 21 +-- libeplayer3/writer/h264.cpp | 28 +-- libeplayer3/writer/mp3.cpp | 20 +-- libeplayer3/writer/mpeg2.cpp | 26 ++- libeplayer3/writer/pcm.cpp | 8 +- libeplayer3/writer/pes.cpp | 139 +++++++-------- libeplayer3/writer/vc1.cpp | 28 +-- libeplayer3/writer/wmv.cpp | 28 +-- libeplayer3/writer/writer.cpp | 38 ++-- 25 files changed, 617 insertions(+), 736 deletions(-) diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index 30130c8..f189c0a 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -1,9 +1,8 @@ noinst_LTLIBRARIES = libeplayer3.la -CXXFLAGS = -Wall - AM_CPPFLAGS = -I$(srcdir)/include -AM_CPPFLAGS += -Wall -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE +AM_CPPFLAGS += -Wall #-fno-rtti +AM_CPPFLAGS += -D_LARGEFILE_SOURCE -D_FILE_OFFSET_BITS=64 -D_LARGEFILE64_SOURCE AM_CPPFLAGS += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS AM_CPPFLAGS += -ggdb diff --git a/libeplayer3/README b/libeplayer3/README index fce93a3..e59e16d 100644 --- a/libeplayer3/README +++ b/libeplayer3/README @@ -1,3 +1,9 @@ +This is a revised libeplayer3 version for Neutrino, rewritten in C++, with +various code parts (e.g. subtitle processing, non-working decoders) removed. +--martii + +The original libeplayer3 README follows: + /* * SCOPE: * ------- diff --git a/libeplayer3/include/input.h b/libeplayer3/include/input.h index dc13eec..a6cc602 100644 --- a/libeplayer3/include/input.h +++ b/libeplayer3/include/input.h @@ -1,3 +1,23 @@ +/* + * input class + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef __INPUT_H__ #define __INPUT_H__ @@ -24,6 +44,7 @@ class Track; class Input { friend class Player; + friend int interrupt_cb(void *arg); private: Track *videoTrack; @@ -36,6 +57,7 @@ class Input float seek_sec_rel; bool isContainerRunning; bool terminating; + bool abortPlayback; Player *player; AVFormatContext *avfc; diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index aafd3c7..655ee72 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -1,3 +1,23 @@ +/* + * manager class + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef __MANAGER_H__ #define __MANAGER_H__ @@ -24,21 +44,13 @@ struct Track { std::string Name; int pid; - - /* length of track */ int64_t duration; - - /* context from ffmpeg */ AVFormatContext *avfc; - /* stream from ffmpeg */ 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) {} }; @@ -49,7 +61,10 @@ class Manager private: Player *player; OpenThreads::Mutex mutex; - std::map videoTracks, audioTracks, subtitleTracks, teletextTracks; + std::map videoTracks, audioTracks, subtitleTracks, teletextTracks; + void addTrack(std::map &tracks, Track &track); + Track *getTrack(std::map &tracks, int pid); + std::vector getTracks(std::map &tracks); public: void addVideoTrack(Track &track); void addAudioTrack(Track &track); diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index c598d48..fd84d04 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -1,3 +1,23 @@ +/* + * output class + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef __OUTPUT_H__ #define __OUTPUT_H__ @@ -54,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(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t Pts); }; #endif diff --git a/libeplayer3/include/pes.h b/libeplayer3/include/pes.h index 67f363e..2e69eb8 100644 --- a/libeplayer3/include/pes.h +++ b/libeplayer3/include/pes.h @@ -28,7 +28,7 @@ #define VC1_VIDEO_PES_START_CODE 0xfd #define AAC_AUDIO_PES_START_CODE 0xcf -int InsertPesHeader(uint8_t *data, int size, unsigned char stream_id, unsigned long long int pts, int pic_start_code); +int InsertPesHeader(uint8_t *data, int size, unsigned char stream_id, int64_t pts, int pic_start_code); int InsertVideoPrivateDataHeader(uint8_t *data, int payload_size); #endif diff --git a/libeplayer3/include/player.h b/libeplayer3/include/player.h index 0e3476a..0195722 100644 --- a/libeplayer3/include/player.h +++ b/libeplayer3/include/player.h @@ -1,3 +1,23 @@ +/* + * player class + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef __PLAYER_H__ #define __PLAYER_H__ @@ -44,52 +64,50 @@ class Player { Manager manager; OpenThreads::Mutex chapterMutex; std::vector chapters; - bool abortPlayback; + pthread_t supervisorThread; + bool abortRequested; bool isHttp; bool isPaused; - bool isCreationPhase; bool isSlowMotion; - int Speed; - int AVSync; + bool hasThreadStarted; + bool isForwarding; + bool isBackWard; + bool isPlaying; - bool isVideo; - bool isAudio; + int Speed; + + uint64_t readCount; std::string url; bool noprobe; /* hack: only minimal probing in av_find_stream_info */ - int hasThreadStarted; - + void SetChapters(std::vector &Chapters); static void* SupervisorThread(void*); public: - bool isForwarding; - bool isBackWard; - bool isPlaying; - uint64_t readCount; - bool SwitchAudio(int pid); bool SwitchVideo(int pid); bool SwitchTeletext(int pid); bool SwitchSubtitle(int pid); + bool GetPts(int64_t &pts); bool GetFrameCount(int64_t &framecount); bool GetDuration(double &duration); + bool GetMetadata(std::vector &keys, std::vector &values); bool SlowMotion(int repeats); bool FastBackward(int speed); bool FastForward(int speed); - bool Open(const char *Url); + bool Open(const char *Url, bool noprobe = false); bool Close(); bool Play(); bool Pause(); bool Continue(); bool Stop(); bool Seek(float pos, bool absolute); - bool Terminate(); + void RequestAbort(); bool GetChapters(std::vector &positions, std::vector &titles); - void SetChapters(std::vector &Chapters); - Player(); + Player(); }; #endif diff --git a/libeplayer3/include/writer.h b/libeplayer3/include/writer.h index de4596d..92ecc7a 100644 --- a/libeplayer3/include/writer.h +++ b/libeplayer3/include/writer.h @@ -1,3 +1,23 @@ +/* + * writer class headers + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + #ifndef __WRITER_H__ #define __WRITER_H__ @@ -27,7 +47,7 @@ class Writer 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 bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); Writer() { Init (); } ~Writer() {} diff --git a/libeplayer3/input.cpp b/libeplayer3/input.cpp index dfac82e..8ff4bf6 100644 --- a/libeplayer3/input.cpp +++ b/libeplayer3/input.cpp @@ -1,12 +1,14 @@ /* - * Container handling for all stream's handled by ffmpeg - * konfetti 2010; based on code from crow + * input class * + * based on libeplayer3 container_ffmpeg.c, konfetti 2010; based on code from crow * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,31 +17,28 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include -#include #include #include -#include #include -#include -#include -#include -#include -#include -#include - -#include - #include "player.h" #include "misc.h" +#define averror(_err,_fun) ({ \ + if (_err < 0) { \ + char _error[512]; \ + av_strerror(_err, _error, sizeof(_error)); \ + fprintf(stderr, "%s %d: %s: %d (%s)\n", __FILE__, __LINE__, #_fun, _err, _error); \ + } \ + _err; \ +}) + Input::Input() { videoTrack = NULL; @@ -48,7 +47,6 @@ Input::Input() teletextTrack = NULL; hasPlayThreadStarted = 0; - isContainerRunning = 0; seek_sec_abs = -1.0; seek_sec_rel = 0.0; terminating = false; @@ -67,14 +65,14 @@ int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts) } if (pts == AV_NOPTS_VALUE) - pts = INVALID_PTS_VALUE; - else if (avfc->start_time == AV_NOPTS_VALUE) - pts = 90000.0 * (double) pts * av_q2d(stream->time_base); - else - pts = 90000.0 * (double) pts * av_q2d(stream->time_base) - 90000.0 * avfc->start_time / AV_TIME_BASE; + return INVALID_PTS_VALUE; - if (pts & 0x8000000000000000ull) - pts = INVALID_PTS_VALUE; + pts = 90000.0 * (double) pts * av_q2d(stream->time_base); + if (avfc->start_time != AV_NOPTS_VALUE) + pts -= 90000.0 * avfc->start_time / AV_TIME_BASE; + + if (pts & 0x8000000000000000ll) + return INVALID_PTS_VALUE; return pts; } @@ -88,23 +86,11 @@ extern "C" void teletext_write(int pid, uint8_t *data, int size); bool Input::Play() { - char threadname[17]; - strncpy(threadname, __func__, sizeof(threadname)); - threadname[16] = 0; - prctl(PR_SET_NAME, (unsigned long) &threadname); - hasPlayThreadStarted = 1; - int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0; + int64_t showtime = 0, bofcount = 0; bool restart_audio_resampling = false; - while (player->isCreationPhase) { - fprintf(stderr, "Thread waiting for end of init phase...\n"); - usleep(1000); - } - fprintf(stderr, "Running!\n"); - - while (player->isPlaying && !player->abortRequested) { //IF MOVIE IS PAUSED, WAIT @@ -123,7 +109,9 @@ bool Input::Play() seek_target_flag = AVSEEK_FLAG_BYTE; seek_target = avio_tell(avfc->pb) + seek_sec_rel * br; } else { - seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + seek_sec_rel) * AV_TIME_BASE; + int64_t pts; + if(player->output.GetPts(pts)) + seek_target = (pts * AV_TIME_BASE)/ 90000.0 + seek_sec_rel * AV_TIME_BASE; } seek_sec_rel = 0.0; } else if (seek_sec_abs >= 0.0) { @@ -147,17 +135,15 @@ bool Input::Play() if (avfc->iformat->flags & AVFMT_TS_DISCONT) { off_t pos = avio_tell(avfc->pb); - if (pos > 0) { - float br; - if (avfc->bit_rate) - br = avfc->bit_rate / 8.0; - else - br = 180000.0; - seek_target = pos + player->Speed * 8 * br; - seek_target_flag = AVSEEK_FLAG_BYTE; - } + if (pos > 0) { + float br = avfc->bit_rate ? avfc->bit_rate / 8.0 : 180000.0; + seek_target_flag = AVSEEK_FLAG_BYTE; + seek_target = pos + player->Speed * 8 * br; + } } else { - seek_target = ((((currentVideoPts > 0) ? currentVideoPts : currentAudioPts) / 90000.0) + player->Speed * 8) * AV_TIME_BASE;; + int64_t pts; + if(player->output.GetPts(pts)) + seek_target = (pts * AV_TIME_BASE)/ 90000.0 + seek_sec_rel * AV_TIME_BASE; } showtime = av_gettime() + 300000; //jump back every 300ms } else { @@ -185,76 +171,63 @@ bool Input::Play() AVPacket packet; av_init_packet(&packet); - int av_res = av_read_frame(avfc, &packet); - if (av_res == AVERROR(EAGAIN)) { + int err = av_read_frame(avfc, &packet); + if (err == AVERROR(EAGAIN)) { av_free_packet(&packet); continue; } - if (av_res) { // av_read_frame failed - fprintf(stderr, "no data ->end of file reached ?\n"); - av_free_packet(&packet); + if (averror(err, av_read_frame)) // EOF? break; // while - } - int64_t pts; player->readCount += packet.size; int pid = avfc->streams[packet.stream_index]->id; - Track *_videoTrack = videoTrack; Track *_audioTrack = audioTrack; Track *_subtitleTrack = subtitleTrack; Track *_teletextTrack = teletextTrack; - if (_videoTrack && (_videoTrack->pid == pid)) { - currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts); - - if (!player->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts)) + int64_t pts = calcPts(avfc, _videoTrack->stream, packet.pts); + if (!player->output.Write(avfc, _videoTrack->stream, &packet, pts)) fprintf(stderr, "writing data to video device failed\n"); } else if (_audioTrack && (_audioTrack->pid == pid)) { if (restart_audio_resampling) { restart_audio_resampling = false; - player->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts); + player->output.Write(avfc, _audioTrack->stream, NULL, 0); } if (!player->isBackWard) { - currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts); - if (!player->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts)) + int64_t pts = calcPts(avfc, _audioTrack->stream, packet.pts); + if (!player->output.Write(avfc, _audioTrack->stream, &packet, pts)) fprintf(stderr, "writing data to audio device failed\n"); } } else if (_subtitleTrack && (_subtitleTrack->pid == pid)) { - float duration = 3.0; + if (((AVStream *) _subtitleTrack->stream)->codec->codec) { + AVSubtitle sub; + memset(&sub, 0, sizeof(sub)); + int got_sub_ptr = 0; - pts = calcPts(avfc, _subtitleTrack->stream, packet.pts); + err = avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet); + averror(err, avcodec_decode_subtitle2); - if (duration > 0.0) { - /* is there a decoder ? */ - if (((AVStream *) _subtitleTrack->stream)->codec->codec) { - AVSubtitle sub; - memset(&sub, 0, sizeof(sub)); - int got_sub_ptr; - - if (avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) { - fprintf(stderr, "error decoding subtitle\n"); - } - - if (got_sub_ptr && sub.num_rects > 0) { - switch (sub.rects[0]->type) { - case SUBTITLE_TEXT: // FIXME? - case SUBTITLE_ASS: - dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid); - break; - case SUBTITLE_BITMAP: - dvbsub_write(&sub, pts); - // avsubtitle_free() will be called by handler - break; - default: - break; + if (got_sub_ptr && sub.num_rects > 0) { + switch (sub.rects[0]->type) { + case SUBTITLE_TEXT: // FIXME? + case SUBTITLE_ASS: + dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid); + break; + case SUBTITLE_BITMAP: { + int64_t pts = calcPts(avfc, _subtitleTrack->stream, packet.pts); + dvbsub_write(&sub, calcPts(avfc, _subtitleTrack->stream, pts)); + // avsubtitle_free() will be called by handler + break; } + default: + break; } } - } /* duration */ + } } else if (_teletextTrack && (_teletextTrack->pid == pid)) { teletext_write(pid, packet.data, packet.size); } @@ -262,12 +235,14 @@ bool Input::Play() av_free_packet(&packet); } /* while */ - if (player && player->abortRequested) + if (player->abortRequested) player->output.Clear(); + else + player->output.Flush(); dvbsub_ass_clear(); - player->abortPlayback = 1; - hasPlayThreadStarted = 0; + abortPlayback = true; + hasPlayThreadStarted = false; return true; } @@ -275,7 +250,10 @@ bool Input::Play() /*static*/ int interrupt_cb(void *arg) { Player *player = (Player *) arg; - return player->abortPlayback | player->abortRequested; + bool res = player->input.abortPlayback || player->abortRequested; + if (res) + fprintf(stderr, "%s %s %d: abort requested (%d/%d)\n", __FILE__, __func__, __LINE__, player->input.abortPlayback, player->abortRequested); + return res; } static void log_callback(void *ptr __attribute__ ((unused)), int lvl __attribute__ ((unused)), const char *format, va_list ap) @@ -293,11 +271,16 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) strcpy(subfile, filename); strcpy(subfile + (lastDot + 1 - filename), format); + if (access(subfile, R_OK)) + return false; + AVFormatContext *subavfc = avformat_alloc_context(); - if (avformat_open_input(&subavfc, subfile, av_find_input_format(format), 0)) { + int err = avformat_open_input(&subavfc, subfile, av_find_input_format(format), 0); + if (averror(err, avformat_open_input)) { avformat_free_context(subavfc); return false; } + avformat_find_stream_info(subavfc, NULL); if (subavfc->nb_streams != 1) { avformat_free_context(subavfc); @@ -311,12 +294,12 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid) return false; } - // fprintf(stderr, "codec=%s\n", avcodec_get_name(c->codec_id)); - if (avcodec_open2(c, codec, NULL) < 0) { - fprintf(stderr, "%s %d: avcodec_open\n", __FILE__, __LINE__); + err = avcodec_open2(c, codec, NULL); + if (averror(err, avcodec_open2)) { avformat_free_context(subavfc); return false; } + AVPacket avpkt; av_init_packet(&avpkt); @@ -356,47 +339,30 @@ bool Input::ReadSubtitles(const char *filename) { bool Input::Init(const char *filename) { - int err; - + abortPlayback = false; av_log_set_callback(log_callback); - if (filename == NULL) { + if (!filename) { fprintf(stderr, "filename NULL\n"); return false; } + fprintf(stderr, "%s %s %d: %s\n", __FILE__, __func__, __LINE__, filename); - if (isContainerRunning) { - fprintf(stderr, "ups already running?\n"); - return false; - } - isContainerRunning = true; - - /* initialize ffmpeg */ avcodec_register_all(); av_register_all(); - avformat_network_init(); - player->abortRequested = 0; - player->abortPlayback = 0; videoTrack = NULL; audioTrack = NULL; subtitleTrack = NULL; teletextTrack = NULL; avfc = avformat_alloc_context(); avfc->interrupt_callback.callback = interrupt_cb; - avfc->interrupt_callback.opaque = (void *) &player; + avfc->interrupt_callback.opaque = (void *) player; - if ((err = avformat_open_input(&avfc, filename, NULL, 0)) != 0) { - char error[512]; - - fprintf(stderr, "avformat_open_input failed %d (%s)\n", err, filename); - av_strerror(err, error, 512); - fprintf(stderr, "Cause: %s\n", error); - - isContainerRunning = false; + int err = avformat_open_input(&avfc, filename, NULL, 0); + if (averror(err, avformat_open_input)) return false; - } avfc->iformat->flags |= AVFMT_SEEK_TO_PTS; avfc->flags = AVFMT_FLAG_GENPTS; @@ -405,17 +371,10 @@ bool Input::Init(const char *filename) avfc->probesize = 8192; } - if (avformat_find_stream_info(avfc, NULL) < 0) { - fprintf(stderr, "Error avformat_find_stream_info\n"); -#ifdef this_is_ok - /* crow reports that sometimes this returns an error - * but the file is played back well. so remove this - * until other works are done and we can prove this. - */ + err = avformat_find_stream_info(avfc, NULL); + if (averror(err, avformat_open_input)) { avformat_close_input(&avfc); - isContainerRunning = false; return false; -#endif } terminating = false; @@ -424,7 +383,6 @@ bool Input::Init(const char *filename) if (!videoTrack && !audioTrack) { avformat_close_input(&avfc); - isContainerRunning = false; return false; } @@ -525,9 +483,9 @@ bool Input::UpdateTracks() snprintf(tmp, sizeof(tmp), "teletext_%d", i); t = av_dict_get(stream->metadata, tmp, NULL, 0); if (t) { - char lang[strlen(t->value)]; - if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) { - track.Name = lang; + char language[strlen(t->value)]; + if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, language, &track.type, &track.mag, &track.page)) { + track.Name = language; player->manager.addTeletextTrack(track); } } @@ -552,7 +510,6 @@ bool Input::UpdateTracks() fprintf(stderr, "not handled or unknown codec_type %d\n", stream->codec->codec_type); break; } - } return true; @@ -560,11 +517,7 @@ bool Input::UpdateTracks() bool Input::Stop() { - if (!isContainerRunning) { - fprintf(stderr, "Container not running\n"); - return false; - } - player->abortRequested = 1; + abortPlayback = true; while (hasPlayThreadStarted != 0) usleep(100000); @@ -574,8 +527,6 @@ bool Input::Stop() if (avfc) avformat_close_input(&avfc); - isContainerRunning = false; - avformat_network_deinit(); return true; @@ -594,16 +545,19 @@ bool Input::GetDuration(double &duration) { duration = 0.0; - if (videoTrack && videoTrack->duration != 0.0) { - duration = videoTrack->duration / 1000.0; + Track *track = videoTrack; + if (track && track->duration != 0.0) { + duration = track->duration / 1000.0; return true; } - if (audioTrack && audioTrack->duration != 0.0) { - duration = audioTrack->duration / 1000.0; + track = audioTrack; + if (track && track->duration != 0.0) { + duration = track->duration / 1000.0; return true; } - if (subtitleTrack && subtitleTrack->duration != 0.0) { - duration = subtitleTrack->duration / 1000.0; + track = subtitleTrack; + if (track && track->duration != 0.0) { + duration = track->duration / 1000.0; return true; } if (avfc && avfc->duration != 0.0) { @@ -665,11 +619,8 @@ bool Input::GetMetadata(std::vector &keys, std::vector keys.push_back(tag->key); values.push_back(tag->value); } - - return true; } - - return false; + return true; } bool Input::GetReadCount(uint64_t &readcount) diff --git a/libeplayer3/manager.cpp b/libeplayer3/manager.cpp index 0a2e758..37f4893 100644 --- a/libeplayer3/manager.cpp +++ b/libeplayer3/manager.cpp @@ -1,10 +1,12 @@ /* - * manager handling. + * manager class * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,8 +15,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -22,132 +23,95 @@ #include "manager.h" #include "player.h" -void Manager::addVideoTrack(Track &track) +void Manager::addTrack(std::map &tracks, Track &track) { OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = videoTracks.find(track.pid); - if (it == videoTracks.end()) { + std::map::iterator it = tracks.find(track.pid); + if (it == tracks.end()) { Track *t = new Track; *t = track; - videoTracks[track.pid] = t; + tracks[track.pid] = t; } else *it->second = track; } +void Manager::addVideoTrack(Track &track) +{ + addTrack(videoTracks, track); +} + void Manager::addAudioTrack(Track &track) { - OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = audioTracks.find(track.pid); - if (it == audioTracks.end()) { - Track *t = new Track; - *t = track; - audioTracks[track.pid] = t; - } else - *it->second = track; + addTrack(audioTracks, track); } void Manager::addSubtitleTrack(Track &track) { - OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = subtitleTracks.find(track.pid); - if (it == subtitleTracks.end()) { - Track *t = new Track; - *t = track; - subtitleTracks[track.pid] = t; - } else - *it->second = track; + addTrack(subtitleTracks, track); } void Manager::addTeletextTrack(Track &track) { + addTrack(teletextTracks, track); +} + +std::vector Manager::getTracks(std::map &tracks) +{ + player->input.UpdateTracks(); + std::vector res; OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = teletextTracks.find(track.pid); - if (it == teletextTracks.end()) { - Track *t = new Track; - *t = track; - teletextTracks[track.pid] = t; - } else - *it->second = track; + for(std::map::iterator it = tracks.begin(); it != tracks.end(); ++it) + if (!it->second->inactive) + res.push_back(*it->second); + return res; } std::vector Manager::getVideoTracks() { - player->input.UpdateTracks(); - std::vector res; - OpenThreads::ScopedLock m_lock(mutex); - for(std::map::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it) - if (!it->second->inactive) - res.push_back(*it->second); - return res; + return getTracks(videoTracks); } std::vector Manager::getAudioTracks() { - player->input.UpdateTracks(); - std::vector res; - OpenThreads::ScopedLock m_lock(mutex); - for(std::map::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it) - if (!it->second->inactive) - res.push_back(*it->second); - return res; + return getTracks(audioTracks); } std::vector Manager::getSubtitleTracks() { - player->input.UpdateTracks(); - std::vector res; - OpenThreads::ScopedLock m_lock(mutex); - for(std::map::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it) - if (!it->second->inactive) - res.push_back(*it->second); - return res; + return getTracks(subtitleTracks); } std::vector Manager::getTeletextTracks() { - player->input.UpdateTracks(); - std::vector res; - OpenThreads::ScopedLock m_lock(mutex); - for(std::map::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it) - if (!it->second->inactive) - res.push_back(*it->second); - return res; + return getTracks(teletextTracks); } -Track *Manager::getVideoTrack(int pid) +Track *Manager::getTrack(std::map &tracks, int pid) { OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = videoTracks.find(pid); - if (it != videoTracks.end() && !it->second->inactive) + std::map::iterator it = tracks.find(pid); + if (it != tracks.end() && !it->second->inactive) return it->second; return NULL; } +Track *Manager::getVideoTrack(int pid) +{ + return getTrack(videoTracks, pid); +} Track *Manager::getAudioTrack(int pid) { - OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = audioTracks.find(pid); - if (it != audioTracks.end() && !it->second->inactive) - return it->second; - return NULL; + return getTrack(audioTracks, pid); } Track *Manager::getSubtitleTrack(int pid) { - OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = subtitleTracks.find(pid); - if (it != subtitleTracks.end() && !it->second->inactive) - return it->second; - return NULL; + return getTrack(subtitleTracks, pid); } Track *Manager::getTeletextTrack(int pid) { - OpenThreads::ScopedLock m_lock(mutex); - std::map::iterator it = teletextTracks.find(pid); - if (it != teletextTracks.end() && !it->second->inactive) - return it->second; - return NULL; + return getTrack(teletextTracks, pid); } bool Manager::initTrackUpdate() diff --git a/libeplayer3/output.cpp b/libeplayer3/output.cpp index 2ee1bb1..07851a1 100644 --- a/libeplayer3/output.cpp +++ b/libeplayer3/output.cpp @@ -1,10 +1,14 @@ /* - * LinuxDVB Output handling. + * output class * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * based on libeplayer3 LinuxDVB Output handling. + * + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -13,8 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -209,12 +212,8 @@ bool Output::Continue() bool Output::Mute(bool b) { OpenThreads::ScopedLock a_lock(audioMutex); - //AUDIO_SET_MUTE has no effect with new player - if (audiofd > -1 && dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL)) - return false; - - return true; + return audiofd > -1 && !dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL); } @@ -237,48 +236,31 @@ bool Output::Flush() bool Output::FastForward(int speed) { OpenThreads::ScopedLock v_lock(videoMutex); - - if (videofd > -1 && dioctl(videofd, VIDEO_FAST_FORWARD, speed)) - return false; - - return true; + return videofd > -1 && !dioctl(videofd, VIDEO_FAST_FORWARD, speed); } bool Output::SlowMotion(int speed) { OpenThreads::ScopedLock v_lock(videoMutex); - - if (videofd > -1 && dioctl(videofd, VIDEO_SLOWMOTION, speed)) - return false; - - return true; + return videofd > -1 && !dioctl(videofd, VIDEO_SLOWMOTION, speed); } bool Output::AVSync(bool b) { OpenThreads::ScopedLock a_lock(audioMutex); - if (audiofd > -1 && dioctl(audiofd, AUDIO_SET_AV_SYNC, b)) - return false; - - return true; + return audiofd > -1 && !dioctl(audiofd, AUDIO_SET_AV_SYNC, b); } bool Output::ClearAudio() { OpenThreads::ScopedLock a_lock(audioMutex); - if (audiofd > -1 && dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL)) - return false; - - return true; + return audiofd > -1 && !dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); } bool Output::ClearVideo() { OpenThreads::ScopedLock v_lock(videoMutex); - if (videofd > -1 && dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL)) - return false; - - return true; + return videofd > -1 && !dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); } bool Output::Clear() @@ -349,20 +331,16 @@ bool Output::SwitchVideo(AVStream *stream) return true; } -bool Output::Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts) +bool Output::Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts) { switch (stream->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: { OpenThreads::ScopedLock v_lock(videoMutex); - if (videofd > -1 && videoWriter) - return videoWriter->Write(videofd, avfc, stream, packet, Pts); - return false; + return videofd > -1 && videoWriter && videoWriter->Write(videofd, avfc, stream, packet, pts); } case AVMEDIA_TYPE_AUDIO: { OpenThreads::ScopedLock a_lock(audioMutex); - if (audiofd > -1 && audioWriter) - return audioWriter->Write(audiofd, avfc, stream, packet, Pts); - return false; + return audiofd > -1 && audioWriter && audioWriter->Write(audiofd, avfc, stream, packet, pts); } default: return false; diff --git a/libeplayer3/player.cpp b/libeplayer3/player.cpp index eba06ae..cd6ce9b 100644 --- a/libeplayer3/player.cpp +++ b/libeplayer3/player.cpp @@ -1,19 +1,30 @@ /* - * GPL - * duckbox 2010 + * linuxdvb output/writer handling + * + * Copyright (C) 2010 duckbox + * Copyright (C) 2014 martii (based on code from libeplayer3) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include -#include -#include -#include -#include #include -#include -#include -#include +#include +#include #include "player.h" #include "misc.h" @@ -21,71 +32,56 @@ #define cMaxSpeed_ff 128 /* fixme: revise */ #define cMaxSpeed_fr -320 /* fixme: revise */ -static pthread_t supervisorThread; - Player::Player() { input.player = this; output.player = this; manager.player = this; - hasThreadStarted = 0; + hasThreadStarted = false; } void *Player::SupervisorThread(void *arg) { + char threadname[17]; + strncpy(threadname, __func__, sizeof(threadname)); + threadname[16] = 0; + prctl(PR_SET_NAME, (unsigned long) &threadname); + Player *player = (Player *) arg; - player->hasThreadStarted = 1; - + player->hasThreadStarted = true; player->input.Play(); - player->hasThreadStarted = 2; - player->Terminate(); - - fprintf(stderr, "terminating\n"); - player->hasThreadStarted = 0; + player->hasThreadStarted = false; + player->Stop(); pthread_exit(NULL); } -bool Player::Open(const char *Url) +bool Player::Open(const char *Url, bool _noprobe) { - if (isPlaying) - Stop(); // shouldn't happen. Most definitely a bug - fprintf(stderr, "URL=%s\n", Url); - if (isPlaying) { // shouldn't happen - fprintf(stderr, "playback already running\n"); - return false; - } + isHttp = false; + noprobe = _noprobe; + abortRequested = false; - isHttp = 0; - - if (!strncmp("file://", Url, 7) || !strncmp("myts://", Url, 7)) { - if (!strncmp("myts://", Url, 7)) { - url = "file"; - url += (Url + 4); - noprobe = 1; - } else { - noprobe = 0; - url = Url; - } - } else if (strstr(Url, "://")) { - isHttp = 1; - if (!strncmp("mms://", Url, 6)) { - url = "mmst"; - url += (Url + 3); - } else - url = Url; - } else { - fprintf(stderr, "Unknown stream (%s)\n", Url); - return false; - } manager.clearTracks(); + if (*Url == '/') { + url = "file://"; + url += Url; + } else if (!strncmp("mms://", Url, 6)) { + url = "mmst"; + url += Url + 3; + isHttp = true; + } else if (strstr(Url, "://")) { + url = Url; + } else { + fprintf(stderr, "%s %s %d: Unknown stream (%s)\n", __FILE__, __func__, __LINE__, Url); + return false; + } + if (!input.Init(url.c_str())) return false; - fprintf(stderr, "exiting with value 0\n"); - return true; } @@ -93,11 +89,11 @@ bool Player::Close() { bool ret = true; - isPaused = 0; - isPlaying = 0; - isForwarding = 0; - isBackWard = 0; - isSlowMotion = 0; + isPaused = false; + isPlaying = false; + isForwarding = false; + isBackWard = false; + isSlowMotion = false; Speed = 0; url.clear(); @@ -106,55 +102,41 @@ bool Player::Close() bool Player::Play() { - pthread_attr_t attr; bool ret = true; if (!isPlaying) { - AVSync = 1; - output.AVSync(true); + output.AVSync(true); - isCreationPhase = 1; // allows the created thread to go into wait mode - ret = output.Play(); + ret = output.Play(); - if (!ret) { - isCreationPhase = 0; // allow thread to go into next state - } else { - isPlaying = 1; - isPaused = 0; - isForwarding = 0; - if (isBackWard) { - isBackWard = 0; - output.Mute(false); - } - isSlowMotion = 0; - Speed = 1; + if (ret) { + isPlaying = true; + isPaused = false; + isForwarding = false; + if (isBackWard) { + isBackWard = false; + output.Mute(false); + } + isSlowMotion = false; + Speed = 1; - if (hasThreadStarted == 0) { - int error; - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED); + if (!hasThreadStarted) { + int err = pthread_create(&supervisorThread, NULL, SupervisorThread, this); - if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, this))) { - fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error)); - - ret = false; - } else { - fprintf(stderr, "Created thread\n"); + if (err) { + fprintf(stderr, "%s %s %d: pthread_create: %d (%s)\n", __FILE__, __func__, __LINE__, err, strerror(err)); + ret = false; + isPlaying = false; + } else { + pthread_detach(supervisorThread); + } } } - fprintf(stderr, "clearing isCreationPhase!\n"); - - isCreationPhase = 0; // allow thread to go into next state - } - } else { fprintf(stderr,"playback already running\n"); ret = false; } - - fprintf(stderr, "exiting with value %d\n", ret); - return ret; } @@ -164,27 +146,24 @@ bool Player::Pause() if (isPlaying && !isPaused) { - if (isSlowMotion) - output.Clear(); + if (isSlowMotion) + output.Clear(); - output.Pause(); + output.Pause(); - isPaused = 1; - //isPlaying = 1; - isForwarding = 0; - if (isBackWard) { - isBackWard = 0; - output.Mute(false); - } - isSlowMotion = 0; + isPaused = true; + //isPlaying = 1; + isForwarding = false; + if (isBackWard) { + isBackWard = false; + output.Mute(false); + } + isSlowMotion = false; Speed = 1; } else { fprintf(stderr,"playback not playing or already in pause mode\n"); ret = false; } - - fprintf(stderr, "exiting with value %d\n", ret); - return ret; } @@ -199,14 +178,14 @@ bool Player::Continue() output.Continue(); - isPaused = 0; + isPaused = false; //isPlaying = 1; - isForwarding = 0; + isForwarding = false; if (isBackWard) { - isBackWard = 0; + isBackWard = false; output.Mute(false); } - isSlowMotion = 0; + isSlowMotion = false; Speed = 1; } else { fprintf(stderr,"continue not possible\n"); @@ -219,87 +198,29 @@ bool Player::Continue() bool Player::Stop() { bool ret = true; - int wait_time = 20; if (isPlaying) { - isPaused = 0; - isPlaying = 0; - isForwarding = 0; - if (isBackWard) { - isBackWard = 0; - output.Mute(false); - } - isSlowMotion = 0; - Speed = 0; + isPaused = false; + isPlaying = false; + isForwarding = false; + if (isBackWard) { + isBackWard = false; + output.Mute(false); + } + isSlowMotion = false; + Speed = 0; - output.Stop(); - input.Stop(); + output.Stop(); + input.Stop(); } else { fprintf(stderr,"stop not possible\n"); ret = false; } - while ((hasThreadStarted == 1) && (--wait_time) > 0) { - fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); - + while (hasThreadStarted) usleep(100000); - } - - if (wait_time == 0) { - fprintf(stderr,"Timeout waiting for thread!\n"); - - ret = false; - } - - fprintf(stderr, "exiting with value %d\n", ret); - - return ret; -} - -// FIXME -bool Player::Terminate() -{ - bool ret = true; - int wait_time = 20; - - fprintf(stderr, "\n"); - - if (isPlaying) { - - if (!abortRequested && !output.Flush()) { - fprintf(stderr,"failed to flush output.\n"); - } - - ret = input.Stop(); - isPaused = 0; - isPlaying = 0; - isForwarding = 0; - isBackWard = 0; - isSlowMotion = 0; - Speed = 0; - - } else { - /* fixme: konfetti: we should return an error here but this seems to be a condition which - * can happen and is not a real error, which leads to a dead neutrino. should investigate - * here later. - */ - } - - while ((hasThreadStarted == 1) && (--wait_time) > 0) { - fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time); - - usleep(100000); - } - - if (wait_time == 0) { - fprintf(stderr,"Timeout waiting for thread!\n"); - - ret = false; - } - - fprintf(stderr, "exiting with value %d\n", ret); return ret; } @@ -309,7 +230,7 @@ bool Player::FastForward(int speed) int ret = true; /* Audio only forwarding not supported */ - if (isVideo && !isHttp && !isBackWard && (!isPaused || isPlaying)) { + if (input.videoTrack && !isHttp && !isBackWard && (!isPaused || isPlaying)) { if ((speed <= 0) || (speed > cMaxSpeed_ff)) { fprintf(stderr, "speed %d out of range (1 - %d) \n", speed, cMaxSpeed_ff); @@ -332,7 +253,7 @@ bool Player::FastBackward(int speed) bool ret = true; /* Audio only reverse play not supported */ - if (isVideo && !isForwarding && (!isPaused || isPlaying)) { + if (input.videoTrack && !isForwarding && (!isPaused || isPlaying)) { if ((speed > 0) || (speed < cMaxSpeed_fr)) { fprintf(stderr, "speed %d out of range (0 - %d) \n", speed, cMaxSpeed_fr); @@ -341,7 +262,7 @@ bool Player::FastBackward(int speed) if (speed == 0) { isBackWard = false; - Speed = false; /* reverse end */ + Speed = 0; /* reverse end */ } else { Speed = speed; isBackWard = true; @@ -351,7 +272,7 @@ bool Player::FastBackward(int speed) #if 0 if (output->Command(player, OUTPUT_REVERSE, NULL) < 0) { fprintf(stderr,"OUTPUT_REVERSE failed\n"); - isBackWard = 0; + isBackWard = false; Speed = 1; ret = false; } @@ -369,7 +290,7 @@ bool Player::FastBackward(int speed) bool Player::SlowMotion(int repeats) { - if (isVideo && !isHttp && isPlaying) { + if (input.videoTrack && !isHttp && isPlaying) { if (isPaused) Continue(); @@ -398,56 +319,43 @@ bool Player::Seek(float pos, bool absolute) bool Player::GetPts(int64_t &pts) { - if (isPlaying) - return output.GetPts(pts); - return false; + pts = INVALID_PTS_VALUE; + return isPlaying && output.GetPts(pts); } bool Player::GetFrameCount(int64_t &frameCount) { - if (isPlaying) - return output.GetFrameCount(frameCount); - return false; + return isPlaying && output.GetFrameCount(frameCount); } bool Player::GetDuration(double &duration) { duration = -1; - if (isPlaying) - return input.GetDuration(duration); - return false; + return isPlaying && input.GetDuration(duration); } bool Player::SwitchVideo(int pid) { Track *track = manager.getVideoTrack(pid); - if (track) - input.SwitchVideo(track); - return !!track; + return track && input.SwitchVideo(track); } bool Player::SwitchAudio(int pid) { Track *track = manager.getAudioTrack(pid); - if (track) - input.SwitchAudio(track); - return !!track; + return track && input.SwitchAudio(track); } bool Player::SwitchSubtitle(int pid) { Track *track = manager.getSubtitleTrack(pid); - if (track) - input.SwitchSubtitle(track); - return !!track; + return track && input.SwitchSubtitle(track); } bool Player::SwitchTeletext(int pid) { Track *track = manager.getTeletextTrack(pid); - if (track) - input.SwitchTeletext(track); - return !!track; + return track && input.SwitchTeletext(track); } bool Player::GetMetadata(std::vector &keys, std::vector &values) @@ -473,3 +381,8 @@ void Player::SetChapters(std::vector &Chapters) OpenThreads::ScopedLock m_lock(chapterMutex); chapters = Chapters; } + +void Player::RequestAbort() +{ + abortRequested = true; +} diff --git a/libeplayer3/writer/ac3.cpp b/libeplayer3/writer/ac3.cpp index acc99af..ec0d5b0 100644 --- a/libeplayer3/writer/ac3.cpp +++ b/libeplayer3/writer/ac3.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -33,11 +33,11 @@ class WriterAC3 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); WriterAC3(); }; -bool WriterAC3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterAC3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; diff --git a/libeplayer3/writer/divx.cpp b/libeplayer3/writer/divx.cpp index 5133e82..5629527 100644 --- a/libeplayer3/writer/divx.cpp +++ b/libeplayer3/writer/divx.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -26,14 +26,7 @@ #include #include #include -#include #include -#include -#include -#include -#include -#include -#include #include #include "misc.h" @@ -45,7 +38,7 @@ class WriterDIVX : public Writer private: bool initialHeader; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); void Init(); WriterDIVX(); }; @@ -55,7 +48,7 @@ void WriterDIVX::Init() initialHeader = true; } -bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) +bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; diff --git a/libeplayer3/writer/dts.cpp b/libeplayer3/writer/dts.cpp index aac6543..1e89ec8 100644 --- a/libeplayer3/writer/dts.cpp +++ b/libeplayer3/writer/dts.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -36,11 +36,11 @@ class WriterDTS : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); WriterDTS(); }; -bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; diff --git a/libeplayer3/writer/flac.cpp b/libeplayer3/writer/flac.cpp index f97b913..707d00b 100644 --- a/libeplayer3/writer/flac.cpp +++ b/libeplayer3/writer/flac.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -33,11 +33,11 @@ class WriterFLAC : public Writer { public: - bool Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts); WriterFLAC(); }; -bool WriterFLAC::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterFLAC::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return -1; diff --git a/libeplayer3/writer/h263.cpp b/libeplayer3/writer/h263.cpp index bb7e60a..188ca88 100644 --- a/libeplayer3/writer/h263.cpp +++ b/libeplayer3/writer/h263.cpp @@ -1,12 +1,14 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * crow 2010 + * Copyright (C) 2010 crow + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -31,11 +32,11 @@ class WriterH263 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); WriterH263(); }; -bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; diff --git a/libeplayer3/writer/h264.cpp b/libeplayer3/writer/h264.cpp index 5f5f06f..f4e54ef 100644 --- a/libeplayer3/writer/h264.cpp +++ b/libeplayer3/writer/h264.cpp @@ -1,12 +1,15 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -52,7 +54,7 @@ class WriterH264 : public Writer bool initialHeader; unsigned int NalLengthBytes; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); void Init(); WriterH264(); }; @@ -64,12 +66,11 @@ void WriterH264::Init(void) NalLengthBytes = 1; } -bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) +bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - unsigned long long int VideoPts; unsigned int TimeDelta; unsigned int TimeScale; int len = 0; @@ -78,7 +79,6 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */ TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */ - VideoPts = pts; if ((packet->size > 3) && ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01) @@ -251,13 +251,13 @@ bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, A iov[ic++].iov_len = NalLength; VideoPosition += NalLength; - iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); + iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, pts, 0); ssize_t l = writev(fd, iov, ic); if (l < 0) return false; len += l; - VideoPts = INVALID_PTS_VALUE; + pts = INVALID_PTS_VALUE; } } while (NalStart < SampleSize); diff --git a/libeplayer3/writer/mp3.cpp b/libeplayer3/writer/mp3.cpp index 73525aa..8d3502e 100644 --- a/libeplayer3/writer/mp3.cpp +++ b/libeplayer3/writer/mp3.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -33,11 +33,11 @@ class WriterMP3 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); WriterMP3(); }; -bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; diff --git a/libeplayer3/writer/mpeg2.cpp b/libeplayer3/writer/mpeg2.cpp index 46c98a9..66be81a 100644 --- a/libeplayer3/writer/mpeg2.cpp +++ b/libeplayer3/writer/mpeg2.cpp @@ -1,12 +1,13 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -35,24 +35,22 @@ class WriterMPEG2 : public Writer { public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); WriterMPEG2(); }; -bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int64_t _pts = pts; - for (int Position = 0; Position < packet->size; ) { int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); struct iovec iov[2]; iov[0].iov_base = PesHeader; - iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, _pts, 0); + iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, pts, 0); iov[1].iov_base = packet->data + Position; iov[1].iov_len = PacketLength; @@ -62,7 +60,7 @@ bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stre break; } Position += PacketLength; - _pts = INVALID_PTS_VALUE; + pts = INVALID_PTS_VALUE; } return true; } diff --git a/libeplayer3/writer/pcm.cpp b/libeplayer3/writer/pcm.cpp index 16f4c84..5ae2f2b 100644 --- a/libeplayer3/writer/pcm.cpp +++ b/libeplayer3/writer/pcm.cpp @@ -1,7 +1,8 @@ /* * linuxdvb output/writer handling. * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -74,7 +75,7 @@ class WriterPCM : public Writer bool restart_audio_resampling; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); bool prepareClipPlay(); int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size); void Init(); @@ -230,7 +231,7 @@ void WriterPCM::Init() extern int64_t calcPts(AVFormatContext *, AVStream *, int64_t); -bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts) +bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts) { if (fd < 0) return false; @@ -325,7 +326,6 @@ bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket continue; } // FIXME. PTS calculation is probably broken. - int64_t pts; int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame), stream->time_base.num * (int64_t) out_sample_rate * c->sample_rate, stream->time_base.den); diff --git a/libeplayer3/writer/pes.cpp b/libeplayer3/writer/pes.cpp index f14ee53..aef9582 100644 --- a/libeplayer3/writer/pes.cpp +++ b/libeplayer3/writer/pes.cpp @@ -1,7 +1,8 @@ /* * linuxdvb output/writer handling. * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -19,10 +20,6 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include #include #include @@ -35,87 +32,85 @@ int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size) { - BitPacker_t ld2 = { data, 0, 32 }; - int i; + BitPacker_t ld2 = { data, 0, 32 }; + int i; - PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8); - PutBits(&ld2, payload_size & 0xff, 8); - PutBits(&ld2, (payload_size >> 8) & 0xff, 8); - PutBits(&ld2, (payload_size >> 16) & 0xff, 8); + PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8); + PutBits(&ld2, payload_size & 0xff, 8); + PutBits(&ld2, (payload_size >> 8) & 0xff, 8); + PutBits(&ld2, (payload_size >> 16) & 0xff, 8); - for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++) - PutBits(&ld2, 0, 8); + for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++) + PutBits(&ld2, 0, 8); - FlushBits(&ld2); + FlushBits(&ld2); - return PES_PRIVATE_DATA_LENGTH + 1; + return PES_PRIVATE_DATA_LENGTH + 1; } -int InsertPesHeader(unsigned char *data, int size, unsigned char stream_id, - unsigned long long int pts, int pic_start_code) +int InsertPesHeader(uint8_t *data, int size, unsigned char stream_id, int64_t pts, int pic_start_code) { - BitPacker_t ld2 = { data, 0, 32 }; + BitPacker_t ld2 = { data, 0, 32 }; - if (size > MAX_PES_PACKET_SIZE) - size = 0; // unbounded + if (size > MAX_PES_PACKET_SIZE) + size = 0; // unbounded - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x0, 8); - PutBits(&ld2, 0x1, 8); // Start Code - PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream - //4 - PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length - //6 = 4+2 - PutBits(&ld2, 0x2, 2); // 10 - PutBits(&ld2, 0x0, 2); // PES_Scrambling_control - PutBits(&ld2, 0x0, 1); // PES_Priority - PutBits(&ld2, 0x0, 1); // data_alignment_indicator - PutBits(&ld2, 0x0, 1); // Copyright - PutBits(&ld2, 0x0, 1); // Original or Copy - //7 = 6+1 - - if (pts != INVALID_PTS_VALUE) - PutBits(&ld2, 0x2, 2); - else - PutBits(&ld2, 0x0, 2); // PTS_DTS flag - - PutBits(&ld2, 0x0, 1); // ESCR_flag - PutBits(&ld2, 0x0, 1); // ES_rate_flag - PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag - PutBits(&ld2, 0x0, 1); // additional_copy_ingo_flag - PutBits(&ld2, 0x0, 1); // PES_CRC_flag - PutBits(&ld2, 0x0, 1); // PES_extension_flag - //8 = 7+1 - - if (pts != INVALID_PTS_VALUE) - PutBits(&ld2, 0x5, 8); - else - PutBits(&ld2, 0x0, 8); // PES_header_data_length - //9 = 8+1 - - if (pts != INVALID_PTS_VALUE) { - PutBits(&ld2, 0x2, 4); - PutBits(&ld2, (pts >> 30) & 0x7, 3); - PutBits(&ld2, 0x1, 1); - PutBits(&ld2, (pts >> 15) & 0x7fff, 15); - PutBits(&ld2, 0x1, 1); - PutBits(&ld2, pts & 0x7fff, 15); - PutBits(&ld2, 0x1, 1); - } - //14 = 9+5 - - if (pic_start_code) { PutBits(&ld2, 0x0, 8); PutBits(&ld2, 0x0, 8); 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 - } + PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream + //4 + PutBits(&ld2, size + 3 + (pts != INVALID_PTS_VALUE ? 5 : 0) + (pic_start_code ? (5) : 0), 16); // PES_packet_length + //6 = 4+2 + PutBits(&ld2, 0x2, 2); // 10 + PutBits(&ld2, 0x0, 2); // PES_Scrambling_control + PutBits(&ld2, 0x0, 1); // PES_Priority + PutBits(&ld2, 0x0, 1); // data_alignment_indicator + PutBits(&ld2, 0x0, 1); // Copyright + PutBits(&ld2, 0x0, 1); // Original or Copy + //7 = 6+1 - FlushBits(&ld2); + if (pts != INVALID_PTS_VALUE) + PutBits(&ld2, 0x2, 2); + else + PutBits(&ld2, 0x0, 2); // PTS_DTS flag - return (ld2.Ptr - data); + PutBits(&ld2, 0x0, 1); // ESCR_flag + PutBits(&ld2, 0x0, 1); // ES_rate_flag + PutBits(&ld2, 0x0, 1); // DSM_trick_mode_flag + PutBits(&ld2, 0x0, 1); // additional_copy_ingo_flag + PutBits(&ld2, 0x0, 1); // PES_CRC_flag + PutBits(&ld2, 0x0, 1); // PES_extension_flag + //8 = 7+1 + if (pts != INVALID_PTS_VALUE) + PutBits(&ld2, 0x5, 8); + else + PutBits(&ld2, 0x0, 8); // PES_header_data_length + //9 = 8+1 + + if (pts != INVALID_PTS_VALUE) { + PutBits(&ld2, 0x2, 4); + PutBits(&ld2, (pts >> 30) & 0x7, 3); + PutBits(&ld2, 0x1, 1); + PutBits(&ld2, (pts >> 15) & 0x7fff, 15); + PutBits(&ld2, 0x1, 1); + PutBits(&ld2, pts & 0x7fff, 15); + PutBits(&ld2, 0x1, 1); + } + //14 = 9+5 + + if (pic_start_code) { + PutBits(&ld2, 0x0, 8); + PutBits(&ld2, 0x0, 8); + 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 + } + + FlushBits(&ld2); + + return (ld2.Ptr - data); } diff --git a/libeplayer3/writer/vc1.cpp b/libeplayer3/writer/vc1.cpp index d451725..7422cd7 100644 --- a/libeplayer3/writer/vc1.cpp +++ b/libeplayer3/writer/vc1.cpp @@ -1,12 +1,15 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -50,7 +52,7 @@ class WriterVC1 : public Writer unsigned char FrameHeaderSeen; double frameRate; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); void Init(); WriterVC1(); }; @@ -60,7 +62,7 @@ void WriterVC1::Init() initialHeader = true; } -bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts) +bool WriterVC1::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; @@ -138,8 +140,6 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket initialHeader = false; } - int64_t _pts = pts; - if (packet->size > 0) { int Position = 0; unsigned char insertSampleHeader = 1; @@ -147,7 +147,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket while (Position < packet->size) { int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); + int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, pts, 0); if (insertSampleHeader) { const unsigned char Vc1FrameStartCode[] = { 0, 0, 1, VC1_FRAME_START_CODE }; @@ -172,7 +172,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket return false; Position += PacketLength; - _pts = INVALID_PTS_VALUE; + pts = INVALID_PTS_VALUE; } } diff --git a/libeplayer3/writer/wmv.cpp b/libeplayer3/writer/wmv.cpp index 8fb5fba..fa62a17 100644 --- a/libeplayer3/writer/wmv.cpp +++ b/libeplayer3/writer/wmv.cpp @@ -1,12 +1,15 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 based on linuxdvb.c code from libeplayer2 + * Copyright (C) 2010 konfetti (based on code from libeplayer2) + * Copyright (C) 2014 martii (based on code from libeplayer3) * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * Copyright (C) 2014 martii + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,8 +18,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include @@ -56,7 +58,7 @@ class WriterWMV : public Writer private: bool initialHeader; public: - bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t pts); void Init(); WriterWMV(); }; @@ -66,7 +68,7 @@ void WriterWMV::Init() initialHeader = 1; } -bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) +bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t pts) { if (fd < 0 || !packet) return false; @@ -120,14 +122,12 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV int Position = 0; bool insertSampleHeader = true; - uint64_t _pts = pts; - while (Position < packet->size) { int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 }; - int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); + int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, pts, 0); if (insertSampleHeader) { unsigned int PesLength; @@ -152,7 +152,7 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV return false; Position += PacketLength; - _pts = INVALID_PTS_VALUE; + pts = INVALID_PTS_VALUE; } } diff --git a/libeplayer3/writer/writer.cpp b/libeplayer3/writer/writer.cpp index c1deac9..e15a426 100644 --- a/libeplayer3/writer/writer.cpp +++ b/libeplayer3/writer/writer.cpp @@ -1,12 +1,12 @@ /* - * linuxdvb output/writer handling. + * linuxdvb output/writer handling * - * konfetti 2010 + * Copyright (C) 2014 martii * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of @@ -15,19 +15,13 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include -#include -#include -#include -#include -#include #include #include @@ -37,18 +31,17 @@ // This does suck ... the original idea was to just link the object files and let them register themselves. // Alas, that didn't work as expected. - +#include "ac3.cpp" #include "divx.cpp" +#include "dts.cpp" +#include "flac.cpp" #include "h263.cpp" #include "h264.cpp" #include "mp3.cpp" -#include "vc1.cpp" -#include "wmv.cpp" -#include "ac3.cpp" -#include "dts.cpp" -#include "flac.cpp" #include "mpeg2.cpp" #include "pcm.cpp" +#include "vc1.cpp" +#include "wmv.cpp" static std::mapwriters __attribute__ ((init_priority (200))); static std::mapvencoding __attribute__ ((init_priority (200))); @@ -66,7 +59,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(int /* fd */, AVFormatContext * /* avfc */, AVStream * /*stream*/, AVPacket * /* packet */, int64_t /* pts */) { return false; } @@ -75,26 +68,21 @@ static Writer writer __attribute__ ((init_priority (300))); Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type) { -fprintf(stderr, "%s %s %d\n", __FILE__,__func__,__LINE__); std::map::iterator it = writers.find(id); if (it != writers.end()) return it->second; -fprintf(stderr, "%s %s %d: no writer found\n", __FILE__,__func__,__LINE__); switch (codec_type) { case AVMEDIA_TYPE_AUDIO: if (id == AV_CODEC_ID_INJECTPCM) // should not happen break; -fprintf(stderr, "%s %s %d: returning injectpcm\n", __FILE__,__func__,__LINE__); return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type); case AVMEDIA_TYPE_VIDEO: if (id == AV_CODEC_ID_MPEG2TS) // should not happen break; -fprintf(stderr, "%s %s %d: returning mpeg2video\n", __FILE__,__func__,__LINE__); return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type); default: break; } -fprintf(stderr, "%s %s %d: returning dummy writer\n", __FILE__,__func__,__LINE__); return &writer; }