[vlc-commits] [Git][videolan/vlc][master] 11 commits: preparser: set the preparsed state only if actually done
Thomas Guillem (@tguillem)
gitlab at videolan.org
Fri Dec 22 16:20:43 UTC 2023
Thomas Guillem pushed to branch master at VideoLAN / VLC
Commits:
d275d1e7 by Thomas Guillem at 2023-12-22T15:55:41+00:00
preparser: set the preparsed state only if actually done
This fixes item with 0 meta, if the preparser failed (or was skipped).
This let a second chance for the player to fetch meta and attachments.
This was happening with every mock media that are skipped by the
preparser.
- - - - -
77390aac by Thomas Guillem at 2023-12-22T15:55:41+00:00
input: add INPUT_EVENT_ATTACHMENTS
Send attachments via the input_thread_t.
The possibility to send attachments via the input_item_t will be removed
soon.
- - - - -
f53180cf by Thomas Guillem at 2023-12-22T15:55:41+00:00
input: add on_attachments_added event to the parser
- - - - -
8499dd99 by Thomas Guillem at 2023-12-22T15:55:41+00:00
preparser: add on_attachments_added
- - - - -
32a94365 by Thomas Guillem at 2023-12-22T15:55:41+00:00
medialibrary: use on_attachments_added
- - - - -
dd7cdf2d by Thomas Guillem at 2023-12-22T15:55:41+00:00
lib: picture: add const
- - - - -
23a5842c by Thomas Guillem at 2023-12-22T15:55:41+00:00
lib: media: use on_attachments_added
- - - - -
a6f45882 by Thomas Guillem at 2023-12-22T15:55:41+00:00
player: add on_media_attachments_added event
- - - - -
48ed9b94 by Thomas Guillem at 2023-12-22T15:55:41+00:00
mock: add attachments support
- - - - -
182c1b63 by Thomas Guillem at 2023-12-22T15:55:41+00:00
mock: add some meta
- - - - -
08e5bcf3 by Thomas Guillem at 2023-12-22T15:55:41+00:00
test: player: test on_media_attachments_added
- - - - -
17 changed files:
- include/vlc_input_item.h
- include/vlc_player.h
- lib/media.c
- lib/picture.c
- lib/picture_internal.h
- modules/demux/mock.c
- modules/gui/qt/dialogs/dialogs_provider.cpp
- modules/gui/qt/player/player_controller.cpp
- modules/misc/medialibrary/MetadataExtractor.cpp
- modules/misc/medialibrary/fs/directory.cpp
- modules/misc/medialibrary/medialibrary.h
- src/input/input.c
- src/input/input_internal.h
- src/input/item.c
- src/player/input.c
- src/preparser/preparser.c
- test/src/player/player.c
Changes:
=====================================
include/vlc_input_item.h
=====================================
@@ -444,6 +444,23 @@ typedef struct input_item_parser_cbs_t
* @param userdata user data set by input_item_Parse()
*/
void (*on_subtree_added)(input_item_t *item, input_item_node_t *subtree, void *userdata);
+
+ /**
+ * Event received when new attachments are added
+ *
+ * @note This callback is optional. It can be called several times for one
+ * parse request. The array contains only new elements after a second call.
+ *
+ * @param item the parsed item
+ * @param array valid array containing new elements, should only be used
+ * within the callback. One and all elements can be held and stored on a
+ * new variable or new array.
+ * @param count number of elements in the array
+ * @param userdata user data set by input_item_Parse()
+ */
+ void (*on_attachments_added)(input_item_t *item,
+ input_attachment_t *const *array,
+ size_t count, void *userdata);
} input_item_parser_cbs_t;
/**
@@ -513,6 +530,9 @@ struct vlc_metadata_cbs {
void (*on_preparse_ended)(input_item_t *, enum input_item_preparse_status status, void *userdata);
void (*on_art_fetch_ended)(input_item_t *, bool fetched, void *userdata);
void (*on_subtree_added)(input_item_t *, input_item_node_t *subtree, void *userdata);
+ void (*on_attachments_added)(input_item_t *item,
+ input_attachment_t *const *array,
+ size_t count, void *userdata);
};
VLC_API int libvlc_MetadataRequest( libvlc_int_t *, input_item_t *,
=====================================
include/vlc_player.h
=====================================
@@ -3186,6 +3186,24 @@ struct vlc_player_cbs
void (*on_media_subitems_changed)(vlc_player_t *player,
input_item_t *media, input_item_node_t *new_subitems, void *data);
+ /**
+ * Called when new attachments are added to the media
+ *
+ * @note It can be called several times for one parse request. The array
+ * contains only new elements after a second call.
+ *
+ * @param player locked player instance
+ * @param media current media
+ * @param array valid array containing new elements, should only be used
+ * within the callback. One and all elements can be held and stored on a
+ * new variable or new array.
+ * @param count number of elements in the array
+ * @param data opaque pointer set by vlc_player_AddListener()
+ */
+ void (*on_media_attachments_added)(vlc_player_t *player,
+ input_item_t *media, input_attachment_t *const *array, size_t count,
+ void *data);
+
/**
* Called when a vout is started or stopped
*
=====================================
lib/media.c
=====================================
@@ -310,15 +310,16 @@ static void input_item_duration_changed( const vlc_event_t *p_event,
libvlc_event_send( &p_md->event_manager, &event );
}
-static void input_item_attachments_found( const vlc_event_t *p_event,
- void * user_data )
+static void input_item_attachments_added( input_item_t *item,
+ input_attachment_t *const *array,
+ size_t count, void *user_data )
{
+ VLC_UNUSED(item);
libvlc_media_t * p_md = user_data;
libvlc_event_t event;
- libvlc_picture_list_t* list = libvlc_picture_list_from_attachments(
- p_event->u.input_item_attachments_found.attachments,
- p_event->u.input_item_attachments_found.count );
+ libvlc_picture_list_t* list =
+ libvlc_picture_list_from_attachments(array, count);
if( !list )
return;
if( !libvlc_picture_list_count(list) )
@@ -409,10 +410,6 @@ static void install_input_item_observer( libvlc_media_t *p_md )
vlc_InputItemDurationChanged,
input_item_duration_changed,
p_md );
- vlc_event_attach( &p_md->p_input_item->event_manager,
- vlc_InputItemAttachmentsFound,
- input_item_attachments_found,
- p_md );
}
/**
@@ -429,10 +426,6 @@ static void uninstall_input_item_observer( libvlc_media_t *p_md )
vlc_InputItemDurationChanged,
input_item_duration_changed,
p_md );
- vlc_event_detach( &p_md->p_input_item->event_manager,
- vlc_InputItemAttachmentsFound,
- input_item_attachments_found,
- p_md );
}
/**
@@ -826,6 +819,7 @@ libvlc_media_get_filestat( libvlc_media_t *p_md, unsigned type, uint64_t *out )
static const struct vlc_metadata_cbs preparser_callbacks = {
.on_preparse_ended = input_item_preparse_ended,
.on_subtree_added = input_item_subtree_added,
+ .on_attachments_added = input_item_attachments_added,
};
int libvlc_media_parse_request(libvlc_instance_t *inst, libvlc_media_t *media,
=====================================
lib/picture.c
=====================================
@@ -208,7 +208,7 @@ libvlc_time_t libvlc_picture_get_time( const libvlc_picture_t* pic )
return pic->time;
}
-libvlc_picture_list_t* libvlc_picture_list_from_attachments( input_attachment_t** attachments,
+libvlc_picture_list_t* libvlc_picture_list_from_attachments( input_attachment_t* const* attachments,
size_t nb_attachments )
{
size_t size = 0;
=====================================
lib/picture_internal.h
=====================================
@@ -44,7 +44,7 @@ libvlc_picture_t* libvlc_picture_new( vlc_object_t* p_obj, picture_t* p_pic,
unsigned int i_width, unsigned int i_height,
bool b_crop );
-libvlc_picture_list_t* libvlc_picture_list_from_attachments( input_attachment_t** attachments,
+libvlc_picture_list_t* libvlc_picture_list_from_attachments( input_attachment_t* const* attachments,
size_t nb_attachments );
#endif /* PICTURE_INTERNAL_H */
=====================================
modules/demux/mock.c
=====================================
@@ -223,6 +223,7 @@ var_Read_float(const char *psz)
X(chapter_count, ssize_t, add_integer, Ssize, 0) \
X(null_names, bool, add_bool, Bool, false) \
X(program_count, ssize_t, add_integer, Ssize, 0) \
+ X(attachment_count, ssize_t, add_integer, Ssize, 0) \
X(can_seek, bool, add_bool, Bool, true) \
X(can_pause, bool, add_bool, Bool, true) \
X(can_control_pace, bool, add_bool, Bool, true) \
@@ -310,6 +311,8 @@ struct demux_sys
struct mock_video_options video;
struct mock_audio_options audio;
struct mock_sub_options sub;
+
+ char *art_url;
};
#undef X
@@ -359,6 +362,100 @@ CreateTitle(demux_t *demux, size_t idx)
return t;
}
+static input_attachment_t *
+CreateAttachment(demux_t *demux, const char *prefix_name, size_t index)
+{
+ input_attachment_t *attach = NULL;
+ picture_t *pic = NULL;
+ block_t *block = NULL;
+
+ char *name;
+ int ret = asprintf(&name, "%s %zu", prefix_name, index);
+ if (ret < 0)
+ return NULL;
+
+ pic = picture_New(VLC_CODEC_RGB24, 100, 100, 1, 1);
+ if (pic == NULL)
+ goto end;
+
+ memset(pic->p[0].p_pixels, 0x80, pic->p[0].i_lines * pic->p[0].i_pitch);
+
+ ret = picture_Export(VLC_OBJECT(demux), &block, NULL, pic, VLC_CODEC_BMP,
+ 0, 0, false);
+ if (ret != VLC_SUCCESS)
+ goto end;
+
+ attach = vlc_input_attachment_New(name, "image/bmp", "Mock Attach Desc",
+ block->p_buffer, block->i_buffer);
+
+end:
+ if (block != NULL)
+ block_Release(block);
+ if (pic != NULL)
+ picture_Release(pic);
+ free(name);
+ return attach;
+}
+
+static int
+GetAttachments(demux_t *demux, input_attachment_t ***attach_array_p,
+ int *attach_count_p)
+{
+ struct demux_sys *sys = demux->p_sys;
+ assert(sys->attachment_count > 0);
+ size_t attachment_count = sys->attachment_count;
+
+ input_attachment_t **attach_array =
+ vlc_alloc(sys->attachment_count, sizeof(*attach_array));
+ if (attach_array == NULL)
+ return VLC_ENOMEM;
+
+ for (size_t i = 0; i < attachment_count; i++)
+ {
+ attach_array[i] = CreateAttachment(demux, "Mock Attach", i);
+
+ if (attach_array[i] == NULL)
+ {
+ if (i == 0)
+ {
+ free(attach_array);
+ return VLC_ENOMEM;
+ }
+ *attach_array_p = attach_array;
+ *attach_count_p = i;
+ return VLC_SUCCESS;
+ }
+
+ if (sys->art_url == NULL
+ && asprintf(&sys->art_url, "attachment://%s",
+ attach_array[i]->psz_name) == -1)
+ sys->art_url = NULL;
+ }
+
+ *attach_array_p = attach_array;
+ *attach_count_p = sys->attachment_count;
+
+ return VLC_SUCCESS;
+}
+
+static vlc_meta_t *
+CreateMeta(demux_t *demux)
+{
+ struct demux_sys *sys = demux->p_sys;
+
+ vlc_meta_t *meta = vlc_meta_New();
+ if (meta == NULL)
+ return NULL;
+
+ vlc_meta_SetArtist(meta, "VideoLAN");
+ vlc_meta_SetGenre(meta, "Best Media Player");
+
+ if (sys->art_url != NULL)
+ vlc_meta_SetArtURL(meta, sys->art_url);
+
+ return meta;
+}
+
static int
Control(demux_t *demux, int query, va_list args)
{
@@ -379,7 +476,15 @@ Control(demux_t *demux, int query, va_list args)
*va_arg(args, vlc_tick_t *) = sys->pts_delay;
return VLC_SUCCESS;
case DEMUX_GET_META:
- return VLC_EGENERIC;
+ {
+ vlc_meta_t *meta_out = va_arg(args, vlc_meta_t *);
+ vlc_meta_t *meta = CreateMeta(demux);
+ if (meta == NULL)
+ return VLC_ENOMEM;
+ vlc_meta_Merge(meta_out, meta);
+ vlc_meta_Delete(meta);
+ return VLC_SUCCESS;
+ }
case DEMUX_GET_SIGNAL:
return VLC_EGENERIC;
case DEMUX_SET_PAUSE_STATE:
@@ -492,7 +597,14 @@ Control(demux_t *demux, int query, va_list args)
case DEMUX_HAS_UNSUPPORTED_META:
return VLC_EGENERIC;
case DEMUX_GET_ATTACHMENTS:
- return VLC_EGENERIC;
+ {
+ input_attachment_t ***attach_array_p = va_arg(args, input_attachment_t***);
+ int *attach_count_p = va_arg(args, int *);
+ if (sys->attachment_count <= 0)
+ return VLC_EGENERIC;
+
+ return GetAttachments(demux, attach_array_p, attach_count_p);
+ }
case DEMUX_CAN_RECORD:
*va_arg(args, bool *) = sys->can_record;
return VLC_SUCCESS;
@@ -1313,6 +1425,8 @@ Close(vlc_object_t *obj)
DeleteTrack(demux, track);
}
vlc_vector_clear(&sys->tracks);
+
+ free(sys->art_url);
}
static int
@@ -1337,6 +1451,7 @@ Open(vlc_object_t *obj)
OPTIONS_AUDIO(READ_SUBOPTION)
OPTIONS_VIDEO(READ_SUBOPTION)
OPTIONS_SUB(READ_SUBOPTION)
+ sys->art_url = NULL;
if (sys->node_count > 0)
{
=====================================
modules/gui/qt/dialogs/dialogs_provider.cpp
=====================================
@@ -403,7 +403,9 @@ void DialogsProvider::mediaInfoDialog( const MLItemId& itemId )
}, Qt::QueuedConnection );
},
// on_subtree_added
- NULL
+ NULL,
+ // on_attachments_added
+ NULL,
};
input_item_parser_id_t * const parser = input_item_Parse( inputItem, VLC_OBJECT( p_intf ), &cbs, this );
=====================================
modules/gui/qt/player/player_controller.cpp
=====================================
@@ -1024,6 +1024,7 @@ static const struct vlc_player_cbs player_cbs = {
on_player_media_meta_changed,
on_player_media_epg_changed,
on_player_subitems_changed,
+ nullptr, // on_media_attachments_added: not used
on_player_vout_changed,
on_player_corks_changed,
on_player_playback_restore_queried,
=====================================
modules/misc/medialibrary/MetadataExtractor.cpp
=====================================
@@ -187,12 +187,14 @@ void MetadataExtractor::onParserSubtreeAdded( input_item_t *,
ctx->mde->addSubtree( *ctx, subtree );
}
-void MetadataExtractor::onAttachmentFound( const vlc_event_t* p_event, void* data )
+void MetadataExtractor::onAttachmentsAdded( input_item_t *,
+ input_attachment_t *const *array,
+ size_t count, void *data )
{
auto ctx = static_cast<ParseContext*>( data );
- for ( auto i = 0u; i < p_event->u.input_item_attachments_found.count; ++i )
+ for ( auto i = 0u; i < count; ++i )
{
- auto a = p_event->u.input_item_attachments_found.attachments[i];
+ auto a = array[i];
auto fcc = image_Mime2Fourcc( a->psz_mime );
if ( fcc != VLC_CODEC_PNG && fcc != VLC_CODEC_JPEG )
continue;
@@ -222,13 +224,10 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
if ( ctx.inputItem == nullptr )
return medialibrary::parser::Status::Fatal;
- if ( vlc_event_attach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
- &MetadataExtractor::onAttachmentFound, &ctx ) != VLC_SUCCESS )
- return medialibrary::parser::Status::Fatal;
-
const input_item_parser_cbs_t cbs = {
&MetadataExtractor::onParserEnded,
&MetadataExtractor::onParserSubtreeAdded,
+ &MetadataExtractor::onAttachmentsAdded,
};
m_currentCtx = &ctx;
ctx.inputItem->i_preparse_depth = 1;
@@ -239,8 +238,6 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
};
if ( ctx.inputParser == nullptr )
{
- vlc_event_detach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
- &MetadataExtractor::onAttachmentFound, &ctx );
m_currentCtx = nullptr;
return medialibrary::parser::Status::Fatal;
}
@@ -260,8 +257,6 @@ medialibrary::parser::Status MetadataExtractor::run( medialibrary::parser::IItem
}
m_currentCtx = nullptr;
}
- vlc_event_detach( &ctx.inputItem->event_manager, vlc_InputItemAttachmentsFound,
- &MetadataExtractor::onAttachmentFound, &ctx );
if ( !ctx.success || ctx.inputParser == nullptr )
return medialibrary::parser::Status::Fatal;
=====================================
modules/misc/medialibrary/fs/directory.cpp
=====================================
@@ -167,6 +167,7 @@ static bool request_metadata_sync( libvlc_int_t *libvlc, input_item_t *media,
static const input_item_parser_cbs_t cbs = {
onParserEnded,
onParserSubtreeAdded,
+ nullptr,
};
auto inputParser = vlc::wrap_cptr( input_item_Parse( media, VLC_OBJECT( libvlc ), &cbs, &req ),
=====================================
modules/misc/medialibrary/medialibrary.h
=====================================
@@ -106,7 +106,9 @@ private:
static void onParserEnded( input_item_t *, int status, void *user_data );
static void onParserSubtreeAdded( input_item_t *, input_item_node_t *subtree,
void *user_data );
- static void onAttachmentFound( const vlc_event_t* p_event, void* data );
+ static void onAttachmentsAdded( input_item_t *,
+ input_attachment_t *const *array,
+ size_t count, void *data );
private:
vlc::threads::condition_variable m_cond;
=====================================
src/input/input.c
=====================================
@@ -3116,6 +3116,12 @@ static void AppendAttachment( input_thread_t *p_input, int i_new,
.type = vlc_InputItemAttachmentsFound,
.u.input_item_attachments_found.attachments = pp_new,
.u.input_item_attachments_found.count = i_new } );
+
+ input_SendEvent(p_input, &(struct vlc_input_event) {
+ .type = INPUT_EVENT_ATTACHMENTS,
+ .attachments = { .array = pp_new, .count = i_new },
+ });
+
free( pp_new );
return;
}
=====================================
src/input/input_internal.h
=====================================
@@ -142,6 +142,9 @@ typedef enum input_event_type_e
/* Thumbnail generation */
INPUT_EVENT_THUMBNAIL_READY,
+
+ /* Attachments */
+ INPUT_EVENT_ATTACHMENTS,
} input_event_type_e;
#define VLC_INPUT_CAPABILITIES_SEEKABLE (1<<0)
@@ -256,6 +259,12 @@ struct vlc_input_event_vout
vlc_es_id_t *id;
};
+struct vlc_input_event_attachments
+{
+ input_attachment_t *const* array;
+ size_t count;
+};
+
struct vlc_input_event
{
input_event_type_e type;
@@ -299,6 +308,8 @@ struct vlc_input_event
float subs_fps;
/* INPUT_EVENT_THUMBNAIL_READY */
picture_t *thumbnail;
+ /* INPUT_EVENT_ATTACHMENTS */
+ struct vlc_input_event_attachments attachments;
};
};
=====================================
src/input/item.c
=====================================
@@ -1414,6 +1414,13 @@ input_item_parser_InputEvent(input_thread_t *input,
parser->cbs->on_subtree_added(input_GetItem(input),
event->subitems, parser->userdata);
break;
+ case INPUT_EVENT_ATTACHMENTS:
+ if (parser->cbs->on_attachments_added != NULL)
+ parser->cbs->on_attachments_added(input_GetItem(input),
+ event->attachments.array,
+ event->attachments.count,
+ parser->userdata);
+ break;
default:
break;
}
=====================================
src/player/input.c
=====================================
@@ -888,6 +888,12 @@ input_thread_Events(input_thread_t *input_thread,
vlc_player_SendEvent(player, on_teletext_transparency_changed,
input->teletext_transparent);
break;
+ case INPUT_EVENT_ATTACHMENTS:
+ vlc_player_SendEvent(player, on_media_attachments_added,
+ input_GetItem(input->thread),
+ event->attachments.array,
+ event->attachments.count);
+ break;
default:
break;
}
=====================================
src/preparser/preparser.c
=====================================
@@ -171,6 +171,27 @@ OnParserSubtreeAdded(input_item_t *item, input_item_node_t *subtree,
task->cbs->on_subtree_added(task->item, subtree, task->userdata);
}
+static void
+OnParserAttachmentsAdded(input_item_t *item,
+ input_attachment_t *const *array,
+ size_t count, void *task_)
+{
+ VLC_UNUSED(item);
+ struct task *task = task_;
+
+ if (task->cbs && task->cbs->on_attachments_added)
+ task->cbs->on_attachments_added(task->item, array, count, task->userdata);
+}
+
+static void
+SetItemPreparsed(struct task *task)
+{
+ int status = atomic_load_explicit(&task->preparse_status,
+ memory_order_relaxed);
+ if (status == ITEM_PREPARSE_DONE)
+ input_item_SetPreparsed(task->item);
+}
+
static void
OnArtFetchEnded(input_item_t *item, bool fetched, void *userdata)
{
@@ -180,7 +201,7 @@ OnArtFetchEnded(input_item_t *item, bool fetched, void *userdata)
struct task *task = userdata;
if (!atomic_load(&task->interrupted))
- input_item_SetPreparsed(task->item);
+ SetItemPreparsed(task);
NotifyPreparseEnded(task, fetched);
TaskDelete(task);
@@ -196,6 +217,7 @@ Parse(struct task *task, vlc_tick_t deadline)
static const input_item_parser_cbs_t cbs = {
.on_ended = OnParserEnded,
.on_subtree_added = OnParserSubtreeAdded,
+ .on_attachments_added = OnParserAttachmentsAdded,
};
vlc_object_t *obj = task->preparser->owner;
@@ -268,7 +290,7 @@ RunnableRun(void *userdata)
return; /* Remove the task and notify from the fetcher callback */
if (!atomic_load(&task->interrupted))
- input_item_SetPreparsed(task->item);
+ SetItemPreparsed(task);
end:
NotifyPreparseEnded(task, false);
=====================================
test/src/player/player.c
=====================================
@@ -118,6 +118,12 @@ struct report_media_subitems
input_item_t **items;
};
+struct report_media_attachments
+{
+ input_attachment_t **array;
+ size_t count;
+};
+
#define REPORT_LIST \
X(input_item_t *, on_current_media_changed) \
X(enum vlc_player_state, on_state_changed) \
@@ -146,6 +152,7 @@ struct report_media_subitems
X(input_item_t *, on_media_meta_changed) \
X(input_item_t *, on_media_epg_changed) \
X(struct report_media_subitems, on_media_subitems_changed) \
+ X(struct report_media_attachments, on_media_attachments_added) \
struct report_timer
{
@@ -204,6 +211,7 @@ struct media_params
size_t title_count;
size_t chapter_count;
+ size_t attachment_count;
bool can_seek;
bool can_pause;
@@ -227,6 +235,7 @@ struct media_params
.video_frame_rate_base = 1, \
.title_count = 0, \
.chapter_count = 0, \
+ .attachment_count = 0, \
.can_seek = true, \
.can_pause = true, \
.error = false, \
@@ -583,6 +592,25 @@ player_on_media_subitems_changed(vlc_player_t *player, input_item_t *media,
VEC_PUSH(on_media_subitems_changed, report);
}
+static void
+player_on_media_attachments_added(vlc_player_t *player,
+ input_item_t *media,
+ input_attachment_t *const *array, size_t count,
+ void *data)
+{
+ (void) media;
+ struct ctx *ctx = get_ctx(player, data);
+
+ struct report_media_attachments report = {
+ .array = vlc_alloc(count, sizeof(input_attachment_t *)),
+ .count = count,
+ };
+ assert(report.array);
+ for (size_t i = 0; i < count; ++i)
+ report.array[i] = vlc_input_attachment_Hold(array[i]);
+ VEC_PUSH(on_media_attachments_added, report);
+}
+
#define VEC_LAST(vec) (vec)->data[(vec)->size - 1]
#define assert_position(ctx, report) do { \
assert(fabs((report)->pos - (report)->time / (float) ctx->params.length) < 0.001); \
@@ -713,6 +741,16 @@ ctx_reset(struct ctx *ctx)
free(report.items);
}
}
+
+ {
+ struct report_media_attachments report;
+ FOREACH_VEC(report, on_media_attachments_added)
+ {
+ for (size_t i = 0; i < report.count; ++i)
+ vlc_input_attachment_Release(report.array[i]);
+ free(report.array);
+ }
+ }
#undef CLEAN_MEDIA_VEC
#undef FOREACH_VEC
@@ -755,7 +793,7 @@ create_mock_media(const char *name, const struct media_params *params)
"video_frame_rate=%u;video_frame_rate_base=%u;"
"title_count=%zu;chapter_count=%zu;"
"can_seek=%d;can_pause=%d;error=%d;null_names=%d;"
- "config=%s",
+ "config=%s;attachment_count=%zu",
params->track_count[VIDEO_ES], params->track_count[AUDIO_ES],
params->track_count[SPU_ES], params->program_count,
params->video_packetized, params->audio_packetized,
@@ -763,7 +801,7 @@ create_mock_media(const char *name, const struct media_params *params)
params->video_frame_rate, params->video_frame_rate_base,
params->title_count, params->chapter_count,
params->can_seek, params->can_pause, params->error, params->null_names,
- params->config ? params->config : "");
+ params->config ? params->config : "", params->attachment_count);
assert(ret != -1);
input_item_t *item = input_item_New(url, name);
assert(item);
@@ -2843,6 +2881,45 @@ test_teletext(struct ctx *ctx)
#endif
}
+static void
+test_attachments(struct ctx *ctx)
+{
+ test_log("attachments\n");
+
+ vlc_player_t *player = ctx->player;
+
+ struct media_params params = DEFAULT_MEDIA_PARAMS(VLC_TICK_FROM_SEC(1));
+ params.attachment_count = 99;
+ player_set_next_mock_media(ctx, "media1", ¶ms);
+
+ player_start(ctx);
+
+ vec_on_media_attachments_added *vec = &ctx->report.on_media_attachments_added;
+
+ while (vec->size == 0)
+ vlc_player_CondWait(player, &ctx->wait);
+
+ input_attachment_t **array = vec->data[0].array;
+ size_t count = vec->data[0].count;
+
+ assert(count == params.attachment_count);
+
+ for (size_t i = 0; i < count; ++i)
+ {
+ input_attachment_t *attach = array[i];
+ assert(strcmp(attach->psz_mime, "image/bmp") == 0);
+ assert(strcmp(attach->psz_description, "Mock Attach Desc") == 0);
+
+ char *name;
+ int ret = asprintf(&name, "Mock Attach %zu", i);
+ assert(ret > 0);
+ assert(strcmp(attach->psz_name, name) == 0);
+ free(name);
+ }
+
+ test_end(ctx);
+}
+
static void
test_audio_loudness_meter_cb(vlc_tick_t date, double momentary_loudness,
void *data)
@@ -2994,6 +3071,7 @@ main(void)
test_programs(&ctx);
test_timers(&ctx);
test_teletext(&ctx);
+ test_attachments(&ctx);
test_delete_while_playback(VLC_OBJECT(ctx.vlc->p_libvlc_int), true);
test_delete_while_playback(VLC_OBJECT(ctx.vlc->p_libvlc_int), false);
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dbe399b593d76d722afadac8272d5939b4c20059...08e5bcf35185893ac70f95f2332c91b0242f536a
--
View it on GitLab: https://code.videolan.org/videolan/vlc/-/compare/dbe399b593d76d722afadac8272d5939b4c20059...08e5bcf35185893ac70f95f2332c91b0242f536a
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance
More information about the vlc-commits
mailing list