Commit e0b8107b authored by François Grisez's avatar François Grisez
Browse files

Add a render callback mechanism to the MS file player

parent 8a357b56
......@@ -3,13 +3,18 @@
#include "mssndcard.h"
#include "msinterfaces.h"
#include "msvideo.h"
/**
* @brief Media file player
*/
typedef struct _MSFilePlayer MSFilePlayer;
/**
* Callbacks definitions
*/
typedef void (*MSFilePlayerEofCallback)(void *user_data);
typedef void (*MSFilePlayerRenderCb)(MSPicture *picture, void *user_data);
/**
* @brief Instanciate a file player
......@@ -33,6 +38,17 @@ MS2_PUBLIC void ms_file_player_free(MSFilePlayer *obj);
*/
MS2_PUBLIC void ms_file_player_set_eof_callback(MSFilePlayer *obj, MSFilePlayerEofCallback cb, void *user_data);
/**
* @brief Set a callback to be notify that a buffer is ready to be render.
* If a callback is set, the video display specified by ms_file_player_new() will
* be disabled.
* @param obj The player
* @param cb Function to call
* @param user_data Data which will be passed to the function
* @return TRUE if successful
*/
MS2_PUBLIC bool_t ms_file_player_set_render_callback(MSFilePlayer *obj, MSFilePlayerRenderCb cb, void *user_data);
/**
* @brief Open a media file
* @param obj A pointer on a MSFilePlayer
......
#include "../../include/mediastreamer2/fileplayer.h"
#include "../../include/mediastreamer2/msfilter.h"
#include "../../include/mediastreamer2/msticker.h"
#include "../../include/mediastreamer2/msextdisplay.h"
#include "../audiofilters/waveheader.h"
#define ms_filter_destroy_and_reset(obj) \
......@@ -55,15 +56,18 @@ struct _MSFilePlayer {
ms_mutex_t cb_access;
MSSndCard *snd_card;
char *video_display;
MSFilePlayerRenderCb render_cb;
void *render_user_data;
};
static bool_t _get_format(const char *filepath, FileFormat *format);
static void _eof_filter_notify_cb(void *userdata, struct _MSFilter *f, unsigned int id, void *arg);
static void _create_decoders(MSFilePlayer *obj);
static void _create_sinks(MSFilePlayer *obj);
static void _destroy_graph(MSFilePlayer *obj);
static bool_t _link_all(MSFilePlayer *obj);
static void _unlink_all(MSFilePlayer *obj);
static void _eof_filter_notify_cb(void *userdata, struct _MSFilter *f, unsigned int id, void *arg);
static void _renderer_filter_notify_cb(void *user_data, struct _MSFilter *f, unsigned int id, void *arg);
static bool_t four_cc_compare(const FourCC arg1, const FourCC arg2) {
return arg1[0] == arg2[0]
......@@ -100,6 +104,16 @@ void ms_file_player_free(MSFilePlayer *obj) {
ms_free(obj);
}
bool_t ms_file_player_set_render_callback(MSFilePlayer *obj, MSFilePlayerRenderCb cb, void *user_data) {
if(obj->is_open) {
ms_error("MSFilePlayer: Render callback cannot be set when a file is open");
return FALSE;
}
obj->render_cb = cb;
obj->render_user_data = user_data;
return TRUE;
}
bool_t ms_file_player_open(MSFilePlayer *obj, const char *filepath) {
wave_header_t header;
int fd;
......@@ -337,10 +351,15 @@ static void _create_sinks(MSFilePlayer *obj) {
ms_error("Could not create audio sink. Soundcard=%s", obj->snd_card->name);
}
}
if(obj->video_pin_fmt.fmt && obj->video_display) {
obj->video_sink = ms_filter_new_from_name(obj->video_display);
if(obj->video_sink == NULL) {
ms_error("Could not create video sink: %s", obj->video_display);
if(obj->video_pin_fmt.fmt) {
if(obj->render_cb) {
obj->video_sink = ms_filter_new(MS_EXT_DISPLAY_ID);
ms_filter_add_notify_callback(obj->video_sink, _renderer_filter_notify_cb, obj, TRUE);
} else if(obj->video_display) {
obj->video_sink = ms_filter_new_from_name(obj->video_display);
if(obj->video_sink == NULL) {
ms_error("Could not create video sink: %s", obj->video_display);
}
}
}
}
......@@ -407,3 +426,11 @@ static void _eof_filter_notify_cb(void *userdata, struct _MSFilter *f, unsigned
}
ms_mutex_unlock(&obj->cb_access);
}
static void _renderer_filter_notify_cb(void *user_data, struct _MSFilter *f, unsigned int id, void *arg) {
if(id == MS_EXT_DISPLAY_ON_DRAW) {
MSFilePlayer *player = (MSFilePlayer *)user_data;
MSExtDisplayOutput *pictures = (MSExtDisplayOutput *)arg;
player->render_cb(&pictures->remote_view, player->render_user_data);
}
}
......@@ -2,6 +2,7 @@
#include "../include/mediastreamer2/fileplayer.h"
static int tester_init() {
ortp_set_log_level_mask(ORTP_MESSAGE | ORTP_WARNING | ORTP_ERROR | ORTP_FATAL);
ms_init();
return 0;
}
......@@ -30,6 +31,10 @@ static void eof_callback(void *user_data) {
ms_mutex_unlock(&obj->mutex);
}
static void render_callback(MSPicture *picture, void *user_data) {
(*(int *)user_data)++;
}
static void wait_for_eof(Eof *obj, int refresh_time_ms, int timeout_ms) {
ms_mutex_lock(&obj->mutex);
while(obj->time_ms < timeout_ms && !obj->eof) {
......@@ -41,9 +46,10 @@ static void wait_for_eof(Eof *obj, int refresh_time_ms, int timeout_ms) {
ms_mutex_unlock(&obj->mutex);
}
static void play_file(const char *filepath, bool_t unsupported_format) {
static void play_file(const char *filepath, bool_t unsupported_format, bool_t test_render_callback) {
bool_t succeed;
Eof eof;
int render_count = 0;
MSFilePlayer *file_player = NULL;
MSSndCard *snd_card = ms_snd_card_manager_get_default_card(ms_snd_card_manager_get());
const char *display_name = video_stream_get_default_video_renderer();
......@@ -55,6 +61,10 @@ static void play_file(const char *filepath, bool_t unsupported_format) {
if(file_player == NULL) return;
ms_file_player_set_eof_callback(file_player, eof_callback, &eof);
if(test_render_callback) {
succeed = ms_file_player_set_render_callback(file_player, render_callback, &render_count);
CU_ASSERT_TRUE(succeed);
}
succeed = ms_file_player_open(file_player, filepath);
if(unsupported_format) {
......@@ -77,39 +87,52 @@ static void play_file(const char *filepath, bool_t unsupported_format) {
ms_file_player_close(file_player);
ms_file_player_free(file_player);
CU_ASSERT_TRUE(eof.eof);
if(test_render_callback) {
CU_ASSERT_TRUE(render_count > 0);
}
}
static void play_hello_8000_wav(void) {
play_file("./sounds/hello8000.wav", FALSE);
play_file("./sounds/hello8000.wav", FALSE, FALSE);
}
static void play_hello_16000_wav(void) {
play_file("./sounds/hello16000.wav", FALSE);
play_file("./sounds/hello16000.wav", FALSE, FALSE);
}
static void play_hello_pcmu_mka(void) {
play_file("./sounds/hello_pcmu.mka", !ms_file_player_matroska_supported());
play_file("./sounds/hello_pcmu.mka", !ms_file_player_matroska_supported(), FALSE);
}
static void play_hello_opus_mka(void) {
play_file("./sounds/hello_opus.mka", !ms_file_player_matroska_supported());
play_file("./sounds/hello_opus.mka", !ms_file_player_matroska_supported(), FALSE);
}
static void play_hello_pcmu_h264_mkv(void) {
play_file("./sounds/hello_pcmu_h264.mkv", !ms_file_player_matroska_supported());
play_file("./sounds/hello_pcmu_h264.mkv", !ms_file_player_matroska_supported(), FALSE);
}
static void play_hello_opus_h264_mkv(void) {
play_file("./sounds/hello_opus_h264.mkv", !ms_file_player_matroska_supported());
play_file("./sounds/hello_opus_h264.mkv", !ms_file_player_matroska_supported(), FALSE);
}
static void play_sintel(void) {
play_file("./sounds/sintel.mkv", !ms_file_player_matroska_supported(), FALSE);
}
static void play_sintel_with_render_callback(void) {
play_file("./sounds/sintel.mkv", !ms_file_player_matroska_supported(), TRUE);
}
static test_t tests[] = {
{ "Play hello8000.wav" , play_hello_8000_wav },
{ "Play hello16000.wav" , play_hello_16000_wav },
{ "Play hello_pcmu.mka" , play_hello_pcmu_mka },
{ "Play hello_opus.mka" , play_hello_opus_mka },
{ "Play hello_pcmu_h264.mkv" , play_hello_pcmu_h264_mkv },
{ "Play hello_opus_h264.mkv" , play_hello_opus_h264_mkv }
{ "Play hello8000.wav" , play_hello_8000_wav },
{ "Play hello16000.wav" , play_hello_16000_wav },
{ "Play hello_pcmu.mka" , play_hello_pcmu_mka },
{ "Play hello_opus.mka" , play_hello_opus_mka },
{ "Play hello_pcmu_h264.mkv" , play_hello_pcmu_h264_mkv },
{ "Play hello_opus_h264.mkv" , play_hello_opus_h264_mkv },
{ "Play sintel" , play_sintel },
{ "Play sintel with render callback" , play_sintel_with_render_callback }
};
test_suite_t player_test_suite = {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment