mirror of
https://github.com/owntone/owntone-server.git
synced 2024-12-27 07:35:57 -05:00
Add seek support to transcode
This commit is contained in:
parent
9fb7ec8e5c
commit
17daace67f
@ -245,6 +245,81 @@ transcode(struct transcode_ctx *ctx, struct evbuffer *evbuf, int wanted)
|
||||
return processed;
|
||||
}
|
||||
|
||||
int
|
||||
transcode_seek(struct transcode_ctx *ctx, int ms)
|
||||
{
|
||||
int64_t start_time;
|
||||
int64_t target_pts;
|
||||
int64_t got_pts;
|
||||
int got_ms;
|
||||
int flags;
|
||||
int ret;
|
||||
|
||||
target_pts = ms * AV_TIME_BASE / 1000;
|
||||
target_pts = av_rescale_q(target_pts, AV_TIME_BASE_Q, ctx->fmtctx->streams[ctx->astream]->time_base);
|
||||
|
||||
start_time = ctx->fmtctx->streams[ctx->astream]->start_time;
|
||||
|
||||
if ((start_time != AV_NOPTS_VALUE) && (start_time > 0))
|
||||
target_pts += start_time;
|
||||
|
||||
ret = av_seek_frame(ctx->fmtctx, ctx->astream, target_pts, AVSEEK_FLAG_BACKWARD);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_XCODE, "Could not seek into stream: %s\n", strerror(AVUNERROR(ret)));
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
avcodec_flush_buffers(ctx->acodec);
|
||||
|
||||
ctx->acodec->hurry_up = 1;
|
||||
flags = 0;
|
||||
while (1)
|
||||
{
|
||||
if (ctx->apacket.data)
|
||||
av_free_packet(&ctx->apacket);
|
||||
|
||||
ret = av_read_frame(ctx->fmtctx, &ctx->apacket);
|
||||
if (ret < 0)
|
||||
{
|
||||
DPRINTF(E_WARN, L_XCODE, "Could not read more data while seeking\n");
|
||||
|
||||
flags = 1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (ctx->apacket.stream_index != ctx->astream)
|
||||
continue;
|
||||
|
||||
/* Need a pts to return the real position */
|
||||
if (ctx->apacket.pts == AV_NOPTS_VALUE)
|
||||
continue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
/* Error while reading frame above */
|
||||
if (flags)
|
||||
return -1;
|
||||
|
||||
/* Copy apacket data & size and do not mess with them */
|
||||
ctx->apacket_data = ctx->apacket.data;
|
||||
ctx->apacket_size = ctx->apacket.size;
|
||||
|
||||
/* Compute position in ms from pts */
|
||||
if ((start_time != AV_NOPTS_VALUE) && (start_time > 0))
|
||||
got_pts -= start_time;
|
||||
|
||||
got_pts = av_rescale_q(ctx->apacket.pts, ctx->fmtctx->streams[ctx->astream]->time_base, AV_TIME_BASE_Q);
|
||||
got_ms = got_pts / (AV_TIME_BASE / 1000);
|
||||
|
||||
DPRINTF(E_DBG, L_XCODE, "Seek wanted %d ms, got %d ms\n", ms, got_ms);
|
||||
|
||||
return got_ms;
|
||||
}
|
||||
|
||||
|
||||
struct transcode_ctx *
|
||||
transcode_setup(struct media_file_info *mfi, off_t *est_size, int wavhdr)
|
||||
{
|
||||
|
@ -9,6 +9,9 @@ struct transcode_ctx;
|
||||
int
|
||||
transcode(struct transcode_ctx *ctx, struct evbuffer *evbuf, int wanted);
|
||||
|
||||
int
|
||||
transcode_seek(struct transcode_ctx *ctx, int ms);
|
||||
|
||||
struct transcode_ctx *
|
||||
transcode_setup(struct media_file_info *mfi, off_t *est_size, int wavhdr);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user