mirror of
https://github.com/tuxbox-fork-migrations/recycled-ni-libstb-hal.git
synced 2025-08-26 23:12:44 +02:00
libeplayer3: continue refresh
Origin commit data
------------------
Branch: master
Commit: 7d49d4d32b
Author: martii <m4rtii@gmx.de>
Date: 2014-04-08 (Tue, 08 Apr 2014)
------------------
No further description and justification available within origin commit message!
------------------
This commit was generated by Migit
This commit is contained in:
@@ -1,9 +1,8 @@
|
|||||||
noinst_LTLIBRARIES = libeplayer3.la
|
noinst_LTLIBRARIES = libeplayer3.la
|
||||||
|
|
||||||
CXXFLAGS = -Wall
|
|
||||||
|
|
||||||
AM_CPPFLAGS = -I$(srcdir)/include
|
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 += -D__STDC_CONSTANT_MACROS -D__STDC_LIMIT_MACROS
|
||||||
AM_CPPFLAGS += -ggdb
|
AM_CPPFLAGS += -ggdb
|
||||||
|
|
||||||
|
@@ -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:
|
* SCOPE:
|
||||||
* -------
|
* -------
|
||||||
|
@@ -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__
|
#ifndef __INPUT_H__
|
||||||
#define __INPUT_H__
|
#define __INPUT_H__
|
||||||
|
|
||||||
@@ -24,6 +44,7 @@ class Track;
|
|||||||
class Input
|
class Input
|
||||||
{
|
{
|
||||||
friend class Player;
|
friend class Player;
|
||||||
|
friend int interrupt_cb(void *arg);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Track *videoTrack;
|
Track *videoTrack;
|
||||||
@@ -36,6 +57,7 @@ class Input
|
|||||||
float seek_sec_rel;
|
float seek_sec_rel;
|
||||||
bool isContainerRunning;
|
bool isContainerRunning;
|
||||||
bool terminating;
|
bool terminating;
|
||||||
|
bool abortPlayback;
|
||||||
|
|
||||||
Player *player;
|
Player *player;
|
||||||
AVFormatContext *avfc;
|
AVFormatContext *avfc;
|
||||||
|
@@ -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__
|
#ifndef __MANAGER_H__
|
||||||
#define __MANAGER_H__
|
#define __MANAGER_H__
|
||||||
|
|
||||||
@@ -24,21 +44,13 @@ struct Track
|
|||||||
{
|
{
|
||||||
std::string Name;
|
std::string Name;
|
||||||
int pid;
|
int pid;
|
||||||
|
|
||||||
/* length of track */
|
|
||||||
int64_t duration;
|
int64_t duration;
|
||||||
|
|
||||||
/* context from ffmpeg */
|
|
||||||
AVFormatContext *avfc;
|
AVFormatContext *avfc;
|
||||||
/* stream from ffmpeg */
|
|
||||||
AVStream *stream;
|
AVStream *stream;
|
||||||
|
|
||||||
bool inactive;
|
bool inactive;
|
||||||
bool is_static;
|
bool is_static;
|
||||||
|
|
||||||
int ac3flags;
|
int ac3flags;
|
||||||
int type, mag, page; // for teletext
|
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), duration(-1), avfc(NULL), stream(NULL), inactive(0), is_static(0), ac3flags(0) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -49,7 +61,10 @@ class Manager
|
|||||||
private:
|
private:
|
||||||
Player *player;
|
Player *player;
|
||||||
OpenThreads::Mutex mutex;
|
OpenThreads::Mutex mutex;
|
||||||
std::map<int,Track *> videoTracks, audioTracks, subtitleTracks, teletextTracks;
|
std::map<int,Track*> videoTracks, audioTracks, subtitleTracks, teletextTracks;
|
||||||
|
void addTrack(std::map<int,Track*> &tracks, Track &track);
|
||||||
|
Track *getTrack(std::map<int,Track*> &tracks, int pid);
|
||||||
|
std::vector<Track> getTracks(std::map<int,Track*> &tracks);
|
||||||
public:
|
public:
|
||||||
void addVideoTrack(Track &track);
|
void addVideoTrack(Track &track);
|
||||||
void addAudioTrack(Track &track);
|
void addAudioTrack(Track &track);
|
||||||
|
@@ -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__
|
#ifndef __OUTPUT_H__
|
||||||
#define __OUTPUT_H__
|
#define __OUTPUT_H__
|
||||||
|
|
||||||
@@ -54,7 +74,7 @@ class Output
|
|||||||
bool GetFrameCount(int64_t &framecount);
|
bool GetFrameCount(int64_t &framecount);
|
||||||
bool SwitchAudio(AVStream *stream);
|
bool SwitchAudio(AVStream *stream);
|
||||||
bool SwitchVideo(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
|
#endif
|
||||||
|
@@ -28,7 +28,7 @@
|
|||||||
#define VC1_VIDEO_PES_START_CODE 0xfd
|
#define VC1_VIDEO_PES_START_CODE 0xfd
|
||||||
#define AAC_AUDIO_PES_START_CODE 0xcf
|
#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);
|
int InsertVideoPrivateDataHeader(uint8_t *data, int payload_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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__
|
#ifndef __PLAYER_H__
|
||||||
#define __PLAYER_H__
|
#define __PLAYER_H__
|
||||||
|
|
||||||
@@ -44,52 +64,50 @@ class Player {
|
|||||||
Manager manager;
|
Manager manager;
|
||||||
OpenThreads::Mutex chapterMutex;
|
OpenThreads::Mutex chapterMutex;
|
||||||
std::vector<Chapter> chapters;
|
std::vector<Chapter> chapters;
|
||||||
bool abortPlayback;
|
pthread_t supervisorThread;
|
||||||
|
|
||||||
bool abortRequested;
|
bool abortRequested;
|
||||||
bool isHttp;
|
bool isHttp;
|
||||||
bool isPaused;
|
bool isPaused;
|
||||||
bool isCreationPhase;
|
|
||||||
bool isSlowMotion;
|
bool isSlowMotion;
|
||||||
int Speed;
|
bool hasThreadStarted;
|
||||||
int AVSync;
|
bool isForwarding;
|
||||||
|
bool isBackWard;
|
||||||
|
bool isPlaying;
|
||||||
|
|
||||||
bool isVideo;
|
int Speed;
|
||||||
bool isAudio;
|
|
||||||
|
uint64_t readCount;
|
||||||
|
|
||||||
std::string url;
|
std::string url;
|
||||||
bool noprobe; /* hack: only minimal probing in av_find_stream_info */
|
bool noprobe; /* hack: only minimal probing in av_find_stream_info */
|
||||||
|
|
||||||
int hasThreadStarted;
|
void SetChapters(std::vector<Chapter> &Chapters);
|
||||||
|
|
||||||
static void* SupervisorThread(void*);
|
static void* SupervisorThread(void*);
|
||||||
public:
|
public:
|
||||||
bool isForwarding;
|
|
||||||
bool isBackWard;
|
|
||||||
bool isPlaying;
|
|
||||||
uint64_t readCount;
|
|
||||||
|
|
||||||
bool SwitchAudio(int pid);
|
bool SwitchAudio(int pid);
|
||||||
bool SwitchVideo(int pid);
|
bool SwitchVideo(int pid);
|
||||||
bool SwitchTeletext(int pid);
|
bool SwitchTeletext(int pid);
|
||||||
bool SwitchSubtitle(int pid);
|
bool SwitchSubtitle(int pid);
|
||||||
|
|
||||||
bool GetPts(int64_t &pts);
|
bool GetPts(int64_t &pts);
|
||||||
bool GetFrameCount(int64_t &framecount);
|
bool GetFrameCount(int64_t &framecount);
|
||||||
bool GetDuration(double &duration);
|
bool GetDuration(double &duration);
|
||||||
|
|
||||||
bool GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
|
bool GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values);
|
||||||
bool SlowMotion(int repeats);
|
bool SlowMotion(int repeats);
|
||||||
bool FastBackward(int speed);
|
bool FastBackward(int speed);
|
||||||
bool FastForward(int speed);
|
bool FastForward(int speed);
|
||||||
bool Open(const char *Url);
|
bool Open(const char *Url, bool noprobe = false);
|
||||||
bool Close();
|
bool Close();
|
||||||
bool Play();
|
bool Play();
|
||||||
bool Pause();
|
bool Pause();
|
||||||
bool Continue();
|
bool Continue();
|
||||||
bool Stop();
|
bool Stop();
|
||||||
bool Seek(float pos, bool absolute);
|
bool Seek(float pos, bool absolute);
|
||||||
bool Terminate();
|
void RequestAbort();
|
||||||
bool GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
|
bool GetChapters(std::vector<int> &positions, std::vector<std::string> &titles);
|
||||||
void SetChapters(std::vector<Chapter> &Chapters);
|
|
||||||
Player();
|
|
||||||
|
|
||||||
|
Player();
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
@@ -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__
|
#ifndef __WRITER_H__
|
||||||
#define __WRITER_H__
|
#define __WRITER_H__
|
||||||
|
|
||||||
@@ -27,7 +47,7 @@ class Writer
|
|||||||
static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type);
|
static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type);
|
||||||
|
|
||||||
virtual void Init(void) { }
|
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() { Init (); }
|
||||||
~Writer() {}
|
~Writer() {}
|
||||||
|
@@ -1,12 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* Container handling for all stream's handled by ffmpeg
|
* input class
|
||||||
* konfetti 2010; based on code from crow
|
|
||||||
*
|
*
|
||||||
|
* 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
|
* Copyright (C) 2014 martii
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* This program is free software; you can redistribute it and/or
|
||||||
* (at your option) any later version.
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <memory.h>
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <errno.h>
|
|
||||||
#include <sys/poll.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <sys/prctl.h>
|
|
||||||
|
|
||||||
#include <linux/dvb/stm_ioctls.h>
|
|
||||||
|
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "misc.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()
|
Input::Input()
|
||||||
{
|
{
|
||||||
videoTrack = NULL;
|
videoTrack = NULL;
|
||||||
@@ -48,7 +47,6 @@ Input::Input()
|
|||||||
teletextTrack = NULL;
|
teletextTrack = NULL;
|
||||||
|
|
||||||
hasPlayThreadStarted = 0;
|
hasPlayThreadStarted = 0;
|
||||||
isContainerRunning = 0;
|
|
||||||
seek_sec_abs = -1.0;
|
seek_sec_abs = -1.0;
|
||||||
seek_sec_rel = 0.0;
|
seek_sec_rel = 0.0;
|
||||||
terminating = false;
|
terminating = false;
|
||||||
@@ -67,14 +65,14 @@ int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pts == AV_NOPTS_VALUE)
|
if (pts == AV_NOPTS_VALUE)
|
||||||
pts = INVALID_PTS_VALUE;
|
return 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;
|
|
||||||
|
|
||||||
if (pts & 0x8000000000000000ull)
|
pts = 90000.0 * (double) pts * av_q2d(stream->time_base);
|
||||||
pts = INVALID_PTS_VALUE;
|
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;
|
return pts;
|
||||||
}
|
}
|
||||||
@@ -88,23 +86,11 @@ extern "C" void teletext_write(int pid, uint8_t *data, int size);
|
|||||||
|
|
||||||
bool Input::Play()
|
bool Input::Play()
|
||||||
{
|
{
|
||||||
char threadname[17];
|
|
||||||
strncpy(threadname, __func__, sizeof(threadname));
|
|
||||||
threadname[16] = 0;
|
|
||||||
prctl(PR_SET_NAME, (unsigned long) &threadname);
|
|
||||||
|
|
||||||
hasPlayThreadStarted = 1;
|
hasPlayThreadStarted = 1;
|
||||||
|
|
||||||
int64_t currentVideoPts = 0, currentAudioPts = 0, showtime = 0, bofcount = 0;
|
int64_t showtime = 0, bofcount = 0;
|
||||||
bool restart_audio_resampling = false;
|
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) {
|
while (player->isPlaying && !player->abortRequested) {
|
||||||
|
|
||||||
//IF MOVIE IS PAUSED, WAIT
|
//IF MOVIE IS PAUSED, WAIT
|
||||||
@@ -123,7 +109,9 @@ bool Input::Play()
|
|||||||
seek_target_flag = AVSEEK_FLAG_BYTE;
|
seek_target_flag = AVSEEK_FLAG_BYTE;
|
||||||
seek_target = avio_tell(avfc->pb) + seek_sec_rel * br;
|
seek_target = avio_tell(avfc->pb) + seek_sec_rel * br;
|
||||||
} else {
|
} 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;
|
seek_sec_rel = 0.0;
|
||||||
} else if (seek_sec_abs >= 0.0) {
|
} else if (seek_sec_abs >= 0.0) {
|
||||||
@@ -147,17 +135,15 @@ bool Input::Play()
|
|||||||
if (avfc->iformat->flags & AVFMT_TS_DISCONT) {
|
if (avfc->iformat->flags & AVFMT_TS_DISCONT) {
|
||||||
off_t pos = avio_tell(avfc->pb);
|
off_t pos = avio_tell(avfc->pb);
|
||||||
|
|
||||||
if (pos > 0) {
|
if (pos > 0) {
|
||||||
float br;
|
float br = avfc->bit_rate ? avfc->bit_rate / 8.0 : 180000.0;
|
||||||
if (avfc->bit_rate)
|
seek_target_flag = AVSEEK_FLAG_BYTE;
|
||||||
br = avfc->bit_rate / 8.0;
|
seek_target = pos + player->Speed * 8 * br;
|
||||||
else
|
}
|
||||||
br = 180000.0;
|
|
||||||
seek_target = pos + player->Speed * 8 * br;
|
|
||||||
seek_target_flag = AVSEEK_FLAG_BYTE;
|
|
||||||
}
|
|
||||||
} else {
|
} 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
|
showtime = av_gettime() + 300000; //jump back every 300ms
|
||||||
} else {
|
} else {
|
||||||
@@ -185,76 +171,63 @@ bool Input::Play()
|
|||||||
AVPacket packet;
|
AVPacket packet;
|
||||||
av_init_packet(&packet);
|
av_init_packet(&packet);
|
||||||
|
|
||||||
int av_res = av_read_frame(avfc, &packet);
|
int err = av_read_frame(avfc, &packet);
|
||||||
if (av_res == AVERROR(EAGAIN)) {
|
if (err == AVERROR(EAGAIN)) {
|
||||||
av_free_packet(&packet);
|
av_free_packet(&packet);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (av_res) { // av_read_frame failed
|
if (averror(err, av_read_frame)) // EOF?
|
||||||
fprintf(stderr, "no data ->end of file reached ?\n");
|
|
||||||
av_free_packet(&packet);
|
|
||||||
break; // while
|
break; // while
|
||||||
}
|
|
||||||
int64_t pts;
|
|
||||||
|
|
||||||
player->readCount += packet.size;
|
player->readCount += packet.size;
|
||||||
|
|
||||||
int pid = avfc->streams[packet.stream_index]->id;
|
int pid = avfc->streams[packet.stream_index]->id;
|
||||||
|
|
||||||
|
|
||||||
Track *_videoTrack = videoTrack;
|
Track *_videoTrack = videoTrack;
|
||||||
Track *_audioTrack = audioTrack;
|
Track *_audioTrack = audioTrack;
|
||||||
Track *_subtitleTrack = subtitleTrack;
|
Track *_subtitleTrack = subtitleTrack;
|
||||||
Track *_teletextTrack = teletextTrack;
|
Track *_teletextTrack = teletextTrack;
|
||||||
|
|
||||||
|
|
||||||
if (_videoTrack && (_videoTrack->pid == pid)) {
|
if (_videoTrack && (_videoTrack->pid == pid)) {
|
||||||
currentVideoPts = pts = calcPts(avfc, _videoTrack->stream, packet.pts);
|
int64_t pts = calcPts(avfc, _videoTrack->stream, packet.pts);
|
||||||
|
if (!player->output.Write(avfc, _videoTrack->stream, &packet, pts))
|
||||||
if (!player->output.Write(avfc, _videoTrack->stream, &packet, currentVideoPts))
|
|
||||||
fprintf(stderr, "writing data to video device failed\n");
|
fprintf(stderr, "writing data to video device failed\n");
|
||||||
} else if (_audioTrack && (_audioTrack->pid == pid)) {
|
} else if (_audioTrack && (_audioTrack->pid == pid)) {
|
||||||
if (restart_audio_resampling) {
|
if (restart_audio_resampling) {
|
||||||
restart_audio_resampling = false;
|
restart_audio_resampling = false;
|
||||||
player->output.Write(avfc, _audioTrack->stream, NULL, currentAudioPts);
|
player->output.Write(avfc, _audioTrack->stream, NULL, 0);
|
||||||
}
|
}
|
||||||
if (!player->isBackWard) {
|
if (!player->isBackWard) {
|
||||||
currentAudioPts = pts = calcPts(avfc, _audioTrack->stream, packet.pts);
|
int64_t pts = calcPts(avfc, _audioTrack->stream, packet.pts);
|
||||||
if (!player->output.Write(avfc, _audioTrack->stream, &packet, currentAudioPts))
|
if (!player->output.Write(avfc, _audioTrack->stream, &packet, pts))
|
||||||
fprintf(stderr, "writing data to audio device failed\n");
|
fprintf(stderr, "writing data to audio device failed\n");
|
||||||
}
|
}
|
||||||
} else if (_subtitleTrack && (_subtitleTrack->pid == pid)) {
|
} 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) {
|
if (got_sub_ptr && sub.num_rects > 0) {
|
||||||
/* is there a decoder ? */
|
switch (sub.rects[0]->type) {
|
||||||
if (((AVStream *) _subtitleTrack->stream)->codec->codec) {
|
case SUBTITLE_TEXT: // FIXME?
|
||||||
AVSubtitle sub;
|
case SUBTITLE_ASS:
|
||||||
memset(&sub, 0, sizeof(sub));
|
dvbsub_ass_write(((AVStream *) _subtitleTrack->stream)->codec, &sub, pid);
|
||||||
int got_sub_ptr;
|
break;
|
||||||
|
case SUBTITLE_BITMAP: {
|
||||||
if (avcodec_decode_subtitle2(((AVStream *) _subtitleTrack->stream)->codec, &sub, &got_sub_ptr, &packet) < 0) {
|
int64_t pts = calcPts(avfc, _subtitleTrack->stream, packet.pts);
|
||||||
fprintf(stderr, "error decoding subtitle\n");
|
dvbsub_write(&sub, calcPts(avfc, _subtitleTrack->stream, pts));
|
||||||
}
|
// avsubtitle_free() will be called by handler
|
||||||
|
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:
|
|
||||||
dvbsub_write(&sub, pts);
|
|
||||||
// avsubtitle_free() will be called by handler
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} /* duration */
|
}
|
||||||
} else if (_teletextTrack && (_teletextTrack->pid == pid)) {
|
} else if (_teletextTrack && (_teletextTrack->pid == pid)) {
|
||||||
teletext_write(pid, packet.data, packet.size);
|
teletext_write(pid, packet.data, packet.size);
|
||||||
}
|
}
|
||||||
@@ -262,12 +235,14 @@ bool Input::Play()
|
|||||||
av_free_packet(&packet);
|
av_free_packet(&packet);
|
||||||
} /* while */
|
} /* while */
|
||||||
|
|
||||||
if (player && player->abortRequested)
|
if (player->abortRequested)
|
||||||
player->output.Clear();
|
player->output.Clear();
|
||||||
|
else
|
||||||
|
player->output.Flush();
|
||||||
|
|
||||||
dvbsub_ass_clear();
|
dvbsub_ass_clear();
|
||||||
player->abortPlayback = 1;
|
abortPlayback = true;
|
||||||
hasPlayThreadStarted = 0;
|
hasPlayThreadStarted = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -275,7 +250,10 @@ bool Input::Play()
|
|||||||
/*static*/ int interrupt_cb(void *arg)
|
/*static*/ int interrupt_cb(void *arg)
|
||||||
{
|
{
|
||||||
Player *player = (Player *) 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)
|
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, filename);
|
||||||
strcpy(subfile + (lastDot + 1 - filename), format);
|
strcpy(subfile + (lastDot + 1 - filename), format);
|
||||||
|
|
||||||
|
if (access(subfile, R_OK))
|
||||||
|
return false;
|
||||||
|
|
||||||
AVFormatContext *subavfc = avformat_alloc_context();
|
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);
|
avformat_free_context(subavfc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
avformat_find_stream_info(subavfc, NULL);
|
avformat_find_stream_info(subavfc, NULL);
|
||||||
if (subavfc->nb_streams != 1) {
|
if (subavfc->nb_streams != 1) {
|
||||||
avformat_free_context(subavfc);
|
avformat_free_context(subavfc);
|
||||||
@@ -311,12 +294,12 @@ bool Input::ReadSubtitle(const char *filename, const char *format, int pid)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// fprintf(stderr, "codec=%s\n", avcodec_get_name(c->codec_id));
|
err = avcodec_open2(c, codec, NULL);
|
||||||
if (avcodec_open2(c, codec, NULL) < 0) {
|
if (averror(err, avcodec_open2)) {
|
||||||
fprintf(stderr, "%s %d: avcodec_open\n", __FILE__, __LINE__);
|
|
||||||
avformat_free_context(subavfc);
|
avformat_free_context(subavfc);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
AVPacket avpkt;
|
AVPacket avpkt;
|
||||||
av_init_packet(&avpkt);
|
av_init_packet(&avpkt);
|
||||||
|
|
||||||
@@ -356,47 +339,30 @@ bool Input::ReadSubtitles(const char *filename) {
|
|||||||
|
|
||||||
bool Input::Init(const char *filename)
|
bool Input::Init(const char *filename)
|
||||||
{
|
{
|
||||||
int err;
|
abortPlayback = false;
|
||||||
|
|
||||||
av_log_set_callback(log_callback);
|
av_log_set_callback(log_callback);
|
||||||
|
|
||||||
if (filename == NULL) {
|
if (!filename) {
|
||||||
fprintf(stderr, "filename NULL\n");
|
fprintf(stderr, "filename NULL\n");
|
||||||
return false;
|
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();
|
avcodec_register_all();
|
||||||
av_register_all();
|
av_register_all();
|
||||||
|
|
||||||
avformat_network_init();
|
avformat_network_init();
|
||||||
|
|
||||||
player->abortRequested = 0;
|
|
||||||
player->abortPlayback = 0;
|
|
||||||
videoTrack = NULL;
|
videoTrack = NULL;
|
||||||
audioTrack = NULL;
|
audioTrack = NULL;
|
||||||
subtitleTrack = NULL;
|
subtitleTrack = NULL;
|
||||||
teletextTrack = NULL;
|
teletextTrack = NULL;
|
||||||
avfc = avformat_alloc_context();
|
avfc = avformat_alloc_context();
|
||||||
avfc->interrupt_callback.callback = interrupt_cb;
|
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) {
|
int err = avformat_open_input(&avfc, filename, NULL, 0);
|
||||||
char error[512];
|
if (averror(err, avformat_open_input))
|
||||||
|
|
||||||
fprintf(stderr, "avformat_open_input failed %d (%s)\n", err, filename);
|
|
||||||
av_strerror(err, error, 512);
|
|
||||||
fprintf(stderr, "Cause: %s\n", error);
|
|
||||||
|
|
||||||
isContainerRunning = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
avfc->iformat->flags |= AVFMT_SEEK_TO_PTS;
|
avfc->iformat->flags |= AVFMT_SEEK_TO_PTS;
|
||||||
avfc->flags = AVFMT_FLAG_GENPTS;
|
avfc->flags = AVFMT_FLAG_GENPTS;
|
||||||
@@ -405,17 +371,10 @@ bool Input::Init(const char *filename)
|
|||||||
avfc->probesize = 8192;
|
avfc->probesize = 8192;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (avformat_find_stream_info(avfc, NULL) < 0) {
|
err = avformat_find_stream_info(avfc, NULL);
|
||||||
fprintf(stderr, "Error avformat_find_stream_info\n");
|
if (averror(err, avformat_open_input)) {
|
||||||
#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.
|
|
||||||
*/
|
|
||||||
avformat_close_input(&avfc);
|
avformat_close_input(&avfc);
|
||||||
isContainerRunning = false;
|
|
||||||
return false;
|
return false;
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
terminating = false;
|
terminating = false;
|
||||||
@@ -424,7 +383,6 @@ bool Input::Init(const char *filename)
|
|||||||
|
|
||||||
if (!videoTrack && !audioTrack) {
|
if (!videoTrack && !audioTrack) {
|
||||||
avformat_close_input(&avfc);
|
avformat_close_input(&avfc);
|
||||||
isContainerRunning = false;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -525,9 +483,9 @@ bool Input::UpdateTracks()
|
|||||||
snprintf(tmp, sizeof(tmp), "teletext_%d", i);
|
snprintf(tmp, sizeof(tmp), "teletext_%d", i);
|
||||||
t = av_dict_get(stream->metadata, tmp, NULL, 0);
|
t = av_dict_get(stream->metadata, tmp, NULL, 0);
|
||||||
if (t) {
|
if (t) {
|
||||||
char lang[strlen(t->value)];
|
char language[strlen(t->value)];
|
||||||
if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, lang, &track.type, &track.mag, &track.page)) {
|
if (5 == sscanf(t->value, "%d %s %d %d %d", &track.pid, language, &track.type, &track.mag, &track.page)) {
|
||||||
track.Name = lang;
|
track.Name = language;
|
||||||
player->manager.addTeletextTrack(track);
|
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);
|
fprintf(stderr, "not handled or unknown codec_type %d\n", stream->codec->codec_type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -560,11 +517,7 @@ bool Input::UpdateTracks()
|
|||||||
|
|
||||||
bool Input::Stop()
|
bool Input::Stop()
|
||||||
{
|
{
|
||||||
if (!isContainerRunning) {
|
abortPlayback = true;
|
||||||
fprintf(stderr, "Container not running\n");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
player->abortRequested = 1;
|
|
||||||
|
|
||||||
while (hasPlayThreadStarted != 0)
|
while (hasPlayThreadStarted != 0)
|
||||||
usleep(100000);
|
usleep(100000);
|
||||||
@@ -574,8 +527,6 @@ bool Input::Stop()
|
|||||||
if (avfc)
|
if (avfc)
|
||||||
avformat_close_input(&avfc);
|
avformat_close_input(&avfc);
|
||||||
|
|
||||||
isContainerRunning = false;
|
|
||||||
|
|
||||||
avformat_network_deinit();
|
avformat_network_deinit();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@@ -594,16 +545,19 @@ bool Input::GetDuration(double &duration)
|
|||||||
{
|
{
|
||||||
duration = 0.0;
|
duration = 0.0;
|
||||||
|
|
||||||
if (videoTrack && videoTrack->duration != 0.0) {
|
Track *track = videoTrack;
|
||||||
duration = videoTrack->duration / 1000.0;
|
if (track && track->duration != 0.0) {
|
||||||
|
duration = track->duration / 1000.0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (audioTrack && audioTrack->duration != 0.0) {
|
track = audioTrack;
|
||||||
duration = audioTrack->duration / 1000.0;
|
if (track && track->duration != 0.0) {
|
||||||
|
duration = track->duration / 1000.0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (subtitleTrack && subtitleTrack->duration != 0.0) {
|
track = subtitleTrack;
|
||||||
duration = subtitleTrack->duration / 1000.0;
|
if (track && track->duration != 0.0) {
|
||||||
|
duration = track->duration / 1000.0;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (avfc && avfc->duration != 0.0) {
|
if (avfc && avfc->duration != 0.0) {
|
||||||
@@ -665,11 +619,8 @@ bool Input::GetMetadata(std::vector<std::string> &keys, std::vector<std::string>
|
|||||||
keys.push_back(tag->key);
|
keys.push_back(tag->key);
|
||||||
values.push_back(tag->value);
|
values.push_back(tag->value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Input::GetReadCount(uint64_t &readcount)
|
bool Input::GetReadCount(uint64_t &readcount)
|
||||||
|
@@ -1,10 +1,12 @@
|
|||||||
/*
|
/*
|
||||||
* manager handling.
|
* manager class
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* Copyright (C) 2014 martii
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* This program is free software; you can redistribute it and/or
|
||||||
* (at your option) any later version.
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -22,132 +23,95 @@
|
|||||||
#include "manager.h"
|
#include "manager.h"
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
|
|
||||||
void Manager::addVideoTrack(Track &track)
|
void Manager::addTrack(std::map<int,Track*> &tracks, Track &track)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||||
std::map<int,Track*>::iterator it = videoTracks.find(track.pid);
|
std::map<int,Track*>::iterator it = tracks.find(track.pid);
|
||||||
if (it == videoTracks.end()) {
|
if (it == tracks.end()) {
|
||||||
Track *t = new Track;
|
Track *t = new Track;
|
||||||
*t = track;
|
*t = track;
|
||||||
videoTracks[track.pid] = t;
|
tracks[track.pid] = t;
|
||||||
} else
|
} else
|
||||||
*it->second = track;
|
*it->second = track;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Manager::addVideoTrack(Track &track)
|
||||||
|
{
|
||||||
|
addTrack(videoTracks, track);
|
||||||
|
}
|
||||||
|
|
||||||
void Manager::addAudioTrack(Track &track)
|
void Manager::addAudioTrack(Track &track)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
addTrack(audioTracks, track);
|
||||||
std::map<int,Track*>::iterator it = audioTracks.find(track.pid);
|
|
||||||
if (it == audioTracks.end()) {
|
|
||||||
Track *t = new Track;
|
|
||||||
*t = track;
|
|
||||||
audioTracks[track.pid] = t;
|
|
||||||
} else
|
|
||||||
*it->second = track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::addSubtitleTrack(Track &track)
|
void Manager::addSubtitleTrack(Track &track)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
addTrack(subtitleTracks, track);
|
||||||
std::map<int,Track*>::iterator it = subtitleTracks.find(track.pid);
|
|
||||||
if (it == subtitleTracks.end()) {
|
|
||||||
Track *t = new Track;
|
|
||||||
*t = track;
|
|
||||||
subtitleTracks[track.pid] = t;
|
|
||||||
} else
|
|
||||||
*it->second = track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Manager::addTeletextTrack(Track &track)
|
void Manager::addTeletextTrack(Track &track)
|
||||||
{
|
{
|
||||||
|
addTrack(teletextTracks, track);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<Track> Manager::getTracks(std::map<int,Track*> &tracks)
|
||||||
|
{
|
||||||
|
player->input.UpdateTracks();
|
||||||
|
std::vector<Track> res;
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||||
std::map<int,Track*>::iterator it = teletextTracks.find(track.pid);
|
for(std::map<int,Track*>::iterator it = tracks.begin(); it != tracks.end(); ++it)
|
||||||
if (it == teletextTracks.end()) {
|
if (!it->second->inactive)
|
||||||
Track *t = new Track;
|
res.push_back(*it->second);
|
||||||
*t = track;
|
return res;
|
||||||
teletextTracks[track.pid] = t;
|
|
||||||
} else
|
|
||||||
*it->second = track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Track> Manager::getVideoTracks()
|
std::vector<Track> Manager::getVideoTracks()
|
||||||
{
|
{
|
||||||
player->input.UpdateTracks();
|
return getTracks(videoTracks);
|
||||||
std::vector<Track> res;
|
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
|
||||||
for(std::map<int,Track*>::iterator it = videoTracks.begin(); it != videoTracks.end(); ++it)
|
|
||||||
if (!it->second->inactive)
|
|
||||||
res.push_back(*it->second);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Track> Manager::getAudioTracks()
|
std::vector<Track> Manager::getAudioTracks()
|
||||||
{
|
{
|
||||||
player->input.UpdateTracks();
|
return getTracks(audioTracks);
|
||||||
std::vector<Track> res;
|
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
|
||||||
for(std::map<int,Track*>::iterator it = audioTracks.begin(); it != audioTracks.end(); ++it)
|
|
||||||
if (!it->second->inactive)
|
|
||||||
res.push_back(*it->second);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Track> Manager::getSubtitleTracks()
|
std::vector<Track> Manager::getSubtitleTracks()
|
||||||
{
|
{
|
||||||
player->input.UpdateTracks();
|
return getTracks(subtitleTracks);
|
||||||
std::vector<Track> res;
|
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
|
||||||
for(std::map<int,Track*>::iterator it = subtitleTracks.begin(); it != subtitleTracks.end(); ++it)
|
|
||||||
if (!it->second->inactive)
|
|
||||||
res.push_back(*it->second);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<Track> Manager::getTeletextTracks()
|
std::vector<Track> Manager::getTeletextTracks()
|
||||||
{
|
{
|
||||||
player->input.UpdateTracks();
|
return getTracks(teletextTracks);
|
||||||
std::vector<Track> res;
|
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
|
||||||
for(std::map<int,Track*>::iterator it = teletextTracks.begin(); it != teletextTracks.end(); ++it)
|
|
||||||
if (!it->second->inactive)
|
|
||||||
res.push_back(*it->second);
|
|
||||||
return res;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *Manager::getVideoTrack(int pid)
|
Track *Manager::getTrack(std::map<int,Track*> &tracks, int pid)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
||||||
std::map<int,Track*>::iterator it = videoTracks.find(pid);
|
std::map<int,Track*>::iterator it = tracks.find(pid);
|
||||||
if (it != videoTracks.end() && !it->second->inactive)
|
if (it != tracks.end() && !it->second->inactive)
|
||||||
return it->second;
|
return it->second;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
Track *Manager::getVideoTrack(int pid)
|
||||||
|
{
|
||||||
|
return getTrack(videoTracks, pid);
|
||||||
|
}
|
||||||
|
|
||||||
Track *Manager::getAudioTrack(int pid)
|
Track *Manager::getAudioTrack(int pid)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
return getTrack(audioTracks, pid);
|
||||||
std::map<int,Track*>::iterator it = audioTracks.find(pid);
|
|
||||||
if (it != audioTracks.end() && !it->second->inactive)
|
|
||||||
return it->second;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *Manager::getSubtitleTrack(int pid)
|
Track *Manager::getSubtitleTrack(int pid)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
return getTrack(subtitleTracks, pid);
|
||||||
std::map<int,Track*>::iterator it = subtitleTracks.find(pid);
|
|
||||||
if (it != subtitleTracks.end() && !it->second->inactive)
|
|
||||||
return it->second;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Track *Manager::getTeletextTrack(int pid)
|
Track *Manager::getTeletextTrack(int pid)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(mutex);
|
return getTrack(teletextTracks, pid);
|
||||||
std::map<int,Track*>::iterator it = teletextTracks.find(pid);
|
|
||||||
if (it != teletextTracks.end() && !it->second->inactive)
|
|
||||||
return it->second;
|
|
||||||
return NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Manager::initTrackUpdate()
|
bool Manager::initTrackUpdate()
|
||||||
|
@@ -1,10 +1,14 @@
|
|||||||
/*
|
/*
|
||||||
* LinuxDVB Output handling.
|
* output class
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* based on libeplayer3 LinuxDVB Output handling.
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* Copyright (C) 2014 martii
|
||||||
* (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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -209,12 +212,8 @@ bool Output::Continue()
|
|||||||
bool Output::Mute(bool b)
|
bool Output::Mute(bool b)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
||||||
|
|
||||||
//AUDIO_SET_MUTE has no effect with new player
|
//AUDIO_SET_MUTE has no effect with new player
|
||||||
if (audiofd > -1 && dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL))
|
return audiofd > -1 && !dioctl(audiofd, b ? AUDIO_STOP : AUDIO_PLAY, NULL);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -237,48 +236,31 @@ bool Output::Flush()
|
|||||||
bool Output::FastForward(int speed)
|
bool Output::FastForward(int speed)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
||||||
|
return videofd > -1 && !dioctl(videofd, VIDEO_FAST_FORWARD, speed);
|
||||||
if (videofd > -1 && dioctl(videofd, VIDEO_FAST_FORWARD, speed))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Output::SlowMotion(int speed)
|
bool Output::SlowMotion(int speed)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
||||||
|
return videofd > -1 && !dioctl(videofd, VIDEO_SLOWMOTION, speed);
|
||||||
if (videofd > -1 && dioctl(videofd, VIDEO_SLOWMOTION, speed))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Output::AVSync(bool b)
|
bool Output::AVSync(bool b)
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
||||||
if (audiofd > -1 && dioctl(audiofd, AUDIO_SET_AV_SYNC, b))
|
return audiofd > -1 && !dioctl(audiofd, AUDIO_SET_AV_SYNC, b);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Output::ClearAudio()
|
bool Output::ClearAudio()
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
||||||
if (audiofd > -1 && dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL))
|
return audiofd > -1 && !dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Output::ClearVideo()
|
bool Output::ClearVideo()
|
||||||
{
|
{
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
||||||
if (videofd > -1 && dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL))
|
return videofd > -1 && !dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL);
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Output::Clear()
|
bool Output::Clear()
|
||||||
@@ -349,20 +331,16 @@ bool Output::SwitchVideo(AVStream *stream)
|
|||||||
return true;
|
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) {
|
switch (stream->codec->codec_type) {
|
||||||
case AVMEDIA_TYPE_VIDEO: {
|
case AVMEDIA_TYPE_VIDEO: {
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> v_lock(videoMutex);
|
||||||
if (videofd > -1 && videoWriter)
|
return videofd > -1 && videoWriter && videoWriter->Write(videofd, avfc, stream, packet, pts);
|
||||||
return videoWriter->Write(videofd, avfc, stream, packet, Pts);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
case AVMEDIA_TYPE_AUDIO: {
|
case AVMEDIA_TYPE_AUDIO: {
|
||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> a_lock(audioMutex);
|
||||||
if (audiofd > -1 && audioWriter)
|
return audiofd > -1 && audioWriter && audioWriter->Write(audiofd, avfc, stream, packet, pts);
|
||||||
return audioWriter->Write(audiofd, avfc, stream, packet, Pts);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
return false;
|
return false;
|
||||||
|
@@ -1,19 +1,30 @@
|
|||||||
/*
|
/*
|
||||||
* GPL
|
* linuxdvb output/writer handling
|
||||||
* duckbox 2010
|
*
|
||||||
|
* 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 <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/socket.h>
|
|
||||||
#include <netdb.h>
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <dirent.h>
|
#include <pthread.h>
|
||||||
#include <errno.h>
|
#include <sys/prctl.h>
|
||||||
#include <poll.h>
|
|
||||||
|
|
||||||
#include "player.h"
|
#include "player.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
@@ -21,71 +32,56 @@
|
|||||||
#define cMaxSpeed_ff 128 /* fixme: revise */
|
#define cMaxSpeed_ff 128 /* fixme: revise */
|
||||||
#define cMaxSpeed_fr -320 /* fixme: revise */
|
#define cMaxSpeed_fr -320 /* fixme: revise */
|
||||||
|
|
||||||
static pthread_t supervisorThread;
|
|
||||||
|
|
||||||
Player::Player()
|
Player::Player()
|
||||||
{
|
{
|
||||||
input.player = this;
|
input.player = this;
|
||||||
output.player = this;
|
output.player = this;
|
||||||
manager.player = this;
|
manager.player = this;
|
||||||
hasThreadStarted = 0;
|
hasThreadStarted = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *Player::SupervisorThread(void *arg)
|
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 *player = (Player *) arg;
|
||||||
player->hasThreadStarted = 1;
|
player->hasThreadStarted = true;
|
||||||
|
|
||||||
player->input.Play();
|
player->input.Play();
|
||||||
player->hasThreadStarted = 2;
|
player->hasThreadStarted = false;
|
||||||
player->Terminate();
|
player->Stop();
|
||||||
|
|
||||||
fprintf(stderr, "terminating\n");
|
|
||||||
player->hasThreadStarted = 0;
|
|
||||||
pthread_exit(NULL);
|
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);
|
fprintf(stderr, "URL=%s\n", Url);
|
||||||
|
|
||||||
if (isPlaying) { // shouldn't happen
|
isHttp = false;
|
||||||
fprintf(stderr, "playback already running\n");
|
noprobe = _noprobe;
|
||||||
return false;
|
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();
|
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()))
|
if (!input.Init(url.c_str()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
fprintf(stderr, "exiting with value 0\n");
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -93,11 +89,11 @@ bool Player::Close()
|
|||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
isPaused = 0;
|
isPaused = false;
|
||||||
isPlaying = 0;
|
isPlaying = false;
|
||||||
isForwarding = 0;
|
isForwarding = false;
|
||||||
isBackWard = 0;
|
isBackWard = false;
|
||||||
isSlowMotion = 0;
|
isSlowMotion = false;
|
||||||
Speed = 0;
|
Speed = 0;
|
||||||
url.clear();
|
url.clear();
|
||||||
|
|
||||||
@@ -106,55 +102,41 @@ bool Player::Close()
|
|||||||
|
|
||||||
bool Player::Play()
|
bool Player::Play()
|
||||||
{
|
{
|
||||||
pthread_attr_t attr;
|
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
|
|
||||||
if (!isPlaying) {
|
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) {
|
if (ret) {
|
||||||
isCreationPhase = 0; // allow thread to go into next state
|
isPlaying = true;
|
||||||
} else {
|
isPaused = false;
|
||||||
isPlaying = 1;
|
isForwarding = false;
|
||||||
isPaused = 0;
|
if (isBackWard) {
|
||||||
isForwarding = 0;
|
isBackWard = false;
|
||||||
if (isBackWard) {
|
output.Mute(false);
|
||||||
isBackWard = 0;
|
}
|
||||||
output.Mute(false);
|
isSlowMotion = false;
|
||||||
}
|
Speed = 1;
|
||||||
isSlowMotion = 0;
|
|
||||||
Speed = 1;
|
|
||||||
|
|
||||||
if (hasThreadStarted == 0) {
|
if (!hasThreadStarted) {
|
||||||
int error;
|
int err = pthread_create(&supervisorThread, NULL, SupervisorThread, this);
|
||||||
pthread_attr_init(&attr);
|
|
||||||
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
|
|
||||||
|
|
||||||
if ((error = pthread_create(&supervisorThread, &attr, SupervisorThread, this))) {
|
if (err) {
|
||||||
fprintf(stderr, "Error creating thread, error:%d:%s\n", error, strerror(error));
|
fprintf(stderr, "%s %s %d: pthread_create: %d (%s)\n", __FILE__, __func__, __LINE__, err, strerror(err));
|
||||||
|
ret = false;
|
||||||
ret = false;
|
isPlaying = false;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Created thread\n");
|
pthread_detach(supervisorThread);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "clearing isCreationPhase!\n");
|
|
||||||
|
|
||||||
isCreationPhase = 0; // allow thread to go into next state
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"playback already running\n");
|
fprintf(stderr,"playback already running\n");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "exiting with value %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -164,27 +146,24 @@ bool Player::Pause()
|
|||||||
|
|
||||||
if (isPlaying && !isPaused) {
|
if (isPlaying && !isPaused) {
|
||||||
|
|
||||||
if (isSlowMotion)
|
if (isSlowMotion)
|
||||||
output.Clear();
|
output.Clear();
|
||||||
|
|
||||||
output.Pause();
|
output.Pause();
|
||||||
|
|
||||||
isPaused = 1;
|
isPaused = true;
|
||||||
//isPlaying = 1;
|
//isPlaying = 1;
|
||||||
isForwarding = 0;
|
isForwarding = false;
|
||||||
if (isBackWard) {
|
if (isBackWard) {
|
||||||
isBackWard = 0;
|
isBackWard = false;
|
||||||
output.Mute(false);
|
output.Mute(false);
|
||||||
}
|
}
|
||||||
isSlowMotion = 0;
|
isSlowMotion = false;
|
||||||
Speed = 1;
|
Speed = 1;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"playback not playing or already in pause mode\n");
|
fprintf(stderr,"playback not playing or already in pause mode\n");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf(stderr, "exiting with value %d\n", ret);
|
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,14 +178,14 @@ bool Player::Continue()
|
|||||||
|
|
||||||
output.Continue();
|
output.Continue();
|
||||||
|
|
||||||
isPaused = 0;
|
isPaused = false;
|
||||||
//isPlaying = 1;
|
//isPlaying = 1;
|
||||||
isForwarding = 0;
|
isForwarding = false;
|
||||||
if (isBackWard) {
|
if (isBackWard) {
|
||||||
isBackWard = 0;
|
isBackWard = false;
|
||||||
output.Mute(false);
|
output.Mute(false);
|
||||||
}
|
}
|
||||||
isSlowMotion = 0;
|
isSlowMotion = false;
|
||||||
Speed = 1;
|
Speed = 1;
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"continue not possible\n");
|
fprintf(stderr,"continue not possible\n");
|
||||||
@@ -219,87 +198,29 @@ bool Player::Continue()
|
|||||||
bool Player::Stop()
|
bool Player::Stop()
|
||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
int wait_time = 20;
|
|
||||||
|
|
||||||
if (isPlaying) {
|
if (isPlaying) {
|
||||||
|
|
||||||
isPaused = 0;
|
isPaused = false;
|
||||||
isPlaying = 0;
|
isPlaying = false;
|
||||||
isForwarding = 0;
|
isForwarding = false;
|
||||||
if (isBackWard) {
|
if (isBackWard) {
|
||||||
isBackWard = 0;
|
isBackWard = false;
|
||||||
output.Mute(false);
|
output.Mute(false);
|
||||||
}
|
}
|
||||||
isSlowMotion = 0;
|
isSlowMotion = false;
|
||||||
Speed = 0;
|
Speed = 0;
|
||||||
|
|
||||||
output.Stop();
|
output.Stop();
|
||||||
input.Stop();
|
input.Stop();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr,"stop not possible\n");
|
fprintf(stderr,"stop not possible\n");
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
while ((hasThreadStarted == 1) && (--wait_time) > 0) {
|
while (hasThreadStarted)
|
||||||
fprintf(stderr, "Waiting for supervisor thread to terminate itself, will try another %d times\n", wait_time);
|
|
||||||
|
|
||||||
usleep(100000);
|
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;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -309,7 +230,7 @@ bool Player::FastForward(int speed)
|
|||||||
int ret = true;
|
int ret = true;
|
||||||
|
|
||||||
/* Audio only forwarding not supported */
|
/* Audio only forwarding not supported */
|
||||||
if (isVideo && !isHttp && !isBackWard && (!isPaused || isPlaying)) {
|
if (input.videoTrack && !isHttp && !isBackWard && (!isPaused || isPlaying)) {
|
||||||
|
|
||||||
if ((speed <= 0) || (speed > cMaxSpeed_ff)) {
|
if ((speed <= 0) || (speed > cMaxSpeed_ff)) {
|
||||||
fprintf(stderr, "speed %d out of range (1 - %d) \n", 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;
|
bool ret = true;
|
||||||
|
|
||||||
/* Audio only reverse play not supported */
|
/* Audio only reverse play not supported */
|
||||||
if (isVideo && !isForwarding && (!isPaused || isPlaying)) {
|
if (input.videoTrack && !isForwarding && (!isPaused || isPlaying)) {
|
||||||
|
|
||||||
if ((speed > 0) || (speed < cMaxSpeed_fr)) {
|
if ((speed > 0) || (speed < cMaxSpeed_fr)) {
|
||||||
fprintf(stderr, "speed %d out of range (0 - %d) \n", 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) {
|
if (speed == 0) {
|
||||||
isBackWard = false;
|
isBackWard = false;
|
||||||
Speed = false; /* reverse end */
|
Speed = 0; /* reverse end */
|
||||||
} else {
|
} else {
|
||||||
Speed = speed;
|
Speed = speed;
|
||||||
isBackWard = true;
|
isBackWard = true;
|
||||||
@@ -351,7 +272,7 @@ bool Player::FastBackward(int speed)
|
|||||||
#if 0
|
#if 0
|
||||||
if (output->Command(player, OUTPUT_REVERSE, NULL) < 0) {
|
if (output->Command(player, OUTPUT_REVERSE, NULL) < 0) {
|
||||||
fprintf(stderr,"OUTPUT_REVERSE failed\n");
|
fprintf(stderr,"OUTPUT_REVERSE failed\n");
|
||||||
isBackWard = 0;
|
isBackWard = false;
|
||||||
Speed = 1;
|
Speed = 1;
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
@@ -369,7 +290,7 @@ bool Player::FastBackward(int speed)
|
|||||||
|
|
||||||
bool Player::SlowMotion(int repeats)
|
bool Player::SlowMotion(int repeats)
|
||||||
{
|
{
|
||||||
if (isVideo && !isHttp && isPlaying) {
|
if (input.videoTrack && !isHttp && isPlaying) {
|
||||||
if (isPaused)
|
if (isPaused)
|
||||||
Continue();
|
Continue();
|
||||||
|
|
||||||
@@ -398,56 +319,43 @@ bool Player::Seek(float pos, bool absolute)
|
|||||||
|
|
||||||
bool Player::GetPts(int64_t &pts)
|
bool Player::GetPts(int64_t &pts)
|
||||||
{
|
{
|
||||||
if (isPlaying)
|
pts = INVALID_PTS_VALUE;
|
||||||
return output.GetPts(pts);
|
return isPlaying && output.GetPts(pts);
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::GetFrameCount(int64_t &frameCount)
|
bool Player::GetFrameCount(int64_t &frameCount)
|
||||||
{
|
{
|
||||||
if (isPlaying)
|
return isPlaying && output.GetFrameCount(frameCount);
|
||||||
return output.GetFrameCount(frameCount);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::GetDuration(double &duration)
|
bool Player::GetDuration(double &duration)
|
||||||
{
|
{
|
||||||
duration = -1;
|
duration = -1;
|
||||||
if (isPlaying)
|
return isPlaying && input.GetDuration(duration);
|
||||||
return input.GetDuration(duration);
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::SwitchVideo(int pid)
|
bool Player::SwitchVideo(int pid)
|
||||||
{
|
{
|
||||||
Track *track = manager.getVideoTrack(pid);
|
Track *track = manager.getVideoTrack(pid);
|
||||||
if (track)
|
return track && input.SwitchVideo(track);
|
||||||
input.SwitchVideo(track);
|
|
||||||
return !!track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::SwitchAudio(int pid)
|
bool Player::SwitchAudio(int pid)
|
||||||
{
|
{
|
||||||
Track *track = manager.getAudioTrack(pid);
|
Track *track = manager.getAudioTrack(pid);
|
||||||
if (track)
|
return track && input.SwitchAudio(track);
|
||||||
input.SwitchAudio(track);
|
|
||||||
return !!track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::SwitchSubtitle(int pid)
|
bool Player::SwitchSubtitle(int pid)
|
||||||
{
|
{
|
||||||
Track *track = manager.getSubtitleTrack(pid);
|
Track *track = manager.getSubtitleTrack(pid);
|
||||||
if (track)
|
return track && input.SwitchSubtitle(track);
|
||||||
input.SwitchSubtitle(track);
|
|
||||||
return !!track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::SwitchTeletext(int pid)
|
bool Player::SwitchTeletext(int pid)
|
||||||
{
|
{
|
||||||
Track *track = manager.getTeletextTrack(pid);
|
Track *track = manager.getTeletextTrack(pid);
|
||||||
if (track)
|
return track && input.SwitchTeletext(track);
|
||||||
input.SwitchTeletext(track);
|
|
||||||
return !!track;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Player::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
|
bool Player::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
|
||||||
@@ -473,3 +381,8 @@ void Player::SetChapters(std::vector<Chapter> &Chapters)
|
|||||||
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(chapterMutex);
|
OpenThreads::ScopedLock<OpenThreads::Mutex> m_lock(chapterMutex);
|
||||||
chapters = Chapters;
|
chapters = Chapters;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Player::RequestAbort()
|
||||||
|
{
|
||||||
|
abortRequested = true;
|
||||||
|
}
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
class WriterAC3 : public Writer
|
class WriterAC3 : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -26,14 +26,7 @@
|
|||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include <linux/dvb/video.h>
|
|
||||||
#include <linux/dvb/audio.h>
|
|
||||||
#include <linux/dvb/stm_ioctls.h>
|
|
||||||
#include <memory.h>
|
|
||||||
#include <asm/types.h>
|
|
||||||
#include <pthread.h>
|
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
@@ -45,7 +38,7 @@ class WriterDIVX : public Writer
|
|||||||
private:
|
private:
|
||||||
bool initialHeader;
|
bool initialHeader;
|
||||||
public:
|
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();
|
void Init();
|
||||||
WriterDIVX();
|
WriterDIVX();
|
||||||
};
|
};
|
||||||
@@ -55,7 +48,7 @@ void WriterDIVX::Init()
|
|||||||
initialHeader = true;
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -36,11 +36,11 @@
|
|||||||
class WriterDTS : public Writer
|
class WriterDTS : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
class WriterFLAC : public Writer
|
class WriterFLAC : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return -1;
|
return -1;
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -31,11 +32,11 @@
|
|||||||
class WriterH263 : public Writer
|
class WriterH263 : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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
|
* Copyright (C) 2014 martii
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* This program is free software; you can redistribute it and/or
|
||||||
* (at your option) any later version.
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -52,7 +54,7 @@ class WriterH264 : public Writer
|
|||||||
bool initialHeader;
|
bool initialHeader;
|
||||||
unsigned int NalLengthBytes;
|
unsigned int NalLengthBytes;
|
||||||
public:
|
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();
|
void Init();
|
||||||
WriterH264();
|
WriterH264();
|
||||||
};
|
};
|
||||||
@@ -64,12 +66,11 @@ void WriterH264::Init(void)
|
|||||||
NalLengthBytes = 1;
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
unsigned long long int VideoPts;
|
|
||||||
unsigned int TimeDelta;
|
unsigned int TimeDelta;
|
||||||
unsigned int TimeScale;
|
unsigned int TimeScale;
|
||||||
int len = 0;
|
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 */
|
TimeDelta = 1000.0 * av_q2d(stream->r_frame_rate); /* rational to double */
|
||||||
TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */
|
TimeScale = (TimeDelta < 23970) ? 1001 : 1000; /* fixme: revise this */
|
||||||
VideoPts = pts;
|
|
||||||
|
|
||||||
if ((packet->size > 3)
|
if ((packet->size > 3)
|
||||||
&& ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01)
|
&& ((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;
|
iov[ic++].iov_len = NalLength;
|
||||||
VideoPosition += 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);
|
ssize_t l = writev(fd, iov, ic);
|
||||||
if (l < 0)
|
if (l < 0)
|
||||||
return false;
|
return false;
|
||||||
len += l;
|
len += l;
|
||||||
|
|
||||||
VideoPts = INVALID_PTS_VALUE;
|
pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
} while (NalStart < SampleSize);
|
} while (NalStart < SampleSize);
|
||||||
|
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -33,11 +33,11 @@
|
|||||||
class WriterMP3 : public Writer
|
class WriterMP3 : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -35,24 +35,22 @@
|
|||||||
class WriterMPEG2 : public Writer
|
class WriterMPEG2 : public Writer
|
||||||
{
|
{
|
||||||
public:
|
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();
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
unsigned char PesHeader[PES_MAX_HEADER_SIZE];
|
||||||
|
|
||||||
int64_t _pts = pts;
|
|
||||||
|
|
||||||
for (int Position = 0; Position < packet->size; ) {
|
for (int Position = 0; Position < packet->size; ) {
|
||||||
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
||||||
struct iovec iov[2];
|
struct iovec iov[2];
|
||||||
iov[0].iov_base = PesHeader;
|
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_base = packet->data + Position;
|
||||||
iov[1].iov_len = PacketLength;
|
iov[1].iov_len = PacketLength;
|
||||||
|
|
||||||
@@ -62,7 +60,7 @@ bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stre
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Position += PacketLength;
|
Position += PacketLength;
|
||||||
_pts = INVALID_PTS_VALUE;
|
pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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
|
* 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;
|
bool restart_audio_resampling;
|
||||||
|
|
||||||
public:
|
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();
|
bool prepareClipPlay();
|
||||||
int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size);
|
int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size);
|
||||||
void Init();
|
void Init();
|
||||||
@@ -230,7 +231,7 @@ void WriterPCM::Init()
|
|||||||
|
|
||||||
extern int64_t calcPts(AVFormatContext *, AVStream *, int64_t);
|
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)
|
if (fd < 0)
|
||||||
return false;
|
return false;
|
||||||
@@ -325,7 +326,6 @@ bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
// FIXME. PTS calculation is probably broken.
|
// FIXME. PTS calculation is probably broken.
|
||||||
int64_t pts;
|
|
||||||
int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame),
|
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.num * (int64_t) out_sample_rate * c->sample_rate,
|
||||||
stream->time_base.den);
|
stream->time_base.den);
|
||||||
|
@@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* 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
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -19,10 +20,6 @@
|
|||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* ***************************** */
|
|
||||||
/* Includes */
|
|
||||||
/* ***************************** */
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@@ -35,87 +32,85 @@
|
|||||||
|
|
||||||
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
|
int InsertVideoPrivateDataHeader(unsigned char *data, int payload_size)
|
||||||
{
|
{
|
||||||
BitPacker_t ld2 = { data, 0, 32 };
|
BitPacker_t ld2 = { data, 0, 32 };
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
PutBits(&ld2, PES_PRIVATE_DATA_FLAG, 8);
|
||||||
PutBits(&ld2, payload_size & 0xff, 8);
|
PutBits(&ld2, payload_size & 0xff, 8);
|
||||||
PutBits(&ld2, (payload_size >> 8) & 0xff, 8);
|
PutBits(&ld2, (payload_size >> 8) & 0xff, 8);
|
||||||
PutBits(&ld2, (payload_size >> 16) & 0xff, 8);
|
PutBits(&ld2, (payload_size >> 16) & 0xff, 8);
|
||||||
|
|
||||||
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++)
|
for (i = 4; i < (PES_PRIVATE_DATA_LENGTH + 1); i++)
|
||||||
PutBits(&ld2, 0, 8);
|
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,
|
int InsertPesHeader(uint8_t *data, int size, unsigned char stream_id, int64_t pts, int pic_start_code)
|
||||||
unsigned long long int pts, int pic_start_code)
|
|
||||||
{
|
{
|
||||||
BitPacker_t ld2 = { data, 0, 32 };
|
BitPacker_t ld2 = { data, 0, 32 };
|
||||||
|
|
||||||
if (size > MAX_PES_PACKET_SIZE)
|
if (size > MAX_PES_PACKET_SIZE)
|
||||||
size = 0; // unbounded
|
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, 0x0, 8);
|
PutBits(&ld2, 0x0, 8);
|
||||||
PutBits(&ld2, 0x1, 8); // Start Code
|
PutBits(&ld2, 0x1, 8); // Start Code
|
||||||
PutBits(&ld2, pic_start_code & 0xff, 8); // 00, for picture start
|
PutBits(&ld2, stream_id, 8); // Stream_id = Audio Stream
|
||||||
PutBits(&ld2, (pic_start_code >> 8) & 0xff, 8); // For any extra information (like in mpeg4p2, the pic_start_code)
|
//4
|
||||||
//14 + 4 = 18
|
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);
|
||||||
}
|
}
|
||||||
|
@@ -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
|
* Copyright (C) 2014 martii
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* This program is free software; you can redistribute it and/or
|
||||||
* (at your option) any later version.
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -50,7 +52,7 @@ class WriterVC1 : public Writer
|
|||||||
unsigned char FrameHeaderSeen;
|
unsigned char FrameHeaderSeen;
|
||||||
double frameRate;
|
double frameRate;
|
||||||
public:
|
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();
|
void Init();
|
||||||
WriterVC1();
|
WriterVC1();
|
||||||
};
|
};
|
||||||
@@ -60,7 +62,7 @@ void WriterVC1::Init()
|
|||||||
initialHeader = true;
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
@@ -138,8 +140,6 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
|
|||||||
initialHeader = false;
|
initialHeader = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t _pts = pts;
|
|
||||||
|
|
||||||
if (packet->size > 0) {
|
if (packet->size > 0) {
|
||||||
int Position = 0;
|
int Position = 0;
|
||||||
unsigned char insertSampleHeader = 1;
|
unsigned char insertSampleHeader = 1;
|
||||||
@@ -147,7 +147,7 @@ bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket
|
|||||||
while (Position < packet->size) {
|
while (Position < packet->size) {
|
||||||
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_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) {
|
if (insertSampleHeader) {
|
||||||
const unsigned char Vc1FrameStartCode[] = { 0, 0, 1, VC1_FRAME_START_CODE };
|
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;
|
return false;
|
||||||
|
|
||||||
Position += PacketLength;
|
Position += PacketLength;
|
||||||
_pts = INVALID_PTS_VALUE;
|
pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
* Copyright (C) 2014 martii
|
||||||
* it under the terms of the GNU General Public License as published by
|
*
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* This program is free software; you can redistribute it and/or
|
||||||
* (at your option) any later version.
|
* 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,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
@@ -56,7 +58,7 @@ class WriterWMV : public Writer
|
|||||||
private:
|
private:
|
||||||
bool initialHeader;
|
bool initialHeader;
|
||||||
public:
|
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();
|
void Init();
|
||||||
WriterWMV();
|
WriterWMV();
|
||||||
};
|
};
|
||||||
@@ -66,7 +68,7 @@ void WriterWMV::Init()
|
|||||||
initialHeader = 1;
|
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)
|
if (fd < 0 || !packet)
|
||||||
return false;
|
return false;
|
||||||
@@ -120,14 +122,12 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV
|
|||||||
int Position = 0;
|
int Position = 0;
|
||||||
bool insertSampleHeader = true;
|
bool insertSampleHeader = true;
|
||||||
|
|
||||||
uint64_t _pts = pts;
|
|
||||||
|
|
||||||
while (Position < packet->size) {
|
while (Position < packet->size) {
|
||||||
|
|
||||||
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE);
|
||||||
|
|
||||||
unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 };
|
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) {
|
if (insertSampleHeader) {
|
||||||
unsigned int PesLength;
|
unsigned int PesLength;
|
||||||
@@ -152,7 +152,7 @@ bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AV
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
Position += PacketLength;
|
Position += PacketLength;
|
||||||
_pts = INVALID_PTS_VALUE;
|
pts = INVALID_PTS_VALUE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -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
|
* This program is free software; you can redistribute it and/or
|
||||||
* it under the terms of the GNU General Public License as published by
|
* modify it under the terms of the GNU General Public License
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
* as published by the Free Software Foundation; either version 2
|
||||||
* (at your option) any later version.
|
* of the License, or (at your option) any later version.
|
||||||
*
|
*
|
||||||
* This program is distributed in the hope that it will be useful,
|
* This program is distributed in the hope that it will be useful,
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
* 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
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program; if not, write to the Free Software
|
* 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 <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <fcntl.h>
|
|
||||||
#include <sys/types.h>
|
|
||||||
#include <sys/stat.h>
|
|
||||||
#include <sys/ioctl.h>
|
|
||||||
#include <sys/uio.h>
|
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <map>
|
#include <map>
|
||||||
@@ -37,18 +31,17 @@
|
|||||||
|
|
||||||
// This does suck ... the original idea was to just link the object files and let them register themselves.
|
// 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.
|
// Alas, that didn't work as expected.
|
||||||
|
#include "ac3.cpp"
|
||||||
#include "divx.cpp"
|
#include "divx.cpp"
|
||||||
|
#include "dts.cpp"
|
||||||
|
#include "flac.cpp"
|
||||||
#include "h263.cpp"
|
#include "h263.cpp"
|
||||||
#include "h264.cpp"
|
#include "h264.cpp"
|
||||||
#include "mp3.cpp"
|
#include "mp3.cpp"
|
||||||
#include "vc1.cpp"
|
|
||||||
#include "wmv.cpp"
|
|
||||||
#include "ac3.cpp"
|
|
||||||
#include "dts.cpp"
|
|
||||||
#include "flac.cpp"
|
|
||||||
#include "mpeg2.cpp"
|
#include "mpeg2.cpp"
|
||||||
#include "pcm.cpp"
|
#include "pcm.cpp"
|
||||||
|
#include "vc1.cpp"
|
||||||
|
#include "wmv.cpp"
|
||||||
|
|
||||||
static std::map<enum AVCodecID,Writer *>writers __attribute__ ((init_priority (200)));
|
static std::map<enum AVCodecID,Writer *>writers __attribute__ ((init_priority (200)));
|
||||||
static std::map<enum AVCodecID,video_encoding_t>vencoding __attribute__ ((init_priority (200)));
|
static std::map<enum AVCodecID,video_encoding_t>vencoding __attribute__ ((init_priority (200)));
|
||||||
@@ -66,7 +59,7 @@ void Writer::Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding)
|
|||||||
aencoding[id] = 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;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -75,26 +68,21 @@ static Writer writer __attribute__ ((init_priority (300)));
|
|||||||
|
|
||||||
Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type)
|
Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type)
|
||||||
{
|
{
|
||||||
fprintf(stderr, "%s %s %d\n", __FILE__,__func__,__LINE__);
|
|
||||||
std::map<enum AVCodecID,Writer*>::iterator it = writers.find(id);
|
std::map<enum AVCodecID,Writer*>::iterator it = writers.find(id);
|
||||||
if (it != writers.end())
|
if (it != writers.end())
|
||||||
return it->second;
|
return it->second;
|
||||||
fprintf(stderr, "%s %s %d: no writer found\n", __FILE__,__func__,__LINE__);
|
|
||||||
switch (codec_type) {
|
switch (codec_type) {
|
||||||
case AVMEDIA_TYPE_AUDIO:
|
case AVMEDIA_TYPE_AUDIO:
|
||||||
if (id == AV_CODEC_ID_INJECTPCM) // should not happen
|
if (id == AV_CODEC_ID_INJECTPCM) // should not happen
|
||||||
break;
|
break;
|
||||||
fprintf(stderr, "%s %s %d: returning injectpcm\n", __FILE__,__func__,__LINE__);
|
|
||||||
return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type);
|
return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type);
|
||||||
case AVMEDIA_TYPE_VIDEO:
|
case AVMEDIA_TYPE_VIDEO:
|
||||||
if (id == AV_CODEC_ID_MPEG2TS) // should not happen
|
if (id == AV_CODEC_ID_MPEG2TS) // should not happen
|
||||||
break;
|
break;
|
||||||
fprintf(stderr, "%s %s %d: returning mpeg2video\n", __FILE__,__func__,__LINE__);
|
|
||||||
return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type);
|
return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type);
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
fprintf(stderr, "%s %s %d: returning dummy writer\n", __FILE__,__func__,__LINE__);
|
|
||||||
return &writer;
|
return &writer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -46,8 +46,6 @@ bool cPlayback::Open(playmode_t PlayMode)
|
|||||||
last_size = 0;
|
last_size = 0;
|
||||||
nPlaybackSpeed = 0;
|
nPlaybackSpeed = 0;
|
||||||
init_jump = -1;
|
init_jump = -1;
|
||||||
|
|
||||||
player = new Player();
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -81,23 +79,9 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
|
|||||||
mAudioStream=0;
|
mAudioStream=0;
|
||||||
mSubtitleStream=-1;
|
mSubtitleStream=-1;
|
||||||
mTeletextStream=-1;
|
mTeletextStream=-1;
|
||||||
char file[strlen(filename) + 1];
|
|
||||||
*file = 0;
|
|
||||||
|
|
||||||
if (!strncmp("file://", filename, 7))
|
|
||||||
filename += 7;
|
|
||||||
|
|
||||||
if(strstr(filename, "://"))
|
|
||||||
isHTTP = true;
|
|
||||||
else if (no_probe)
|
|
||||||
strcat(file, "myts://");
|
|
||||||
else
|
|
||||||
strcat(file, "file://");
|
|
||||||
|
|
||||||
strcat(file, filename);
|
|
||||||
|
|
||||||
//try to open file
|
//try to open file
|
||||||
if(player && player->Open(file)) {
|
if(player && player->Open(filename, no_probe)) {
|
||||||
if (pm != PLAYMODE_TS) {
|
if (pm != PLAYMODE_TS) {
|
||||||
player->output.Open();
|
player->output.Open();
|
||||||
|
|
||||||
@@ -113,21 +97,18 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
|
|||||||
* with the exception of timeshift. but this should be handled
|
* with the exception of timeshift. but this should be handled
|
||||||
* outside this lib or with another function!
|
* outside this lib or with another function!
|
||||||
*/
|
*/
|
||||||
if (pm != PLAYMODE_TS)
|
if (pm != PLAYMODE_TS) {
|
||||||
{
|
if ((ret) && (!isHTTP)) {
|
||||||
if ((ret) && (!isHTTP))
|
//pause playback in case of timeshift
|
||||||
{
|
//FIXME: no picture on tv
|
||||||
//pause playback in case of timeshift
|
if (!player->Pause()) {
|
||||||
//FIXME: no picture on tv
|
ret = false;
|
||||||
if (!player || !player->Pause())
|
printf("failed to pause playback\n");
|
||||||
{
|
} else
|
||||||
ret = false;
|
playing = true;
|
||||||
printf("failed to pause playback\n");
|
} else
|
||||||
} else
|
playing = true;
|
||||||
playing = true;
|
}
|
||||||
} else
|
|
||||||
playing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("%s:%s - return=%d\n", FILENAME, __FUNCTION__, ret);
|
printf("%s:%s - return=%d\n", FILENAME, __FUNCTION__, ret);
|
||||||
|
|
||||||
@@ -135,13 +116,11 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un
|
|||||||
if (fn_ts.rfind(".ts") == fn_ts.length() - 3)
|
if (fn_ts.rfind(".ts") == fn_ts.length() - 3)
|
||||||
fn_xml = fn_ts.substr(0, fn_ts.length() - 3) + ".xml";
|
fn_xml = fn_ts.substr(0, fn_ts.length() - 3) + ".xml";
|
||||||
|
|
||||||
if (pm == PLAYMODE_TS)
|
if (pm == PLAYMODE_TS) {
|
||||||
{
|
|
||||||
struct stat s;
|
struct stat s;
|
||||||
if (!stat(filename, &s))
|
if (!stat(filename, &s))
|
||||||
last_size = s.st_size;
|
last_size = s.st_size;
|
||||||
if (player)
|
if (player) {
|
||||||
{
|
|
||||||
ret = true;
|
ret = true;
|
||||||
videoDecoder->Stop(false);
|
videoDecoder->Stop(false);
|
||||||
audioDecoder->Stop();
|
audioDecoder->Stop();
|
||||||
@@ -156,18 +135,9 @@ bool cPlayback::Stop(void)
|
|||||||
printf("%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
|
printf("%s:%s playing %d\n", FILENAME, __FUNCTION__, playing);
|
||||||
//if(playing==false) return false;
|
//if(playing==false) return false;
|
||||||
|
|
||||||
if(player)
|
player->Stop();
|
||||||
player->Stop();
|
player->output.Close();
|
||||||
|
player->Close();
|
||||||
if(player)
|
|
||||||
player->output.Close();
|
|
||||||
|
|
||||||
if(player)
|
|
||||||
player->Close();
|
|
||||||
if(player) {
|
|
||||||
delete player;
|
|
||||||
player = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
playing=false;
|
playing=false;
|
||||||
return true;
|
return true;
|
||||||
@@ -177,8 +147,7 @@ bool cPlayback::SetAPid(int pid, bool ac3 __attribute__((unused)))
|
|||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
if(pid!=mAudioStream){
|
if(pid!=mAudioStream){
|
||||||
if(player)
|
player->SwitchAudio(pid);
|
||||||
player->SwitchAudio(pid);
|
|
||||||
mAudioStream=pid;
|
mAudioStream=pid;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -188,8 +157,7 @@ bool cPlayback::SetSubtitlePid(int pid)
|
|||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
if(pid!=mSubtitleStream){
|
if(pid!=mSubtitleStream){
|
||||||
if(player)
|
player->SwitchSubtitle(pid);
|
||||||
player->SwitchSubtitle(pid);
|
|
||||||
mSubtitleStream = pid;
|
mSubtitleStream = pid;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -199,8 +167,7 @@ bool cPlayback::SetTeletextPid(int pid)
|
|||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
if(pid!=mTeletextStream){
|
if(pid!=mTeletextStream){
|
||||||
if(player)
|
player->SwitchTeletext(pid);
|
||||||
player->SwitchTeletext(pid);
|
|
||||||
mTeletextStream=pid;
|
mTeletextStream=pid;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@@ -216,69 +183,47 @@ bool cPlayback::SetSpeed(int speed)
|
|||||||
videoDecoder->closeDevice();
|
videoDecoder->closeDevice();
|
||||||
decoders_closed = true;
|
decoders_closed = true;
|
||||||
usleep(500000);
|
usleep(500000);
|
||||||
if (player) {
|
player->output.Open();
|
||||||
player->output.Open();
|
playing = player->Play();
|
||||||
playing = player->Play();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(playing==false)
|
if(playing==false)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(player)
|
int result = 0;
|
||||||
{
|
|
||||||
int result = 0;
|
|
||||||
|
|
||||||
nPlaybackSpeed = speed;
|
nPlaybackSpeed = speed;
|
||||||
|
|
||||||
if (speed > 1)
|
if (speed > 1) {
|
||||||
{
|
/* direction switch ? */
|
||||||
/* direction switch ? */
|
if (player->isBackWard) {
|
||||||
if (player->isBackWard)
|
result = player->FastBackward(0);
|
||||||
{
|
}
|
||||||
result = player->FastBackward(0);
|
result = player->FastForward(speed);
|
||||||
|
} else if (speed < 0) {
|
||||||
printf("result = %d\n", result);
|
/* direction switch ? */
|
||||||
}
|
if (player->isForwarding) {
|
||||||
result = player->FastForward(speed);
|
|
||||||
} else
|
|
||||||
if (speed < 0)
|
|
||||||
{
|
|
||||||
/* direction switch ? */
|
|
||||||
if (player->isForwarding)
|
|
||||||
{
|
|
||||||
result = player->Continue();
|
|
||||||
|
|
||||||
printf("result = %d\n", result);
|
|
||||||
}
|
|
||||||
|
|
||||||
result = player->FastBackward(speed);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
if (speed == 0)
|
|
||||||
{
|
|
||||||
/* konfetti: hmmm accessing the member isn't very proper */
|
|
||||||
if ((player->isForwarding) || (!player->isBackWard))
|
|
||||||
player->Pause();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
player->FastForward(0);
|
|
||||||
}
|
|
||||||
} else
|
|
||||||
{
|
|
||||||
result = player->Continue();
|
result = player->Continue();
|
||||||
}
|
}
|
||||||
|
result = player->FastBackward(speed);
|
||||||
if (init_jump > -1)
|
} else if (speed == 0) {
|
||||||
{
|
/* konfetti: hmmm accessing the member isn't very proper */
|
||||||
SetPosition(init_jump);
|
if ((player->isForwarding) || (!player->isBackWard))
|
||||||
init_jump = -1;
|
player->Pause();
|
||||||
|
else {
|
||||||
|
player->FastForward(0);
|
||||||
}
|
}
|
||||||
if (result != 0)
|
} else {
|
||||||
{
|
result = player->Continue();
|
||||||
printf("returning false\n");
|
}
|
||||||
return false;
|
|
||||||
}
|
if (init_jump > -1) {
|
||||||
|
SetPosition(init_jump);
|
||||||
|
init_jump = -1;
|
||||||
|
}
|
||||||
|
if (!result) {
|
||||||
|
printf("returning false\n");
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -292,8 +237,7 @@ bool cPlayback::GetSpeed(int &speed) const
|
|||||||
|
|
||||||
void cPlayback::GetPts(uint64_t &pts)
|
void cPlayback::GetPts(uint64_t &pts)
|
||||||
{
|
{
|
||||||
if (player)
|
player->GetPts((int64_t &) pts);
|
||||||
player->GetPts((int64_t &) pts);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// in milliseconds
|
// in milliseconds
|
||||||
@@ -325,15 +269,14 @@ bool cPlayback::GetPosition(int &position, int &duration)
|
|||||||
|
|
||||||
if(playing==false) return false;
|
if(playing==false) return false;
|
||||||
|
|
||||||
if (player && !player->isPlaying) {
|
if (!player->isPlaying) {
|
||||||
printf("cPlayback::%s !!!!EOF!!!! < -1\n", __func__);
|
printf("cPlayback::%s !!!!EOF!!!! < -1\n", __func__);
|
||||||
position = duration + 1000;
|
position = duration + 1000;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t vpts = 0;
|
int64_t vpts = 0;
|
||||||
if(player)
|
player->GetPts(vpts);
|
||||||
player->GetPts(vpts);
|
|
||||||
|
|
||||||
if(vpts <= 0) {
|
if(vpts <= 0) {
|
||||||
//printf("ERROR: vpts==0");
|
//printf("ERROR: vpts==0");
|
||||||
@@ -347,8 +290,7 @@ bool cPlayback::GetPosition(int &position, int &duration)
|
|||||||
|
|
||||||
double length = 0;
|
double length = 0;
|
||||||
|
|
||||||
if(player)
|
player->GetDuration(length);
|
||||||
player->GetDuration(length);
|
|
||||||
|
|
||||||
if(length <= 0) {
|
if(length <= 0) {
|
||||||
duration = duration+1000;
|
duration = duration+1000;
|
||||||
@@ -374,8 +316,7 @@ bool cPlayback::SetPosition(int position, bool absolute)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
float pos = (position/1000.0);
|
float pos = (position/1000.0);
|
||||||
if(player)
|
player->Seek(pos, absolute);
|
||||||
player->Seek(pos, absolute);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,15 +325,14 @@ void cPlayback::FindAllPids(int *pids, unsigned int *ac3flags, unsigned int *num
|
|||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
if(player) {
|
std::vector<Track> tracks = player->manager.getAudioTracks();
|
||||||
std::vector<Track> tracks = player->manager.getAudioTracks();
|
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
||||||
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
pids[i] = it->pid;
|
||||||
pids[i] = it->pid;
|
ac3flags[i] = it->ac3flags;
|
||||||
ac3flags[i] = it->ac3flags;
|
language[i] = it->Name;
|
||||||
language[i] = it->Name;
|
i++;
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*numpids = i;
|
*numpids = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,14 +341,13 @@ void cPlayback::FindAllSubtitlePids(int *pids, unsigned int *numpids, std::strin
|
|||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
if(player) {
|
std::vector<Track> tracks = player->manager.getSubtitleTracks();
|
||||||
std::vector<Track> tracks = player->manager.getSubtitleTracks();
|
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
||||||
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
pids[i] = it->pid;
|
||||||
pids[i] = it->pid;
|
language[i] = it->Name;
|
||||||
language[i] = it->Name;
|
i++;
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*numpids = i;
|
*numpids = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -417,17 +356,15 @@ void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, st
|
|||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
unsigned int i = 0;
|
unsigned int i = 0;
|
||||||
|
|
||||||
if(player) {
|
std::vector<Track> tracks = player->manager.getTeletextTracks();
|
||||||
std::vector<Track> tracks = player->manager.getTeletextTracks();
|
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
||||||
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end() && i < *numpids; ++it) {
|
pids[i] = it->pid;
|
||||||
pids[i] = it->pid;
|
if (it->type != 2 && it->type != 5) // return subtitles only
|
||||||
if (it->type != 2 && it->type != 5) // return subtitles only
|
continue;
|
||||||
continue;
|
char tmp[80];
|
||||||
char tmp[80];
|
snprintf(tmp, sizeof(tmp), "%d %d %s %d %d %d", it->pid, it->pid, it->Name.c_str(), it->type, it->mag, it->page); //FIXME
|
||||||
snprintf(tmp, sizeof(tmp), "%d %d %s %d %d %d", it->pid, it->pid, it->Name.c_str(), it->type, it->mag, it->page); //FIXME
|
language[i] = std::string(tmp);
|
||||||
language[i] = std::string(tmp);
|
i++;
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
*numpids = i;
|
*numpids = i;
|
||||||
}
|
}
|
||||||
@@ -435,30 +372,14 @@ void cPlayback::FindAllTeletextsubtitlePids(int *pids, unsigned int *numpids, st
|
|||||||
int cPlayback::GetTeletextPid(void)
|
int cPlayback::GetTeletextPid(void)
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
if(player) {
|
std::vector<Track> tracks = player->manager.getTeletextTracks();
|
||||||
std::vector<Track> tracks = player->manager.getTeletextTracks();
|
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end(); ++it) {
|
||||||
for (std::vector<Track>::iterator it = tracks.begin(); it != tracks.end(); ++it) {
|
if (it->type == 1)
|
||||||
if (it->type == 1)
|
return it->pid;
|
||||||
return it->pid;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
/* dummy functions for subtitles */
|
|
||||||
void cPlayback::FindAllSubs(uint16_t * /*pids*/, unsigned short * /*supp*/, uint16_t *num, std::string * /*lang*/)
|
|
||||||
{
|
|
||||||
*num = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool cPlayback::SelectSubtitles(int pid)
|
|
||||||
{
|
|
||||||
printf("%s:%s pid %d\n", FILENAME, __func__, pid);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
|
void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string> &titles)
|
||||||
{
|
{
|
||||||
player->GetChapters(positions, titles);
|
player->GetChapters(positions, titles);
|
||||||
@@ -467,8 +388,6 @@ void cPlayback::GetChapters(std::vector<int> &positions, std::vector<std::string
|
|||||||
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
|
void cPlayback::GetMetadata(std::vector<std::string> &keys, std::vector<std::string> &values)
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
if (!player)
|
|
||||||
return;
|
|
||||||
player->input.GetMetadata(keys, values);
|
player->input.GetMetadata(keys, values);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -476,24 +395,25 @@ cPlayback::cPlayback(int num __attribute__((unused)))
|
|||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
playing=false;
|
playing=false;
|
||||||
|
|
||||||
|
player = new Player();
|
||||||
}
|
}
|
||||||
|
|
||||||
cPlayback::~cPlayback()
|
cPlayback::~cPlayback()
|
||||||
{
|
{
|
||||||
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
printf("%s:%s\n", FILENAME, __FUNCTION__);
|
||||||
|
if(player)
|
||||||
|
delete player;
|
||||||
}
|
}
|
||||||
|
|
||||||
void cPlayback::RequestAbort() {
|
void cPlayback::RequestAbort() {
|
||||||
if (player) {
|
player->RequestAbort();
|
||||||
player->abortRequested = 1;
|
while (player->isPlaying)
|
||||||
while (player->isPlaying)
|
usleep(100000);
|
||||||
usleep(100000);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool cPlayback::IsPlaying() {
|
bool cPlayback::IsPlaying() {
|
||||||
if (player)
|
return player->isPlaying;
|
||||||
return player->isPlaying;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user