HTTP dvrfile streaming: add subscription handling - fixes #2540

This commit is contained in:
Jaroslav Kysela 2014-12-12 12:06:55 +01:00
parent 5ec120c378
commit a609cd2edb
3 changed files with 49 additions and 7 deletions

View file

@ -561,6 +561,7 @@ subscription_unsubscribe(th_subscription_t *s)
free(s->ths_hostname);
free(s->ths_username);
free(s->ths_client);
free(s->ths_dvrfile);
free(s);
gtimer_arm(&subscription_reschedule_timer,
@ -894,6 +895,9 @@ subscription_create_msg(th_subscription_t *s)
if(s->ths_service != NULL)
htsmsg_add_str(m, "service", s->ths_service->s_nicename ?: "");
else if(s->ths_dvrfile != NULL)
htsmsg_add_str(m, "service", s->ths_dvrfile ?: "");
else if (s->ths_mmi != NULL && s->ths_mmi->mmi_mux != NULL) {
char buf[512];
mpegts_mux_t *mm = s->ths_mmi->mmi_mux;

View file

@ -95,6 +95,7 @@ typedef struct th_subscription {
char *ths_hostname;
char *ths_username;
char *ths_client;
char *ths_dvrfile;
/**
* This is the list of service candidates we have

View file

@ -1097,7 +1097,7 @@ page_play(http_connection_t *hc, const char *remain, void *opaque)
static int
page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
{
int fd, i;
int fd, i, ret;
struct stat st;
const char *content = NULL, *range;
dvr_entry_t *de;
@ -1107,6 +1107,8 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
char disposition[256];
off_t content_len, chunk;
intmax_t file_start, file_end;
void *tcp_id;
th_subscription_t *sub;
#if defined(PLATFORM_LINUX)
ssize_t r;
#elif defined(PLATFORM_FREEBSD) || defined(PLATFORM_DARWIN)
@ -1133,7 +1135,7 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
return HTTP_STATUS_NOT_FOUND;
}
fname = strdup(de->de_filename);
fname = tvh_strdupa(de->de_filename);
content = muxer_container_type2mime(de->de_mc, 1);
pthread_mutex_unlock(&global_lock);
@ -1153,7 +1155,6 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
}
fd = tvh_open(fname, O_RDONLY, 0);
free(fname);
if(fd < 0)
return HTTP_STATUS_NOT_FOUND;
@ -1195,14 +1196,40 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
return HTTP_STATUS_INTERNAL;
}
pthread_mutex_lock(&global_lock);
tcp_id = http_stream_preop(hc);
tcp_get_ip_str((struct sockaddr*)hc->hc_peer, range_buf, 50);
sub = NULL;
if (tcp_id && !hc->hc_no_output && content_len > 64*1024) {
sub = subscription_create(NULL, 1, "HTTP",
SUBSCRIPTION_NONE, NULL,
range_buf, hc->hc_username,
http_arg_get(&hc->hc_args, "User-Agent"));
if (sub == NULL) {
http_stream_postop(tcp_id);
tcp_id = NULL;
} else {
basename = malloc(strlen(fname) + 7 + 1);
strcpy(basename, "file://");
strcat(basename, fname);
sub->ths_dvrfile = basename;
}
}
pthread_mutex_unlock(&global_lock);
if (tcp_id == NULL) {
close(fd);
return HTTP_STATUS_NOT_ALLOWED;
}
http_send_header(hc, range ? HTTP_STATUS_PARTIAL_CONTENT : HTTP_STATUS_OK,
content, content_len, NULL, NULL, 10,
range ? range_buf : NULL,
disposition[0] ? disposition : NULL);
ret = 0;
if(!hc->hc_no_output) {
while(content_len > 0) {
chunk = MIN(1024 * 1024 * 1024, content_len);
chunk = MIN(1024 * (sub ? 128 : 1024 * 1024), content_len);
#if defined(PLATFORM_LINUX)
r = sendfile(hc->hc_fd, fd, NULL, chunk);
#elif defined(PLATFORM_FREEBSD)
@ -1212,14 +1239,24 @@ page_dvrfile(http_connection_t *hc, const char *remain, void *opaque)
sendfile(fd, hc->hc_fd, 0, NULL, &r, 0);
#endif
if(r < 0) {
close(fd);
return -1;
ret = -1;
break;
}
content_len -= r;
if (sub) {
sub->ths_bytes_in += r;
sub->ths_bytes_out += r;
}
}
}
close(fd);
return 0;
pthread_mutex_lock(&global_lock);
if (sub)
subscription_unsubscribe(sub);
http_stream_postop(tcp_id);
pthread_mutex_unlock(&global_lock);
return ret;
}
/**