Origin commit data
------------------
Branch: master
Commit: b6b07f7d3d
Author: vanhofen <vanhofen@gmx.de>
Date: 2018-04-11 (Wed, 11 Apr 2018)


------------------
No further description and justification available within origin commit message!

------------------
This commit was generated by Migit
This commit is contained in:
vanhofen
2018-04-11 23:37:22 +02:00
7 changed files with 215 additions and 56 deletions

View File

@@ -117,7 +117,7 @@ bool cPlayback::Start(char *filename, int vpid, int vtype, int apid, int ac3, in
}
else
isHTTP = true;
PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL};
PlayFiles_t playbackFiles = { (char *) file.c_str(), NULL, NULL, NULL, 0, 0, 0, 0};
if (player->playback->Command(player, PLAYBACK_OPEN, &playbackFiles) == 0)
{
if (pm == PLAYMODE_TS)

View File

@@ -1353,40 +1353,142 @@ static int32_t interrupt_cb(void *ctx)
}
#ifdef SAM_CUSTOM_IO
typedef struct CustomIOCtx_t
{
FILE *pFile;
FILE *pMoovFile;
int64_t iOffset;
char *szFile;
uint64_t iFileSize;
char *szMoovAtomFile;
uint64_t iMoovAtomOffset;
} CustomIOCtx_t;
CustomIOCtx_t *custom_io_tab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL};
int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize)
{
size_t ret = fread((void *) buffer, (size_t) 1, (size_t) lSize, (FILE *)ptr);
return (int)ret;
CustomIOCtx_t *io = (CustomIOCtx_t *)ptr;
int ret = 0;
if (!io->pMoovFile)
{
ret = (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pFile);
}
else
{
if ((uint64_t)io->iOffset < io->iMoovAtomOffset)
{
ret = (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pFile);
buffer += ret;
lSize -= ret;
}
if ((uint64_t)io->iOffset + ret >= io->iMoovAtomOffset)
{
if (ret)
{
if (fseeko(io->pMoovFile, io->iOffset + ret - io->iMoovAtomOffset, SEEK_SET))
{
// something goes wrong
ffmpeg_err("fseeko on moov atom file fail \n");
lSize = 0;
}
}
ret += (int)fread((void *) buffer, (size_t) 1, (size_t) lSize, io->pMoovFile);
}
io->iOffset += ret;
}
return ret;
}
// whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE
int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence)
{
if (AVSEEK_SIZE == whence)
CustomIOCtx_t *io = (CustomIOCtx_t *)ptr;
int64_t ret = -1;
if (!io->pMoovFile)
{
return -1;
if (AVSEEK_SIZE != whence)
{
ret = (int64_t)fseeko(io->pFile, (off_t)pos, whence);
if (0 == ret)
{
ret = (int64_t)ftello(io->pFile);
}
}
}
int ret = fseeko((FILE *)ptr, (off_t)pos, whence);
if (0 == ret)
else
{
return (off_t)ftello((FILE *)ptr);
switch (whence)
{
case SEEK_SET:
ret = pos;
break;
case SEEK_CUR:
ret += pos;
break;
case SEEK_END:
ret = io->iFileSize + pos;
break;
case AVSEEK_SIZE:
return io->iFileSize;
default:
return -1;
}
if (ret >= 0 && (uint64_t)ret <= io->iFileSize)
{
if ((uint64_t)ret < io->iMoovAtomOffset)
{
if (!fseeko(io->pFile, (off_t)ret, SEEK_SET))
io->iOffset = (uint64_t)ret;
else
ret = -1;
}
else
{
if (!fseeko(io->pMoovFile, (off_t)(ret - io->iMoovAtomOffset), SEEK_SET))
io->iOffset = ret;
else
ret = -1;
}
}
else
{
ret = -1;
}
}
return ret;
}
AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_buffer_size)
AVIOContext *container_ffmpeg_get_avio_context(CustomIOCtx_t *custom_io, size_t avio_ctx_buffer_size)
{
if (strstr(filename, "file://") == filename)
{
filename += 7;
}
if (strstr(custom_io->szFile, "file://") == custom_io->szFile)
custom_io->szFile += 7;
FILE *pFile = fopen(filename, "rb");
if (NULL == pFile)
custom_io->pFile = fopen(custom_io->szFile, "rb");
if (NULL == custom_io->pFile)
{
return NULL;
}
if (custom_io->szMoovAtomFile && custom_io->szMoovAtomFile[0] != '\0')
{
if (strstr(custom_io->szMoovAtomFile, "file://") == custom_io->szMoovAtomFile)
custom_io->szMoovAtomFile += 7;
custom_io->pMoovFile = fopen(custom_io->szMoovAtomFile, "rb");
if (NULL == custom_io->pMoovFile)
{
fclose(custom_io->pFile);
return NULL;
}
}
AVIOContext *avio_ctx = NULL;
uint8_t *avio_ctx_buffer = NULL;
@@ -1395,7 +1497,7 @@ AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_b
{
return NULL;
}
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, pFile, &SAM_ReadFunc, NULL, &SAM_SeekFunc);
avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, custom_io, &SAM_ReadFunc, NULL, &SAM_SeekFunc);
if (!avio_ctx)
{
return NULL;
@@ -1404,7 +1506,7 @@ AVIOContext *container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_b
}
#endif
int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int32_t AVIdx)
int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uint64_t fileSize, char *moovAtomFile, uint64_t moovAtomOffset, int32_t AVIdx)
{
int32_t err = 0;
AVInputFormat *fmt = NULL;
@@ -1416,7 +1518,16 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int
if (0 == strstr(filename, "://") ||
0 == strncmp(filename, "file://", 7))
{
AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096);
AVIOContext *avio_ctx = NULL;
custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t));
memset(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t));
custom_io_tab[AVIdx]->szFile = filename;
custom_io_tab[AVIdx]->iFileSize = fileSize;
custom_io_tab[AVIdx]->szMoovAtomFile = moovAtomFile;
custom_io_tab[AVIdx]->iMoovAtomOffset = moovAtomOffset;
avio_ctx = container_ffmpeg_get_avio_context(custom_io_tab[AVIdx], 4096);
if (avio_ctx)
{
avContextTab[AVIdx]->pb = avio_ctx;
@@ -1424,6 +1535,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int
}
else
{
free(custom_io_tab[AVIdx]);
custom_io_tab[AVIdx] = NULL;
return cERR_CONTAINER_FFMPEG_OPEN;
}
}
@@ -1782,15 +1895,17 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
av_log_set_callback(ffmpeg_silen_callback);
context->playback->abortRequested = 0;
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0);
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \
playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
if (0 != res)
{
return res;
}
if (playFilesNames->szSecondFile)
if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0')
{
res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1);
res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \
playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
}
if (0 != res)
@@ -2575,7 +2690,12 @@ static int32_t container_ffmpeg_stop(Context_t *context)
* avformat_close_input do not expect custom io, so it try
* to release incorrectly
*/
fclose(avContextTab[i]->pb->opaque);
CustomIOCtx_t *io = (CustomIOCtx_t *)avContextTab[i]->pb->opaque;
if (io->pFile)
fclose(io->pFile);
if (io->pMoovFile)
fclose(io->pMoovFile);
free(custom_io_tab[i]);
av_freep(&(avContextTab[i]->pb->buffer));
av_freep(&(avContextTab[i]->pb));
use_custom_io[i] = 0;
@@ -3180,4 +3300,4 @@ Container_t FFMPEGContainer =
"FFMPEG",
&Command,
FFMPEG_Capabilities
};
};

