|
|
|
|
@ -115,6 +115,7 @@ struct media_player *media_player_new(struct call_monologue *ml) {
|
|
|
|
|
|
|
|
|
|
mp->tt_obj.tt = &media_player_thread;
|
|
|
|
|
mutex_init(&mp->lock);
|
|
|
|
|
|
|
|
|
|
mp->run_func = media_player_read_packet; // default
|
|
|
|
|
mp->call = obj_get(ml->call);
|
|
|
|
|
mp->ml = ml;
|
|
|
|
|
@ -386,11 +387,28 @@ static void media_player_read_packet(struct media_player *mp) {
|
|
|
|
|
int ret = av_read_frame(mp->fmtctx, &mp->pkt);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
if (ret == AVERROR_EOF) {
|
|
|
|
|
ilog(LOG_DEBUG, "EOF reading from media stream");
|
|
|
|
|
if (mp->repeat > 1){
|
|
|
|
|
ilog(LOG_DEBUG, "EOF reading from media stream but will repeat %li time",mp->repeat);
|
|
|
|
|
mp->repeat = mp->repeat - 1;
|
|
|
|
|
int64_t ret64 = avio_seek(mp->fmtctx->pb, 0, SEEK_SET);
|
|
|
|
|
if (ret64 != 0)
|
|
|
|
|
ilog(LOG_ERR, "Failed to seek to beginning of media file");
|
|
|
|
|
ret = av_seek_frame(mp->fmtctx, -1, 0, 0);
|
|
|
|
|
if (ret < 0)
|
|
|
|
|
ilog(LOG_ERR, "Failed to seek to beginning of media file");
|
|
|
|
|
ret = av_read_frame(mp->fmtctx, &mp->pkt);
|
|
|
|
|
} else {
|
|
|
|
|
ilog(LOG_DEBUG, "EOF reading from media stream");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
if (ret < 0 && ret != AVERROR_EOF) {
|
|
|
|
|
ilog(LOG_ERR, "Error while reading from media stream");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
ilog(LOG_ERR, "Error while reading from media stream");
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!mp->fmtctx->streams) {
|
|
|
|
|
@ -471,20 +489,22 @@ found:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// call->master_lock held in W
|
|
|
|
|
static void media_player_play_start(struct media_player *mp) {
|
|
|
|
|
static void media_player_play_start(struct media_player *mp, long long repeat) {
|
|
|
|
|
// needed to have usable duration for some formats. ignore errors.
|
|
|
|
|
avformat_find_stream_info(mp->fmtctx, NULL);
|
|
|
|
|
|
|
|
|
|
mp->next_run = rtpe_now;
|
|
|
|
|
// give ourselves a bit of a head start with decoding
|
|
|
|
|
timeval_add_usec(&mp->next_run, -50000);
|
|
|
|
|
|
|
|
|
|
media_player_read_packet(mp);
|
|
|
|
|
mp->repeat = repeat;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// call->master_lock held in W
|
|
|
|
|
int media_player_play_file(struct media_player *mp, const str *file) {
|
|
|
|
|
int media_player_play_file(struct media_player *mp, const str *file, long long repeat) {
|
|
|
|
|
#ifdef WITH_TRANSCODING
|
|
|
|
|
if (media_player_play_init(mp))
|
|
|
|
|
return -1;
|
|
|
|
|
@ -498,7 +518,8 @@ int media_player_play_file(struct media_player *mp, const str *file) {
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
media_player_play_start(mp);
|
|
|
|
|
media_player_play_start(mp,repeat);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
#else
|
|
|
|
|
@ -555,7 +576,7 @@ static int64_t __mp_avio_seek(void *opaque, int64_t offset, int whence) {
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// call->master_lock held in W
|
|
|
|
|
int media_player_play_blob(struct media_player *mp, const str *blob) {
|
|
|
|
|
int media_player_play_blob(struct media_player *mp, const str *blob, long long repeat) {
|
|
|
|
|
#ifdef WITH_TRANSCODING
|
|
|
|
|
const char *err;
|
|
|
|
|
int av_ret = 0;
|
|
|
|
|
@ -593,7 +614,7 @@ int media_player_play_blob(struct media_player *mp, const str *blob) {
|
|
|
|
|
if (av_ret < 0)
|
|
|
|
|
goto err;
|
|
|
|
|
|
|
|
|
|
media_player_play_start(mp);
|
|
|
|
|
media_player_play_start(mp,repeat);
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
@ -630,7 +651,7 @@ err:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// call->master_lock held in W
|
|
|
|
|
int media_player_play_db(struct media_player *mp, long long id) {
|
|
|
|
|
int media_player_play_db(struct media_player *mp, long long id, long long repeat) {
|
|
|
|
|
const char *err;
|
|
|
|
|
AUTO_CLEANUP_GBUF(query);
|
|
|
|
|
|
|
|
|
|
@ -677,7 +698,7 @@ success:;
|
|
|
|
|
|
|
|
|
|
str blob;
|
|
|
|
|
str_init_len(&blob, row[0], lengths[0]);
|
|
|
|
|
int ret = media_player_play_blob(mp, &blob);
|
|
|
|
|
int ret = media_player_play_blob(mp, &blob, repeat);
|
|
|
|
|
|
|
|
|
|
mysql_free_result(res);
|
|
|
|
|
|
|
|
|
|
@ -730,7 +751,6 @@ void media_player_free(void) {
|
|
|
|
|
|
|
|
|
|
#ifdef WITH_TRANSCODING
|
|
|
|
|
void media_player_loop(void *p) {
|
|
|
|
|
//ilog(LOG_DEBUG, "media_player_loop");
|
|
|
|
|
timerthread_run(&media_player_thread);
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
|