From 1c676196afede1f0f2749e1f96e0a3101674d48c Mon Sep 17 00:00:00 2001 From: martii Date: Sun, 19 Jan 2014 12:25:35 +0100 Subject: [PATCH] libeplayer3/libspark: cPlayback: implement retrieval of metadata --- generic-pc/playback.cpp | 6 +++ generic-pc/playback.h | 1 + libeplayer3/container/container_ass.c | 2 +- libeplayer3/container/container_ffmpeg.c | 65 ++++++++++++++++++++++++ libeplayer3/include/container.h | 1 + libeplayer3/include/playback.h | 2 +- libeplayer3/playback/playback.c | 15 ++++++ libspark/playback_libeplayer3.cpp | 20 ++++++++ libspark/playback_libeplayer3.h | 1 + 9 files changed, 111 insertions(+), 2 deletions(-) diff --git a/generic-pc/playback.cpp b/generic-pc/playback.cpp index 50d6f69..6928474 100644 --- a/generic-pc/playback.cpp +++ b/generic-pc/playback.cpp @@ -122,6 +122,12 @@ void cPlayback::GetChapters(std::vector &positions, std::vector &keys, std::vector &values) +{ + keys.clear(); + values.clear(); +} + cPlayback::cPlayback(int /*num*/) { printf("%s:%s\n", FILENAME, __func__); diff --git a/generic-pc/playback.h b/generic-pc/playback.h index ff66d35..cb5b12f 100644 --- a/generic-pc/playback.h +++ b/generic-pc/playback.h @@ -48,6 +48,7 @@ class cPlayback void FindAllSubs(int *pids, unsigned int *supported, unsigned int *numpida, std::string *language); bool SelectSubtitles(int pid); void GetChapters(std::vector &positions, std::vector &titles); + void GetMetadata(std::vector &keys, std::vector &values); // cPlayback(int num = 0); ~cPlayback(); diff --git a/libeplayer3/container/container_ass.c b/libeplayer3/container/container_ass.c index e7c89d9..33fcbc0 100644 --- a/libeplayer3/container/container_ass.c +++ b/libeplayer3/container/container_ass.c @@ -56,7 +56,7 @@ #ifdef ASS_DEBUG -static short debug_level = 10; +static short debug_level = 0; #define ass_printf(level, fmt, x...) do { \ if (debug_level >= level) printf("[%s:%s] " fmt, __FILE__, __FUNCTION__, ## x); } while (0) diff --git a/libeplayer3/container/container_ffmpeg.c b/libeplayer3/container/container_ffmpeg.c index 5e88e4b..348dbb3 100644 --- a/libeplayer3/container/container_ffmpeg.c +++ b/libeplayer3/container/container_ffmpeg.c @@ -1508,6 +1508,67 @@ static int container_ffmpeg_get_info(Context_t * context, char **infoString) } +static int container_ffmpeg_get_metadata(Context_t * context, char ***p) +{ + Track_t *videoTrack = NULL; + Track_t *audioTrack = NULL; + AVDictionaryEntry *tag = NULL; + size_t psize = 1; + char **pp; + + if (!context) { + fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); + return cERR_CONTAINER_FFMPEG_ERR; + } + + if (!p || *p) { + fprintf(stderr, "BUG %s:%d\n", __func__, __LINE__); + return cERR_CONTAINER_FFMPEG_ERR; + } + + context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack); + context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack); + + if (avContext->metadata) + psize += av_dict_count(avContext->metadata); + if (videoTrack) + psize += av_dict_count(((AVStream *)(videoTrack->stream))->metadata); + if (audioTrack) + psize += av_dict_count(((AVStream *)(audioTrack->stream))->metadata); + + *p = malloc(sizeof(char *) * psize * 2); + if (!*p) { + fprintf(stderr, "MALLOC %s:%d\n", __func__, __LINE__); + return cERR_CONTAINER_FFMPEG_ERR; + } + pp = *p; + + if (avContext->metadata) + while ((tag = av_dict_get(avContext->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + *pp++ = strdup(tag->key); + *pp++ = strdup(tag->value); + } + + if (videoTrack) { + tag = NULL; + while ((tag = av_dict_get(((AVStream *)(videoTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + *pp++ = strdup(tag->key); + *pp++ = strdup(tag->value); + } + } + if (audioTrack) { + tag = NULL; + while ((tag = av_dict_get(((AVStream *)(audioTrack->stream))->metadata, "", tag, AV_DICT_IGNORE_SUFFIX))) { + *pp++ = strdup(tag->key); + *pp++ = strdup(tag->value); + } + } + *pp++ = NULL; + *pp = NULL; + + return cERR_CONTAINER_FFMPEG_NO_ERROR; +} + static int Command(void *_context, ContainerCmd_t command, void *argument) { Context_t *context = (Context_t *) _context; @@ -1560,6 +1621,10 @@ static int Command(void *_context, ContainerCmd_t command, void *argument) ret = container_ffmpeg_get_info(context, (char **) argument); break; } + case CONTAINER_METADATA:{ + ret = container_ffmpeg_get_metadata(context, (char ***) argument); + break; + } case CONTAINER_STATUS:{ *((int *) argument) = hasPlayThreadStarted; break; diff --git a/libeplayer3/include/container.h b/libeplayer3/include/container.h index dac8709..21347d1 100644 --- a/libeplayer3/include/container.h +++ b/libeplayer3/include/container.h @@ -18,6 +18,7 @@ typedef enum { CONTAINER_SWITCH_DVBSUBTITLE, CONTAINER_SWITCH_TELETEXT, CONTAINER_INFO, + CONTAINER_METADATA, CONTAINER_STATUS, CONTAINER_LAST_PTS, CONTAINER_DATA diff --git a/libeplayer3/include/playback.h b/libeplayer3/include/playback.h index 3179d43..6654137 100644 --- a/libeplayer3/include/playback.h +++ b/libeplayer3/include/playback.h @@ -6,7 +6,7 @@ typedef enum { PLAYBACK_OPEN, PLAYBACK_CLOSE, PLAYBACK_PLAY, PLAYBACK_STOP, PLAYBACK_PAUSE, PLAYBACK_CONTINUE, PLAYBACK_FLUSH, PLAYBACK_TERM, PLAYBACK_FASTFORWARD, PLAYBACK_SEEK, PLAYBACK_SEEK_ABS, PLAYBACK_PTS, PLAYBACK_LENGTH, PLAYBACK_SWITCH_AUDIO, - PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_SLOWMOTION, + PLAYBACK_SWITCH_SUBTITLE, PLAYBACK_INFO, PLAYBACK_METADATA, PLAYBACK_SLOWMOTION, PLAYBACK_FASTBACKWARD, PLAYBACK_GET_FRAME_COUNT, PLAYBACK_SWITCH_TELETEXT, PLAYBACK_SWITCH_DVBSUBTITLE, PLAYBACK_FRAMEBUFFER_LOCK, diff --git a/libeplayer3/playback/playback.c b/libeplayer3/playback/playback.c index b198702..271b74a 100644 --- a/libeplayer3/playback/playback.c +++ b/libeplayer3/playback/playback.c @@ -862,6 +862,17 @@ static int PlaybackInfo(Context_t * context, char **infoString) return ret; } +static int PlaybackMetadata(Context_t * context, char ***metadata) +{ + int ret = cERR_PLAYBACK_NO_ERROR; + + if (context->container && context->container->selectedContainer) + context->container->selectedContainer->Command(context, + CONTAINER_METADATA, + metadata); + return ret; +} + static int Command(void *_context, PlaybackCmd_t command, void *argument) { Context_t *context = (Context_t *) _context; /* to satisfy compiler */ @@ -932,6 +943,10 @@ static int Command(void *_context, PlaybackCmd_t command, void *argument) ret = PlaybackInfo(context, (char **) argument); break; } + case PLAYBACK_METADATA:{ + ret = PlaybackMetadata(context, (char ***) argument); + break; + } case PLAYBACK_SLOWMOTION:{ ret = PlaybackSlowMotion(context, (int *) argument); break; diff --git a/libspark/playback_libeplayer3.cpp b/libspark/playback_libeplayer3.cpp index 1b2b318..102c810 100644 --- a/libspark/playback_libeplayer3.cpp +++ b/libspark/playback_libeplayer3.cpp @@ -726,6 +726,25 @@ void cPlayback::GetChapters(std::vector &positions, std::vector &keys, std::vector &values) +{ + keys.clear(); + values.clear(); + char **metadata = NULL; + if (player && player->playback) { + player->playback->Command(player, PLAYBACK_METADATA, &metadata); + if (metadata) { + for (char **m = metadata; *m;) { + keys.push_back(*m); + free(*m++); + values.push_back(*m); + free(*m++); + } + free(metadata); + } + } +} + // cPlayback::cPlayback(int num __attribute__((unused)), void (*fbcb)(uint32_t **, unsigned int *, unsigned int *, unsigned int *, void (**)(void))) { @@ -769,6 +788,7 @@ unsigned long long cPlayback::GetReadCount() { } return 0; } + #if 0 bool cPlayback::IsPlaying(void) const { diff --git a/libspark/playback_libeplayer3.h b/libspark/playback_libeplayer3.h index a88b70f..ac9ed15 100644 --- a/libspark/playback_libeplayer3.h +++ b/libspark/playback_libeplayer3.h @@ -55,6 +55,7 @@ class cPlayback bool SelectSubtitles(int pid); #endif void GetChapters(std::vector &positions, std::vector &titles); + void GetMetadata(std::vector &keys, std::vector &values); #if 0 // Functions that are not used by movieplayer.cpp: bool GetOffset(off64_t &offset);