|
|
|
@ -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 |
|
|
|
|