From e9b361f9f8249126b63f0804f45399a8fc779e8a Mon Sep 17 00:00:00 2001 From: martii Date: Sun, 6 Apr 2014 11:35:17 +0200 Subject: [PATCH] libeplayer3: implement Writer class Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/889d68740cb5e46d2796d102cfd65b238fa81445 Author: martii Date: 2014-04-06 (Sun, 06 Apr 2014) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3/container/container_ffmpeg.cpp | 171 ++---- libeplayer3/include/manager.h | 7 +- libeplayer3/include/misc.h | 40 +- libeplayer3/include/output.h | 3 +- libeplayer3/include/pes.h | 38 +- libeplayer3/include/writer.h | 69 +-- libeplayer3/manager/audio.cpp | 11 +- libeplayer3/manager/chapter.cpp | 3 +- libeplayer3/manager/subtitle.cpp | 10 +- libeplayer3/manager/teletext.cpp | 10 +- libeplayer3/manager/video.cpp | 10 +- libeplayer3/output/linuxdvb.cpp | 607 ++++----------------- libeplayer3/output/output.cpp | 10 - libeplayer3/output/writer/ac3.cpp | 137 +---- libeplayer3/output/writer/divx.cpp | 146 ++--- libeplayer3/output/writer/dts.cpp | 123 +---- libeplayer3/output/writer/flac.cpp | 118 +--- libeplayer3/output/writer/h263.cpp | 132 +---- libeplayer3/output/writer/h264.cpp | 231 ++------ libeplayer3/output/writer/mp3.cpp | 146 +---- libeplayer3/output/writer/mpeg2.cpp | 156 ++---- libeplayer3/output/writer/pcm.cpp | 245 ++++----- libeplayer3/output/writer/vc1.cpp | 348 +++++------- libeplayer3/output/writer/wmv.cpp | 226 +++----- libeplayer3/output/writer/writer.cpp | 189 +++---- libeplayer3/playback/playback.cpp | 20 +- libspark/playback_libeplayer3.cpp | 21 +- 27 files changed, 850 insertions(+), 2377 deletions(-) diff --git a/libeplayer3/container/container_ffmpeg.cpp b/libeplayer3/container/container_ffmpeg.cpp index 5771b41..357eefb 100644 --- a/libeplayer3/container/container_ffmpeg.cpp +++ b/libeplayer3/container/container_ffmpeg.cpp @@ -39,6 +39,8 @@ #include #include +#include + #include "common.h" #include "misc.h" #include "debug.h" @@ -103,72 +105,6 @@ static float seek_sec_abs = -1.0, seek_sec_rel = 0.0; /* MISC Functions */ /* ***************************** */ -static const char *Codec2Encoding(AVCodecContext * codec) -{ - fprintf(stderr, "Codec ID: %ld (%.8lx)\n", (long) codec->codec_id, (long) codec->codec_id); - switch (codec->codec_id) { - case AV_CODEC_ID_MPEG1VIDEO: - case AV_CODEC_ID_MPEG2VIDEO: - return "V_MPEG1"; - case AV_CODEC_ID_H263: - case AV_CODEC_ID_H263P: - case AV_CODEC_ID_H263I: - return "V_H263"; - case AV_CODEC_ID_FLV1: - return "V_FLV"; - case AV_CODEC_ID_VP5: - case AV_CODEC_ID_VP6: - case AV_CODEC_ID_VP6F: - return "V_VP6"; - case AV_CODEC_ID_RV10: - case AV_CODEC_ID_RV20: - return "V_RMV"; - case AV_CODEC_ID_MPEG4: - case AV_CODEC_ID_MSMPEG4V1: - case AV_CODEC_ID_MSMPEG4V2: - case AV_CODEC_ID_MSMPEG4V3: - return "V_MSCOMP"; - case AV_CODEC_ID_WMV1: - case AV_CODEC_ID_WMV2: - case AV_CODEC_ID_WMV3: - return "V_WMV"; - case AV_CODEC_ID_VC1: - return "V_VC1"; - case AV_CODEC_ID_H264: - return "V_MPEG4/ISO/AVC"; - case AV_CODEC_ID_AVS: - return "V_AVS"; - case AV_CODEC_ID_MP2: - return "A_MPEG/L3"; - case AV_CODEC_ID_MP3: - return "A_MP3"; - case AV_CODEC_ID_AC3: - return "A_AC3"; - case AV_CODEC_ID_EAC3: - return "A_EAC3"; - case AV_CODEC_ID_DTS: - return "A_DTS"; -/* subtitle */ - case AV_CODEC_ID_SSA: - return "S_TEXT/ASS"; /* Hellmaster1024: seems to be ASS instead of SSA */ - case AV_CODEC_ID_TEXT: /* Hellmaster1024: i dont have most of this, but lets hope it is normal text :-) */ - case AV_CODEC_ID_DVD_SUBTITLE: - case AV_CODEC_ID_DVB_SUBTITLE: - case AV_CODEC_ID_XSUB: - case AV_CODEC_ID_MOV_TEXT: - case AV_CODEC_ID_HDMV_PGS_SUBTITLE: - case AV_CODEC_ID_DVB_TELETEXT: - case AV_CODEC_ID_SRT: - return "S_TEXT/SRT"; /* fixme */ - default: - // Default to injected-pcm for unhandled audio types. - if (codec->codec_type == AVMEDIA_TYPE_AUDIO) - return "A_IPCM"; - ffmpeg_err("Codec ID %ld (%.8lx) not found\n", (long) codec->codec_id, (long) codec->codec_id); - } - return NULL; -} - int64_t calcPts(AVFormatContext *avfc, AVStream * stream, int64_t pts) { if (!avfc || !stream) { @@ -219,10 +155,9 @@ static void *FFMPEGThread(void *arg) } ffmpeg_printf(10, "Running!\n"); - while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) { - AudioVideoOut_t avOut; - avOut.restart_audio_resampling = 0; + bool restart_audio_resampling = false; + while (context && context->playback && context->playback->isPlaying && !context->playback->abortRequested) { //IF MOVIE IS PAUSED, WAIT if (context->playback->isPaused) { @@ -291,7 +226,7 @@ static void *FFMPEGThread(void *arg) if (res < 0 && context->playback->BackWard) bofcount = 1; seek_target = INT64_MIN; - avOut.restart_audio_resampling = 1; + restart_audio_resampling = true; // flush streams unsigned int i; @@ -321,8 +256,6 @@ static void *FFMPEGThread(void *arg) context->playback->readCount += packet.size; - avOut.packet = &packet; - int pid = avContext->streams[packet.stream_index]->id; if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) @@ -343,28 +276,16 @@ static void *FFMPEGThread(void *arg) currentVideoPts = pts = calcPts(avContext, videoTrack->stream, packet.pts); ffmpeg_printf(200, "VideoTrack index = %d %lld\n", pid, currentVideoPts); - - avOut.pts = pts; - - avOut.type = "video"; - avOut.stream = videoTrack->stream; - avOut.avfc = avContext; - - if (context->output->video->Write(context, &avOut) < 0) { + if (!context->output->video->Write(avContext, videoTrack->stream, &packet, currentVideoPts)) ffmpeg_err("writing data to video device failed\n"); - } } else if (audioTrack && (audioTrack->Id == pid)) { - context->currentAudioPtsP = ¤tAudioPts; //FIXME, temporary workaround only + if (restart_audio_resampling) { + restart_audio_resampling = false; + context->output->audio->Write(avContext, audioTrack->stream, NULL, currentAudioPts); + } if (!context->playback->BackWard) { currentAudioPts = pts = calcPts(avContext, audioTrack->stream, packet.pts); - - ffmpeg_printf(200, "AudioTrack index = %d\n", pid); - avOut.pts = pts; - avOut.type = "audio"; - avOut.stream = audioTrack->stream; - avOut.avfc = avContext; - - if (context->output->audio->Write(context, &avOut) < 0) + if (!context->output->audio->Write(avContext, audioTrack->stream, &packet, currentAudioPts)) ffmpeg_err("writing data to audio device failed\n"); } } else if (subtitleTrack && (subtitleTrack->Id == pid)) { @@ -492,7 +413,6 @@ static void container_ffmpeg_read_subtitle(Context_t * context, const char *file track.Name = format; track.is_static = 1; track.Id = pid; - track.Encoding = strcmp(format, "srt") ? "S_TEXT/ASS" : "S_TEXT/SRT"; context->manager->subtitle->Command(context, MANAGER_ADD, &track); } @@ -505,6 +425,10 @@ static void container_ffmpeg_read_subtitles(Context_t * context, const char *fil container_ffmpeg_read_subtitle(context, filename, "ssa", 0xFFFD); } +// from output/linuxdvb.cpp ... FIXME! +extern AVStream *audioStream; +extern AVStream *videoStream; + int container_ffmpeg_init(Context_t * context, const char *filename) { int err; @@ -582,13 +506,23 @@ int container_ffmpeg_init(Context_t * context, const char *filename) terminating = 0; int res = container_ffmpeg_update_tracks(context, filename); +audioStream = NULL; +videoStream = NULL; + unsigned int n, found_av = 0; for (n = 0; n < avContext->nb_streams; n++) { AVStream *stream = avContext->streams[n]; switch (stream->codec->codec_type) { case AVMEDIA_TYPE_AUDIO: - case AVMEDIA_TYPE_VIDEO: + if (!audioStream) + audioStream = stream; found_av = 1; + break; + case AVMEDIA_TYPE_VIDEO: + if (!videoStream) + videoStream = stream; + found_av = 1; + break; default: break; } @@ -645,11 +579,6 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) Track_t track; AVStream *stream = avContext->streams[n]; - const char *encoding = Codec2Encoding(stream->codec); - - if (encoding != NULL) - ffmpeg_printf(1, "%d. encoding = %s\n", n, encoding); - if (!stream->id) stream->id = n + 1; @@ -660,9 +589,7 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) case AVMEDIA_TYPE_VIDEO: ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", stream->codec->codec_type); - if (encoding != NULL) { track.Name = "und"; - track.Encoding = encoding; track.avfc = avContext; track.Id = stream->id; @@ -679,14 +606,10 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) ffmpeg_err("failed to add track %d\n", n); } - } else { - ffmpeg_err("codec type video but codec unknown %d\n", stream->codec->codec_id); - } break; case AVMEDIA_TYPE_AUDIO: ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n", stream->codec->codec_type); - if (encoding != NULL) { AVDictionaryEntry *lang; lang = av_dict_get(stream->metadata, "language", NULL, 0); @@ -695,7 +618,6 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) ffmpeg_printf(10, "Language %s\n", track.Name.c_str()); - track.Encoding = encoding; track.Id = stream->id; track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; @@ -706,6 +628,28 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; } + switch(stream->codec->codec_id) { + case AUDIO_ENCODING_MPEG2: + track.ac3flags = 9; + break; + case AV_CODEC_ID_MP3: + track.ac3flags = 4; + break; + case AV_CODEC_ID_AC3: + track.ac3flags = 1; + break; + case AV_CODEC_ID_EAC3: + track.ac3flags = 7; + break; + case AV_CODEC_ID_DTS: + track.ac3flags = 6; + break; + case AV_CODEC_ID_AAC: + track.ac3flags = 5; + break; + default: + track.ac3flags = 0; + } if (context->manager->audio) { if (context->manager->audio->Command(context, MANAGER_ADD, &track) < 0) { /* konfetti: fixme: is this a reason to return with error? */ @@ -713,9 +657,6 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) } } - } else { - ffmpeg_err("codec type audio but codec unknown %d\n", stream->codec->codec_id); - } break; case AVMEDIA_TYPE_SUBTITLE: { @@ -729,7 +670,6 @@ int container_ffmpeg_update_tracks(Context_t * context, const char *filename) ffmpeg_printf(10, "Language %s\n", track.Name.c_str()); - track.Encoding = encoding; track.Id = stream->id; track.duration = (double) stream->duration * av_q2d(stream->time_base) * 1000.0; @@ -908,11 +848,16 @@ static int container_ffmpeg_get_length(Context_t * context, double *length) static int container_ffmpeg_switch_audio(Context_t * context, int *arg) { - ffmpeg_printf(10, "track %d\n", *arg); - /* Hellmaster1024: nothing to do here! */ - float sec = -5.0; - context->playback->Command(context, PLAYBACK_SEEK, (void *) &sec); - return cERR_CONTAINER_FFMPEG_NO_ERROR; + Track_t *audioTrack = NULL; + context->manager->audio->Command(context, MANAGER_GET_TRACK, &arg); + if (audioTrack) { + audioStream = audioTrack->stream; + ffmpeg_printf(10, "track %d\n", *arg); + /* Hellmaster1024: nothing to do here! */ + float sec = -5.0; + context->playback->Command(context, PLAYBACK_SEEK, (void *) &sec); + } + return cERR_CONTAINER_FFMPEG_NO_ERROR; } static int container_ffmpeg_switch_subtitle(Context_t * context __attribute__ ((unused)), int *arg __attribute__ ((unused))) diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index 5f87cfc..ab9a76b 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -19,7 +19,6 @@ typedef enum { MANAGER_GET, MANAGER_GETNAME, MANAGER_SET, - MANAGER_GETENCODING, MANAGER_DEL, MANAGER_GET_TRACK, MANAGER_INIT_UPDATE @@ -32,7 +31,6 @@ typedef enum { typedef struct Track_s { std::string Name; - const char *Encoding; int Id; /* new field for ffmpeg - add at the end so no problem @@ -52,7 +50,10 @@ typedef struct Track_s { int is_static; long long int chapter_start; long long int chapter_end; - Track_s() : Encoding(NULL), Id(0), language(NULL), duration(-1), avfc(NULL), stream(NULL), pending(0), is_static(0), chapter_start(0), chapter_end(0) {} + + int ac3flags; + + Track_s() : Id(-1), language(NULL), duration(-1), avfc(NULL), stream(NULL), pending(0), is_static(0), chapter_start(0), chapter_end(0), ac3flags(-1) {} } Track_t; struct Context_s; diff --git a/libeplayer3/include/misc.h b/libeplayer3/include/misc.h index 468b94d..7c383e7 100644 --- a/libeplayer3/include/misc.h +++ b/libeplayer3/include/misc.h @@ -1,44 +1,18 @@ #ifndef misc_123 #define misc_123 -#include - /* some useful things needed by many files ... */ -/* ***************************** */ -/* Types */ -/* ***************************** */ +#define INVALID_PTS_VALUE 0x200000000ll -typedef struct BitPacker_s { - unsigned char *Ptr; /* write pointer */ - unsigned int BitBuffer; /* bitreader shifter */ - int Remaining; /* number of remaining in the shifter */ -} BitPacker_t; - -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define INVALID_PTS_VALUE 0x200000000ull - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ +struct BitPacker_t +{ + unsigned char *Ptr; /* write pointer */ + unsigned int BitBuffer; /* bitreader shifter */ + int Remaining; /* number of remaining in the shifter */ +}; void PutBits(BitPacker_t * ld, unsigned int code, unsigned int length); void FlushBits(BitPacker_t * ld); -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static inline char *getExtension(char *name) -{ - if (name) { - char *ext = strrchr(name, '.'); - if (ext) - return ext + 1; - } - return NULL; -} #endif diff --git a/libeplayer3/include/output.h b/libeplayer3/include/output.h index 867e361..425b82e 100644 --- a/libeplayer3/include/output.h +++ b/libeplayer3/include/output.h @@ -28,7 +28,6 @@ typedef enum { OUTPUT_AVSYNC, OUTPUT_CLEAR, OUTPUT_PTS, - OUTPUT_SWITCH, OUTPUT_SLOWMOTION, OUTPUT_AUDIOMUTE, OUTPUT_REVERSE, @@ -54,7 +53,7 @@ typedef struct Context_s Context_t; typedef struct Output_s { const char *Name; int (*Command) (Context_t *, OutputCmd_t, const char *); - int (*Write) (Context_t *, AudioVideoOut_t *privateData); + bool (*Write) (AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts); const char **Capabilities; } Output_t; diff --git a/libeplayer3/include/pes.h b/libeplayer3/include/pes.h index 670177a..67f363e 100644 --- a/libeplayer3/include/pes.h +++ b/libeplayer3/include/pes.h @@ -1,30 +1,32 @@ #ifndef pes_123 #define pes_123 -#define PES_MAX_HEADER_SIZE 64 -#define PES_PRIVATE_DATA_FLAG 0x80 -#define PES_PRIVATE_DATA_LENGTH 8 -#define PES_LENGTH_BYTE_0 5 -#define PES_LENGTH_BYTE_1 4 -#define PES_FLAGS_BYTE 7 -#define PES_EXTENSION_DATA_PRESENT 0x01 -#define PES_HEADER_DATA_LENGTH_BYTE 8 -#define PES_START_CODE_RESERVED_4 0xfd -#define PES_VERSION_FAKE_START_CODE 0x31 +#include + +#define PES_MAX_HEADER_SIZE 64 +#define PES_PRIVATE_DATA_FLAG 0x80 +#define PES_PRIVATE_DATA_LENGTH 8 +#define PES_LENGTH_BYTE_0 5 +#define PES_LENGTH_BYTE_1 4 +#define PES_FLAGS_BYTE 7 +#define PES_EXTENSION_DATA_PRESENT 0x01 +#define PES_HEADER_DATA_LENGTH_BYTE 8 +#define PES_START_CODE_RESERVED_4 0xfd +#define PES_VERSION_FAKE_START_CODE 0x31 -#define MAX_PES_PACKET_SIZE (65535) +#define MAX_PES_PACKET_SIZE 65535 /* start codes */ -#define PCM_PES_START_CODE 0xbd -#define PRIVATE_STREAM_1_PES_START_CODE 0xbd +#define PCM_PES_START_CODE 0xbd +#define PRIVATE_STREAM_1_PES_START_CODE 0xbd #define H263_VIDEO_PES_START_CODE 0xfe -#define H264_VIDEO_PES_START_CODE 0xe2 -#define MPEG_VIDEO_PES_START_CODE 0xe0 -#define MPEG_AUDIO_PES_START_CODE 0xc0 -#define VC1_VIDEO_PES_START_CODE 0xfd -#define AAC_AUDIO_PES_START_CODE 0xcf +#define H264_VIDEO_PES_START_CODE 0xe2 +#define MPEG_VIDEO_PES_START_CODE 0xe0 +#define MPEG_AUDIO_PES_START_CODE 0xc0 +#define VC1_VIDEO_PES_START_CODE 0xfd +#define AAC_AUDIO_PES_START_CODE 0xcf int InsertPesHeader(uint8_t *data, int size, unsigned char stream_id, unsigned long long int pts, int pic_start_code); int InsertVideoPrivateDataHeader(uint8_t *data, int payload_size); diff --git a/libeplayer3/include/writer.h b/libeplayer3/include/writer.h index e51b901..dca081a 100644 --- a/libeplayer3/include/writer.h +++ b/libeplayer3/include/writer.h @@ -3,6 +3,7 @@ #include #include +#include extern "C" { #include @@ -12,61 +13,23 @@ extern "C" { #include } -typedef enum { eNone, eAudio, eVideo, eGfx } eWriterType_t; +#include -struct Context_s; -typedef struct Context_s Context_t; +#define AV_CODEC_ID_INJECTPCM AV_CODEC_ID_PCM_S16LE -typedef struct { - int fd; - int64_t Pts; - int restart_audio_resampling; - AVFormatContext *avfc; - AVStream *stream; - AVPacket *packet; - Context_t *context; -} WriterAVCallData_t; +class Writer +{ + public: + static void Register(Writer *w, enum AVCodecID id, video_encoding_t encoding); + static void Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding); + static video_encoding_t GetVideoEncoding(enum AVCodecID id); + static audio_encoding_t GetAudioEncoding(enum AVCodecID id); + static Writer *GetWriter(enum AVCodecID id, enum AVMediaType codec_type); -typedef struct WriterCaps_s { - const char *name; - eWriterType_t type; - const char *textEncoding; - /* fixme: revise if this is an enum! */ - int dvbEncoding; -} WriterCaps_t; - -typedef struct Writer_s { - int (*reset) (); - int (*writeData) (WriterAVCallData_t *); - WriterCaps_t *caps; -} Writer_t; - -extern Writer_t WriterAudioIPCM; -extern Writer_t WriterAudioPCM; -extern Writer_t WriterAudioMP3; -extern Writer_t WriterAudioMPEGL3; -extern Writer_t WriterAudioAC3; -extern Writer_t WriterAudioEAC3; -//extern Writer_t WriterAudioAAC; -extern Writer_t WriterAudioDTS; -//extern Writer_t WriterAudioWMA; -extern Writer_t WriterAudioFLAC; -extern Writer_t WriterAudioVORBIS; - -extern Writer_t WriterVideoMPEG2; -extern Writer_t WriterVideoMPEGH264; -extern Writer_t WriterVideoH264; -extern Writer_t WriterVideoWMV; -extern Writer_t WriterVideoDIVX; -extern Writer_t WriterVideoFOURCC; -extern Writer_t WriterVideoMSCOMP; -extern Writer_t WriterVideoH263; -extern Writer_t WriterVideoFLV; -extern Writer_t WriterVideoVC1; - -Writer_t *getWriter(char *encoding); - -Writer_t *getDefaultVideoWriter(); -Writer_t *getDefaultAudioWriter(); + virtual void Init(void) { } + virtual bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + Writer() { Init (); } + ~Writer() {} +}; #endif diff --git a/libeplayer3/manager/audio.cpp b/libeplayer3/manager/audio.cpp index 2a8aba9..4e5f1d2 100644 --- a/libeplayer3/manager/audio.cpp +++ b/libeplayer3/manager/audio.cpp @@ -97,7 +97,9 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) char tmp[len]; snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(it->second.Encoding); + snprintf(tmp, len, "%d\n", it->second.ac3flags); + tracklist[j + 1] = strdup(tmp); + j += 2; } tracklist[j] = NULL; @@ -141,13 +143,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) *((Track_t **) argument) = NULL; break; } - case MANAGER_GETENCODING:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Encoding); - else - *((char **) argument) = strdup(""); - break; - } case MANAGER_GETNAME:{ if (CurrentPid > -1) *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); diff --git a/libeplayer3/manager/chapter.cpp b/libeplayer3/manager/chapter.cpp index 8d4dfcd..2a77808 100644 --- a/libeplayer3/manager/chapter.cpp +++ b/libeplayer3/manager/chapter.cpp @@ -92,7 +92,8 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) char tmp[len]; snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(it->second.Encoding); + tracklist[j + 1] = strdup(""); + j += 2; } tracklist[j] = NULL; diff --git a/libeplayer3/manager/subtitle.cpp b/libeplayer3/manager/subtitle.cpp index 0112008..900e064 100644 --- a/libeplayer3/manager/subtitle.cpp +++ b/libeplayer3/manager/subtitle.cpp @@ -94,7 +94,8 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) char tmp[len]; snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(it->second.Encoding); + tracklist[j + 1] = strdup(""); + j += 2; } tracklist[j] = NULL; @@ -136,13 +137,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) *((Track_t **) argument) = NULL; break; } - case MANAGER_GETENCODING:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Encoding); - else - *((char **) argument) = strdup(""); - break; - } case MANAGER_GETNAME:{ if (CurrentPid > -1) *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); diff --git a/libeplayer3/manager/teletext.cpp b/libeplayer3/manager/teletext.cpp index 2f2922f..694af28 100644 --- a/libeplayer3/manager/teletext.cpp +++ b/libeplayer3/manager/teletext.cpp @@ -94,7 +94,8 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) char tmp[len]; snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(it->second.Encoding); + tracklist[j + 1] = strdup(""); + j += 2; } tracklist[j] = NULL; @@ -137,13 +138,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) *((Track_t **) argument) = NULL; break; } - case MANAGER_GETENCODING:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Encoding); - else - *((char **) argument) = strdup(""); - break; - } case MANAGER_GETNAME:{ if (CurrentPid > -1) *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); diff --git a/libeplayer3/manager/video.cpp b/libeplayer3/manager/video.cpp index d56f49f..10f1966 100644 --- a/libeplayer3/manager/video.cpp +++ b/libeplayer3/manager/video.cpp @@ -97,7 +97,8 @@ static char **ManagerList(Context_t * context __attribute__ ((unused))) char tmp[len]; snprintf(tmp, len, "%d %s\n", it->second.Id, it->second.Name.c_str()); tracklist[j] = strdup(tmp); - tracklist[j + 1] = strdup(it->second.Encoding); + tracklist[j + 1] = strdup(""); + j += 2; } tracklist[j] = NULL; @@ -140,13 +141,6 @@ static int Command(Context_t *context, ManagerCmd_t command, void *argument) *((Track_t **) argument) = NULL; break; } - case MANAGER_GETENCODING:{ - if (CurrentPid > -1) - *((char **) argument) = strdup(Tracks[CurrentPid].Encoding); - else - *((char **) argument) = strdup(""); - break; - } case MANAGER_GETNAME:{ if (CurrentPid > -1) *((char **) argument) = strdup(Tracks[CurrentPid].Name.c_str()); diff --git a/libeplayer3/output/linuxdvb.cpp b/libeplayer3/output/linuxdvb.cpp index 3956177..ef96d5b 100644 --- a/libeplayer3/output/linuxdvb.cpp +++ b/libeplayer3/output/linuxdvb.cpp @@ -37,6 +37,10 @@ #include #include +#include +#include +#include + #include "common.h" #include "output.h" #include "writer.h" @@ -69,12 +73,26 @@ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x ); #define cERR_LINUXDVB_NO_ERROR 0 #define cERR_LINUXDVB_ERROR -1 +#define dioctl(fd,req,arg) ({ \ + int _r = ioctl(fd,req,arg); \ + if (_r) \ + fprintf(stderr, "%s %d: ioctl '%s' failed: %d (%s)\n", __FILE__, __LINE__, #req, errno, strerror(errno)); \ + _r; \ +}) + static const char VIDEODEV[] = "/dev/dvb/adapter0/video0"; static const char AUDIODEV[] = "/dev/dvb/adapter0/audio0"; static int videofd = -1; static int audiofd = -1; +static Writer *videoWriter = NULL; +static Writer *audioWriter = NULL; +OpenThreads::Mutex audioMutex, videoMutex; + +AVStream *audioStream = NULL; +AVStream *videoStream = NULL; + unsigned long long int sCURRENT_PTS = 0; pthread_mutex_t LinuxDVBmutex; @@ -119,7 +137,7 @@ int LinuxDvbOpen(Context_t * context __attribute__ ((unused)), char *type) linuxdvb_printf(10, "v%d a%d\n", video, audio); - if (video && videofd < 0) { + if (videoStream && videofd < 0) { videofd = open(VIDEODEV, O_RDWR); if (videofd < 0) { @@ -129,29 +147,10 @@ int LinuxDvbOpen(Context_t * context __attribute__ ((unused)), char *type) return cERR_LINUXDVB_ERROR; } - if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); - } - - if (ioctl - (videofd, VIDEO_SELECT_SOURCE, - (void *) VIDEO_SOURCE_MEMORY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SELECT_SOURCE: %s\n", strerror(errno)); - } - - if (ioctl - (videofd, VIDEO_SET_STREAMTYPE, - (void *) STREAM_TYPE_PROGRAM) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_STREAMTYPE: %s\n", strerror(errno)); - } - - if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); - } + dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); + dioctl(videofd, VIDEO_SELECT_SOURCE, (void *) VIDEO_SOURCE_MEMORY); + dioctl(videofd, VIDEO_SET_STREAMTYPE, (void *) STREAM_TYPE_PROGRAM); + dioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); } if (audio && audiofd < 0) { @@ -167,24 +166,9 @@ int LinuxDvbOpen(Context_t * context __attribute__ ((unused)), char *type) return cERR_LINUXDVB_ERROR; } - if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); - } - - if (ioctl - (audiofd, AUDIO_SELECT_SOURCE, - (void *) AUDIO_SOURCE_MEMORY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SELECT_SOURCE: %s\n", strerror(errno)); - } - - if (ioctl - (audiofd, AUDIO_SET_STREAMTYPE, - (void *) STREAM_TYPE_PROGRAM) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_STREAMTYPE: %s\n", strerror(errno)); - } + dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); + dioctl(audiofd, AUDIO_SELECT_SOURCE, (void *) AUDIO_SOURCE_MEMORY); + dioctl(audiofd, AUDIO_SET_STREAMTYPE, (void *) STREAM_TYPE_PROGRAM); } return cERR_LINUXDVB_NO_ERROR; @@ -221,90 +205,29 @@ int LinuxDvbClose(Context_t * context, char *type) int LinuxDvbPlay(Context_t * context, char *type) { int ret = cERR_LINUXDVB_NO_ERROR; - Writer_t *writer; unsigned char video = !strcmp("video", type); unsigned char audio = !strcmp("audio", type); linuxdvb_printf(10, "v%d a%d\n", video, audio); - if (video && videofd != -1) { - char *Encoding = NULL; - context->manager->video->Command(context, MANAGER_GETENCODING, - &Encoding); + AVStream *_videoStream = videoStream; + AVStream *_audioStream = audioStream; + if (_videoStream) + videoWriter = Writer::GetWriter(_videoStream->codec->codec_id, _videoStream->codec->codec_type); + if (_audioStream) + audioWriter = Writer::GetWriter(_audioStream->codec->codec_id, _audioStream->codec->codec_type); - linuxdvb_printf(10, "V %s\n", Encoding); + if (_videoStream && videofd > -1) { - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_err - ("cannot found writer for encoding %s using default\n", - Encoding); - if (ioctl - (videofd, VIDEO_SET_ENCODING, - (void *) VIDEO_ENCODING_AUTO) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - } else { - linuxdvb_printf(20, "found writer %s for encoding %s\n", - writer->caps->name, Encoding); - if (ioctl - (videofd, VIDEO_SET_ENCODING, - (void *) writer->caps->dvbEncoding) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_ENCODING: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - } - - if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_SET_ENCODING, videoWriter->GetVideoEncoding(_videoStream->codec->codec_id)) + || dioctl(videofd, VIDEO_PLAY, NULL)) ret = cERR_LINUXDVB_ERROR; - } - free(Encoding); } - if (audio && audiofd != -1) { - char *Encoding = NULL; - context->manager->audio->Command(context, MANAGER_GETENCODING, - &Encoding); - - linuxdvb_printf(20, "0 A %s\n", Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_err - ("cannot found writer for encoding %s using default\n", - Encoding); - if (ioctl - (audiofd, AUDIO_SET_ENCODING, - (void *) AUDIO_ENCODING_MP3) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - } else { - linuxdvb_printf(20, "found writer %s for encoding %s\n", - writer->caps->name, Encoding); - if (ioctl - (audiofd, AUDIO_SET_ENCODING, - (void *) writer->caps->dvbEncoding) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_ENCODING: %s\n", strerror(errno)); - ret = -1; - } - } - - if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); + if (_audioStream && audiofd > -1) { + if (dioctl(audiofd, AUDIO_SET_ENCODING, audioWriter->GetAudioEncoding(_audioStream->codec->codec_id)) + || dioctl(audiofd, AUDIO_PLAY, NULL)) ret = cERR_LINUXDVB_ERROR; - } - free(Encoding); } return ret; @@ -321,38 +244,22 @@ int LinuxDvbStop(Context_t * context __attribute__ ((unused)), char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (video && videofd != -1) { - if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); - } + dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); /* set back to normal speed (end trickmodes) */ - if (ioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); - } - if (ioctl(videofd, VIDEO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); + dioctl(videofd, VIDEO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); + + if (dioctl(videofd, VIDEO_STOP, NULL)) ret = cERR_LINUXDVB_ERROR; - } } if (audio && audiofd != -1) { - if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); - } + dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); /* set back to normal speed (end trickmodes) */ - if (ioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); - } - if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + dioctl(audiofd, AUDIO_SET_SPEED, DVB_SPEED_NORMAL_PLAY); + + if (dioctl(audiofd, AUDIO_STOP, NULL)) ret = cERR_LINUXDVB_ERROR; - } } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -371,18 +278,12 @@ int LinuxDvbPause(Context_t * context __attribute__ ((unused)), char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (video && videofd != -1) { - if (ioctl(videofd, VIDEO_FREEZE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FREEZE: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_FREEZE, NULL)) ret = cERR_LINUXDVB_ERROR; - } } if (audio && audiofd != -1) { - if (ioctl(audiofd, AUDIO_PAUSE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PAUSE: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_PAUSE, NULL)) ret = cERR_LINUXDVB_ERROR; - } } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -400,18 +301,12 @@ int LinuxDvbContinue(Context_t * context linuxdvb_printf(10, "v%d a%d\n", video, audio); if (video && videofd != -1) { - if (ioctl(videofd, VIDEO_CONTINUE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CONTINUE: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_CONTINUE, NULL)) ret = cERR_LINUXDVB_ERROR; - } } if (audio && audiofd != -1) { - if (ioctl(audiofd, AUDIO_CONTINUE, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CONTINUE: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_CONTINUE, NULL)) ret = cERR_LINUXDVB_ERROR; - } } linuxdvb_printf(10, "exiting\n"); @@ -428,10 +323,7 @@ int LinuxDvbReverseDiscontinuity(Context_t * context linuxdvb_printf(50, "\n"); - if (ioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_DISCONTINUITY: %s\n", strerror(errno)); - } + dioctl(videofd, VIDEO_DISCONTINUITY, (void *) dis_type); linuxdvb_printf(50, "exiting\n"); @@ -449,21 +341,13 @@ int LinuxDvbAudioMute(Context_t * context if (*flag == '1') { //AUDIO_SET_MUTE has no effect with new player //if (ioctl(audiofd, AUDIO_SET_MUTE, 1) == -1) - if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno)); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_STOP, NULL)) ret = cERR_LINUXDVB_ERROR; - } } else { //AUDIO_SET_MUTE has no effect with new player //if (ioctl(audiofd, AUDIO_SET_MUTE, 0) == -1) - if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - //linuxdvb_err("AUDIO_SET_MUTE: %s\n", strerror(errno)); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_PLAY, NULL)) ret = cERR_LINUXDVB_ERROR; - } } } @@ -483,19 +367,11 @@ int LinuxDvbFlush(Context_t * context __attribute__ ((unused)), char *type) if ((video && videofd != -1) || (audio && audiofd != -1)) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - if (video && videofd != -1) { - if (ioctl(videofd, VIDEO_FLUSH, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FLUSH: %s\n", strerror(errno)); - } - } + if (video && videofd != -1) + dioctl(videofd, VIDEO_FLUSH, NULL); - if (audio && audiofd != -1) { - if (ioctl(audiofd, AUDIO_FLUSH, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_FLUSH: %s\n", strerror(errno)); - } - } + if (audio && audiofd != -1) + dioctl(audiofd, AUDIO_FLUSH, NULL); releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } @@ -522,12 +398,8 @@ int LinuxDvbFastForward(Context_t * context, char *type) /* konfetti comment: speed is a value given in skipped frames */ - if (ioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed) == - -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_FAST_FORWARD: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_FAST_FORWARD, context->playback->Speed)) ret = cERR_LINUXDVB_ERROR; - } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } @@ -538,12 +410,7 @@ int LinuxDvbFastForward(Context_t * context, char *type) } #else -static unsigned int SpeedList[] = { - 1000, 1100, 1200, 1300, 1500, - 2000, 3000, 4000, 5000, 8000, - 12000, 16000, - 125, 250, 500, 700, 800, 900 -}; +static unsigned int SpeedList[] = { 1000, 1100, 1200, 1300, 1500, 2000, 3000, 4000, 5000, 8000, 12000, 16000, 125, 250, 500, 700, 800, 900 }; int LinuxDvbFastForward(Context_t * context, char *type) { @@ -558,16 +425,12 @@ int LinuxDvbFastForward(Context_t * context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - speedIndex = - context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); + speedIndex = context->playback->Speed % (sizeof(SpeedList) / sizeof(int)); linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - if (ioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex]) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SET_SPEED: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_SET_SPEED, SpeedList[speedIndex])) ret = cERR_LINUXDVB_ERROR; - } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } @@ -581,9 +444,7 @@ int LinuxDvbFastForward(Context_t * context, char *type) linuxdvb_printf(1, "speedIndex %d\n", speedIndex); - if (ioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex]) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_SPEED: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_SET_SPEED, SpeedList[speedIndex])) { ret = cERR_LINUXDVB_ERROR; } @@ -618,11 +479,7 @@ int LinuxDvbSlowMotion(Context_t * context, char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (video && videofd != -1) { - if (ioctl - (videofd, VIDEO_SLOWMOTION, - context->playback->SlowMotion) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_SLOWMOTION: %s\n", strerror(errno)); + if (dioctl (videofd, VIDEO_SLOWMOTION, context->playback->SlowMotion)) { ret = cERR_LINUXDVB_ERROR; } } @@ -648,12 +505,8 @@ int LinuxDvbAVSync(Context_t * context, char *type if (audiofd != -1) { getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - if (ioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync) == - -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_SET_AV_SYNC: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_SET_AV_SYNC, context->playback->AVSync)) ret = cERR_LINUXDVB_ERROR; - } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); } @@ -673,18 +526,12 @@ int LinuxDvbClear(Context_t * context __attribute__ ((unused)), char *type) getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (video && videofd != -1) { - if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL)) ret = cERR_LINUXDVB_ERROR; - } } if (audio && audiofd != -1) { - if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL)) ret = cERR_LINUXDVB_ERROR; - } } releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); @@ -705,8 +552,8 @@ int LinuxDvbPts(Context_t * context // pts is a non writting requests and can be done in parallel to other requests //getLinuxDVBMutex(FILENAME, __FUNCTION__,__LINE__); - if ((videofd > -1 && !ioctl(videofd, VIDEO_GET_PTS, (void *) &sCURRENT_PTS)) - || (audiofd > -1 && !ioctl(audiofd, AUDIO_GET_PTS, (void *) &sCURRENT_PTS))) + if ((videofd > -1 && !dioctl(videofd, VIDEO_GET_PTS, (void *) &sCURRENT_PTS)) + || (audiofd > -1 && !dioctl(audiofd, AUDIO_GET_PTS, (void *) &sCURRENT_PTS))) ret = cERR_LINUXDVB_NO_ERROR; else sCURRENT_PTS = 0; @@ -730,16 +577,12 @@ int LinuxDvbGetFrameCount(Context_t * context getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); if (videofd != -1) { - if (ioctl(videofd, VIDEO_GET_PLAY_INFO, (void *) &playInfo) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_GET_PLAY_INFO: %s\n", strerror(errno)); + if (dioctl(videofd, VIDEO_GET_PLAY_INFO, (void *) &playInfo)) { ret = cERR_LINUXDVB_ERROR; } else linuxdvb_err("V: %llu\n", playInfo.frame_count); } else if (audiofd != -1) { - if (ioctl(audiofd, AUDIO_GET_PLAY_INFO, (void *) &playInfo) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_GET_PLAY_INFO: %s\n", strerror(errno)); + if (dioctl(audiofd, AUDIO_GET_PLAY_INFO, (void *) &playInfo)) { ret = cERR_LINUXDVB_ERROR; } else linuxdvb_err("A: %llu\n", playInfo.frame_count); @@ -755,281 +598,57 @@ int LinuxDvbGetFrameCount(Context_t * context return ret; } -int LinuxDvbSwitch(Context_t * context, char *type) +bool output_switch_audio(AVStream *stream) { - unsigned char audio = !strcmp("audio", type); - unsigned char video = !strcmp("video", type); - Writer_t *writer; - - linuxdvb_printf(10, "v%d a%d\n", video, audio); - - if ((video && videofd != -1) || (audio && audiofd != -1)) { - getLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - if (audio && audiofd != -1) { - char *Encoding = NULL; - if (context && context->manager && context->manager->audio) { - context->manager->audio->Command(context, - MANAGER_GETENCODING, - &Encoding); - - linuxdvb_printf(10, "A %s\n", Encoding); - - writer = getWriter(Encoding); - - if (ioctl(audiofd, AUDIO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_STOP: %s\n", strerror(errno)); - - } - - if (ioctl(audiofd, AUDIO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_CLEAR_BUFFER: %s\n", - strerror(errno)); - - } - - if (writer == NULL) { - linuxdvb_err - ("cannot found writer for encoding %s using default\n", - Encoding); - if (ioctl - (audiofd, AUDIO_SET_ENCODING, - (void *) AUDIO_ENCODING_MP3) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", - errno); - linuxdvb_err("AUDIO_SET_ENCODING: %s\n", - strerror(errno)); - } - } else { - linuxdvb_printf(10, - "found writer %s for encoding %s\n", - writer->caps->name, Encoding); - if (ioctl - (audiofd, AUDIO_SET_ENCODING, - (void *) writer->caps->dvbEncoding) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", - errno); - linuxdvb_err("AUDIO_SET_ENCODING: %s\n", - strerror(errno)); - } - } - - if (ioctl(audiofd, AUDIO_PLAY, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("AUDIO_PLAY: %s\n", strerror(errno)); - } - free(Encoding); - } else - linuxdvb_printf(20, "no context for Audio\n"); - } - - if (video && videofd != -1) { - char *Encoding = NULL; - if (context && context->manager && context->manager->video) { - context->manager->video->Command(context, - MANAGER_GETENCODING, - &Encoding); - - if (ioctl(videofd, VIDEO_STOP, NULL) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_STOP: %s\n", strerror(errno)); - } - - if (ioctl(videofd, VIDEO_CLEAR_BUFFER) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_CLEAR_BUFFER: %s\n", - strerror(errno)); - } - - linuxdvb_printf(10, "V %s\n", Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_err - ("cannot found writer for encoding %s using default\n", - Encoding); - if (ioctl - (videofd, VIDEO_SET_ENCODING, - (void *) VIDEO_ENCODING_AUTO) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", - errno); - linuxdvb_err("VIDEO_SET_ENCODING: %s\n", - strerror(errno)); - } - } else { - linuxdvb_printf(10, - "found writer %s for encoding %s\n", - writer->caps->name, Encoding); - if (ioctl - (videofd, VIDEO_SET_ENCODING, - (void *) writer->caps->dvbEncoding) == -1) { - linuxdvb_err("ioctl failed with errno %d\n", - errno); - linuxdvb_err("VIDEO_SET_ENCODING: %s\n", - strerror(errno)); - } - } - - if (ioctl(videofd, VIDEO_PLAY, NULL) == -1) { - /* konfetti: fixme: think on this, I think we should - * return an error here and stop the playback mode - */ - linuxdvb_err("ioctl failed with errno %d\n", errno); - linuxdvb_err("VIDEO_PLAY: %s\n", strerror(errno)); - } - free(Encoding); - } else - linuxdvb_printf(20, "no context for Video\n"); - } - - releaseLinuxDVBMutex(FILENAME, __FUNCTION__, __LINE__); - - } - - linuxdvb_printf(10, "exiting\n"); - - return cERR_LINUXDVB_NO_ERROR; + if (audiofd < 0) + return false; + audioMutex.lock(); + audioStream = stream; + audioWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); + audio_encoding_t enc = Writer::GetAudioEncoding(stream->codec->codec_id); + dioctl(audiofd, AUDIO_STOP, NULL); + dioctl(audiofd, AUDIO_CLEAR_BUFFER, NULL); + dioctl (audiofd, AUDIO_SET_ENCODING, (void *) enc); + dioctl(audiofd, AUDIO_PLAY, NULL); + audioMutex.unlock(); + return true; } -static int Write(Context_t *context, AudioVideoOut_t *out) +bool output_switch_video(AVStream *stream) { - int ret = cERR_LINUXDVB_NO_ERROR; - int res = 0; - unsigned char video = 0; - unsigned char audio = 0; - Writer_t *writer; - WriterAVCallData_t call; - call.stream = out->stream; - call.avfc = out->avfc; + if (videofd < 0) + return false; + videoMutex.lock(); + videoStream = stream; + videoWriter = Writer::GetWriter(stream->codec->codec_id, stream->codec->codec_type); + video_encoding_t enc = Writer::GetVideoEncoding(stream->codec->codec_id); + dioctl(videofd, VIDEO_STOP, NULL); + dioctl(videofd, VIDEO_CLEAR_BUFFER, NULL); + dioctl(videofd, VIDEO_SET_ENCODING, (void *) enc); + dioctl(videofd, VIDEO_PLAY, NULL); + videoMutex.unlock(); + return true; +} - if (out == NULL) { - linuxdvb_err("null pointer passed\n"); - return cERR_LINUXDVB_ERROR; - } - - video = !strcmp("video", out->type); - audio = !strcmp("audio", out->type); - - linuxdvb_printf(20, "DataLength=%u Pts=%llu\n", out->packet->size, out->pts); - linuxdvb_printf(20, "v%d a%d\n", video, audio); - - if (video) { - char *Encoding = NULL; - context->manager->video->Command(context, MANAGER_GETENCODING, - &Encoding); - - linuxdvb_printf(20, "Encoding = %s\n", Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_printf(20, "searching default writer ... %s\n", - Encoding); - writer = getDefaultVideoWriter(); +static bool Write(AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &Pts) +{ + switch (stream->codec->codec_type) { + case AVMEDIA_TYPE_VIDEO: + return videoWriter->Write(videofd, avfc, stream, packet, Pts); + case AVMEDIA_TYPE_AUDIO: + return audioWriter->Write(audiofd, avfc, stream, packet, Pts); + default: + return false; } - - if (writer == NULL) { - linuxdvb_err("unknown video codec and no default writer %s\n", - Encoding); - ret = cERR_LINUXDVB_ERROR; - } else { - call.fd = videofd; - call.Pts = out->pts; - call.packet = out->packet; - - if (writer->writeData) - res = writer->writeData(&call); - - if (res < 0) { - linuxdvb_err("failed to write data %d - %d\n", res, errno); - linuxdvb_err("%s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - } - - free(Encoding); - } else if (audio) { - char *Encoding = NULL; - context->manager->audio->Command(context, MANAGER_GETENCODING, - &Encoding); - - linuxdvb_printf(20, "%s::%s Encoding = %s\n", FILENAME, - __FUNCTION__, Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_printf(20, "searching default writer ... %s\n", - Encoding); - writer = getDefaultAudioWriter(); - } - - if (writer == NULL) { - linuxdvb_err("unknown audio codec %s and no default writer\n", - Encoding); - ret = cERR_LINUXDVB_ERROR; - } else { - call.fd = audiofd; - call.Pts = out->pts; - call.packet = out->packet; - - call.restart_audio_resampling = out->restart_audio_resampling; - call.context = context; - - if (writer->writeData) - res = writer->writeData(&call); - - if (res < 0) { - linuxdvb_err("failed to write data %d - %d\n", res, errno); - linuxdvb_err("%s\n", strerror(errno)); - ret = cERR_LINUXDVB_ERROR; - } - } - - free(Encoding); - } - - return ret; } static int reset(Context_t * context) { - int ret = cERR_LINUXDVB_NO_ERROR; - Writer_t *writer; - char *Encoding = NULL; - - context->manager->video->Command(context, MANAGER_GETENCODING, - &Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_err("unknown video codec %s\n", Encoding); - ret = cERR_LINUXDVB_ERROR; - } else { - writer->reset(); - } - - free(Encoding); - - context->manager->audio->Command(context, MANAGER_GETENCODING, - &Encoding); - - writer = getWriter(Encoding); - - if (writer == NULL) { - linuxdvb_err("unknown video codec %s\n", Encoding); - ret = cERR_LINUXDVB_ERROR; - } else { - writer->reset(); - } - - free(Encoding); - - return ret; + if (videoWriter) + videoWriter->Init(); + if (audioWriter) + audioWriter->Init(); + return cERR_LINUXDVB_NO_ERROR; } static int Command(Context_t *context, OutputCmd_t command, const char *argument) @@ -1099,10 +718,6 @@ static int Command(Context_t *context, OutputCmd_t command, const char *argument (unsigned long long int) pts; break; } - case OUTPUT_SWITCH:{ - ret = LinuxDvbSwitch(context, (char *) argument); - break; - } case OUTPUT_SLOWMOTION:{ return LinuxDvbSlowMotion(context, (char *) argument); break; diff --git a/libeplayer3/output/output.cpp b/libeplayer3/output/output.cpp index 400e94e..a225a1c 100644 --- a/libeplayer3/output/output.cpp +++ b/libeplayer3/output/output.cpp @@ -271,16 +271,6 @@ static int Command(Context_t *context, OutputCmd_t command, const char *argument ret = cERR_OUTPUT_INTERNAL_ERROR; break; } - case OUTPUT_SWITCH:{ - if (context && context->playback) { - if (context->playback->isAudio) - return context->output->audio->Command(context, OUTPUT_SWITCH, "audio"); - if (context->playback->isVideo) - return context->output->video->Command(context, OUTPUT_SWITCH, "video"); - } else - ret = cERR_OUTPUT_INTERNAL_ERROR; - break; - } case OUTPUT_SLOWMOTION:{ if (context && context->playback) { if (context->playback->isVideo) diff --git a/libeplayer3/output/writer/ac3.cpp b/libeplayer3/output/writer/ac3.cpp index c1b7801..acc99af 100644 --- a/libeplayer3/output/writer/ac3.cpp +++ b/libeplayer3/output/writer/ac3.cpp @@ -19,129 +19,44 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define AC3_HEADER_LENGTH 7 - -#define AC3_DEBUG - -#ifdef AC3_DEBUG - -static short debug_level = 0; - -#define ac3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_printf(level, fmt, x...) -#endif - -#ifndef AC3_SILENT -#define ac3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define ac3_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterAC3 : public Writer { - return 0; + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterAC3(); +}; + +bool WriterAC3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) +{ + if (fd < 0 || !packet) + return false; + + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + struct iovec iov[2]; + + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, PRIVATE_STREAM_1_PES_START_CODE, pts, 0); + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; + + return writev(fd, iov, 2) > -1; } -static int writeData(WriterAVCallData_t *call) +WriterAC3::WriterAC3() { - ac3_printf(10, "\n"); - - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - - ac3_printf(10, "AudioPts %lld\n", call->Pts); - - if (call->fd < 0) { - ac3_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - struct iovec iov[2]; - - iov[0].iov_base = PesHeader; - iov[0].iov_len = - InsertPesHeader(PesHeader, call->packet->size, - PRIVATE_STREAM_1_PES_START_CODE, call->Pts, 0); - iov[1].iov_base = call->packet->data; - iov[1].iov_len = call->packet->size; - - return writev(call->fd, iov, 2); + Register(this, AV_CODEC_ID_AC3, AUDIO_ENCODING_AC3); + Register(this, AV_CODEC_ID_EAC3, AUDIO_ENCODING_AC3); } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ - -static WriterCaps_t caps_ac3 = { - "ac3", - eAudio, - "A_AC3", - AUDIO_ENCODING_AC3 -}; - -struct Writer_s WriterAudioAC3 = { - &reset, - &writeData, - &caps_ac3 -}; - -static WriterCaps_t caps_eac3 = { - "ac3", - eAudio, - "A_AC3", - AUDIO_ENCODING_AC3 -}; - -struct Writer_s WriterAudioEAC3 = { - &reset, - &writeData, - &caps_eac3 -}; +static WriterAC3 writer_ac3 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/divx.cpp b/libeplayer3/output/writer/divx.cpp index 5dc0e66..323dd27 100644 --- a/libeplayer3/output/writer/divx.cpp +++ b/libeplayer3/output/writer/divx.cpp @@ -40,80 +40,39 @@ #include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define DIVX_DEBUG - -#ifdef DIVX_DEBUG - -static short debug_level = 0; - -#define divx_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_printf(level, fmt, x...) -#endif - -#ifndef DIVX_SILENT -#define divx_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define divx_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ -static int initialHeader = 1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ -static int reset() +class WriterDIVX : public Writer { - initialHeader = 1; - return 0; + private: + bool initialHeader; + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + void Init(); + WriterDIVX(); +}; + +void WriterDIVX::Init() +{ + initialHeader = true; } -static int writeData(WriterAVCallData_t *call) +bool WriterDIVX::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return false; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned char FakeHeaders[64]; // 64bytes should be enough to make the fake headers unsigned int FakeHeaderLength; unsigned char Version = 5; - unsigned int FakeStartCode = - (Version << 8) | PES_VERSION_FAKE_START_CODE; + unsigned int FakeStartCode = (Version << 8) | PES_VERSION_FAKE_START_CODE; unsigned int usecPerFrame = 41708; /* Hellmaster1024: default value */ BitPacker_t ld = { FakeHeaders, 0, 32 }; - divx_printf(10, "\n"); - - if (call->fd < 0) { - divx_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - divx_printf(10, "AudioPts %lld\n", call->Pts); - - usecPerFrame = 1000000 / av_q2d(call->stream->r_frame_rate); - - divx_printf(10, "Microsecends per frame = %d\n", usecPerFrame); + usecPerFrame = 1000000 / av_q2d(stream->r_frame_rate); memset(FakeHeaders, 0, sizeof(FakeHeaders)); @@ -136,67 +95,28 @@ static int writeData(WriterAVCallData_t *call) struct iovec iov[4]; int ic = 0; iov[ic].iov_base = PesHeader; - iov[ic++].iov_len = - InsertPesHeader(PesHeader, call->packet->size, MPEG_VIDEO_PES_START_CODE, - call->Pts, FakeStartCode); + iov[ic++].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); iov[ic].iov_base = FakeHeaders; iov[ic++].iov_len = FakeHeaderLength; if (initialHeader) { - iov[ic].iov_base = call->stream->codec->extradata; - iov[ic++].iov_len = call->stream->codec->extradata_size; + iov[ic].iov_base = stream->codec->extradata; + iov[ic++].iov_len = stream->codec->extradata_size; - initialHeader = 0; + initialHeader = false; } - iov[ic].iov_base = call->packet->data; - iov[ic++].iov_len = call->packet->size; + iov[ic].iov_base = packet->data; + iov[ic++].iov_len = packet->size; - int len = writev(call->fd, iov, ic); - - divx_printf(10, "xvid_Write < len=%d\n", len); - - return len; + return writev(fd, iov, ic) > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterDIVX::WriterDIVX() +{ + Register(this, AV_CODEC_ID_MPEG4, VIDEO_ENCODING_MPEG4P2); + Register(this, AV_CODEC_ID_MSMPEG4V1, VIDEO_ENCODING_MPEG4P2); + Register(this, AV_CODEC_ID_MSMPEG4V2, VIDEO_ENCODING_MPEG4P2); + Register(this, AV_CODEC_ID_MSMPEG4V3, VIDEO_ENCODING_MPEG4P2); +} -static WriterCaps_t mpeg4p2_caps = { - "mscomp", - eVideo, - "V_MSCOMP", - VIDEO_ENCODING_MPEG4P2 -}; - -struct Writer_s WriterVideoMSCOMP = { - &reset, - &writeData, - &mpeg4p2_caps -}; - -static WriterCaps_t fourcc_caps = { - "fourcc", - eVideo, - "V_MS/VFW/FOURCC", - VIDEO_ENCODING_MPEG4P2 -}; - -struct Writer_s WriterVideoFOURCC = { - &reset, - &writeData, - &fourcc_caps -}; - -static WriterCaps_t divx_caps = { - "divx", - eVideo, - "V_MKV/XVID", - VIDEO_ENCODING_MPEG4P2 -}; - -struct Writer_s WriterVideoDIVX = { - &reset, - &writeData, - &divx_caps -}; +static WriterDIVX writer_divx __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/dts.cpp b/libeplayer3/output/writer/dts.cpp index 25d38ce..06d1aaa 100644 --- a/libeplayer3/output/writer/dts.cpp +++ b/libeplayer3/output/writer/dts.cpp @@ -19,97 +19,41 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ #define PES_AUDIO_PRIVATE_HEADER_SIZE 16 // consider maximum private header size. #define PES_AUDIO_HEADER_SIZE (32 + PES_AUDIO_PRIVATE_HEADER_SIZE) -#define PES_AUDIO_PACKET_SIZE 2028 -#define SPDIF_AUDIO_PACKET_SIZE (1024 * sizeof(unsigned int) * 2) // stereo 32bit samples. -#define DTS_DEBUG - -#ifdef DTS_DEBUG - -static short debug_level = 0; - -#define dts_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_printf(level, fmt, x...) -#endif - -#ifndef DTS_SILENT -#define dts_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define dts_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ -static int reset() +class WriterDTS : public Writer { - return 0; -} + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterDTS(); +}; -static int writeData(WriterAVCallData_t *call) +bool WriterDTS::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return false; + unsigned char PesHeader[PES_AUDIO_HEADER_SIZE]; - dts_printf(10, "AudioPts %lld\n", call->Pts); - - if (call->fd < 0) { - dts_err("file pointer < 0. ignoring ...\n"); - return 0; - } // #define DO_BYTESWAP #ifdef DO_BYTESWAP - unsigned char *Data = (unsigned char *) malloc(call->packet->size); - memcpy(Data, call->packet->data, call->packet->size); + unsigned char Data[packet->size]; + memcpy(Data, packet->data, packet->size); /* 16-bit byte swap all data before injecting it */ - for (i = 0; i < call->packet->size; i += 2) { + for (i = 0; i < packet->size; i += 2) { unsigned char Tmp = Data[i]; Data[i] = Data[i + 1]; Data[i + 1] = Tmp; @@ -119,41 +63,20 @@ static int writeData(WriterAVCallData_t *call) struct iovec iov[2]; iov[0].iov_base = PesHeader; - iov[0].iov_len = - InsertPesHeader(PesHeader, call->packet->size, - MPEG_AUDIO_PES_START_CODE - /*PRIVATE_STREAM_1_PES_START_CODE */ , call->Pts, - 0); + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE /*PRIVATE_STREAM_1_PES_START_CODE */ , pts, 0); #ifdef DO_BYTESPWAP iov[1].iov_base = Data; #else - iov[1].iov_base = call->packet->data; + iov[1].iov_base = packet->data; #endif - iov[1].iov_len = call->packet->size; + iov[1].iov_len = packet->size; - int len = writev(call->fd, iov, 2); - -#ifdef DO_BYTESWAP - free(Data); -#endif - - dts_printf(10, "< len %d\n", len); - return len; + return writev(fd, iov, 2) > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterDTS::WriterDTS() +{ + Register(this, AV_CODEC_ID_DTS, AUDIO_ENCODING_DTS); +} -static WriterCaps_t caps = { - "dts", - eAudio, - "A_DTS", - AUDIO_ENCODING_DTS -}; - -struct Writer_s WriterAudioDTS = { - &reset, - &writeData, - &caps -}; +static WriterDTS writer_dts __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/flac.cpp b/libeplayer3/output/writer/flac.cpp index 75ca276..1665c0d 100644 --- a/libeplayer3/output/writer/flac.cpp +++ b/libeplayer3/output/writer/flac.cpp @@ -19,117 +19,43 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" -#include "misc.h" #include "pes.h" +#include "misc.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define FLAC_DEBUG - -#ifdef FLAC_DEBUG - -static short debug_level = 0; - -#define flac_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define flac_printf(level, fmt, x...) -#endif - -#ifndef FLAC_SILENT -#define flac_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define flac_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterFLAC : public Writer { - return 0; -} + public: + bool Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterFLAC(); +}; -static int writeData(WriterAVCallData_t *call) +bool WriterFLAC::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return -1; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - - flac_printf(10, "AudioPts %lld\n", call->Pts); - - if ((call->packet->data == NULL) || (call->packet->size <= 0)) { - flac_err("parsing NULL Data. ignoring...\n"); - return 0; - } - - if (call->fd < 0) { - flac_err("file pointer < 0. ignoring ...\n"); - return 0; - } - struct iovec iov[2]; + iov[0].iov_base = PesHeader; - iov[0].iov_len = InsertPesHeader(PesHeader, call->packet->size, MPEG_AUDIO_PES_START_CODE, call->Pts, 0); - iov[1].iov_base = call->packet->data; - iov[1].iov_len = call->packet->size; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; - int len = writev(call->fd, iov, 2); - - flac_printf(10, "flac_Write-< len=%d\n", len); - return len; + return writev(fd, iov, 2) > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterFLAC::WriterFLAC() +{ + Register(this, AV_CODEC_ID_FLAC, AUDIO_ENCODING_LPCM); +} -static WriterCaps_t caps_flac = { - "flac", - eAudio, - "A_FLAC", - AUDIO_ENCODING_LPCM //AUDIO_ENCODING_FLAC -}; - -struct Writer_s WriterAudioFLAC = { - &reset, - &writeData, - &caps_flac -}; +static WriterFLAC writer_flac __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/h263.cpp b/libeplayer3/output/writer/h263.cpp index 8c9db77..469e054 100644 --- a/libeplayer3/output/writer/h263.cpp +++ b/libeplayer3/output/writer/h263.cpp @@ -19,98 +19,33 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define H263_DEBUG - -#ifdef H263_DEBUG - -static short debug_level = 0; -static const char *FILENAME = "h263.c"; - -#define h263_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0) -#else -#define h263_printf(level, fmt, x...) -#endif - -#ifndef H263_SILENT -#define h263_err(fmt, x...) do { printf("[%s:%s] " fmt, FILENAME, __FUNCTION__, ## x); } while (0) -#else -#define h263_err(fmt, x...) -#endif -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterH263 : public Writer { - return 0; -} + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterH263(); +}; -static int writeData(WriterAVCallData_t *call) +bool WriterH263::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return false; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int len = 0; - h263_printf(10, "VideoPts %lld\n", call->Pts); + int HeaderLength = InsertPesHeader(PesHeader, packet->size, H263_VIDEO_PES_START_CODE, pts, 0); - if (call->fd < 0) { - h263_err("file pointer < 0. ignoring ...\n"); - return 0; - } + int PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); - int HeaderLength = - InsertPesHeader(PesHeader, call->packet->size, H263_VIDEO_PES_START_CODE, - call->Pts, 0); - - int PrivateHeaderLength = - InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->packet->size); - - int PesLength = - PesHeader[PES_LENGTH_BYTE_0] + - (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; + int PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; @@ -122,40 +57,17 @@ static int writeData(WriterAVCallData_t *call) struct iovec iov[2]; iov[0].iov_base = PesHeader; iov[0].iov_len = HeaderLength; - iov[1].iov_base = call->packet->data; - iov[1].iov_len = call->packet->size; - len = writev(call->fd, iov, 2); - - h263_printf(10, "< len %d\n", len); - return len; + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; + return writev(fd, iov, 2) > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterH263::WriterH263() +{ + Register(this, AV_CODEC_ID_H263, VIDEO_ENCODING_H263); + Register(this, AV_CODEC_ID_H263P, VIDEO_ENCODING_H263); + Register(this, AV_CODEC_ID_H263I, VIDEO_ENCODING_H263); + Register(this, AV_CODEC_ID_FLV1, VIDEO_ENCODING_FLV1); +} -static WriterCaps_t caps_h263 = { - "h263", - eVideo, - "V_H263", - VIDEO_ENCODING_H263 -}; - -struct Writer_s WriterVideoH263 = { - &reset, - &writeData, - &caps_h263 -}; - -static WriterCaps_t caps_flv = { - "FLV", - eVideo, - "V_FLV", - VIDEO_ENCODING_FLV1 -}; - -struct Writer_s WriterVideoFLV = { - &reset, - &writeData, - &caps_flv -}; +static WriterH263 writer_h263 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/h264.cpp b/libeplayer3/output/writer/h264.cpp index da92dc0..6e7001f 100644 --- a/libeplayer3/output/writer/h264.cpp +++ b/libeplayer3/output/writer/h264.cpp @@ -19,62 +19,21 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define H264_DEBUG - -#ifdef H264_DEBUG - -static short debug_level = 0; - -#define h264_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_printf(level, fmt, x...) -#endif - -#ifndef H264_SILENT -#define h264_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define h264_err(fmt, x...) -#endif - #define NALU_TYPE_PLAYER2_CONTAINER_PARAMETERS 24 #define CONTAINER_PARAMETERS_VERSION 0x00 -/* ***************************** */ -/* Types */ -/* ***************************** */ typedef struct avcC_s { unsigned char Version; /* configurationVersion */ unsigned char Profile; /* AVCProfileIndication */ @@ -85,31 +44,30 @@ typedef struct avcC_s { unsigned char Params[1]; /* {length,params}{length,params}...sequence then picture */ } avcC_t; - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ const unsigned char Head[] = { 0, 0, 0, 1 }; -static int initialHeader = 1; -static unsigned int NalLengthBytes = 1; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterH264 : public Writer { - initialHeader = 1; - return 0; + private: + bool initialHeader; + unsigned int NalLengthBytes; + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + void Init(); + WriterH264(); +}; + +void WriterH264::Init(void) +{ + initialHeader = true; + initialHeader = 1; + NalLengthBytes = 1; } -static int writeData(WriterAVCallData_t *call) +bool WriterH264::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return false; unsigned char PesHeader[PES_MAX_HEADER_SIZE]; unsigned long long int VideoPts; unsigned int TimeDelta; @@ -118,50 +76,37 @@ static int writeData(WriterAVCallData_t *call) int ic = 0; struct iovec iov[128]; - TimeDelta = 1000.0 * av_q2d(call->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 */ + VideoPts = pts; - VideoPts = call->Pts; - - h264_printf(10, "VideoPts %lld - %d %d\n", call->Pts, TimeDelta, TimeScale); - - if (call->fd < 0) { - h264_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - if ((call->packet->size > 3) - && - ((call->packet->data[0] == 0x00 && call->packet->data[1] == 0x00 - && call->packet->data[2] == 0x00 && call->packet->data[3] == 0x01) - || (call->packet->data[0] == 0xff && call->packet->data[1] == 0xff - && call->packet->data[2] == 0xff && call->packet->data[3] == 0xff))) { + if ((packet->size > 3) + && ((packet->data[0] == 0x00 && packet->data[1] == 0x00 && packet->data[2] == 0x00 && packet->data[3] == 0x01) + || (packet->data[0] == 0xff && packet->data[1] == 0xff && packet->data[2] == 0xff && packet->data[3] == 0xff))) { unsigned int PacketLength = 0; unsigned int FakeStartCode = /* (call->Version << 8) | */ PES_VERSION_FAKE_START_CODE; iov[ic++].iov_base = PesHeader; if (initialHeader) { - initialHeader = 0; - iov[ic].iov_base = call->stream->codec->extradata; - iov[ic++].iov_len = call->stream->codec->extradata_size; - PacketLength += call->stream->codec->extradata_size; + initialHeader = false; + iov[ic].iov_base = stream->codec->extradata; + iov[ic++].iov_len = stream->codec->extradata_size; + PacketLength += stream->codec->extradata_size; } - iov[ic].iov_base = call->packet->data; - iov[ic++].iov_len = call->packet->size; - PacketLength += call->packet->size; + iov[ic].iov_base = packet->data; + iov[ic++].iov_len = packet->size; + PacketLength += packet->size; /*Hellmaster1024: some packets will only be accepted by the player if we send one byte more than data is available. The content of this byte does not matter. It will be ignored by the player */ - iov[ic].iov_base = (char *) ""; + iov[ic].iov_base = (void *) ""; iov[ic++].iov_len = 1; iov[0].iov_len = - InsertPesHeader(PesHeader, PacketLength, - MPEG_VIDEO_PES_START_CODE, call->Pts, - FakeStartCode); - return writev(call->fd, iov, ic); + InsertPesHeader(PesHeader, PacketLength, MPEG_VIDEO_PES_START_CODE, pts, FakeStartCode); + return writev(fd, iov, ic) > -1; } if (initialHeader) { - avcC_t *avcCHeader = (avcC_t *) call->stream->codec->extradata; + avcC_t *avcCHeader = (avcC_t *) stream->codec->extradata; unsigned int i; unsigned int ParamSets; unsigned int ParamOffset; @@ -169,13 +114,12 @@ static int writeData(WriterAVCallData_t *call) unsigned int ParametersLength; if (avcCHeader == NULL) { - h264_err("private_data NULL\n"); - return -1; + fprintf(stderr, "stream->codec->extradata == NULL\n"); + return false; } if (avcCHeader->Version != 1) - h264_err("Error unknown avcC version (%x). Expect problems.\n", - avcCHeader->Version); + fprintf(stderr, "Error unknown avcC version (%x). Expect problems.\n", avcCHeader->Version); ParametersLength = 0; @@ -211,33 +155,16 @@ static int writeData(WriterAVCallData_t *call) ic = 0; iov[ic].iov_base = PesHeader; - iov[ic++].iov_len = - InsertPesHeader(PesHeader, ParametersLength, - MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, - 0); + iov[ic++].iov_len = InsertPesHeader(PesHeader, ParametersLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); iov[ic].iov_base = HeaderData; iov[ic++].iov_len = ParametersLength; - len = writev(call->fd, iov, ic); + len = writev(fd, iov, ic); if (len < 0) - return len; + return false; NalLengthBytes = (avcCHeader->NalLengthMinusOne & 0x03) + 1; ParamSets = avcCHeader->NumParamSets & 0x1f; - h264_printf(20, "avcC contents:\n"); - h264_printf(20, " version: %d\n", - avcCHeader->Version); - h264_printf(20, " profile: %d\n", - avcCHeader->Profile); - h264_printf(20, " profile compatibility: %d\n", - avcCHeader->Compatibility); - h264_printf(20, " level: %d\n", - avcCHeader->Level); - h264_printf(20, " nal length bytes: %d\n", - NalLengthBytes); - h264_printf(20, " number of sequence param sets: %d\n", - ParamSets); - ParamOffset = 0; ic = 0; iov[ic++].iov_base = PesHeader; @@ -246,9 +173,6 @@ static int writeData(WriterAVCallData_t *call) (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1]; - h264_printf(20, " sps %d has length %d\n", i, - PsLength); - iov[ic].iov_base = (char *) Head; iov[ic++].iov_len = sizeof(Head); InitialHeaderLength += sizeof(Head); @@ -260,18 +184,12 @@ static int writeData(WriterAVCallData_t *call) ParamSets = avcCHeader->Params[ParamOffset]; - h264_printf(20, " number of picture param sets: %d\n", - ParamSets); - ParamOffset++; for (i = 0; i < ParamSets; i++) { unsigned int PsLength = (avcCHeader->Params[ParamOffset] << 8) + avcCHeader->Params[ParamOffset + 1]; - h264_printf(20, " pps %d has length %d\n", i, - PsLength); - iov[ic].iov_base = (char *) Head; iov[ic++].iov_len = sizeof(Head); InitialHeaderLength += sizeof(Head); @@ -281,19 +199,16 @@ static int writeData(WriterAVCallData_t *call) ParamOffset += PsLength + 2; } - iov[0].iov_len = - InsertPesHeader(PesHeader, InitialHeaderLength, - MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, - 0); - ssize_t l = writev(call->fd, iov, ic); + iov[0].iov_len = InsertPesHeader(PesHeader, InitialHeaderLength, MPEG_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + ssize_t l = writev(fd, iov, ic); if (l < 0) - return l; + return false; len += l; initialHeader = 0; } - unsigned int SampleSize = call->packet->size; + unsigned int SampleSize = packet->size; unsigned int NalStart = 0; unsigned int VideoPosition = 0; @@ -302,7 +217,7 @@ static int writeData(WriterAVCallData_t *call) unsigned char NalData[4]; int NalPresent = 1; - memcpy(NalData, call->packet->data + VideoPosition, NalLengthBytes); + memcpy(NalData, packet->data + VideoPosition, NalLengthBytes); VideoPosition += NalLengthBytes; NalStart += NalLengthBytes; switch (NalLengthBytes) { @@ -313,25 +228,15 @@ static int writeData(WriterAVCallData_t *call) NalLength = (NalData[0] << 8) | (NalData[1]); break; case 3: - NalLength = - (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]); + NalLength = (NalData[0] << 16) | (NalData[1] << 8) | (NalData[2]); break; default: - NalLength = - (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) - | (NalData[3]); + NalLength = (NalData[0] << 24) | (NalData[1] << 16) | (NalData[2] << 8) | (NalData[3]); break; } - h264_printf(20, - "NalStart = %u + NalLength = %u > SampleSize = %u\n", - NalStart, NalLength, SampleSize); - if (NalStart + NalLength > SampleSize) { - h264_printf(20, - "nal length past end of buffer - size %u frame offset %u left %u\n", - NalLength, NalStart, SampleSize - NalStart); - + fprintf(stderr, "nal length past end of buffer - size %u frame offset %u left %u\n", NalLength, NalStart, SampleSize - NalStart); NalStart = SampleSize; } else { NalStart += NalLength; @@ -344,46 +249,28 @@ static int writeData(WriterAVCallData_t *call) iov[ic++].iov_len = sizeof(Head); } - iov[ic].iov_base = call->packet->data + VideoPosition; + iov[ic].iov_base = packet->data + VideoPosition; iov[ic++].iov_len = NalLength; VideoPosition += NalLength; - h264_printf(20, " pts=%llu\n", VideoPts); - iov[0].iov_len = InsertPesHeader(PesHeader, NalLength, MPEG_VIDEO_PES_START_CODE, VideoPts, 0); - ssize_t l = writev(call->fd, iov, ic); + ssize_t l = writev(fd, iov, ic); if (l < 0) - return l; + return false; len += l; VideoPts = INVALID_PTS_VALUE; } } while (NalStart < SampleSize); - if (len < 0) { - h264_err("error writing data errno = %d\n", errno); - h264_err("%s\n", strerror(errno)); - } - - h264_printf(10, "< len %d\n", len); - return len; + return len > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterH264::WriterH264() +{ + Register(this, AV_CODEC_ID_H264, VIDEO_ENCODING_H264); +} -static WriterCaps_t caps = { - "h264", - eVideo, - "V_MPEG4/ISO/AVC", - VIDEO_ENCODING_H264 -}; - -struct Writer_s WriterVideoH264 = { - &reset, - &writeData, - &caps -}; +static WriterH264 writerh264 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/mp3.cpp b/libeplayer3/output/writer/mp3.cpp index a5719c2..cebd801 100644 --- a/libeplayer3/output/writer/mp3.cpp +++ b/libeplayer3/output/writer/mp3.cpp @@ -19,145 +19,45 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define MP3_DEBUG - -#ifdef MP3_DEBUG - -static short debug_level = 0; - -#define mp3_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_printf(level, fmt, x...) -#endif - -#ifndef MP3_SILENT -#define mp3_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mp3_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterMP3 : public Writer { - return 0; -} + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterMP3(); +}; -static int writeData(WriterAVCallData_t *call) +bool WriterMP3::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) { + if (fd < 0 || !packet) + return false; + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - - mp3_printf(10, "AudioPts %lld\n", call->Pts); - - if ((call->packet->data == NULL) || (call->packet->size <= 0)) { - mp3_err("parsing NULL Data. ignoring...\n"); - return 0; - } - - if (call->fd < 0) { - mp3_err("file pointer < 0. ignoring ...\n"); - return 0; - } - struct iovec iov[2]; + iov[0].iov_base = PesHeader; - iov[0].iov_len = - InsertPesHeader(PesHeader, call->packet->size, MPEG_AUDIO_PES_START_CODE, - call->Pts, 0); - iov[1].iov_base = call->packet->data; - iov[1].iov_len = call->packet->size; + iov[0].iov_len = InsertPesHeader(PesHeader, packet->size, MPEG_AUDIO_PES_START_CODE, pts, 0); + iov[1].iov_base = packet->data; + iov[1].iov_len = packet->size; - int len = writev(call->fd, iov, 2); - - mp3_printf(10, "mp3_Write-< len=%d\n", len); - return len; + return writev(fd, iov, 2) > -1; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterMP3::WriterMP3() +{ + Register(this, AV_CODEC_ID_MP3, AUDIO_ENCODING_MP3); + Register(this, AV_CODEC_ID_MP2, AUDIO_ENCODING_MPEG2); +// Register(this, AV_CODEC_ID_VORBIS, AUDIO_ENCODING_VORBIS); +} -static WriterCaps_t caps_mp3 = { - "mp3", - eAudio, - "A_MP3", - AUDIO_ENCODING_MP3 -}; - -struct Writer_s WriterAudioMP3 = { - &reset, - &writeData, - &caps_mp3 -}; - -static WriterCaps_t caps_mpegl3 = { - "mpeg/l3", - eAudio, - "A_MPEG/L3", - AUDIO_ENCODING_MPEG2 -}; - -struct Writer_s WriterAudioMPEGL3 = { - &reset, - &writeData, - &caps_mpegl3 -}; - -static WriterCaps_t caps_vorbis = { - "vorbis", - eAudio, - "A_VORBIS", - AUDIO_ENCODING_VORBIS -}; - -struct Writer_s WriterAudioVORBIS = { - &reset, - &writeData, - &caps_vorbis -}; +static WriterMP3 writer_mp3 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/mpeg2.cpp b/libeplayer3/output/writer/mpeg2.cpp index e8845e4..8630b54 100644 --- a/libeplayer3/output/writer/mpeg2.cpp +++ b/libeplayer3/output/writer/mpeg2.cpp @@ -19,146 +19,58 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" +#include + #include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ - -#define MPEG2_DEBUG - -#ifdef MPEG2_DEBUG - -static short debug_level = 0; - -#define mpeg2_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_printf(level, fmt, x...) -#endif - -#ifndef MPEG2_SILENT -#define mpeg2_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define mpeg2_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int reset() +class WriterMPEG2 : public Writer { - return 0; -} + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + WriterMPEG2(); +}; -static int writeData(WriterAVCallData_t *call) +bool WriterMPEG2::Write(int fd, AVFormatContext * /* avfc */, AVStream * /* stream */, AVPacket *packet, int64_t &pts) { - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int len = 0; - int Position = 0; + if (fd < 0 || !packet) + return false; - mpeg2_printf(10, "VideoPts %lld\n", call->Pts); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - if (call->fd < 0) { - mpeg2_err("file pointer < 0. ignoring ...\n"); - return 0; - } + int64_t _pts = pts; - while (Position < call->packet->size) { - int PacketLength = (call->packet->size - Position) <= MAX_PES_PACKET_SIZE ? - (call->packet->size - Position) : MAX_PES_PACKET_SIZE; + for (int Position = 0; Position < packet->size; ) { + int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); + struct iovec iov[2]; + iov[0].iov_base = PesHeader; + iov[0].iov_len = InsertPesHeader(PesHeader, PacketLength, 0xe0, _pts, 0); + iov[1].iov_base = packet->data + Position; + iov[1].iov_len = PacketLength; - int Remaining = call->packet->size - Position - PacketLength; - - mpeg2_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", - PacketLength, Remaining, Position); - - struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = - InsertPesHeader(PesHeader, PacketLength, 0xe0, call->Pts, 0); - iov[1].iov_base = call->packet->data + Position; - iov[1].iov_len = PacketLength; - - ssize_t l = writev(call->fd, iov, 2); - if (l < 0) { - len = l; - break; + ssize_t l = writev(fd, iov, 2); + if (l < 0) { + return false; + break; + } + Position += PacketLength; + _pts = INVALID_PTS_VALUE; } - len += l; - - Position += PacketLength; - call->Pts = INVALID_PTS_VALUE; - } - - mpeg2_printf(10, "< len %d\n", len); - return len; + return true; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ -static WriterCaps_t caps = { - "mpeg2", - eVideo, - "V_MPEG2", - VIDEO_ENCODING_AUTO -}; +WriterMPEG2::WriterMPEG2() +{ + Register(this, AV_CODEC_ID_MPEG2TS, VIDEO_ENCODING_AUTO); +} -struct Writer_s WriterVideoMPEG2 = { - &reset, - &writeData, - &caps -}; - -static WriterCaps_t h264_caps = { - "mpges_h264", - eVideo, - "V_MPEG2/H264", - VIDEO_ENCODING_H264 -}; - -struct Writer_s WriterVideoMPEGH264 = { - &reset, - &writeData, - &h264_caps -}; +static WriterMPEG2 writer_mpeg2 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/pcm.cpp b/libeplayer3/output/writer/pcm.cpp index 34ead9b..f850a43 100644 --- a/libeplayer3/output/writer/pcm.cpp +++ b/libeplayer3/output/writer/pcm.cpp @@ -19,107 +19,70 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ -#define PCM_DEBUG - -#ifdef PCM_DEBUG - -static short debug_level = 0; - -#define pcm_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_printf(level, fmt, x...) -#endif - -#ifndef PCM_SILENT -#define pcm_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define pcm_err(fmt, x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static int initialHeader = 1; - -static unsigned int SubFrameLen = 0; -static unsigned int SubFramesPerPES = 0; +extern "C" { +#include +#include +#include +#include +#include +} // reference: search for TypeLpcmDVDAudio in player/frame_parser/frame_parser_audio_lpcm.cpp -static const unsigned char clpcm_prv[14] = { 0xA0, //sub_stream_id - 0, 0, //resvd and UPC_EAN_ISRC stuff, unused - 0x0A, //private header length - 0, 9, //first_access_unit_pointer - 0x00, //emph,rsvd,stereo,downmix - 0x0F, //quantisation word length 1,2 - 0x0F, //audio sampling freqency 1,2 - 0, //resvd, multi channel type - 0, //bit shift on channel GR2, assignment - 0x80, //dynamic range control - 0, 0 //resvd for copyright management +static const unsigned char clpcm_prv[14] = { + 0xA0, //sub_stream_id + 0, 0, //resvd and UPC_EAN_ISRC stuff, unused + 0x0A, //private header length + 0, 9, //first_access_unit_pointer + 0x00, //emph,rsvd,stereo,downmix + 0x0F, //quantisation word length 1,2 + 0x0F, //audio sampling freqency 1,2 + 0, //resvd, multi channel type + 0, //bit shift on channel GR2, assignment + 0x80, //dynamic range control + 0, 0 //resvd for copyright management }; -static unsigned char lpcm_prv[14]; -static unsigned char breakBuffer[8192]; -static unsigned int breakBufferFillSize = 0; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ - -static int uNoOfChannels; -static int uSampleRate; -static int uBitsPerSample; - -static int prepareClipPlay() +class WriterPCM : public Writer { - printf("rate: %d ch: %d bits: %d (%d bps)\n", - uSampleRate /*Format->dwSamplesPerSec */ , - uNoOfChannels /*Format->wChannels */ , - uBitsPerSample /*Format->wBitsPerSample */ , - (uBitsPerSample /*Format->wBitsPerSample */ / 8) - ); + private: + unsigned int SubFrameLen; + unsigned int SubFramesPerPES; + unsigned char lpcm_prv[14]; + unsigned char breakBuffer[8192]; + unsigned int breakBufferFillSize; + int uNoOfChannels; + int uSampleRate; + int uBitsPerSample; + SwrContext *swr; + AVFrame *decoded_frame; + int out_sample_rate; + int out_channels; + uint64_t out_channel_layout; + bool initialHeader; + bool restart_audio_resampling; + + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + bool prepareClipPlay(); + int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size); + void Init(); + WriterPCM(); +}; + +bool WriterPCM::prepareClipPlay() +{ SubFrameLen = 0; SubFramesPerPES = 0; breakBufferFillSize = 0; @@ -159,7 +122,7 @@ static int prepareClipPlay() SubFrameLen *= (uBitsPerSample / 8); //rewrite PES size to have as many complete subframes per PES as we can - // FIXME: PES header size was hardcoded to 18 in previous code. Actual size returned by InsertPesHeader is 14. + // FIXME: PES header size was hardcoded to 18 in earlier code. Actual size returned by InsertPesHeader is 14. SubFramesPerPES = ((2048 - 18) - sizeof(lpcm_prv)) / SubFrameLen; SubFrameLen *= SubFramesPerPES; @@ -173,26 +136,18 @@ static int prepareClipPlay() break; default: printf("inappropriate bits per sample (%d) - must be 16 or 24\n", uBitsPerSample); - return 1; + return false; } - return 0; + return true; } - -static int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) +int WriterPCM::writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) { unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - pcm_printf(10, "AudioPts %lld\n", Pts); - - if (fd < 0) { - pcm_err("file pointer < 0. ignoring ...\n"); - return 0; - } - if (initialHeader) { - initialHeader = 0; + initialHeader = false; prepareClipPlay(); } @@ -268,36 +223,32 @@ static int writePCM(int fd, int64_t Pts, uint8_t *data, unsigned int size) return size; } - -SwrContext *swr = NULL; -AVFrame *decoded_frame = NULL; -int out_sample_rate = 44100; -int out_channels = 2; -uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO; -int restart_audio_resampling = 1; - -static int reset() +void WriterPCM::Init() { - initialHeader = 1; - restart_audio_resampling = 1; - return 0; + initialHeader = true; + restart_audio_resampling = true; } -int64_t calcPts(AVFormatContext *, AVStream *, int64_t); +extern int64_t calcPts(AVFormatContext *, AVStream *, int64_t); -static int writeData(WriterAVCallData_t *call) +bool WriterPCM::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts) { - AVCodecContext *c = call->stream->codec; - AVPacket *packet = call->packet; - uint8_t *packet_data = packet->data; + if (fd < 0) + return false; + + if (!packet) { +fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); + restart_audio_resampling = true; + return true; + } + + AVCodecContext *c = stream->codec; unsigned int packet_size = packet->size; - if (call->restart_audio_resampling) - restart_audio_resampling = 1; - if (restart_audio_resampling) { - restart_audio_resampling = 0; - initialHeader = 1; +fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); + restart_audio_resampling = false; + initialHeader = true; if (swr) { swr_free(&swr); @@ -316,21 +267,20 @@ static int writeData(WriterAVCallData_t *call) while (packet_size > 0) { int got_frame = 0; - if (!decoded_frame) { - if (!(decoded_frame = av_frame_alloc())) { + if (decoded_frame) + av_frame_unref(decoded_frame); + else if (!(decoded_frame = av_frame_alloc())) { fprintf(stderr, "out of memory\n"); exit(1); - } - } else - av_frame_unref(decoded_frame); + } int len = avcodec_decode_audio4(c, decoded_frame, &got_frame, packet); if (len < 0) { - restart_audio_resampling = 1; +fprintf(stderr, "%s %s %d\n", __FILE__, __func__, __LINE__); + restart_audio_resampling = true; break; } - packet_data += len; packet_size -= len; if (!got_frame) @@ -387,38 +337,35 @@ static int writeData(WriterAVCallData_t *call) // FIXME. PTS calculation is probably broken. int64_t pts; int64_t next_in_pts = av_rescale(av_frame_get_best_effort_timestamp(decoded_frame), - call->stream->time_base.num * (int64_t) out_sample_rate * c->sample_rate, - call->stream->time_base.den); + stream->time_base.num * (int64_t) out_sample_rate * c->sample_rate, + stream->time_base.den); int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts), - call->stream->time_base.den, - call->stream->time_base.num * (int64_t) out_sample_rate * c->sample_rate); - *(call->context->currentAudioPtsP) = pts = calcPts(call->avfc, call->stream, next_out_pts); + stream->time_base.den, + stream->time_base.num * (int64_t) out_sample_rate * c->sample_rate); + pts = calcPts(avfc, stream, next_out_pts); out_samples = swr_convert(swr, &output, out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples); uSampleRate = out_sample_rate; uNoOfChannels = av_get_channel_layout_nb_channels(out_channel_layout); uBitsPerSample = 16; - writePCM(call->fd, pts, output, out_samples * sizeof(short) * out_channels); + writePCM(fd, pts, output, out_samples * sizeof(short) * out_channels); av_freep(&output); } - return packet->size; + return true; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterPCM::WriterPCM() +{ + swr = NULL; + decoded_frame = NULL; + out_sample_rate = 44100; + out_channels = 2; + out_channel_layout = AV_CH_LAYOUT_STEREO; + restart_audio_resampling = true; -static WriterCaps_t caps_ipcm = { - "ipcm", - eAudio, - "A_IPCM", - AUDIO_ENCODING_LPCMA -}; + Register(this, AV_CODEC_ID_PCM_S16LE/*FIXME*/, AUDIO_ENCODING_LPCMA); +} -struct Writer_s WriterAudioIPCM = { - &reset, - &writeData, - &caps_ipcm -}; +static WriterPCM writer_pcm __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/vc1.cpp b/libeplayer3/output/writer/vc1.cpp index e8d4d98..f656225 100644 --- a/libeplayer3/output/writer/vc1.cpp +++ b/libeplayer3/output/writer/vc1.cpp @@ -19,267 +19,169 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" +#include + #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ +#define WMV3_PRIVATE_DATA_LENGTH 4 -#define WMV3_PRIVATE_DATA_LENGTH 4 - -#define METADATA_STRUCT_A_START 12 -#define METADATA_STRUCT_B_START 24 -#define METADATA_STRUCT_B_FRAMERATE_START 32 -#define METADATA_STRUCT_C_START 8 +#define METADATA_STRUCT_A_START 12 +#define METADATA_STRUCT_B_START 24 +#define METADATA_STRUCT_B_FRAMERATE_START 32 +#define METADATA_STRUCT_C_START 8 -#define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80 -#define VC1_FRAME_START_CODE 0x0d +#define VC1_SEQUENCE_LAYER_METADATA_START_CODE 0x80 +#define VC1_FRAME_START_CODE 0x0d -#define VC1_DEBUG - -#ifdef VC1_DEBUG - -static short debug_level = 0; - -#define vc1_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_printf(level, fmt, x...) -#endif - -#ifndef VC1_SILENT -#define vc1_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define vc1_err(fmt, x...) -#endif - - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -static const unsigned char SequenceLayerStartCode[] = - { 0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE }; - - -static const unsigned char Metadata[] = { - 0x00, 0x00, 0x00, 0xc5, - 0x04, 0x00, 0x00, 0x00, - 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ - 0x00, 0x00, 0x00, 0x00, /* Struct A */ - 0x00, 0x00, 0x00, 0x00, - 0x0c, 0x00, 0x00, 0x00, - 0x60, 0x00, 0x00, 0x00, /* Struct B */ - 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 +class WriterVC1 : public Writer +{ + private: + bool initialHeader; + unsigned char FrameHeaderSeen; + double frameRate; + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + void Init(); + WriterVC1(); }; -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ -static int initialHeader = 1; -static unsigned char FrameHeaderSeen = 0; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ -static int reset() +void WriterVC1::Init() { - initialHeader = 1; - FrameHeaderSeen = 0; - return 0; + initialHeader = true; } -static int writeData(WriterAVCallData_t *call) +bool WriterVC1::Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts) { - int len = 0; - - if (call->fd < 0) { - vc1_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - vc1_printf(10, "VideoPts %lld\n", call->Pts); - - vc1_printf(10, "Got Private Size %d\n", call->stream->codec->extradata_size); - + if (fd < 0 || !packet) + return false; if (initialHeader) { + initialHeader = false; + FrameHeaderSeen = false; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - unsigned char PesPayload[128]; - unsigned char *PesPtr; - unsigned int crazyFramerate = 0; - struct iovec iov[2]; + const unsigned char SequenceLayerStartCode[] = + { 0x00, 0x00, 0x01, VC1_SEQUENCE_LAYER_METADATA_START_CODE }; - vc1_printf(10, "Framerate: %f\n", 1000.0 * av_q2d(call->stream->r_frame_rate)); - vc1_printf(10, "biWidth: %d\n", call->stream->codec->width); - vc1_printf(10, "biHeight: %d\n", call->stream->codec->height); - crazyFramerate = ((10000000.0 / av_q2d(call->stream->r_frame_rate))); + const unsigned char Metadata[] = { + 0x00, 0x00, 0x00, 0xc5, + 0x04, 0x00, 0x00, 0x00, + 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ + 0x00, 0x00, 0x00, 0x00, /* Struct A */ + 0x00, 0x00, 0x00, 0x00, + 0x0c, 0x00, 0x00, 0x00, + 0x60, 0x00, 0x00, 0x00, /* Struct B */ + 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00 + }; - vc1_printf(10, "crazyFramerate: %u\n", crazyFramerate); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + unsigned char PesPayload[128]; + unsigned char *PesPtr; + unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate))); + struct iovec iov[2]; - memset(PesPayload, 0, sizeof(PesPayload)); - PesPtr = PesPayload; + memset(PesPayload, 0, sizeof(PesPayload)); - memcpy(PesPtr, SequenceLayerStartCode, - sizeof(SequenceLayerStartCode)); - PesPtr += sizeof(SequenceLayerStartCode); + PesPtr = PesPayload; - memcpy(PesPtr, Metadata, sizeof(Metadata)); - PesPtr += METADATA_STRUCT_C_START; - PesPtr += WMV3_PRIVATE_DATA_LENGTH; + memcpy(PesPtr, SequenceLayerStartCode, sizeof(SequenceLayerStartCode)); + PesPtr += sizeof(SequenceLayerStartCode); - /* Metadata Header Struct A */ - *PesPtr++ = (call->stream->codec->height >> 0) & 0xff; - *PesPtr++ = (call->stream->codec->height >> 8) & 0xff; - *PesPtr++ = (call->stream->codec->height >> 16) & 0xff; - *PesPtr++ = call->stream->codec->height >> 24; - *PesPtr++ = (call->stream->codec->width >> 0) & 0xff; - *PesPtr++ = (call->stream->codec->width >> 8) & 0xff; - *PesPtr++ = (call->stream->codec->width >> 16) & 0xff; - *PesPtr++ = call->stream->codec->width >> 24; + memcpy(PesPtr, Metadata, sizeof(Metadata)); + PesPtr += METADATA_STRUCT_C_START; + PesPtr += WMV3_PRIVATE_DATA_LENGTH; - PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ + /* Metadata Header Struct A */ + *PesPtr++ = (stream->codec->height >> 0) & 0xff; + *PesPtr++ = (stream->codec->height >> 8) & 0xff; + *PesPtr++ = (stream->codec->height >> 16) & 0xff; + *PesPtr++ = stream->codec->height >> 24; + *PesPtr++ = (stream->codec->width >> 0) & 0xff; + *PesPtr++ = (stream->codec->width >> 8) & 0xff; + *PesPtr++ = (stream->codec->width >> 16) & 0xff; + *PesPtr++ = stream->codec->width >> 24; - *PesPtr++ = (crazyFramerate >> 0) & 0xff; - *PesPtr++ = (crazyFramerate >> 8) & 0xff; - *PesPtr++ = (crazyFramerate >> 16) & 0xff; - *PesPtr++ = crazyFramerate >> 24; + PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ - iov[0].iov_base = PesHeader; - iov[1].iov_base = PesPayload; - iov[1].iov_len = PesPtr - PesPayload; - iov[0].iov_len = - InsertPesHeader(PesHeader, iov[1].iov_len, - VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, - 0); - len = writev(call->fd, iov, 2); + *PesPtr++ = (usecPerFrame >> 0) & 0xff; + *PesPtr++ = (usecPerFrame >> 8) & 0xff; + *PesPtr++ = (usecPerFrame >> 16) & 0xff; + *PesPtr++ = usecPerFrame >> 24; - /* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */ - iov[0].iov_base = PesHeader; - iov[1].iov_base = call->stream->codec->extradata; - iov[1].iov_len = call->stream->codec->extradata_size; - iov[0].iov_len = - InsertPesHeader(PesHeader, iov[1].iov_len, - VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, - 0); - len = writev(call->fd, iov, 2); + iov[0].iov_base = PesHeader; + iov[1].iov_base = PesPayload; + iov[1].iov_len = PesPtr - PesPayload; + iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + if (writev(fd, iov, 2) < 0) + return false; - initialHeader = 0; - } + /* For VC1 the codec private data is a standard vc1 sequence header so we just copy it to the output */ + iov[0].iov_base = PesHeader; + iov[1].iov_base = stream->codec->extradata; + iov[1].iov_len = stream->codec->extradata_size; + iov[0].iov_len = InsertPesHeader(PesHeader, iov[1].iov_len, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); + if (writev(fd, iov, 2) < 0) + return false; - if (call->packet->size > 0 && call->packet->data) { - int Position = 0; - unsigned char insertSampleHeader = 1; - - while (Position < call->packet->size) { - - int PacketLength = - (call->packet->size - Position) <= - MAX_PES_PACKET_SIZE ? (call->packet->size - - Position) : MAX_PES_PACKET_SIZE; - - int Remaining = call->packet->size - Position - PacketLength; - - vc1_printf(20, "PacketLength=%d, Remaining=%d, Position=%d\n", - PacketLength, Remaining, Position); - - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - int HeaderLength = - InsertPesHeader(PesHeader, PacketLength, - VC1_VIDEO_PES_START_CODE, call->Pts, 0); - - if (insertSampleHeader) { - const unsigned char Vc1FrameStartCode[] = - { 0, 0, 1, VC1_FRAME_START_CODE }; - -/* - vc1_printf(10, "Data Start: {00 00 01 0d} - "); - int i; - for (i = 0; i < 4; i++) vc1_printf(10, "%02x ", call->packet->data[i]); - vc1_printf(10, "\n"); -*/ - - if (!FrameHeaderSeen && (call->packet->size > 3) - && (memcmp(call->packet->data, Vc1FrameStartCode, 4) == 0)) - FrameHeaderSeen = 1; - if (!FrameHeaderSeen) { - memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, - sizeof(Vc1FrameStartCode)); - HeaderLength += sizeof(Vc1FrameStartCode); - } - insertSampleHeader = 0; - } - - struct iovec iov[2]; - iov[0].iov_base = PesHeader; - iov[0].iov_len = HeaderLength; - iov[1].iov_base = call->packet->data + Position; - iov[1].iov_len = PacketLength; - - ssize_t l = writev(call->fd, iov, 2); - if (l < 0) { - len = l; - break; - } - len += l; - - Position += PacketLength; - call->Pts = INVALID_PTS_VALUE; + initialHeader = false; } - } - vc1_printf(10, "< %d\n", len); - return len; + int64_t _pts = pts; + + if (packet->size > 0) { + int Position = 0; + unsigned char insertSampleHeader = 1; + + while (Position < packet->size) { + int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); + unsigned char PesHeader[PES_MAX_HEADER_SIZE]; + int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); + + if (insertSampleHeader) { + const unsigned char Vc1FrameStartCode[] = { 0, 0, 1, VC1_FRAME_START_CODE }; + + if (!FrameHeaderSeen && (packet->size > 3) && (memcmp(packet->data, Vc1FrameStartCode, 4) == 0)) + FrameHeaderSeen = true; + if (!FrameHeaderSeen) { + memcpy(&PesHeader[HeaderLength], Vc1FrameStartCode, sizeof(Vc1FrameStartCode)); + HeaderLength += sizeof(Vc1FrameStartCode); + } + insertSampleHeader = 0; + } + + struct iovec iov[2]; + iov[0].iov_base = PesHeader; + iov[0].iov_len = HeaderLength; + iov[1].iov_base = packet->data + Position; + iov[1].iov_len = PacketLength; + + ssize_t l = writev(fd, iov, 2); + if (l < 0) + return false; + + Position += PacketLength; + _pts = INVALID_PTS_VALUE; + } + } + + return true; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterVC1::WriterVC1() +{ + Register(this, AV_CODEC_ID_VC1, VIDEO_ENCODING_VC1); +} -static WriterCaps_t caps = { - "vc1", - eVideo, - "V_VC1", - VIDEO_ENCODING_VC1 -}; - -struct Writer_s WriterVideoVC1 = { - &reset, - &writeData, - &caps -}; +static WriterVC1 writer_vc1 __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/wmv.cpp b/libeplayer3/output/writer/wmv.cpp index 1f3ff06..fa283d6 100644 --- a/libeplayer3/output/writer/wmv.cpp +++ b/libeplayer3/output/writer/wmv.cpp @@ -19,241 +19,151 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - #include -#include #include +#include +#include #include -#include -#include -#include -#include #include -#include -#include -#include -#include -#include -#include #include -#include "common.h" -#include "output.h" -#include "debug.h" #include "misc.h" #include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ +#include #define WMV3_PRIVATE_DATA_LENGTH 4 -#define METADATA_STRUCT_A_START 12 -#define METADATA_STRUCT_B_START 24 -#define METADATA_STRUCT_B_FRAMERATE_START 32 -#define METADATA_STRUCT_C_START 8 - -#define WMV_DEBUG - -#ifdef WMV_DEBUG - -static short debug_level = 0; - -#define wmv_printf(level, fmt, x...) do { \ -if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_printf(level, fmt, x...) -#endif - -#ifndef WMV_SILENT -#define wmv_err(fmt, x...) do { printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) -#else -#define wmv_err(fmt, x...) -#endif - - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -typedef struct { - unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH]; - unsigned int width; - unsigned int height; - unsigned int framerate; -} awmv_t; - static const unsigned char Metadata[] = { 0x00, 0x00, 0x00, 0xc5, 0x04, 0x00, 0x00, 0x00, +#define METADATA_STRUCT_C_START 8 0xc0, 0x00, 0x00, 0x00, /* Struct C set for for advanced profile */ +#define METADATA_STRUCT_A_START 12 0x00, 0x00, 0x00, 0x00, /* Struct A */ 0x00, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, +#define METADATA_STRUCT_B_START 24 0x60, 0x00, 0x00, 0x00, /* Struct B */ 0x00, 0x00, 0x00, 0x00, +#define METADATA_STRUCT_B_FRAMERATE_START 32 0x00, 0x00, 0x00, 0x00 }; -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ -static int initialHeader = 1; +class WriterWMV : public Writer +{ + private: + bool initialHeader; + public: + bool Write(int fd, AVFormatContext *avfc, AVStream *stream, AVPacket *packet, int64_t &pts); + void Init(); + WriterWMV(); +}; -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* MISC Functions */ -/* ***************************** */ -static int reset() +void WriterWMV::Init() { initialHeader = 1; - return 0; } -static int writeData(WriterAVCallData_t *call) +bool WriterWMV::Write(int fd, AVFormatContext * /* avfc */, AVStream *stream, AVPacket *packet, int64_t &pts) { - awmv_t private_data; - int len = 0; + if (fd < 0 || !packet) + return false; - wmv_printf(10, "\n"); - - if (call->fd < 0) { - wmv_err("file pointer < 0. ignoring ...\n"); - return 0; - } - - wmv_printf(10, "VideoPts %lld\n", call->Pts); - wmv_printf(10, "Got Private Size %d\n", call->stream->codec->extradata_size); - - memcpy(private_data.privateData, call->stream->codec->extradata, call->stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : call->stream->codec->extradata_size); - - private_data.width = call->stream->codec->width; - private_data.height = call->stream->codec->height; - private_data.framerate = 1000.0 * av_q2d(call->stream->r_frame_rate); /* rational to double */ - - -#define PES_MIN_HEADER_SIZE 9 if (initialHeader) { +#define PES_MIN_HEADER_SIZE 9 unsigned char PesPacket[PES_MIN_HEADER_SIZE + 128]; unsigned char *PesPtr; unsigned int MetadataLength; - unsigned int crazyFramerate = 0; - - wmv_printf(10, "biWidth: %d\n", private_data.width); - wmv_printf(10, "biHeight: %d\n", private_data.height); - - crazyFramerate = ((10000000.0 / private_data.framerate) * 1000.0); - wmv_printf(10, "crazyFramerate: %u\n", crazyFramerate); + unsigned int usecPerFrame = ((10000000.0 / av_q2d(stream->r_frame_rate))); PesPtr = &PesPacket[PES_MIN_HEADER_SIZE]; memcpy(PesPtr, Metadata, sizeof(Metadata)); PesPtr += METADATA_STRUCT_C_START; - memcpy(PesPtr, private_data.privateData, WMV3_PRIVATE_DATA_LENGTH); + unsigned char privateData[WMV3_PRIVATE_DATA_LENGTH] = { 0 }; + memcpy(privateData, stream->codec->extradata, stream->codec->extradata_size > WMV3_PRIVATE_DATA_LENGTH ? WMV3_PRIVATE_DATA_LENGTH : stream->codec->extradata_size); + + memcpy(PesPtr, privateData, WMV3_PRIVATE_DATA_LENGTH); PesPtr += WMV3_PRIVATE_DATA_LENGTH; /* Metadata Header Struct A */ - *PesPtr++ = (private_data.height >> 0) & 0xff; - *PesPtr++ = (private_data.height >> 8) & 0xff; - *PesPtr++ = (private_data.height >> 16) & 0xff; - *PesPtr++ = private_data.height >> 24; - *PesPtr++ = (private_data.width >> 0) & 0xff; - *PesPtr++ = (private_data.width >> 8) & 0xff; - *PesPtr++ = (private_data.width >> 16) & 0xff; - *PesPtr++ = private_data.width >> 24; + *PesPtr++ = (stream->codec->height >> 0) & 0xff; + *PesPtr++ = (stream->codec->height >> 8) & 0xff; + *PesPtr++ = (stream->codec->height >> 16) & 0xff; + *PesPtr++ = stream->codec->height >> 24; + *PesPtr++ = (stream->codec->width >> 0) & 0xff; + *PesPtr++ = (stream->codec->width >> 8) & 0xff; + *PesPtr++ = (stream->codec->width >> 16) & 0xff; + *PesPtr++ = stream->codec->width >> 24; PesPtr += 12; /* Skip flag word and Struct B first 8 bytes */ - *PesPtr++ = (crazyFramerate >> 0) & 0xff; - *PesPtr++ = (crazyFramerate >> 8) & 0xff; - *PesPtr++ = (crazyFramerate >> 16) & 0xff; - *PesPtr++ = crazyFramerate >> 24; + *PesPtr++ = (usecPerFrame >> 0) & 0xff; + *PesPtr++ = (usecPerFrame >> 8) & 0xff; + *PesPtr++ = (usecPerFrame >> 16) & 0xff; + *PesPtr++ = usecPerFrame >> 24; MetadataLength = PesPtr - &PesPacket[PES_MIN_HEADER_SIZE]; - int HeaderLength = - InsertPesHeader(PesPacket, MetadataLength, - VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, - 0); + int HeaderLength = InsertPesHeader(PesPacket, MetadataLength, VC1_VIDEO_PES_START_CODE, INVALID_PTS_VALUE, 0); - len = write(call->fd, PesPacket, HeaderLength + MetadataLength); + if (write(fd, PesPacket, HeaderLength + MetadataLength) < 0) + return false; - initialHeader = 0; + initialHeader = false; } - if (call->packet->size > 0 && call->packet->data) { + if (packet->size > 0 && packet->data) { int Position = 0; - unsigned char insertSampleHeader = 1; - while (Position < call->packet->size) { + bool insertSampleHeader = true; - int PacketLength = (call->packet->size - Position) <= MAX_PES_PACKET_SIZE ? (call->packet->size - Position) : MAX_PES_PACKET_SIZE; + uint64_t _pts = pts; - unsigned char PesHeader[PES_MAX_HEADER_SIZE]; - memset(PesHeader, '0', PES_MAX_HEADER_SIZE); - int HeaderLength = - InsertPesHeader(PesHeader, PacketLength, - VC1_VIDEO_PES_START_CODE, call->Pts, 0); - unsigned char *PacketStart; + while (Position < packet->size) { + + int PacketLength = std::min(packet->size - Position, MAX_PES_PACKET_SIZE); + + unsigned char PesHeader[PES_MAX_HEADER_SIZE] = { 0 }; + int HeaderLength = InsertPesHeader(PesHeader, PacketLength, VC1_VIDEO_PES_START_CODE, _pts, 0); if (insertSampleHeader) { unsigned int PesLength; unsigned int PrivateHeaderLength; - PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], call->packet->size); + PrivateHeaderLength = InsertVideoPrivateDataHeader(&PesHeader[HeaderLength], packet->size); /* Update PesLength */ - PesLength = PesHeader[PES_LENGTH_BYTE_0] + - (PesHeader[PES_LENGTH_BYTE_1] << 8) + - PrivateHeaderLength; + PesLength = PesHeader[PES_LENGTH_BYTE_0] + (PesHeader[PES_LENGTH_BYTE_1] << 8) + PrivateHeaderLength; PesHeader[PES_LENGTH_BYTE_0] = PesLength & 0xff; PesHeader[PES_LENGTH_BYTE_1] = (PesLength >> 8) & 0xff; - PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += - PrivateHeaderLength; + PesHeader[PES_HEADER_DATA_LENGTH_BYTE] += PrivateHeaderLength; PesHeader[PES_FLAGS_BYTE] |= PES_EXTENSION_DATA_PRESENT; HeaderLength += PrivateHeaderLength; - insertSampleHeader = 0; + insertSampleHeader = false; } - PacketStart = (unsigned char *) malloc(call->packet->size + HeaderLength); + uint8_t PacketStart[packet->size + HeaderLength]; memcpy(PacketStart, PesHeader, HeaderLength); - memcpy(PacketStart + HeaderLength, call->packet->data + Position, - PacketLength); - - len = - write(call->fd, PacketStart, PacketLength + HeaderLength); - free(PacketStart); + memcpy(PacketStart + HeaderLength, packet->data + Position, PacketLength); + if (write(fd, PacketStart, PacketLength + HeaderLength) < 0) + return false; Position += PacketLength; - call->Pts = INVALID_PTS_VALUE; + _pts = INVALID_PTS_VALUE; } } - wmv_printf(10, "< %d\n", len); - return len; + return true; } -/* ***************************** */ -/* Writer Definition */ -/* ***************************** */ +WriterWMV::WriterWMV() +{ + Register(this, AV_CODEC_ID_WMV1, VIDEO_ENCODING_WMV); + Register(this, AV_CODEC_ID_WMV2, VIDEO_ENCODING_WMV); + Register(this, AV_CODEC_ID_WMV3, VIDEO_ENCODING_WMV); +} -static WriterCaps_t caps = { - "wmv", - eVideo, - "V_WMV", - VIDEO_ENCODING_WMV -}; - -struct Writer_s WriterVideoWMV = { - &reset, - &writeData, - &caps -}; +static WriterWMV writer_wmv __attribute__ ((init_priority (300))); diff --git a/libeplayer3/output/writer/writer.cpp b/libeplayer3/output/writer/writer.cpp index f5a971e..c1deac9 100644 --- a/libeplayer3/output/writer/writer.cpp +++ b/libeplayer3/output/writer/writer.cpp @@ -19,128 +19,97 @@ * */ -/* ***************************** */ -/* Includes */ -/* ***************************** */ - -#include +#include #include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pes.h" #include "writer.h" -/* ***************************** */ -/* Makros/Constants */ -/* ***************************** */ +// 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. -#define WRITER_DEBUG +#include "divx.cpp" +#include "h263.cpp" +#include "h264.cpp" +#include "mp3.cpp" +#include "vc1.cpp" +#include "wmv.cpp" +#include "ac3.cpp" +#include "dts.cpp" +#include "flac.cpp" +#include "mpeg2.cpp" +#include "pcm.cpp" -#ifdef WRITER_DEBUG +static std::mapwriters __attribute__ ((init_priority (200))); +static std::mapvencoding __attribute__ ((init_priority (200))); +static std::mapaencoding __attribute__ ((init_priority (200))); -static short debug_level = 0; - -#define writer_printf(level, x...) do { \ -if (debug_level >= level) printf(x); } while (0) -#else -#define writer_printf(level, x...) -#endif - -#ifndef WRITER_SILENT -#define writer_err(x...) do { printf(x); } while (0) -#else -#define writer_err(x...) -#endif - -/* ***************************** */ -/* Types */ -/* ***************************** */ - -/* ***************************** */ -/* Varaibles */ -/* ***************************** */ - -static Writer_t *AvailableWriter[] = { - &WriterAudioIPCM, -// &WriterAudioPCM, - &WriterAudioMP3, - &WriterAudioMPEGL3, - &WriterAudioAC3, - &WriterAudioEAC3, -// &WriterAudioAAC, - &WriterAudioDTS, -// &WriterAudioWMA, - &WriterAudioFLAC, - &WriterAudioVORBIS, - - &WriterVideoMPEG2, - &WriterVideoMPEGH264, - &WriterVideoH264, - &WriterVideoDIVX, - &WriterVideoFOURCC, - &WriterVideoMSCOMP, - &WriterVideoWMV, - &WriterVideoH263, - &WriterVideoFLV, - &WriterVideoVC1, - NULL -}; - -/* ***************************** */ -/* Prototypes */ -/* ***************************** */ - -/* ***************************** */ -/* Functions */ -/* ***************************** */ - -Writer_t *getWriter(char *encoding) +void Writer::Register(Writer *w, enum AVCodecID id, video_encoding_t encoding) { - int i; - - for (i = 0; AvailableWriter[i] != NULL; i++) { - if (strcmp(AvailableWriter[i]->caps->textEncoding, encoding) == 0) { - writer_printf(50, "%s: found writer \"%s\" for \"%s\"\n", - __func__, AvailableWriter[i]->caps->name, - encoding); - return AvailableWriter[i]; - } - } - - writer_printf(1, "%s: no writer found for \"%s\"\n", __func__, - encoding); - - return NULL; + writers[id] = w; + vencoding[id] = encoding; } -Writer_t *getDefaultVideoWriter() +void Writer::Register(Writer *w, enum AVCodecID id, audio_encoding_t encoding) { - int i; - - for (i = 0; AvailableWriter[i] != NULL; i++) { - if (strcmp(AvailableWriter[i]->caps->textEncoding, "V_MPEG2") == 0) { - writer_printf(50, "%s: found writer \"%s\"\n", __func__, - AvailableWriter[i]->caps->name); - return AvailableWriter[i]; - } - } - - writer_printf(1, "%s: no writer found\n", __func__); - - return NULL; + writers[id] = w; + aencoding[id] = encoding; } -Writer_t *getDefaultAudioWriter() +bool Writer::Write(int /* fd */, AVFormatContext * /* avfc */, AVStream * /*stream*/, AVPacket * /* packet */, int64_t & /* pts */) { - int i; - - for (i = 0; AvailableWriter[i] != NULL; i++) { - if (strcmp(AvailableWriter[i]->caps->textEncoding, "A_MP3") == 0) { - writer_printf(50, "%s: found writer \"%s\"\n", __func__, - AvailableWriter[i]->caps->name); - return AvailableWriter[i]; - } - } - - writer_printf(1, "%s: no writer found\n", __func__); - - return NULL; + return false; +} + +static Writer writer __attribute__ ((init_priority (300))); + +Writer *Writer::GetWriter(enum AVCodecID id, enum AVMediaType codec_type) +{ +fprintf(stderr, "%s %s %d\n", __FILE__,__func__,__LINE__); + std::map::iterator it = writers.find(id); + if (it != writers.end()) + return it->second; +fprintf(stderr, "%s %s %d: no writer found\n", __FILE__,__func__,__LINE__); + switch (codec_type) { + case AVMEDIA_TYPE_AUDIO: + if (id == AV_CODEC_ID_INJECTPCM) // should not happen + break; +fprintf(stderr, "%s %s %d: returning injectpcm\n", __FILE__,__func__,__LINE__); + return GetWriter(AV_CODEC_ID_INJECTPCM, codec_type); + case AVMEDIA_TYPE_VIDEO: + if (id == AV_CODEC_ID_MPEG2TS) // should not happen + break; +fprintf(stderr, "%s %s %d: returning mpeg2video\n", __FILE__,__func__,__LINE__); + return GetWriter(AV_CODEC_ID_MPEG2TS, codec_type); + default: + break; + } +fprintf(stderr, "%s %s %d: returning dummy writer\n", __FILE__,__func__,__LINE__); + return &writer; +} + +video_encoding_t Writer::GetVideoEncoding(enum AVCodecID id) +{ + std::map::iterator it = vencoding.find(id); + if (it != vencoding.end()) + return it->second; + return VIDEO_ENCODING_AUTO; +} + +audio_encoding_t Writer::GetAudioEncoding(enum AVCodecID id) +{ + std::map::iterator it = aencoding.find(id); + if (it != aencoding.end()) + return it->second; + return AUDIO_ENCODING_LPCMA; } diff --git a/libeplayer3/playback/playback.cpp b/libeplayer3/playback/playback.cpp index e0b2801..5b5f5b1 100644 --- a/libeplayer3/playback/playback.cpp +++ b/libeplayer3/playback/playback.cpp @@ -627,24 +627,26 @@ static int PlaybackSwitchAudio(Context_t * context, int *track) if (context->playback->isPlaying) { if (context->manager && context->manager->audio) { - context->manager->audio->Command(context, MANAGER_GET, - &curtrackid); + context->manager->audio->Command(context, MANAGER_GET, &curtrackid); context->manager->audio->Command(context, MANAGER_SET, track); - context->manager->audio->Command(context, MANAGER_GET, - &nextrackid); + context->manager->audio->Command(context, MANAGER_GET, &nextrackid); } if (nextrackid != curtrackid) { //PlaybackPause(context); - if (context->output && context->output->audio) - context->output->audio->Command(context, OUTPUT_SWITCH, "audio"); - - if (context->container - && context->container->selectedContainer) + if (context->container && context->container->selectedContainer) context->container->selectedContainer->Command(context, CONTAINER_SWITCH_AUDIO, (const char *)&nextrackid); + //FIXME + Track_t *t=NULL; + context->manager->audio->Command(context, MANAGER_GET_TRACK, &t); +extern bool output_switch_audio(AVStream*); + if(t) + output_switch_audio(t->stream); + //FIXME + //PlaybackContinue(context); } } else { diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index a0b2abc..cff0516 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -491,26 +491,7 @@ void cPlayback::FindAllPids(int *apids, unsigned int *ac3flags, unsigned int *nu if (2 == sscanf(TrackList[i], "%d %s\n", &_pid, _lang)) { apids[j]=_pid; // atUnknown, atMPEG, atMP3, atAC3, atDTS, atAAC, atPCM, atOGG, atFLAC - if( !strncmp("A_MPEG/L3", TrackList[i+1], 9)) - ac3flags[j] = 3; - if( !strncmp("A_MP3", TrackList[i+1], 5)) - ac3flags[j] = 4; - else if(!strncmp("A_AC3", TrackList[i+1], 5)) - ac3flags[j] = 1; - else if(!strncmp("A_EAC3", TrackList[i+1], 6)) - ac3flags[j] = 7; - else if(!strncmp("A_DTS", TrackList[i+1], 5)) - ac3flags[j] = 6; - else if(!strncmp("A_AAC", TrackList[i+1], 5)) - ac3flags[j] = 5; - else if(!strncmp("A_PCM", TrackList[i+1], 5)) - ac3flags[j] = 0; //todo - else if(!strncmp("A_VORBIS", TrackList[i+1], 8)) - ac3flags[j] = 0; //todo - else if(!strncmp("A_FLAC", TrackList[i+1], 6)) - ac3flags[j] = 0; //todo - else - ac3flags[j] = 0; //todo + ac3flags[j] = atoi(TrackList[i+1]); language[j]=std::string(_lang); } }