View File

@@ -9,12 +9,16 @@
#include "playback.h"
#include <pthread.h>
typedef char PlayFilesTab_t[2];
typedef struct PlayFiles_t
{
char *szFirstFile;
char *szSecondFile;
char *szFirstMoovAtomFile;
char *szSecondMoovAtomFile;
uint64_t iFirstFileSize;
uint64_t iSecondFileSize;
uint64_t iFirstMoovAtomOffset;
uint64_t iSecondMoovAtomOffset;
} PlayFiles_t;
typedef struct Context_s

View File

@@ -504,14 +504,14 @@ static void UpdateVideoTrack()
HandleTracks(g_player->manager->video, (PlaybackCmd_t) - 1, "vc");
}
static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB)
static int ParseParams(int argc, char *argv[], PlayFiles_t *playbackFiles, int *pAudioTrackIdx, int *subtitleTrackIdx, uint32_t *linuxDvbBufferSizeMB)
{
int ret = 0;
int c;
//int digit_optind = 0;
//int aopt = 0, bopt = 0;
//char *copt = 0, *dopt = 0;
while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:")) != -1)
while ((c = getopt(argc, argv, "we3dlsrimva:n:x:u:c:h:o:p:P:t:9:0:1:4:f:b:F:S:O:")) != -1)
{
switch (c)
{
@@ -572,8 +572,14 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
*subtitleTrackIdx = atoi(optarg);
break;
case 'x':
strncpy(audioFile, optarg, IPTV_MAX_FILE_PATH - 1);
map_inter_file_path(audioFile);
if (optarg[0] != '\0')
{
playbackFiles->szSecondFile = malloc(IPTV_MAX_FILE_PATH);
playbackFiles->szSecondFile[0] = '\0';
strncpy(playbackFiles->szSecondFile, optarg, IPTV_MAX_FILE_PATH - 1);
playbackFiles->szSecondFile[IPTV_MAX_FILE_PATH] = '\0';
map_inter_file_path(playbackFiles->szSecondFile);
}
break;
case 'h':
ffmpeg_av_dict_set("headers", optarg, 0);
@@ -624,6 +630,22 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
case 'b':
*linuxDvbBufferSizeMB = 1024 * 1024 * atoi(optarg);
break;
case 'S':
playbackFiles->iFirstFileSize = (uint64_t) strtoull(optarg, (char **)NULL, 10);
break;
case 'O':
playbackFiles->iFirstMoovAtomOffset = (uint64_t) strtoull(optarg, (char **)NULL, 10);
break;
case 'F':
if (optarg[0] != '\0')
{
playbackFiles->szFirstMoovAtomFile = malloc(IPTV_MAX_FILE_PATH);
playbackFiles->szFirstMoovAtomFile[0] = '\0';
strncpy(playbackFiles->szFirstMoovAtomFile, optarg, IPTV_MAX_FILE_PATH - 1);
playbackFiles->szFirstMoovAtomFile[IPTV_MAX_FILE_PATH] = '\0';
map_inter_file_path(playbackFiles->szFirstMoovAtomFile);
}
break;
default:
printf("?? getopt returned character code 0%o ??\n", c);
ret = -1;
@@ -633,14 +655,16 @@ static int ParseParams(int argc, char *argv[], char *file, char *audioFile, int
if (0 == ret && optind < argc)
{
ret = 0;
playbackFiles->szFirstFile = malloc(IPTV_MAX_FILE_PATH);
playbackFiles->szFirstFile[0] = '\0';
if (NULL == strstr(argv[optind], "://"))
{
strcpy(file, "file://");
strcpy(playbackFiles->szFirstFile, "file://");
}
strcat(file, argv[optind]);
map_inter_file_path(file);
printf("file: [%s]\n", file);
strcat(playbackFiles->szFirstFile, argv[optind]);
playbackFiles->szFirstFile[IPTV_MAX_FILE_PATH] = '\0';
map_inter_file_path(playbackFiles->szFirstFile);
printf("file: [%s]\n", playbackFiles->szFirstFile);
++optind;
}
else
@@ -654,11 +678,6 @@ int main(int argc, char *argv[])
{
pthread_t termThread;
int isTermThreadStarted = 0;
char file[IPTV_MAX_FILE_PATH];
memset(file, '\0', sizeof(file));
char audioFile[IPTV_MAX_FILE_PATH];
memset(audioFile, '\0', sizeof(audioFile));
int audioTrackIdx = -1;
int subtitleTrackIdx = -1;
@@ -669,9 +688,11 @@ int main(int argc, char *argv[])
memset(argvBuff, '\0', sizeof(argvBuff));
int commandRetVal = -1;
/* inform client that we can handle additional commands */
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 45);
fprintf(stderr, "{\"EPLAYER3_EXTENDED\":{\"version\":%d}}\n", 47);
if (0 != ParseParams(argc, argv, file, audioFile, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
PlayFiles_t playbackFiles;
memset(&playbackFiles, 0x00, sizeof(playbackFiles));
if (0 != ParseParams(argc, argv, &playbackFiles, &audioTrackIdx, &subtitleTrackIdx, &linuxDvbBufferSizeMB))
{
printf("Usage: exteplayer3 filePath [-u user-agent] [-c cookies] [-h headers] [-p prio] [-a] [-d] [-w] [-l] [-s] [-i] [-t audioTrackId] [-9 subtitleTrackId] [-x separateAudioUri] plabackUri\n");
printf("[-b size] Linux DVB output buffer size in MB\n");
@@ -701,6 +722,9 @@ int main(int argc, char *argv[])
printf("[-0 idx] video MPEG-DASH representation index\n");
printf("[-1 idx] audio MPEG-DASH representation index\n");
printf("[-f ffopt=ffval] any other ffmpeg option\n");
printf("[-F path to additional file with moov atom data (used for mp4 playback in progressive download mode)\n");
printf("[-O moov atom offset in the original file (used for mp4 playback in progressive download mode)\n");
printf("[-S remote file size (used for mp4 playback in progressive download mode)\n");
exit(1);
}
@@ -762,19 +786,13 @@ int main(int argc, char *argv[])
g_player->manager->video->Command(g_player, MANAGER_REGISTER_UPDATED_TRACK_INFO, UpdateVideoTrack);
if (strncmp(file, "rtmp", 4) && strncmp(file, "ffrtmp", 4))
if (strncmp(playbackFiles.szFirstFile, "rtmp", 4) && strncmp(playbackFiles.szFirstFile, "ffrtmp", 4))
{
g_player->playback->noprobe = 1;
}
PlayFiles_t playbackFiles = {file, NULL};
if ('\0' != audioFile[0])
{
playbackFiles.szSecondFile = audioFile;
}
commandRetVal = g_player->playback->Command(g_player, PLAYBACK_OPEN, &playbackFiles);
fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, file, commandRetVal);
fprintf(stderr, "{\"PLAYBACK_OPEN\":{\"OutputName\":\"%s\", \"file\":\"%s\", \"sts\":%d}}\n", g_player->output->Name, playbackFiles.szFirstFile, commandRetVal);
if (commandRetVal < 0)
{
if (NULL != g_player)

View File

@@ -33,6 +33,7 @@
#include <stdint.h>
#include <stdbool.h>
#include <assert.h>
#include <time.h>
#include "common.h"
#include "misc.h"
@@ -309,8 +310,13 @@ int32_t LinuxDvbBuffClose(Context_t *context __attribute__((unused)))
pthread_cond_signal(&bufferingdDataAddedCond);
/* wait for thread end */
#if 0
/* This code couse symbol versioning of clock_gettime@GLIBC_2.17 */
clock_gettime(CLOCK_REALTIME, &max_wait);
max_wait.tv_sec += 1;
#else
max_wait.tv_sec = time(NULL) + 2;
#endif
pthread_cond_timedwait(&bufferingExitCond, &bufferingMtx, &max_wait);
pthread_mutex_unlock(&bufferingMtx);

View File

@@ -396,7 +396,7 @@ static int writeData(WriterAVCallData_t *call)
ic = 0;
iov[ic++].iov_base = PesHeader;
//if (initialHeader)
if (!avc3)
{
if (CodecData)
{

View File

@@ -100,7 +100,7 @@ const uint8_t Head[] = {0, 0, 0, 1};
static int32_t initialHeader = 1;
static uint32_t NalLengthBytes = 1;
static int avc3 = 0;
static int sps_pps_in_stream = 0;
/* ***************************** */
/* Prototypes */
/* ***************************** */
@@ -263,12 +263,23 @@ static int32_t writeData(void *_call)
(call->len > 3) && ((call->data[0] == 0x00 && call->data[1] == 0x00 && call->data[2] == 0x00 && call->data[3] == 0x01) ||
(call->data[0] == 0xff && call->data[1] == 0xff && call->data[2] == 0xff && call->data[3] == 0xff))))
{
uint32_t i = 0;
uint8_t InsertPrivData = !sps_pps_in_stream;
uint32_t PacketLength = 0;
uint32_t FakeStartCode = /*(call->Version << 8) | */PES_VERSION_FAKE_START_CODE;
uint32_t FakeStartCode = PES_VERSION_FAKE_START_CODE;
iov[ic++].iov_base = PesHeader;
initialHeader = 0;
if (initialHeader)
while (InsertPrivData && i < 36 && (call->len - i) > 5)
{
if ((call->data[i] == 0x00 && call->data[i + 1] == 0x00 && call->data[i + 2] == 0x00 && call->data[i + 3] == 0x01 && (call->data[i + 4] == 0x67 || call->data[i + 4] == 0x68)))
{
InsertPrivData = 0;
sps_pps_in_stream = 1;
}
i += 1;
}
if (InsertPrivData && call->private_size > 0 /*&& initialHeader*/) // some rtsp streams can update codec data at runtime
{
initialHeader = 0;
iov[ic].iov_base = call->private_data;
@@ -299,7 +310,7 @@ static int32_t writeData(void *_call)
return 0;
}
if (initialHeader)
if (!avc3)
{
uint8_t *private_data = call->private_data;
uint32_t private_size = call->private_size;