rework pts/dts of audio stream. Spacing. Fix crash

This commit is contained in:
Isaac Connor 2018-12-04 18:23:08 -05:00
commit bc5f8d0d8d
14 changed files with 336 additions and 318 deletions

View File

@ -32,6 +32,7 @@ configure_file(httpd/com.zoneminder.systemctl.rules.httpd.in ${CMAKE_CURRENT_SOU
# Configure the Nginx zoneminder files
configure_file(nginx/zm-nginx.conf ${CMAKE_CURRENT_SOURCE_DIR}/zm-nginx.conf COPYONLY)
configure_file(nginx/zoneminder.nginx.conf.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.nginx.conf @ONLY)
configure_file(nginx/redirect.nginx.conf ${CMAKE_CURRENT_SOURCE_DIR}/redirect.nginx.conf COPYONLY)
configure_file(nginx/zoneminder.nginx.tmpfiles.in ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.nginx.tmpfiles.conf @ONLY)
configure_file(nginx/zm-web-user.conf ${CMAKE_CURRENT_SOURCE_DIR}/zm-web-user.conf COPYONLY)
configure_file(nginx/zoneminder.php-fpm.conf ${CMAKE_CURRENT_SOURCE_DIR}/zoneminder.php-fpm.conf COPYONLY)
@ -62,6 +63,7 @@ install(FILES com.zoneminder.systemctl.rules.httpd DESTINATION /etc/zm/www PERMI
# Install the Nginx zoneminder files
install(FILES zm-nginx.conf DESTINATION /usr/lib/systemd/system/zoneminder.service.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zoneminder.nginx.conf DESTINATION /etc/zm/www PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES redirect.nginx.conf DESTINATION /etc/zm/www PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zoneminder.nginx.tmpfiles.conf DESTINATION /usr/lib/tmpfiles.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES com.zoneminder.systemctl.rules.nginx DESTINATION /etc/zm/www PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)
install(FILES zm-web-user.conf DESTINATION /etc/zm/conf.d PERMISSIONS OWNER_WRITE OWNER_READ GROUP_READ WORLD_READ)

View File

@ -0,0 +1,2 @@
# Auto redirect to https
return 301 https://$host$request_uri;

View File

@ -1,5 +1,7 @@
listen 443 ssl;
listen [::]:443 ssl;
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name = localhost $hostname;
ssl_certificate "/etc/pki/tls/certs/localhost.crt";
ssl_certificate_key "/etc/pki/tls/private/localhost.key";
@ -8,9 +10,9 @@ ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
# Auto-redirect HTTP requests to HTTPS
if ($scheme != "https") {
rewrite ^/?(zm)(.*)$ https://$host/$1$2 permanent;
# Auto redirect to server/zm when no url suffix was given
location = / {
return 301 zm;
}
location /cgi-bin-zm {
@ -32,7 +34,7 @@ location /zm {
index index.php;
location ~ \.php$ {
if (!-f $request_filename) { return 404; }
try_files $uri =404;
expires epoch;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
@ -51,3 +53,5 @@ location /zm {
}
}
}

View File

@ -61,8 +61,7 @@ New installs
6. Configure the web server
This package uses the HTTPS protocol by default to access the web portal,
using the default self signed certificate on your system. Requests using
HTTP will auto-redirect to HTTPS.
using the default self signed certificate on your system.
Inspect the web server configuration file and verify it meets your needs:
@ -71,9 +70,13 @@ New installs
If you are running other web enabled services then you may need to edit
this file to suite. See README.https to learn about other alternatives.
If you wish http requests to auto-redirect to https requests, then link or
copy /etc/zm/www/redirect.nginx.conf into /etc/nginx/default.d folder.
When in doubt, proceed with the default:
sudo ln -sf /etc/zm/www/zoneminder.nginx.conf /etc/nginx/default.d/
sudo ln -sf /etc/zm/www/zoneminder.nginx.conf /etc/nginx/conf.d/
sudo ln -sf /etc/zm/www/redirect.nginx.conf /etc/nginx/default.d/
7. Edit /etc/sysconfig/fcgiwrap and set DAEMON_PROCS to the maximum number of
simulatneous streams the server should support. Generally, a good minimum

View File

@ -390,6 +390,7 @@ EOF
%config(noreplace) %attr(640,root,nginx) %{_sysconfdir}/zm/conf.d/*.conf
%ghost %attr(640,root,nginx) %{_sysconfdir}/zm/conf.d/zmcustom.conf
%config(noreplace) %{_sysconfdir}/zm/www/zoneminder.nginx.conf
%config(noreplace) %{_sysconfdir}/zm/www/redirect.nginx.conf
%ghost %{_sysconfdir}/zm/www/zoneminder.conf
%config(noreplace) %{_sysconfdir}/zm/www/com.zoneminder.systemctl.rules.nginx
%ghost %{_datadir}/polkit-1/rules.d/com.zoneminder.systemctl.rules

View File

@ -2,6 +2,7 @@
# Create files from the .in files
configure_file(apache.conf.in "${CMAKE_CURRENT_BINARY_DIR}/apache.conf" @ONLY)
configure_file(nginx.conf.in "${CMAKE_CURRENT_BINARY_DIR}/nginx.conf" @ONLY)
configure_file(logrotate.conf.in "${CMAKE_CURRENT_BINARY_DIR}/logrotate.conf" @ONLY)
configure_file(syslog.conf.in "${CMAKE_CURRENT_BINARY_DIR}/syslog.conf" @ONLY)
configure_file(com.zoneminder.systemctl.policy.in "${CMAKE_CURRENT_BINARY_DIR}/com.zoneminder.systemctl.policy" @ONLY)

61
misc/nginx.conf.in Normal file
View File

@ -0,0 +1,61 @@
#
# PLEASE NOTE THAT THIS FILE IS INTENDED FOR GUIDANCE ONLY AND MAY NOT BE APPROPRIATE FOR YOUR DISTRIBUTION
#
server {
listen 443 ssl default_server;
listen [::]:443 ssl default_server;
server_name = localhost $hostname;
ssl_certificate "/etc/pki/tls/certs/localhost.crt";
ssl_certificate_key "/etc/pki/tls/private/localhost.key";
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 10m;
ssl_ciphers PROFILE=SYSTEM;
ssl_prefer_server_ciphers on;
# Auto redirect to server/zm when no url suffix was given
location = / {
return 301 zm;
}
location /cgi-bin-zm {
gzip off;
alias "@ZM_CGIDIR@";
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_pass unix:/run/fcgiwrap.sock;
}
location /zm/cache {
alias "@ZM_CACHEDIR@";
}
location /zm {
gzip off;
alias "@ZM_WEBDIR@";
index index.php;
location ~ \.php$ {
try_files $uri =404;
expires epoch;
include /etc/nginx/fastcgi_params;
fastcgi_param SCRIPT_FILENAME $request_filename;
fastcgi_index index.php;
fastcgi_pass unix:/run/php-fpm/www.sock;
}
location ~ \.(jpg|jpeg|gif|png|ico)$ {
access_log off;
expires 33d;
}
location /zm/api/ {
alias "@ZM_WEBDIR@";
rewrite ^/zm/api(.+)$ /zm/api/app/webroot/index.php?p=$1 last;
}
}
}

View File

@ -208,7 +208,7 @@ sub zmDbGetMonitor {
return undef;
}
my $res = $sth->execute($id);
if ( $res ) {
if ( !$res ) {
Error("Can't execute '$sql': ".$sth->errstr());
return undef;
}

View File

@ -507,7 +507,7 @@ void EventStream::processCommand(const CmdMsg *msg) {
//if ( errno != EAGAIN )
{
Error("Can't sendto on sd %d: %s", sd, strerror(errno));
exit(-1);
//exit(-1);
}
}
// quit after sending a status, if this was a quit request
@ -844,7 +844,7 @@ Debug(3,"cur_frame_id (%d-1) mod frame_mod(%d)",curr_frame_id, frame_mod);
// so if it is 2, then we send every other frame, if is it 4 then every fourth frame, etc.
if ( (frame_mod == 1) || (((curr_frame_id-1)%frame_mod) == 0) ) {
delta_us = (unsigned int)(frame_data->delta * 1000000);
Debug(3,"frame delta %u ", delta_us);
Debug(3,"frame delta %uus ", delta_us);
// if effective > base we should speed up frame delivery
delta_us = (unsigned int)((delta_us * base_fps)/effective_fps);
Debug(3,"delta %u = base_fps(%f)/effective fps(%f)", delta_us, base_fps, effective_fps);

View File

@ -815,6 +815,7 @@ unsigned int Monitor::GetLastWriteIndex() const {
}
uint64_t Monitor::GetLastEventId() const {
#if 0
Debug(2, "mem_ptr(%x), State(%d) last_read_index(%d) last_read_time(%d) last_event(%" PRIu64 ")",
mem_ptr,
shared_data->state,
@ -822,6 +823,7 @@ uint64_t Monitor::GetLastEventId() const {
shared_data->last_read_time,
shared_data->last_event
);
#endif
return shared_data->last_event;
}

View File

@ -64,7 +64,8 @@ void StreamBase::updateFrameRate(double fps) {
base_fps = fps;
effective_fps = (base_fps*abs(replay_rate))/ZM_RATE_BASE;
frame_mod = 1;
Debug(3, "FPS:%.2f, MaxFPS:%.2f, BaseFPS:%.2f, EffectiveFPS:%.2f, FrameMod:%d", fps, maxfps, base_fps, effective_fps, frame_mod);
Debug(3, "FPS:%.2f, MaxFPS:%.2f, BaseFPS:%.2f, EffectiveFPS:%.2f, FrameMod:%d, replay_rate(%d)",
fps, maxfps, base_fps, effective_fps, frame_mod, replay_rate);
// Min frame repeat?
while( effective_fps > maxfps ) {
effective_fps /= 2.0;

View File

@ -31,10 +31,15 @@ extern "C" {
#include "libavutil/time.h"
}
VideoStore::VideoStore(const char *filename_in, const char *format_in,
VideoStore::VideoStore(
const char *filename_in,
const char *format_in,
AVStream *p_video_in_stream,
AVStream *p_audio_in_stream, int64_t nStartTime,
Monitor *monitor) {
AVStream *p_audio_in_stream,
int64_t nStartTime,
Monitor *monitor
) {
video_in_stream = p_video_in_stream;
audio_in_stream = p_audio_in_stream;
@ -85,7 +90,6 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
oc->metadata = pmetadata;
out_format = oc->oformat;
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
video_out_stream = avformat_new_stream(oc, NULL);
if ( !video_out_stream ) {
@ -96,8 +100,8 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
}
// Since we are not re-encoding, all we have to do is copy the parameters
video_out_ctx = video_out_stream->codec;
//video_out_ctx = avcodec_alloc_context3(NULL);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// Copy params from instream to ctx
ret = avcodec_parameters_to_context(video_out_ctx,
video_in_stream->codecpar);
@ -149,33 +153,23 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
Warning("Encoder Option %s not recognized by ffmpeg codec", e->key);
}
#else
video_out_stream =
avformat_new_stream(oc, NULL);
//(AVCodec *)(video_in_ctx->codec));
//avformat_new_stream(oc,(const AVCodec *)(video_in_ctx->codec));
if ( !video_out_stream ) {
Fatal("Unable to create video out stream");
} else {
Debug(2, "Success creating video out stream");
}
video_out_ctx = video_out_stream->codec;
ret = avcodec_copy_context(video_out_ctx, video_in_ctx);
if ( ret < 0 ) {
Fatal("Unable to copy in video ctx to out video ctx %s\n",
Fatal("Unable to copy in video ctx to out video ctx %s",
av_make_error_string(ret).c_str());
} else {
Debug(3, "Success copying ctx");
}
if ( !video_out_ctx->codec_tag ) {
Debug(2, "No codec_tag");
if (!oc->oformat->codec_tag ||
av_codec_get_id(oc->oformat->codec_tag,
video_in_ctx->codec_tag) ==
video_out_ctx->codec_id ||
av_codec_get_tag(oc->oformat->codec_tag,
video_in_ctx->codec_id) <= 0) {
if (
!oc->oformat->codec_tag
||
av_codec_get_id(oc->oformat->codec_tag, video_in_ctx->codec_tag) == video_out_ctx->codec_id
||
av_codec_get_tag(oc->oformat->codec_tag, video_in_ctx->codec_id) <= 0
) {
Warning("Setting codec tag");
video_out_ctx->codec_tag = video_in_ctx->codec_tag;
}
@ -238,7 +232,6 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
if ( audio_in_stream ) {
Debug(3, "Have audio stream");
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
audio_in_ctx = avcodec_alloc_context3(NULL);
ret = avcodec_parameters_to_context(audio_in_ctx,
audio_in_stream->codecpar);
@ -255,7 +248,7 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
return;
}
} else {
Debug(3, "Got AAC");
Debug(2, "Got AAC");
audio_out_stream =
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
@ -264,22 +257,20 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
avformat_new_stream(oc, (AVCodec *)audio_in_ctx->codec);
#endif
if ( !audio_out_stream ) {
Error("Unable to create audio out stream\n");
Error("Unable to create audio out stream");
audio_out_stream = NULL;
} else {
Debug(2, "setting parameters");
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
audio_out_ctx = avcodec_alloc_context3(audio_out_codec);
// Copy params from instream to ctx
ret = avcodec_parameters_to_context(audio_out_ctx,
audio_in_stream->codecpar);
ret = avcodec_parameters_to_context(
audio_out_ctx, audio_in_stream->codecpar);
if ( ret < 0 ) {
Error("Unable to copy audio params to ctx %s",
av_make_error_string(ret).c_str());
}
ret = avcodec_parameters_from_context(audio_out_stream->codecpar,
audio_out_ctx);
ret = avcodec_parameters_from_context(
audio_out_stream->codecpar, audio_out_ctx);
if ( ret < 0 ) {
Error("Unable to copy audio params to stream %s",
av_make_error_string(ret).c_str());
@ -291,7 +282,6 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
Debug(2, "Setting audio codec tag to %d",
audio_out_ctx->codec_tag);
}
#else
audio_out_ctx = audio_out_stream->codec;
ret = avcodec_copy_context(audio_out_ctx, audio_in_ctx);
@ -323,7 +313,6 @@ VideoStore::VideoStore(const char *filename_in, const char *format_in,
}
} // end if audio_in_stream
video_first_pts = 0;
video_first_dts = 0;
video_last_pts = 0;
@ -343,16 +332,12 @@ bool VideoStore::open() {
if ( !(out_format->flags & AVFMT_NOFILE) ) {
ret = avio_open2(&oc->pb, filename, AVIO_FLAG_WRITE, NULL, NULL);
if ( ret < 0 ) {
Error("Could not open out file '%s': %s\n", filename,
Error("Could not open out file '%s': %s", filename,
av_make_error_string(ret).c_str());
return false;
}
}
// os->ctx_inited = 1;
// avio_flush(ctx->pb);
// av_dict_free(&opts);
zm_dump_stream_format(oc, 0, 0, 1);
if (audio_out_stream) zm_dump_stream_format(oc, 1, 0, 1);
@ -367,11 +352,11 @@ bool VideoStore::open() {
/* Write the stream header, if any. */
ret = avformat_write_header(oc, NULL);
} else if (av_dict_count(opts) != 0) {
Warning("some options not set\n");
Warning("some options not set");
}
if ( opts ) av_dict_free(&opts);
if ( ret < 0 ) {
Error("Error occurred when writing out file header to %s: %s\n",
Error("Error occurred when writing out file header to %s: %s",
filename, av_make_error_string(ret).c_str());
/* free the stream */
avio_closep(&oc->pb);
@ -419,7 +404,7 @@ VideoStore::~VideoStore() {
ret =
avcodec_encode_audio2(audio_out_ctx, &pkt, NULL, &got_packet);
if ( ret < 0 ) {
Error("ERror encoding audio while flushing (%d) (%s)", ret,
Error("Error encoding audio while flushing (%d) (%s)", ret,
av_err2str(ret));
break;
}
@ -470,6 +455,7 @@ VideoStore::~VideoStore() {
Debug(3, "Not closing avio because we are not writing to a file.");
}
} // end if ( oc->pb )
// I wonder if we should be closing the file first.
// I also wonder if we really need to be doing all the ctx
// allocation/de-allocation constantly, or whether we can just re-use it.
@ -488,17 +474,19 @@ VideoStore::~VideoStore() {
#endif
video_out_ctx = NULL;
Debug(4, "Success freeing video_out_ctx");
}
} // end if video_out_stream
if ( audio_out_stream ) {
if ( audio_in_codec ) {
avcodec_close(audio_in_ctx);
audio_in_codec = NULL;
} // end if audio_in_codec
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// We allocate and copy in newer ffmpeg, so need to free it
avcodec_free_context(&audio_in_ctx);
#endif
audio_in_ctx = NULL;
audio_in_codec = NULL;
} // end if audio_in_codec
avcodec_close(audio_out_ctx);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
@ -523,7 +511,7 @@ VideoStore::~VideoStore() {
converted_in_samples = NULL;
}
#endif
}
} // end if audio_out_stream
/* free the stream */
avformat_free_context(oc);
@ -552,21 +540,17 @@ bool VideoStore::setup_resampler() {
Error("Could not find codec for AAC");
return false;
}
Debug(2, "Have audio out codec");
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
// audio_out_ctx = audio_out_stream->codec;
audio_out_ctx = avcodec_alloc_context3(audio_out_codec);
if ( !audio_out_ctx ) {
Error("could not allocate codec ctx for AAC");
audio_out_stream = NULL;
return false;
}
Debug(2, "Have audio_out_ctx");
// Now copy them to the out stream
audio_out_stream = avformat_new_stream(oc, NULL);
audio_out_stream = avformat_new_stream(oc, audio_out_codec);
#else
audio_out_stream = avformat_new_stream(oc, NULL);
audio_out_ctx = audio_out_stream->codec;
@ -592,8 +576,7 @@ bool VideoStore::setup_resampler() {
if ( audio_out_codec->supported_samplerates ) {
int found = 0;
for (unsigned int i = 0; audio_out_codec->supported_samplerates[i];
i++) {
for ( unsigned int i = 0; audio_out_codec->supported_samplerates[i]; i++) {
if ( audio_out_ctx->sample_rate ==
audio_out_codec->supported_samplerates[i] ) {
found = 1;
@ -605,7 +588,7 @@ bool VideoStore::setup_resampler() {
} else {
audio_out_ctx->sample_rate =
audio_out_codec->supported_samplerates[0];
Debug(1, "Sampel rate is no good, setting to (%d)",
Debug(1, "Sample rate is no good, setting to (%d)",
audio_out_codec->supported_samplerates[0]);
}
}
@ -620,16 +603,6 @@ bool VideoStore::setup_resampler() {
audio_out_ctx->time_base =
(AVRational){1, audio_out_ctx->sample_rate};
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
ret = avcodec_parameters_from_context(audio_out_stream->codecpar,
audio_out_ctx);
if (ret < 0) {
Error("Could not initialize stream parameteres");
return false;
}
#endif
AVDictionary *opts = NULL;
if ( (ret = av_dict_set(&opts, "strict", "experimental", 0)) < 0 ) {
Error("Couldn't set experimental");
@ -637,13 +610,23 @@ bool VideoStore::setup_resampler() {
ret = avcodec_open2(audio_out_ctx, audio_out_codec, &opts);
av_dict_free(&opts);
if ( ret < 0 ) {
Error("could not open codec (%d) (%s)\n", ret, av_make_error_string(ret).c_str());
Error("could not open codec (%d) (%s)",
ret, av_make_error_string(ret).c_str());
audio_out_codec = NULL;
audio_out_ctx = NULL;
audio_out_stream = NULL;
return false;
}
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
ret = avcodec_parameters_from_context(
audio_out_stream->codecpar, audio_out_ctx);
if ( ret < 0 ) {
Error("Could not initialize stream parameteres");
return false;
}
#endif
Debug(1,
"Audio out bit_rate (%d) sample_rate(%d) channels(%d) fmt(%d) "
"layout(%d) frame_size(%d)",
@ -667,19 +650,19 @@ bool VideoStore::setup_resampler() {
// Setup the audio resampler
resample_ctx = avresample_alloc_context();
if ( !resample_ctx ) {
Error("Could not allocate resample ctx\n");
Error("Could not allocate resample ctx");
return false;
}
// Some formats (i.e. WAV) do not produce the proper channel layout
if (audio_in_ctx->channel_layout == 0) {
uint64_t layout = av_get_channel_layout("mono");
av_opt_set_int(resample_ctx, "in_channel_layout",
av_get_channel_layout("mono"), 0);
Debug(1, "Bad channel layout. Need to set it to mono (%d).", layout);
if ( audio_in_ctx->channel_layout == 0 ) {
av_opt_set_int(resample_ctx, "in_channel_layout", layout, 0);
Debug(1, "Bad in channel layout. Need to set it to mono (%d).", layout);
} else {
av_opt_set_int(resample_ctx, "in_channel_layout",
audio_in_ctx->channel_layout, 0);
layout = audio_in_ctx->channel_layout;
}
av_opt_set_int(resample_ctx, "in_sample_fmt",
@ -691,7 +674,7 @@ bool VideoStore::setup_resampler() {
// av_opt_set_int( resample_ctx, "out_channel_layout",
// audio_out_ctx->channel_layout, 0);
av_opt_set_int(resample_ctx, "out_channel_layout",
av_get_channel_layout("mono"), 0);
layout, 0);
av_opt_set_int(resample_ctx, "out_sample_fmt",
audio_out_ctx->sample_fmt, 0);
av_opt_set_int(resample_ctx, "out_sample_rate",
@ -701,37 +684,12 @@ bool VideoStore::setup_resampler() {
ret = avresample_open(resample_ctx);
if ( ret < 0 ) {
Error("Could not open resample ctx\n");
Error("Could not open resample ctx");
return false;
} else {
Debug(2, "Success opening resampler");
}
#if 0
/**
* Allocate as many pointers as there are audio channels.
* Each pointer will later point to the audio samples of the corresponding
* channels (although it may be NULL for interleaved formats).
*/
if (!( converted_in_samples = reinterpret_cast<uint8_t *>calloc( audio_out_ctx->channels, sizeof(*converted_in_samples))) ) {
Error("Could not allocate converted in sample pointers\n");
return;
}
/**
* Allocate memory for the samples of all channels in one consecutive
* block for convenience.
*/
if ( (ret = av_samples_alloc( &converted_in_samples, NULL,
audio_out_ctx->channels,
audio_out_ctx->frame_size,
audio_out_ctx->sample_fmt, 0)) < 0 ) {
Error("Could not allocate converted in samples (error '%s')\n",
av_make_error_string(ret).c_str());
av_freep(converted_in_samples);
free(converted_in_samples);
return;
}
#endif
out_frame->nb_samples = audio_out_ctx->frame_size;
out_frame->format = audio_out_ctx->sample_fmt;
out_frame->channel_layout = audio_out_ctx->channel_layout;
@ -739,13 +697,16 @@ bool VideoStore::setup_resampler() {
// The codec gives us the frame size, in samples, we calculate the size of the
// samples buffer in bytes
unsigned int audioSampleBuffer_size = av_samples_get_buffer_size(
NULL, audio_out_ctx->channels, audio_out_ctx->frame_size,
NULL, audio_out_ctx->channels,
audio_out_ctx->frame_size,
audio_out_ctx->sample_fmt, 0);
converted_in_samples = (uint8_t *)av_malloc(audioSampleBuffer_size);
if ( !converted_in_samples ) {
Error("Could not allocate converted in sample pointers\n");
Error("Could not allocate converted in sample pointers");
return false;
} else {
Debug(2, "Frame Size %d, sample buffer size %d", audio_out_ctx->frame_size, audioSampleBuffer_size);
}
// Setup the data pointers in the AVFrame
@ -753,7 +714,7 @@ bool VideoStore::setup_resampler() {
audio_out_ctx->sample_fmt,
(const uint8_t *)converted_in_samples,
audioSampleBuffer_size, 0) < 0) {
Error("Could not allocate converted in sample pointers\n");
Error("Could not allocate converted in sample pointers");
return false;
}
@ -788,8 +749,7 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
video_out_stream->time_base.den
);
} else {
duration =
av_rescale_q(
duration = av_rescale_q(
ipkt->pts - video_last_pts,
video_in_stream->time_base,
video_out_stream->time_base);
@ -800,7 +760,8 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
duration
);
if ( duration <= 0 ) {
duration = ipkt->duration ? ipkt->duration : av_rescale_q(1,video_in_stream->time_base, video_out_stream->time_base);
// Why are we setting the duration to 1?
duration = av_rescale_q(1, video_in_stream->time_base, video_out_stream->time_base);
}
}
opkt.duration = duration;
@ -808,17 +769,13 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
// Scale the PTS of the outgoing packet to be the correct time base
if ( ipkt->pts != AV_NOPTS_VALUE ) {
if ( !video_first_pts ) {
// ffmpeg has a bug where it screws up the pts to massively negative.
if ( (!video_first_pts) && (ipkt->pts >= 0) ) {
// This is the first packet.
opkt.pts = 0;
Debug(2, "Starting video first_pts will become %" PRId64, ipkt->pts);
video_first_pts = ipkt->pts;
} else {
if ( 0 && ipkt->pts < video_first_pts ) {
Debug(1, "Resetting first_pts from %" PRId64 " to %" PRId64, video_last_pts, ipkt->pts);
video_first_pts -= video_last_pts;
// wrap around, need to figure out the distance FIXME having this wrong should cause a jump, but then play ok?
}
opkt.pts = av_rescale_q(
ipkt->pts - video_first_pts,
video_in_stream->time_base,
@ -833,17 +790,12 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
}
// Just because the in stream wraps, doesn't mean the out needs to. Really, if we are limiting ourselves to 10min segments I can't imagine every wrapping in the out. So need to handle in wrap, without causing out wrap.
if ( ipkt->dts != AV_NOPTS_VALUE ) {
if ( !video_first_dts ) {
if ( (!video_first_dts) && ( ipkt->dts >= 0 ) ) {
// This is the first packet.
opkt.dts = 0;
Debug(1, "Starting video first_dts will become (%" PRId64 ")", ipkt->dts);
video_first_dts = ipkt->dts;
} else {
if ( 0 && ipkt->dts < video_first_dts ) {
Debug(1, "Resetting first_dts from (%" PRId64 ") to (%" PRId64")",
video_first_dts, ipkt->dts);
video_first_dts -= video_last_dts;
}
opkt.dts = av_rescale_q(
ipkt->dts - video_first_dts,
video_in_stream->time_base,
@ -868,10 +820,8 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
opkt.flags = ipkt->flags;
opkt.pos = -1;
opkt.data = ipkt->data;
opkt.size = ipkt->size;
opkt.stream_index = video_out_stream->index;
dumpPacket(video_out_stream, &opkt, "writing video packet");
@ -879,23 +829,13 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
Warning("%s:%d: Mangled AVPacket: discarding frame", __FILE__, __LINE__);
dumpPacket(video_in_stream, ipkt,"In Packet");
dumpPacket(video_out_stream, &opkt);
#if 0
} else if ((video_next_dts > 0) && (video_next_dts > opkt.dts)) {
Warning("%s:%d: DTS out of order: %lld \u226E %lld; discarding frame",
__FILE__, __LINE__, video_next_dts, opkt.dts);
video_next_dts = opkt.dts;
dumpPacket(&opkt);
#endif
} else {
ret = av_interleaved_write_frame(oc, &opkt);
if ( ret < 0 ) {
// There's nothing we can really do if the frame is rejected, just drop it
// and get on with the next
Warning(
"%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d) "
" ",
"%s:%d: Writing frame [av_interleaved_write_frame()] failed: %s(%d)",
__FILE__, __LINE__, av_make_error_string(ret).c_str(), ret);
#if LIBAVCODEC_VERSION_CHECK(57, 64, 0, 64, 0)
zm_dump_codecpar(video_in_stream->codecpar);
@ -910,7 +850,6 @@ int VideoStore::writeVideoFramePacket(AVPacket *ipkt) {
} // end int VideoStore::writeVideoFramePacket( AVPacket *ipkt )
int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
Debug(4, "writeAudioFrame");
if ( !audio_out_stream ) {
Debug(1, "Called writeAudioFramePacket when no audio_out_stream");
@ -949,9 +888,10 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
int data_present;
if ( (ret = avcodec_decode_audio4(audio_in_ctx, in_frame,
&data_present, ipkt)) < 0 ) {
Error("Could not decode frame (error '%s')\n",
Error("Could not decode frame (error '%s')",
av_make_error_string(ret).c_str());
dumpPacket(video_in_stream, ipkt);
// I'm not sure if we should be freeing the frame.
av_frame_free(&in_frame);
return 0;
}
@ -962,20 +902,18 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
#endif
int frame_size = out_frame->nb_samples;
// Resample the in into the audioSampleBuffer until we proceed the whole
// Resample the in into the audioSampleBuffer until we process the whole
// decoded data
if ((ret =
avresample_convert(resample_ctx, NULL, 0, 0, in_frame->data,
0, in_frame->nb_samples)) < 0) {
Error("Could not resample frame (error '%s')\n",
av_make_error_string(ret).c_str());
ret = avresample_convert(resample_ctx, NULL, 0, 0,
in_frame->data, 0, in_frame->nb_samples);
av_frame_unref(in_frame);
if ( ret < 0 ) {
Error("Could not resample frame (error '%s')",
av_make_error_string(ret).c_str());
return 0;
}
av_frame_unref(in_frame);
int samples_available = avresample_available(resample_ctx);
if ( samples_available < frame_size ) {
Debug(1, "Not enough samples yet (%d)", samples_available);
return 0;
@ -985,7 +923,7 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
// Read a frame audio data from the resample fifo
if ( avresample_read(resample_ctx, out_frame->data, frame_size) !=
frame_size) {
Warning("Error reading resampled audio: ");
Warning("Error reading resampled audio.");
return 0;
}
Debug(2,
@ -1004,11 +942,9 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
return 0;
}
// av_frame_unref( out_frame );
if ( (ret = avcodec_receive_packet(audio_out_ctx, &opkt)) < 0 ) {
if ( AVERROR(EAGAIN) == ret ) {
// THe codec may need more samples than it has, perfectly valid
// The codec may need more samples than it has, perfectly valid
Debug(3, "Could not recieve packet (error '%s')",
av_make_error_string(ret).c_str());
} else {
@ -1016,13 +952,12 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
av_make_error_string(ret).c_str());
}
zm_av_packet_unref(&opkt);
av_frame_unref(in_frame);
// av_frame_unref( out_frame );
return 0;
}
#else
if ((ret = avcodec_encode_audio2(audio_out_ctx, &opkt, out_frame,
&data_present)) < 0) {
if ( (ret = avcodec_encode_audio2(
audio_out_ctx, &opkt, out_frame, &data_present)) < 0 ) {
Error("Could not encode frame (error '%s')",
av_make_error_string(ret).c_str());
zm_av_packet_unref(&opkt);
@ -1043,25 +978,36 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
opkt.size = ipkt->size;
}
if ( out_frame ) {
opkt.duration = out_frame->nb_samples;
} else if ( ipkt->duration != AV_NOPTS_VALUE ) {
opkt.duration = av_rescale_q(
ipkt->duration,
audio_in_stream->time_base,
audio_out_stream->time_base);
} else {
// calculate it?
}
dumpPacket(audio_out_stream, &opkt);
// PTS is difficult, because of the buffering of the audio packets in the
// resampler. So we have to do it once we actually have a packet...
// audio_last_pts is the pts of ipkt, audio_next_pts is the last pts of the
// out
// Scale the PTS of the outgoing packet to be the correct time base
#if 0
#if 1
if ( ipkt->pts != AV_NOPTS_VALUE ) {
if ( !audio_last_pts ) {
if ( !audio_first_pts ) {
opkt.pts = 0;
Debug(1, "No audio_last_pts");
audio_first_pts = ipkt->pts;
Debug(1, "No audio_first_pts");
} else {
if ( audio_last_pts > ipkt->pts ) {
Debug(1, "Resetting audio_start_pts from (%d) to (%d)", audio_last_pts, ipkt->pts);
opkt.pts = audio_next_pts + av_rescale_q(ipkt->pts, audio_in_stream->time_base, audio_out_stream->time_base);
} else {
opkt.pts = audio_next_pts + av_rescale_q(ipkt->pts - audio_last_pts, audio_in_stream->time_base, audio_out_stream->time_base);
}
Debug(2, "audio opkt.pts = %d from ipkt->pts(%d) - last_pts(%d)", opkt.pts, ipkt->pts, audio_last_pts);
opkt.pts = av_rescale_q(
ipkt->pts - audio_first_pts,
audio_in_stream->time_base,
audio_out_stream->time_base);
Debug(2, "audio opkt.pts = %d from ipkt->pts(%d) - first_pts(%d)",
opkt.pts, ipkt->pts, audio_first_pts);
}
audio_last_pts = ipkt->pts;
} else {
@ -1073,59 +1019,52 @@ int VideoStore::writeAudioFramePacket(AVPacket *ipkt) {
opkt.dts = audio_next_dts;
#endif
#if 0
if ( ipkt->dts == AV_NOPTS_VALUE ) {
#if 1
if ( ipkt->dts != AV_NOPTS_VALUE ) {
// So if the in has no dts assigned... still need an out dts... so we use cur_dts?
#if 0
if ( audio_last_dts >= audio_in_stream->cur_dts ) {
Debug(1, "Resetting audio_last_dts from (%d) to cur_dts (%d)", audio_last_dts, audio_in_stream->cur_dts);
opkt.dts = audio_next_dts + av_rescale_q( audio_in_stream->cur_dts, AV_TIME_BASE_Q, audio_out_stream->time_base);
} else {
opkt.dts = audio_next_dts + av_rescale_q( audio_in_stream->cur_dts - audio_last_dts, AV_TIME_BASE_Q, audio_out_stream->time_base);
}
audio_last_dts = audio_in_stream->cur_dts;
Debug(2, "opkt.dts = %d from video_in_stream->cur_dts(%d) - last_dts(%d)", opkt.dts, audio_in_stream->cur_dts, audio_last_dts);
#endif
if ( !audio_first_dts ) {
opkt.dts = 0;
audio_first_dts = ipkt->dts;
} else {
if ( audio_last_dts >= ipkt->dts ) {
Debug(1, "Resetting audio_last_dts from (%d) to (%d)", audio_last_dts, ipkt->dts );
opkt.dts = audio_next_dts + av_rescale_q(ipkt->dts, audio_in_stream->time_base, audio_out_stream->time_base);
opkt.dts = av_rescale_q(
ipkt->dts - audio_first_dts,
audio_in_stream->time_base,
audio_out_stream->time_base);
Debug(2, "opkt.dts = %" PRId64 " from ipkt.dts(%" PRId64 ") - first_dts(%" PRId64 ")",
opkt.dts, ipkt->dts, audio_first_dts);
}
audio_last_dts = ipkt->dts;
} else {
opkt.dts = audio_next_dts + av_rescale_q(ipkt->dts - audio_last_dts, audio_in_stream->time_base, audio_out_stream->time_base);
Debug(2, "opkt.dts = %d from previous(%d) + ( ipkt->dts(%d) - last_dts(%d) )", opkt.dts, audio_next_dts, ipkt->dts, audio_last_dts );
}
}
opkt.dts = AV_NOPTS_VALUE;
}
#endif
// audio_last_dts = ipkt->dts;
if ( opkt.dts > opkt.pts ) {
Debug(1,
"opkt.dts(%d) must be <= opkt.pts(%d). Decompression must happen "
"before presentation.",
"opkt.dts(%" PRId64 ") must be <= opkt.pts(%" PRId64 ")."
"Decompression must happen before presentation.",
opkt.dts, opkt.pts);
opkt.dts = opkt.pts;
}
// I wonder if we could just use duration instead of all the hoop jumping
// above?
//
if (out_frame) {
opkt.duration = out_frame->nb_samples;
} else {
opkt.duration = ipkt->duration;
}
// opkt.duration = av_rescale_q(ipkt->duration, audio_in_stream->time_base,
// audio_out_stream->time_base);
dumpPacket( audio_out_stream, &opkt );
// pkt.pos: byte position in stream, -1 if unknown
opkt.pos = -1;
opkt.stream_index = audio_out_stream->index;
audio_next_dts = opkt.dts + opkt.duration;
audio_next_pts = opkt.pts + opkt.duration;
//audio_next_dts = opkt.dts + opkt.duration;
//audio_next_pts = opkt.pts + opkt.duration;
ret = av_interleaved_write_frame(oc, &opkt);
if ( ret != 0 ) {
Error("Error writing audio frame packet: %s\n",
Error("Error writing audio frame packet: %s",
av_make_error_string(ret).c_str());
} else {
Debug(2, "Success writing audio frame");

View File

@ -51,7 +51,8 @@ class Server {
} else if ( $this->Id() ) {
return $this->{'Name'};
}
return $_SERVER['SERVER_NAME'];
# Use HTTP_HOST instead of SERVER_NAME here for nginx compatiblity
return $_SERVER['HTTP_HOST'];
}
public function Protocol( $new = null ) {
@ -93,7 +94,8 @@ class Server {
if ( $this->Id() ) {
$url .= $this->Hostname();
} else {
$url .= $_SERVER['SERVER_NAME'];
# Use HTTP_HOST instead of SERVER_NAME here for nginx compatiblity
$url .= $_SERVER['HTTP_HOST'];
}
if ( $port ) {
$url .= ':'.$port;

View File

@ -617,7 +617,7 @@ if ( canEdit('Monitors') ) {
$new_monitor = new Monitor($mid);
//fixDevices();
if ( $monitor['Type'] != 'WebSite' ) {
if ( $new_monitor->Type() != 'WebSite' ) {
$new_monitor->zmcControl('start');
$new_monitor->zmaControl('start');
}