Merge pull request #305 from chme/streamsetup
Reduce dependency to media file in stream setup methods
This commit is contained in:
commit
51e6008ef6
|
@ -491,7 +491,7 @@ httpd_stream_file(struct evhttp_request *req, int id)
|
||||||
|
|
||||||
stream_cb = stream_chunk_xcode_cb;
|
stream_cb = stream_chunk_xcode_cb;
|
||||||
|
|
||||||
st->xcode = transcode_setup(mfi, XCODE_PCM16_HEADER, &st->size);
|
st->xcode = transcode_setup(mfi->data_kind, mfi->path, mfi->song_length, XCODE_PCM16_HEADER, &st->size);
|
||||||
if (!st->xcode)
|
if (!st->xcode)
|
||||||
{
|
{
|
||||||
DPRINTF(E_WARN, L_HTTPD, "Transcoding setup failed, aborting streaming\n");
|
DPRINTF(E_WARN, L_HTTPD, "Transcoding setup failed, aborting streaming\n");
|
||||||
|
|
16
src/pipe.c
16
src/pipe.c
|
@ -41,36 +41,36 @@ static int g_fd = -1;
|
||||||
static uint16_t *g_buf = NULL;
|
static uint16_t *g_buf = NULL;
|
||||||
|
|
||||||
int
|
int
|
||||||
pipe_setup(struct media_file_info *mfi)
|
pipe_setup(const char *path)
|
||||||
{
|
{
|
||||||
struct stat sb;
|
struct stat sb;
|
||||||
|
|
||||||
if (!mfi->path)
|
if (!path)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Path to pipe is NULL\n");
|
DPRINTF(E_LOG, L_PLAYER, "Path to pipe is NULL\n");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_PLAYER, "Setting up pipe: %s\n", mfi->path);
|
DPRINTF(E_DBG, L_PLAYER, "Setting up pipe: %s\n", path);
|
||||||
|
|
||||||
if (lstat(mfi->path, &sb) < 0)
|
if (lstat(path, &sb) < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Could not lstat() '%s': %s\n", mfi->path, strerror(errno));
|
DPRINTF(E_LOG, L_PLAYER, "Could not lstat() '%s': %s\n", path, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISFIFO(sb.st_mode))
|
if (!S_ISFIFO(sb.st_mode))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Source type is pipe, but path is not a fifo: %s\n", mfi->path);
|
DPRINTF(E_LOG, L_PLAYER, "Source type is pipe, but path is not a fifo: %s\n", path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
pipe_cleanup();
|
pipe_cleanup();
|
||||||
|
|
||||||
g_fd = open(mfi->path, O_RDONLY | O_NONBLOCK);
|
g_fd = open(path, O_RDONLY | O_NONBLOCK);
|
||||||
if (g_fd < 0)
|
if (g_fd < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Could not open pipe for reading '%s': %s\n", mfi->path, strerror(errno));
|
DPRINTF(E_LOG, L_PLAYER, "Could not open pipe for reading '%s': %s\n", path, strerror(errno));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,9 @@
|
||||||
#define __PIPE_H__
|
#define __PIPE_H__
|
||||||
|
|
||||||
#include <event2/buffer.h>
|
#include <event2/buffer.h>
|
||||||
#include "db.h"
|
|
||||||
|
|
||||||
int
|
int
|
||||||
pipe_setup(struct media_file_info *mfi);
|
pipe_setup(const char *path);
|
||||||
|
|
||||||
void
|
void
|
||||||
pipe_cleanup(void);
|
pipe_cleanup(void);
|
||||||
|
|
|
@ -666,7 +666,7 @@ stream_setup(struct player_source *ps, struct media_file_info *mfi)
|
||||||
switch (ps->data_kind)
|
switch (ps->data_kind)
|
||||||
{
|
{
|
||||||
case DATA_KIND_FILE:
|
case DATA_KIND_FILE:
|
||||||
ps->xcode = transcode_setup(mfi, XCODE_PCM16_NOHEADER, NULL);
|
ps->xcode = transcode_setup(mfi->data_kind, mfi->path, mfi->song_length, XCODE_PCM16_NOHEADER, NULL);
|
||||||
ret = ps->xcode ? 0 : -1;
|
ret = ps->xcode ? 0 : -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -678,13 +678,13 @@ stream_setup(struct player_source *ps, struct media_file_info *mfi)
|
||||||
free(mfi->path);
|
free(mfi->path);
|
||||||
mfi->path = url;
|
mfi->path = url;
|
||||||
|
|
||||||
ps->xcode = transcode_setup(mfi, XCODE_PCM16_NOHEADER, NULL);
|
ps->xcode = transcode_setup(mfi->data_kind, mfi->path, mfi->song_length, XCODE_PCM16_NOHEADER, NULL);
|
||||||
ret = ps->xcode ? 0 : -1;
|
ret = ps->xcode ? 0 : -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATA_KIND_SPOTIFY:
|
case DATA_KIND_SPOTIFY:
|
||||||
#ifdef HAVE_SPOTIFY_H
|
#ifdef HAVE_SPOTIFY_H
|
||||||
ret = spotify_playback_setup(mfi);
|
ret = spotify_playback_setup(mfi->path);
|
||||||
#else
|
#else
|
||||||
DPRINTF(E_LOG, L_PLAYER, "Player source has data kind 'spotify' (%d), but forked-daapd is compiled without spotify support - cannot setup source '%s' (%s)\n",
|
DPRINTF(E_LOG, L_PLAYER, "Player source has data kind 'spotify' (%d), but forked-daapd is compiled without spotify support - cannot setup source '%s' (%s)\n",
|
||||||
ps->data_kind, mfi->title, mfi->path);
|
ps->data_kind, mfi->title, mfi->path);
|
||||||
|
@ -693,7 +693,7 @@ stream_setup(struct player_source *ps, struct media_file_info *mfi)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DATA_KIND_PIPE:
|
case DATA_KIND_PIPE:
|
||||||
ret = pipe_setup(mfi);
|
ret = pipe_setup(mfi->path);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -1643,16 +1643,16 @@ notify_cb(int fd, short what, void *arg)
|
||||||
|
|
||||||
/* Thread: player */
|
/* Thread: player */
|
||||||
int
|
int
|
||||||
spotify_playback_setup(struct media_file_info *mfi)
|
spotify_playback_setup(const char *path)
|
||||||
{
|
{
|
||||||
sp_link *link;
|
sp_link *link;
|
||||||
|
|
||||||
DPRINTF(E_DBG, L_SPOTIFY, "Playback setup request\n");
|
DPRINTF(E_DBG, L_SPOTIFY, "Playback setup request\n");
|
||||||
|
|
||||||
link = fptr_sp_link_create_from_string(mfi->path);
|
link = fptr_sp_link_create_from_string(path);
|
||||||
if (!link)
|
if (!link)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_SPOTIFY, "Playback setup failed, invalid Spotify link: %s\n", mfi->path);
|
DPRINTF(E_LOG, L_SPOTIFY, "Playback setup failed, invalid Spotify link: %s\n", path);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,12 +2,11 @@
|
||||||
#ifndef __SPOTIFY_H__
|
#ifndef __SPOTIFY_H__
|
||||||
#define __SPOTIFY_H__
|
#define __SPOTIFY_H__
|
||||||
|
|
||||||
#include "db.h"
|
|
||||||
#include <event2/event.h>
|
#include <event2/event.h>
|
||||||
#include <event2/buffer.h>
|
#include <event2/buffer.h>
|
||||||
|
|
||||||
int
|
int
|
||||||
spotify_playback_setup(struct media_file_info *mfi);
|
spotify_playback_setup(const char *path);
|
||||||
|
|
||||||
int
|
int
|
||||||
spotify_playback_play();
|
spotify_playback_play();
|
||||||
|
|
|
@ -580,7 +580,7 @@ flush_encoder(struct encode_ctx *ctx, unsigned int stream_index)
|
||||||
/* --------------------------- INPUT/OUTPUT INIT --------------------------- */
|
/* --------------------------- INPUT/OUTPUT INIT --------------------------- */
|
||||||
|
|
||||||
static int
|
static int
|
||||||
open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video)
|
open_input(struct decode_ctx *ctx, enum data_kind data_kind, const char *path, int decode_video)
|
||||||
{
|
{
|
||||||
AVDictionary *options;
|
AVDictionary *options;
|
||||||
AVCodec *decoder;
|
AVCodec *decoder;
|
||||||
|
@ -597,10 +597,10 @@ open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video
|
||||||
|
|
||||||
# ifndef HAVE_FFMPEG
|
# ifndef HAVE_FFMPEG
|
||||||
// Without this, libav is slow to probe some internet streams, which leads to RAOP timeouts
|
// Without this, libav is slow to probe some internet streams, which leads to RAOP timeouts
|
||||||
if (mfi->data_kind == DATA_KIND_HTTP)
|
if (data_kind == DATA_KIND_HTTP)
|
||||||
ctx->ifmt_ctx->probesize = 64000;
|
ctx->ifmt_ctx->probesize = 64000;
|
||||||
# endif
|
# endif
|
||||||
if (mfi->data_kind == DATA_KIND_HTTP)
|
if (data_kind == DATA_KIND_HTTP)
|
||||||
av_dict_set(&options, "icy", "1", 0);
|
av_dict_set(&options, "icy", "1", 0);
|
||||||
|
|
||||||
// TODO Newest versions of ffmpeg have timeout and reconnect options we should use
|
// TODO Newest versions of ffmpeg have timeout and reconnect options we should use
|
||||||
|
@ -608,14 +608,14 @@ open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video
|
||||||
ctx->ifmt_ctx->interrupt_callback.opaque = ctx;
|
ctx->ifmt_ctx->interrupt_callback.opaque = ctx;
|
||||||
ctx->timestamp = av_gettime();
|
ctx->timestamp = av_gettime();
|
||||||
|
|
||||||
ret = avformat_open_input(&ctx->ifmt_ctx, mfi->path, NULL, &options);
|
ret = avformat_open_input(&ctx->ifmt_ctx, path, NULL, &options);
|
||||||
|
|
||||||
if (options)
|
if (options)
|
||||||
av_dict_free(&options);
|
av_dict_free(&options);
|
||||||
|
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_XCODE, "Cannot open '%s': %s\n", mfi->path, err2str(ret));
|
DPRINTF(E_LOG, L_XCODE, "Cannot open '%s': %s\n", path, err2str(ret));
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -628,7 +628,7 @@ open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video
|
||||||
|
|
||||||
if (ctx->ifmt_ctx->nb_streams > MAX_STREAMS)
|
if (ctx->ifmt_ctx->nb_streams > MAX_STREAMS)
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_XCODE, "File '%s' has too many streams (%u)\n", mfi->path, ctx->ifmt_ctx->nb_streams);
|
DPRINTF(E_LOG, L_XCODE, "File '%s' has too many streams (%u)\n", path, ctx->ifmt_ctx->nb_streams);
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -636,7 +636,7 @@ open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video
|
||||||
stream_index = av_find_best_stream(ctx->ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &decoder, 0);
|
stream_index = av_find_best_stream(ctx->ifmt_ctx, AVMEDIA_TYPE_AUDIO, -1, -1, &decoder, 0);
|
||||||
if ((stream_index < 0) || (!decoder))
|
if ((stream_index < 0) || (!decoder))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_XCODE, "Did not find audio stream or suitable decoder for %s\n", mfi->path);
|
DPRINTF(E_LOG, L_XCODE, "Did not find audio stream or suitable decoder for %s\n", path);
|
||||||
goto out_fail;
|
goto out_fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -664,7 +664,7 @@ open_input(struct decode_ctx *ctx, struct media_file_info *mfi, int decode_video
|
||||||
stream_index = av_find_best_stream(ctx->ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
stream_index = av_find_best_stream(ctx->ifmt_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
|
||||||
if ((stream_index < 0) || (!decoder))
|
if ((stream_index < 0) || (!decoder))
|
||||||
{
|
{
|
||||||
DPRINTF(E_LOG, L_XCODE, "Did not find video stream or suitable decoder for '%s': %s\n", mfi->path, err2str(ret));
|
DPRINTF(E_LOG, L_XCODE, "Did not find video stream or suitable decoder for '%s': %s\n", path, err2str(ret));
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1231,7 +1231,7 @@ close_filters(struct encode_ctx *ctx)
|
||||||
/* Setup */
|
/* Setup */
|
||||||
|
|
||||||
struct decode_ctx *
|
struct decode_ctx *
|
||||||
transcode_decode_setup(struct media_file_info *mfi, int decode_video)
|
transcode_decode_setup(enum data_kind data_kind, const char *path, uint32_t song_length, int decode_video)
|
||||||
{
|
{
|
||||||
struct decode_ctx *ctx;
|
struct decode_ctx *ctx;
|
||||||
|
|
||||||
|
@ -1242,13 +1242,13 @@ transcode_decode_setup(struct media_file_info *mfi, int decode_video)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (open_input(ctx, mfi, decode_video) < 0)
|
if (open_input(ctx, data_kind, path, decode_video) < 0)
|
||||||
{
|
{
|
||||||
free(ctx);
|
free(ctx);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->duration = mfi->song_length;
|
ctx->duration = song_length;
|
||||||
|
|
||||||
av_init_packet(&ctx->packet);
|
av_init_packet(&ctx->packet);
|
||||||
|
|
||||||
|
@ -1292,7 +1292,7 @@ transcode_encode_setup(struct decode_ctx *src_ctx, enum transcode_profile profil
|
||||||
}
|
}
|
||||||
|
|
||||||
struct transcode_ctx *
|
struct transcode_ctx *
|
||||||
transcode_setup(struct media_file_info *mfi, enum transcode_profile profile, off_t *est_size)
|
transcode_setup(enum data_kind data_kind, const char *path, uint32_t song_length, enum transcode_profile profile, off_t *est_size)
|
||||||
{
|
{
|
||||||
struct transcode_ctx *ctx;
|
struct transcode_ctx *ctx;
|
||||||
|
|
||||||
|
@ -1303,7 +1303,7 @@ transcode_setup(struct media_file_info *mfi, enum transcode_profile profile, off
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx->decode_ctx = transcode_decode_setup(mfi, profile & XCODE_HAS_VIDEO);
|
ctx->decode_ctx = transcode_decode_setup(data_kind, path, song_length, profile & XCODE_HAS_VIDEO);
|
||||||
if (!ctx->decode_ctx)
|
if (!ctx->decode_ctx)
|
||||||
{
|
{
|
||||||
free(ctx);
|
free(ctx);
|
||||||
|
|
|
@ -28,13 +28,13 @@ struct decoded_frame;
|
||||||
|
|
||||||
// Setting up
|
// Setting up
|
||||||
struct decode_ctx *
|
struct decode_ctx *
|
||||||
transcode_decode_setup(struct media_file_info *mfi, int decode_video);
|
transcode_decode_setup(enum data_kind data_kind, const char *path, uint32_t song_length, int decode_video);
|
||||||
|
|
||||||
struct encode_ctx *
|
struct encode_ctx *
|
||||||
transcode_encode_setup(struct decode_ctx *src_ctx, enum transcode_profile profile, off_t *est_size);
|
transcode_encode_setup(struct decode_ctx *src_ctx, enum transcode_profile profile, off_t *est_size);
|
||||||
|
|
||||||
struct transcode_ctx *
|
struct transcode_ctx *
|
||||||
transcode_setup(struct media_file_info *mfi, enum transcode_profile profile, off_t *est_size);
|
transcode_setup(enum data_kind data_kind, const char *path, uint32_t song_length, enum transcode_profile profile, off_t *est_size);
|
||||||
|
|
||||||
struct decode_ctx *
|
struct decode_ctx *
|
||||||
transcode_decode_setup_raw(void);
|
transcode_decode_setup_raw(void);
|
||||||
|
|
Loading…
Reference in New Issue