From 038d9e613d73c1fdbf41abf3dad4626d28d869f8 Mon Sep 17 00:00:00 2001 From: martii Date: Mon, 23 Dec 2013 16:47:29 +0100 Subject: [PATCH] libeplayer3, libspark/playback_libeplayer3: chapter support Origin commit data ------------------ Branch: master Commit: https://github.com/neutrino-images/ni-libstb-hal/commit/450ac45c3086d555aa884d5eb639454e651aab25 Author: martii Date: 2013-12-23 (Mon, 23 Dec 2013) ------------------ No further description and justification available within origin commit message! ------------------ This commit was generated by Migit --- libeplayer3/Makefile.am | 2 +- libeplayer3/container/container_ffmpeg.c | 27 ++- libeplayer3/include/manager.h | 3 + libeplayer3/manager/chapter.c | 224 +++++++++++++++++++++++ libeplayer3/manager/manager.c | 6 +- libeplayer3/playback/playback.c | 1 + libspark/playback_libeplayer3.cpp | 37 +++- libspark/playback_libeplayer3.h | 2 +- 8 files changed, 287 insertions(+), 15 deletions(-) create mode 100644 libeplayer3/manager/chapter.c diff --git a/libeplayer3/Makefile.am b/libeplayer3/Makefile.am index 0746290..19e721f 100644 --- a/libeplayer3/Makefile.am +++ b/libeplayer3/Makefile.am @@ -9,7 +9,7 @@ libeplayer3_la_SOURCES = \ container/container.c container/container_ffmpeg.c container/text_srt.c \ container/text_ssa.c container/container_ass.c \ manager/audio.c manager/manager.c manager/subtitle.c manager/video.c \ - manager/dvbsubtitle.c manager/teletext.c \ + manager/dvbsubtitle.c manager/teletext.c manager/chapter.c \ output/output_subtitle.c output/linuxdvb.c output/output.c output/output_pipe.c \ playback/playback.c output/writer/writer.c output/writer/aac.c output/writer/wmv.c \ output/writer/ac3.c output/writer/divx.c output/writer/wma.c output/writer/pes.c \ diff --git a/libeplayer3/container/container_ffmpeg.c b/libeplayer3/container/container_ffmpeg.c index c04e233..b1240c2 100644 --- a/libeplayer3/container/container_ffmpeg.c +++ b/libeplayer3/container/container_ffmpeg.c @@ -908,16 +908,23 @@ int container_ffmpeg_update_tracks(Context_t * context, char *filename, int init if (terminating) return cERR_CONTAINER_FFMPEG_NO_ERROR; - Track_t *audioTrack = NULL; - Track_t *subtitleTrack = NULL; - Track_t *dvbsubtitleTrack = NULL; - Track_t *teletextTrack = NULL; - - context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); - if (initial) - context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack); - context->manager->dvbsubtitle->Command(context, MANAGER_GET_TRACK, &dvbsubtitleTrack); - context->manager->teletext->Command(context, MANAGER_GET_TRACK, &teletextTrack); + if (context->manager->chapter) { + unsigned int i; + context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); + for (i = 0; i < avContext->nb_chapters; i++) { + Track_t track; + memset(&track, 0, sizeof(track)); + track.Id = i; + AVDictionaryEntry *title; + AVChapter *ch = avContext->chapters[i]; + title = av_dict_get(ch->metadata, "title", NULL, 0); + track.Name = strdup(title ? title->value : "und"); + ffmpeg_printf(10, "Chapter %s\n", track.Name); + track.chapter_start = (double) ch->start * av_q2d(ch->time_base) * 1000.0; + track.chapter_end = (double) ch->end * av_q2d(ch->time_base) * 1000.0; + context->manager->chapter->Command(context, MANAGER_ADD, &track); + } + } if (context->manager->video) context->manager->video->Command(context, MANAGER_INIT_UPDATE, NULL); diff --git a/libeplayer3/include/manager.h b/libeplayer3/include/manager.h index 081f3e3..11f3d19 100644 --- a/libeplayer3/include/manager.h +++ b/libeplayer3/include/manager.h @@ -59,6 +59,8 @@ typedef struct Track_s { int inject_raw_pcm; int pending; + long long int chapter_start; + long long int chapter_end; } Track_t; typedef struct Manager_s { @@ -75,6 +77,7 @@ typedef struct ManagerHandler_s { Manager_t *subtitle; Manager_t *dvbsubtitle; Manager_t *teletext; + Manager_t *chapter; } ManagerHandler_t; void freeTrack(Track_t * track); diff --git a/libeplayer3/manager/chapter.c b/libeplayer3/manager/chapter.c new file mode 100644 index 0000000..16e499f --- /dev/null +++ b/libeplayer3/manager/chapter.c @@ -0,0 +1,224 @@ +/* + * chapter manager handling. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +/* ***************************** */ +/* Includes */ +/* ***************************** */ + +#include +#include + +#include "manager.h" +#include "common.h" + +/* ***************************** */ +/* Makros/Constants */ +/* ***************************** */ +#define TRACKWRAP 64 + +#define CHAPTER_MGR_DEBUG + +#ifdef CHAPTER_MGR_DEBUG + +static short debug_level = 0; + +#define chapter_mgr_printf(level, x...) do { \ +if (debug_level >= level) printf(x); } while (0) +#else +#define chapter_mgr_printf(level, x...) +#endif + +#ifndef CHAPTER_MGR_SILENT +#define chapter_mgr_err(x...) do { printf(x); } while (0) +#else +#define chapter_mgr_err(x...) +#endif + +/* Error Constants */ +#define cERR_CHAPTER_MGR_NO_ERROR 0 +#define cERR_CHAPTER_MGR_ERROR -1 + +static const char FILENAME[] = __FILE__; + +/* ***************************** */ +/* Types */ +/* ***************************** */ + +/* ***************************** */ +/* Varaibles */ +/* ***************************** */ + +static Track_t *Tracks = NULL; +static int TrackCount = 0; +static int CurrentTrack = 0; //TRACK[0] as default. + +/* ***************************** */ +/* Prototypes */ +/* ***************************** */ + +/* ***************************** */ +/* Functions */ +/* ***************************** */ + +static int ManagerAdd(Context_t * context __attribute__((unused)), Track_t track) +{ + chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); + + if (Tracks == NULL) { + Tracks = malloc(sizeof(Track_t) * TRACKWRAP); + int i; + for (i = 0; i < TRACKWRAP; i++) + Tracks[i].Id = -1; + } + + if (Tracks == NULL) { + chapter_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__); + return cERR_CHAPTER_MGR_ERROR; + } + + int i; + for (i = 0; i < TRACKWRAP; i++) { + if (Tracks[i].Id == track.Id) { + Tracks[i].pending = 0; + return cERR_CHAPTER_MGR_NO_ERROR; + } + } + + if (TrackCount < TRACKWRAP) { + copyTrack(&Tracks[TrackCount], &track); + + TrackCount++; + } else { + chapter_mgr_err("%s:%s TrackCount out if range %d - %d\n", FILENAME, + __FUNCTION__, TrackCount, TRACKWRAP); + return cERR_CHAPTER_MGR_ERROR; + } + + chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); + + return cERR_CHAPTER_MGR_NO_ERROR; +} + +static char **ManagerList(Context_t * context __attribute__ ((unused))) +{ + int i = 0, j = 0; + char **tracklist = NULL; + + chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); + + if (Tracks != NULL) { + + tracklist = malloc(sizeof(char *) * ((TrackCount * 2) + 1)); + + if (tracklist == NULL) { + chapter_mgr_err("%s:%s malloc failed\n", FILENAME, __FUNCTION__); + return NULL; + } + + for (i = 0, j = 0; i < TrackCount; i++, j += 2) { + if (Tracks[i].pending) + continue; + char tmp[20]; + snprintf(tmp, sizeof(tmp), "%d", (int)Tracks[i].chapter_start); + tracklist[j] = strdup(tmp); + tracklist[j + 1] = strdup(Tracks[i].Name); + } + tracklist[j] = NULL; + } + + chapter_mgr_printf(10, "%s::%s return %p (%d - %d)\n", FILENAME, + __FUNCTION__, tracklist, j, TrackCount); + + return tracklist; +} + +static int ManagerDel(Context_t * context __attribute__((unused))) +{ + int i = 0; + + chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); + + if (Tracks != NULL) { + for (i = 0; i < TrackCount; i++) { + freeTrack(&Tracks[i]); + } + free(Tracks); + Tracks = NULL; + } else { + chapter_mgr_err("%s::%s nothing to delete!\n", FILENAME, + __FUNCTION__); + return cERR_CHAPTER_MGR_ERROR; + } + + TrackCount = 0; + CurrentTrack = 0; + + chapter_mgr_printf(10, "%s::%s return no error\n", FILENAME, + __FUNCTION__); + + return cERR_CHAPTER_MGR_NO_ERROR; +} + +static int Command(void *_context, ManagerCmd_t command, void *argument) +{ + Context_t *context = (Context_t *) _context; + int ret = cERR_CHAPTER_MGR_NO_ERROR; + + chapter_mgr_printf(10, "%s::%s\n", FILENAME, __FUNCTION__); + + switch (command) { + case MANAGER_ADD:{ + Track_t *track = argument; + ret = ManagerAdd(context, *track); + break; + } + case MANAGER_LIST:{ + container_ffmpeg_update_tracks(context, context->playback->uri, 0); + *((char ***) argument) = (char **) ManagerList(context); + break; + } + case MANAGER_DEL:{ + ret = ManagerDel(context); + break; + } + case MANAGER_INIT_UPDATE:{ + int i; + for (i = 0; i < TrackCount; i++) + Tracks[i].pending = 1; + break; + } + default: + chapter_mgr_err("%s::%s ContainerCmd %d not supported!\n", FILENAME, + __FUNCTION__, command); + ret = cERR_CHAPTER_MGR_ERROR; + break; + } + + chapter_mgr_printf(10, "%s:%s: returning %d\n", FILENAME, __FUNCTION__, + ret); + + return ret; +} + + +struct Manager_s ChapterManager = { + "Chapter", + &Command, + NULL +}; diff --git a/libeplayer3/manager/manager.c b/libeplayer3/manager/manager.c index 25e8067..e86577d 100644 --- a/libeplayer3/manager/manager.c +++ b/libeplayer3/manager/manager.c @@ -42,12 +42,16 @@ extern Manager_t VideoManager; extern Manager_t SubtitleManager; extern Manager_t DvbSubtitleManager; extern Manager_t TeletextManager; +extern Manager_t ChapterManager; ManagerHandler_t ManagerHandler = { "ManagerHandler", &AudioManager, &VideoManager, - &SubtitleManager, &DvbSubtitleManager, &TeletextManager + &SubtitleManager, + &DvbSubtitleManager, + &TeletextManager, + &ChapterManager }; /* ***************************** */ diff --git a/libeplayer3/playback/playback.c b/libeplayer3/playback/playback.c index 033b9e1..725a3d6 100644 --- a/libeplayer3/playback/playback.c +++ b/libeplayer3/playback/playback.c @@ -197,6 +197,7 @@ static int PlaybackClose(Context_t * context) context->manager->subtitle->Command(context, MANAGER_DEL, NULL); context->manager->dvbsubtitle->Command(context, MANAGER_DEL, NULL); context->manager->teletext->Command(context, MANAGER_DEL, NULL); + context->manager->chapter->Command(context, MANAGER_DEL, NULL); context->playback->isPaused = 0; context->playback->isPlaying = 0; diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index 4c0adfe..5fd46c2 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -190,6 +190,21 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, un free(TrackList); } } + //Chapters + if(player && player->manager && player->manager->chapter) { + char ** TrackList = NULL; + player->manager->chapter->Command(player, MANAGER_LIST, &TrackList); + if (TrackList != NULL) { + printf("Chapter List\n"); + int i = 0; + for (i = 0; TrackList[i] != NULL; i+=2) { + printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + free(TrackList[i]); + free(TrackList[i+1]); + } + free(TrackList); + } + } if (pm != PLAYMODE_TS && player && player->output && player->playback) { player->output->Command(player, OUTPUT_OPEN, NULL); @@ -683,14 +698,32 @@ bool cPlayback::SelectSubtitles(int pid) printf("%s:%s pid %d\n", FILENAME, __func__, pid); return false; } +#endif -/* another dummy function for DVD playback(?) */ void cPlayback::GetChapters(std::vector &positions, std::vector &titles) { positions.clear(); titles.clear(); + + if(player && player->manager && player->manager->chapter) { + char ** TrackList = NULL; + player->manager->chapter->Command(player, MANAGER_LIST, &TrackList); + if (TrackList != NULL) { + printf("%s: Chapter List\n", __func__); + int i = 0; + for (i = 0; TrackList[i] != NULL; i+=2) { + printf("\t%s - %s\n", TrackList[i], TrackList[i+1]); + int pos = atoi(TrackList[i]); + std::string title(TrackList[i + 1]); + positions.push_back(pos); + titles.push_back(title); + free(TrackList[i]); + free(TrackList[i+1]); + } + free(TrackList); + } + } } -#endif // cPlayback::cPlayback(int num __attribute__((unused)), void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void))) diff --git a/libspark/playback_libeplayer3.h b/libspark/playback_libeplayer3.h index 73437e4..c9379b7 100644 --- a/libspark/playback_libeplayer3.h +++ b/libspark/playback_libeplayer3.h @@ -53,8 +53,8 @@ class cPlayback #if 0 void FindAllSubs(uint16_t *pids, unsigned short *supported, uint16_t *numpida, std::string *language); bool SelectSubtitles(int pid); - void GetChapters(std::vector &positions, std::vector &titles); #endif + void GetChapters(std::vector &positions, std::vector &titles); #if 0 // Functions that are not used by movieplayer.cpp: bool GetOffset(off64_t &offset);