libeplayer3: sync with max_10

Origin commit data
------------------
Branch: master
Commit: 61a2a148d5
Author: vanhofen <vanhofen@gmx.de>
Date: 2023-01-24 (Tue, 24 Jan 2023)

Origin message was:
------------------
- libeplayer3: sync with max_10

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

------------------
This commit was generated by Migit
This commit is contained in:
vanhofen
2023-01-24 21:00:47 +01:00
parent 85d1f1edf4
commit 272d5b11ce
65 changed files with 1100 additions and 959 deletions

View File

@@ -107,7 +107,7 @@ static void update_finish_timeout()
* this is the reason for additional validation when we what to close immediately
*/
if (!progressive_playback && 0 == ret && currPts >= maxInjectedPts &&
((currPts - maxInjectedPts) / 90000) < 2)
((currPts - maxInjectedPts) / 90000) < 2)
{
/* close immediately
*/
@@ -271,7 +271,7 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
}
while ((flag == 0 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF) ||
(flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF))
(flag == 1 && hasfillerThreadStarted[id] == 1 && avContextTab[0] != NULL && avContextTab[0]->pb != NULL && rwdiff > FILLBUFDIFF))
{
if (0 == PlaybackDieNow(0))
{
@@ -335,9 +335,13 @@ static void ffmpeg_filler(Context_t *context, int32_t id, int32_t *inpause, int3
if (size > 0)
{
if (flag == 1 && hasfillerThreadStarted[id] == 2) break;
if (flag == 1 && hasfillerThreadStarted[id] == 2)
break;
len = ffmpeg_read_org(avContextTab[0]->pb->opaque, buf, size);
if (flag == 1 && hasfillerThreadStarted[id] == 2) break;
if (flag == 1 && hasfillerThreadStarted[id] == 2)
break;
ffmpeg_printf(20, "buffer-status (free buffer=%d)\n", rwdiff - FILLBUFDIFF - len);

View File

@@ -85,7 +85,6 @@ static int32_t selectContainer(Context_t *context, char *extension)
return ret;
}
static int Command(Context_t *context, ContainerCmd_t command, void *argument __attribute__((unused)))
{
int ret = 0;
@@ -117,7 +116,6 @@ static int Command(Context_t *context, ContainerCmd_t command, void *argument __
return ret;
}
ContainerHandler_t ContainerHandler =
{
"Output",

View File

@@ -56,12 +56,6 @@
/* Makros/Constants */
/* ***************************** */
#if (LIBAVFORMAT_VERSION_MAJOR > 56)
#define TS_BYTES_SEEKING 0
#else
#define TS_BYTES_SEEKING 1
#endif
/* Some STB with old kernels have problem with default
* read/write functions in ffmpeg which use open/read
* due to this we set own which use fopen/fread from
@@ -122,12 +116,37 @@ static int32_t mutexInitialized = 0;
/* ***************************** */
static int32_t container_ffmpeg_seek_bytes(off_t pos);
static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute);
//static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec);
static int32_t container_ffmpeg_get_length(Context_t *context, int64_t *length);
static int64_t calcPts(uint32_t avContextIdx, AVStream *stream, int64_t pts);
static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t pts);
void LinuxDvbBuffSetStamp(void *stamp);
static int32_t container_ffmpeg_stop(Context_t *context);
static char *g_graphic_sub_path;
const char *GetGraphicSubPath()
{
return g_graphic_sub_path;
}
void E2iSendMsg(const char *format, ...)
{
va_list args;
va_start(args, format);
vfprintf(stderr, format, args);
va_end(args);
}
void E2iStartMsg(void)
{
flockfile(stderr);
}
void E2iEndMsg(void)
{
funlockfile(stderr);
}
/* Progressive playback means that we play local file
* but this local file can grows up, for example
* we start playback before download was finished
@@ -179,7 +198,6 @@ static int32_t Write(Write_FN WriteFun, Context_t *context, void *privateData, i
return ret;
}
#include "buff_ffmpeg.c"
#include "wrapped_ffmpeg.c"
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
@@ -205,6 +223,10 @@ static int32_t aac_latm_software_decode = 0;
static int32_t ac3_software_decode = 0;
static int32_t eac3_software_decode = 0;
static int32_t dts_software_decode = 0;
static int32_t amr_software_decode = 1;
static int32_t vorbis_software_decode = 1;
static int32_t opus_software_decode = 1;
static int32_t pcm_resampling = 1;
static int32_t stereo_software_decoder = 0;
static int32_t insert_pcm_as_lpcm = 0;
@@ -263,6 +285,21 @@ void dts_software_decoder_set(const int32_t val)
dts_software_decode = val;
}
void amr_software_decoder_set(const int32_t val)
{
amr_software_decode = val;
}
void vorbis_software_decoder_set(const int32_t val)
{
vorbis_software_decode = val;
}
void opus_software_decoder_set(const int32_t val)
{
opus_software_decode = val;
}
void stereo_software_decoder_set(const int32_t val)
{
stereo_software_decoder = val;
@@ -327,7 +364,15 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
#endif
case AV_CODEC_ID_RV10:
case AV_CODEC_ID_RV20:
return "V_RMV";
return "V_RV20";
case AV_CODEC_ID_RV30:
return "V_RV30";
case AV_CODEC_ID_RV40:
return "V_RV40";
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(58, 21, 100)
case AV_CODEC_ID_AVS2:
return "V_AVS2";
#endif
case AV_CODEC_ID_MPEG4:
return "V_MPEG4";
#if LIBAVCODEC_VERSION_MAJOR < 53
@@ -336,7 +381,7 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
case AV_CODEC_ID_MSMPEG4V1:
case AV_CODEC_ID_MSMPEG4V2:
case AV_CODEC_ID_MSMPEG4V3:
return "V_DIVX3";
return "V_MPEG4"; //"V_DIVX3";
case AV_CODEC_ID_WMV1:
*version = 1;
return "V_WMV";
@@ -370,10 +415,17 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
MPEG4AudioConfig m4ac;
int off = avpriv_mpeg4audio_get_config(&m4ac, extradata, extradata_size * 8, 1);
ffmpeg_printf(1, "aac [%d] off[%d]\n", m4ac.object_type, off);
if (off < 0 || 2 != m4ac.object_type)
if (off < 0)
{
return "A_IPCM";
}
else if (0 == m4ac.chan_config && STB_HISILICON != GetSTBType())
{
// according to https://wiki.multimedia.cx/index.php/ADTS
// "MPEG-4 Channel Configuration - in the case of 0, the channel configuration is sent via an inband PCE"
// we already have AAC_LATM formatter which will include PCE
return (aac_latm_software_decode) ? "A_IPCM" : "A_AAC_LATM";
}
}
return (aac_software_decode) ? "A_IPCM" : "A_AAC";
case AV_CODEC_ID_AAC_LATM:
@@ -385,6 +437,7 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
case AV_CODEC_ID_DTS:
return (dts_software_decode) ? "A_IPCM" : "A_DTS";
case AV_CODEC_ID_WMAV1:
return "A_IPCM";
case AV_CODEC_ID_WMAV2:
return (wma_software_decode) ? "A_IPCM" : "A_WMA";
case AV_CODEC_ID_WMAPRO:
@@ -397,8 +450,6 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
return "A_IPCM";
case AV_CODEC_ID_RA_288:
return "A_IPCM";
case AV_CODEC_ID_VORBIS:
return "A_IPCM";
case AV_CODEC_ID_FLAC:
return "A_IPCM";
case AV_CODEC_ID_PCM_S8:
@@ -417,8 +468,12 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
case AV_CODEC_ID_PCM_U32BE:
return pcm_resampling ? "A_IPCM" : "A_PCM";
case AV_CODEC_ID_AMR_NB:
return "A_IPCM";//return "A_AMR";
case AV_CODEC_ID_AMR_WB:
return amr_software_decode ? "A_IPCM" : "A_AMR";
case AV_CODEC_ID_VORBIS:
return vorbis_software_decode ? "A_IPCM" : "A_VORBIS";
case AV_CODEC_ID_OPUS :
return opus_software_decode ? "A_IPCM" : "A_OPUS";
/* In exteplayer3 embedded text subtitle simple printed
* to output like other data. Maybe worth to consider is to use
* linux socket or pipe to put
@@ -431,8 +486,6 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
#endif
return "S_TEXT/ASS"; /* Hellmaster1024: seems to be ASS instead of SSA */
case AV_CODEC_ID_DVD_SUBTITLE:
case AV_CODEC_ID_DVB_SUBTITLE:
case AV_CODEC_ID_XSUB:
case AV_CODEC_ID_MOV_TEXT:
case AV_CODEC_ID_DVB_TELETEXT:
// case CODEC_ID_DVB_TELETEXT:
@@ -447,6 +500,10 @@ static char *Codec2Encoding(int32_t codec_id, int32_t media_type, uint8_t *extra
return "S_TEXT/WEBVTT";
case AV_CODEC_ID_HDMV_PGS_SUBTITLE:
return "S_GRAPHIC/PGS";
case AV_CODEC_ID_DVB_SUBTITLE:
return "S_GRAPHIC/DVB";
case AV_CODEC_ID_XSUB:
return "S_GRAPHIC/XSUB";
default:
ffmpeg_err("Codec ID %d (%.8x) not found\n", codec_id, codec_id);
// Default to injected-pcm for unhandled audio types.
@@ -477,7 +534,7 @@ static int64_t doCalcPts(int64_t start_time, const AVRational time_base, int64_t
}
else
{
pts &= 0x01FFFFFFFF; // PES header can handle only 33 bit PTS
pts &= 0x01FFFFFFFFull; // PES header can handle only 33 bit PTS
}
return pts;
@@ -564,10 +621,15 @@ static void FFMPEGThread(Context_t *context)
int32_t out_channels = 2;
uint64_t out_channel_layout = AV_CH_LAYOUT_STEREO;
uint32_t cAVIdx = 0;
void *stamp = 0;
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(56, 34, 100)
#ifdef __sh__
Mpeg4P2Context *mpeg4p2_context = NULL;
#else
Mpeg4P2Context *mpeg4p2_context = mpeg4p2_context_open();
#endif
#endif
#ifdef HAVE_FLV2MPEG4_CONVERTER
Flv2Mpeg4Context flv2mpeg4_context;
memset(&flv2mpeg4_context, 0, sizeof(Flv2Mpeg4Context));
@@ -581,11 +643,9 @@ static void FFMPEGThread(Context_t *context)
}
ffmpeg_printf(10, "Running!\n");
#ifdef __sh__
uint32_t bufferSize = 0;
context->output->Command(context, OUTPUT_GET_BUFFER_SIZE, &bufferSize);
ffmpeg_printf(10, "bufferSize [%u]\n", bufferSize);
#endif
int8_t isWaitingForFinish = 0;
@@ -595,11 +655,11 @@ static void FFMPEGThread(Context_t *context)
* we will not wait here because we can still fill
* DVB drivers buffers at PAUSE time
*
* In the future we can add buffering queue before injection in to
* AUDIO, VIDEO decoders, so we can not wait here
*/
#ifdef __sh__
//IF MOVIE IS PAUSED, WAIT
/* ST DVB drivers skip data if they are written during pause
* so, we must wait here if there is not buffering queue
*/
if (0 == bufferSize && context->playback->isPaused)
{
ffmpeg_printf(20, "paused\n");
@@ -704,6 +764,12 @@ static void FFMPEGThread(Context_t *context)
}
}
reset_finish_timeout();
/*
if (bufferSize > 0)
{
context->output->Command(context, OUTPUT_CLEAR, NULL);
}
*/
}
else
{
@@ -846,7 +912,7 @@ static void FFMPEGThread(Context_t *context)
#endif
#ifdef HAVE_FLV2MPEG4_CONVERTER
if (get_codecpar(avContextTab[cAVIdx]->streams[packet.stream_index])->codec_id == AV_CODEC_ID_FLV1 &&
0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7))
0 == memcmp(videoTrack->Encoding, "V_MPEG4", 7))
{
flv2mpeg4_write_packet(context, &flv2mpeg4_context, videoTrack, cAVIdx, &currentVideoPts, &latestPts, &packet);
update_max_injected_pts(latestPts);
@@ -967,7 +1033,9 @@ static void FFMPEGThread(Context_t *context)
pcmExtradata.bits_per_coded_sample = get_codecpar(audioTrack->stream)->bits_per_coded_sample;
pcmExtradata.sample_rate = get_codecpar(audioTrack->stream)->sample_rate;
pcmExtradata.bit_rate = get_codecpar(audioTrack->stream)->bit_rate;
pcmExtradata.ffmpeg_codec_id = get_codecpar(audioTrack->stream)->codec_id;
pcmExtradata.block_align = get_codecpar(audioTrack->stream)->block_align;
pcmExtradata.frame_size = get_codecpar(audioTrack->stream)->frame_size;
pcmExtradata.codec_id = get_codecpar(audioTrack->stream)->codec_id;
pcmExtradata.bResampling = restart_audio_resampling;
uint8_t *pAudioExtradata = get_codecpar(audioTrack->stream)->extradata;
@@ -1136,7 +1204,7 @@ static void FFMPEGThread(Context_t *context)
if (e < 0)
{
ffmpeg_err("swr_init: %d (icl=%d ocl=%d isr=%d osr=%d isf=%d osf=%d\n",
-e, (int32_t)c->channel_layout, (int32_t)out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16);
-e, (int32_t)c->channel_layout, (int32_t)out_channel_layout, c->sample_rate, out_sample_rate, c->sample_fmt, AV_SAMPLE_FMT_S16);
swr_free(&swr);
swr = NULL;
}
@@ -1152,11 +1220,11 @@ static void FFMPEGThread(Context_t *context)
continue;
}
int64_t next_in_pts = av_rescale(wrapped_frame_get_best_effort_timestamp(decoded_frame),
((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate,
((AVStream *) audioTrack->stream)->time_base.den);
((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate,
((AVStream *) audioTrack->stream)->time_base.den);
int64_t next_out_pts = av_rescale(swr_next_pts(swr, next_in_pts),
((AVStream *) audioTrack->stream)->time_base.den,
((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate);
((AVStream *) audioTrack->stream)->time_base.den,
((AVStream *) audioTrack->stream)->time_base.num * (int64_t)out_sample_rate * c->sample_rate);
currentAudioPts = audioTrack->pts = pts = calcPts(cAVIdx, audioTrack->stream, next_out_pts);
out_samples = swr_convert(swr, &output[0], out_samples, (const uint8_t **) &decoded_frame->data[0], in_samples);
@@ -1168,9 +1236,9 @@ static void FFMPEGThread(Context_t *context)
pcmExtradata.sample_rate = out_sample_rate;
// The data described by the sample format is always in native-endian order
#ifdef WORDS_BIGENDIAN
pcmExtradata.ffmpeg_codec_id = AV_CODEC_ID_PCM_S16BE;
pcmExtradata.codec_id = AV_CODEC_ID_PCM_S16BE;
#else
pcmExtradata.ffmpeg_codec_id = AV_CODEC_ID_PCM_S16LE;
pcmExtradata.codec_id = AV_CODEC_ID_PCM_S16LE;
#endif
//////////////////////////////////////////////////////////////////////
@@ -1215,6 +1283,27 @@ static void FFMPEGThread(Context_t *context)
ffmpeg_err("(aac) writing data to audio device failed\n");
}
}
else if (pcmExtradata.codec_id == AV_CODEC_ID_VORBIS || pcmExtradata.codec_id == AV_CODEC_ID_OPUS ||
pcmExtradata.codec_id == AV_CODEC_ID_WMAV1 || pcmExtradata.codec_id == AV_CODEC_ID_WMAV2 ||
pcmExtradata.codec_id == AV_CODEC_ID_WMAPRO || pcmExtradata.codec_id == AV_CODEC_ID_WMALOSSLESS)
{
avOut.data = packet.data;
avOut.len = packet.size;
avOut.pts = pts;
avOut.extradata = (uint8_t *) &pcmExtradata;
avOut.extralen = sizeof(pcmExtradata);
avOut.frameRate = 0;
avOut.timeScale = 0;
avOut.width = 0;
avOut.height = 0;
avOut.type = "audio";
pcmExtradata.private_data = pAudioExtradata;
pcmExtradata.private_size = audioExtradataSize;
if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0)
{
ffmpeg_err("writing data to audio device failed\n");
}
}
else
{
avOut.data = packet.data;
@@ -1250,15 +1339,19 @@ static void FFMPEGThread(Context_t *context)
// duration in milliseconds
duration = (int64_t)av_rescale(get_packet_duration(&packet), (int64_t)stream->time_base.num * 1000, stream->time_base.den);
}
if (duration > 0)
if (duration > 0 || duration == -1)
{
SubtitleOut_t subOut;
memset(&subOut, 0, sizeof(subOut));
subOut.trackId = pid;
subOut.data = (uint8_t *)packet.data;
subOut.pts = pts;
subOut.trackId = pid;
subOut.data = (uint8_t *)packet.data;
subOut.len = packet.size;
subOut.pts = pts;
subOut.durationMS = duration;
subOut.extradata = get_codecpar(stream)->extradata;
subOut.extralen = get_codecpar(stream)->extradata_size;
subOut.width = get_codecpar(stream)->width;;
subOut.height = get_codecpar(stream)->height;;
if (Write(context->output->subtitle->Write, context, &subOut, pts) < 0)
{
ffmpeg_err("writing data to teletext fifo failed\n");
@@ -1281,7 +1374,7 @@ static void FFMPEGThread(Context_t *context)
/*
if(ffmpegStatus == AVERROR(EAGAIN))
{
continue;
continue;
}
*/
ffmpegStatus = 0;
@@ -1309,18 +1402,8 @@ static void FFMPEGThread(Context_t *context)
int64_t tmpLength = 0;
if (0 == container_ffmpeg_get_length(context, &tmpLength) && tmpLength > 0 && get_play_pts() > 0)
{
#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{
seek_target_bytes = 0;
do_seek_target_bytes = 1;
}
else
#endif
{
seek_target_seconds = 0;
do_seek_target_seconds = 1;
}
seek_target_seconds = 0;
do_seek_target_seconds = 1;
bEndProcess = 0;
context->output->Command(context, OUTPUT_CLEAR, NULL);
context->output->Command(context, OUTPUT_PLAY, NULL);
@@ -1556,7 +1639,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
}
#ifdef USE_CUSTOM_IO
if (0 == strstr(filename, "://") ||
0 == strncmp(filename, "file://", 7))
0 == strncmp(filename, "file://", 7))
{
AVIOContext *avio_ctx = NULL;
custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t));
@@ -1608,11 +1691,11 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
}
if (0 == strncmp(filename, "rtmp://", 7) ||
0 == strncmp(filename, "rtmpe://", 8) ||
0 == strncmp(filename, "rtmps://", 8) ||
0 == strncmp(filename, "rtmpt://", 8) ||
0 == strncmp(filename, "rtmpte://", 9) ||
0 == strncmp(filename, "rtmpts://", 9))
0 == strncmp(filename, "rtmpe://", 8) ||
0 == strncmp(filename, "rtmps://", 8) ||
0 == strncmp(filename, "rtmpt://", 8) ||
0 == strncmp(filename, "rtmpte://", 9) ||
0 == strncmp(filename, "rtmpts://", 9))
{
/* At first we need to check which protocol
* implementations we have
@@ -1652,7 +1735,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
* only by librtmp
*/
if (strstr(filename, " token=") ||
strstr(filename, " jtv="))
strstr(filename, " jtv="))
{
rtmpProtoImplType = RTMP_LIBRTMP;
}
@@ -1802,7 +1885,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
}
}
else if (0 == strncmp(filename, "http://", 7) ||
0 == strncmp(filename, "https://", 8))
0 == strncmp(filename, "https://", 8))
{
char num[16];
@@ -1822,8 +1905,8 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
if (avContextTab[AVIdx] != NULL && ((err = avformat_open_input(&avContextTab[AVIdx], filename, fmt, pavio_opts)) != 0))
{
if (rtmp_proto_impl == 0 && //err == AVERROR_UNKNOWN &&
rtmpProtoImplType == RTMP_NATIVE &&
numOfRTMPImpl > 1)
rtmpProtoImplType == RTMP_NATIVE &&
numOfRTMPImpl > 1)
{
// retry with librtmp
err = avformat_open_input(&avContextTab[AVIdx], filename + 2, fmt, pavio_opts);
@@ -1836,7 +1919,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
ffmpeg_err("avformat_open_input failed %d (%s)\n", err, filename);
av_strerror(err, error, 512);
fprintf(stderr, "{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
E2iSendMsg("{\"FF_ERROR\":{\"msg\":\"%s\",\"code\":%i}}\n", error, err);
if (avio_opts != NULL)
{
@@ -1848,7 +1931,7 @@ int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uin
}
if (avContextTab[AVIdx] != NULL)
{
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59,0,100)
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 0, 100)
avContextTab[AVIdx]->iformat->flags |= AVFMT_SEEK_TO_PTS;
#endif
avContextTab[AVIdx]->flags = AVFMT_FLAG_GENPTS;
@@ -1961,7 +2044,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
context->playback->abortRequested = 0;
int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \
playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0);
if (0 != res)
{
@@ -1971,7 +2054,7 @@ int32_t container_ffmpeg_init(Context_t *context, PlayFiles_t *playFilesNames)
if (playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0')
{
res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \
playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1);
}
if (0 != res)
@@ -2029,7 +2112,6 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
if ((avContextTab[0] != NULL) && (FFMPEG_DEBUG_LEVEL > 0))
av_dump_format(avContextTab[0], 0, filename, 0);
uint32_t cAVIdx = 0;
for (cAVIdx = 0; cAVIdx < IPTV_AV_CONTEXT_MAX_NUM; cAVIdx += 1)
@@ -2142,9 +2224,9 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
}
encoding = Codec2Encoding((int32_t)get_codecpar(stream)->codec_id, (int32_t)get_codecpar(stream)->codec_type, \
(uint8_t *)get_codecpar(stream)->extradata, \
(int)get_codecpar(stream)->extradata_size, \
(int)get_codecpar(stream)->profile, &version);
(uint8_t *)get_codecpar(stream)->extradata, \
(int)get_codecpar(stream)->extradata_size, \
(int)get_codecpar(stream)->profile, &version);
if (encoding != NULL && !strncmp(encoding, "A_IPCM", 6) && insert_pcm_as_lpcm)
{
@@ -2348,7 +2430,7 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_AAC)
{
if (0 == strncmp(avContext->iformat->name, "mpegts", 6) ||
0 == strncmp(avContext->iformat->name, "hls,", 4))
0 == strncmp(avContext->iformat->name, "hls,", 4))
{
const char marker[] = "ADTS";
track.aacbuflen = sizeof(marker) / sizeof(char);
@@ -2381,15 +2463,16 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
int32_t object_type = 2; // LC
int32_t sample_index = aac_get_sample_rate_index(get_codecpar(stream)->sample_rate);
int32_t chan_config = get_codecpar(stream)->channels - 1;
int32_t chan_config = get_chan_config(get_codecpar(stream)->channels);
ffmpeg_printf(1, "aac object_type %d\n", object_type);
ffmpeg_printf(1, "aac sample_index %d\n", sample_index);
ffmpeg_printf(1, "aac chan_config %d\n", chan_config);
int off = -1;
if (get_codecpar(stream)->extradata_size >= 2)
{
MPEG4AudioConfig m4ac;
int off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
off = avpriv_mpeg4audio_get_config(&m4ac, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size * 8, 1);
if (off >= 0)
{
object_type = m4ac.object_type;
@@ -2406,12 +2489,26 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
ffmpeg_printf(1, "aac sample_index %d\n", sample_index);
ffmpeg_printf(1, "aac chan_config %d\n", chan_config);
if (off >= 0 && chan_config == 0) // channel config must be send in the inband PCE
{
track.aacbuf = malloc(AAC_HEADER_LENGTH + MAX_PCE_SIZE);
GetBitContext gb;
PutBitContext pb;
init_put_bits(&pb, track.aacbuf + AAC_HEADER_LENGTH, MAX_PCE_SIZE);
init_get_bits8(&gb, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
skip_bits_long(&gb, off + 3);
put_bits(&pb, 3, 5); //ID_PCE
track.aacbuflen = AAC_HEADER_LENGTH + (avpriv_copy_pce_data(&pb, &gb) + 3) / 8;
flush_put_bits(&pb);
}
else
{
track.aacbuflen = AAC_HEADER_LENGTH;
track.aacbuf = malloc(AAC_HEADER_LENGTH + 1);
}
// https://wiki.multimedia.cx/index.php/ADTS
object_type -= 1; //ADTS - profile, the MPEG-4 Audio Object Type minus 1
track.aacbuflen = AAC_HEADER_LENGTH;
track.aacbuf = malloc(8);
track.aacbuf[0] = 0xFF;
track.aacbuf[1] = 0xF1;
//track.aacbuf[1] |=0x8;
@@ -2432,46 +2529,34 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
ffmpeg_err("AV_CODEC_ID_AAC extradata not available\n");
}
*/
}
#ifdef __sh__
else if (get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV1 ||
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2 ||
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO ||
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0)
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAV2 ||
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMAPRO ||
get_codecpar(stream)->codec_id == AV_CODEC_ID_WMALOSSLESS) //if (get_codecpar(stream)->extradata_size > 0)
{
ffmpeg_printf(10, "Create WMA ExtraData\n");
uint16_t channels = get_codecpar(stream)->channels;
uint32_t rate = get_codecpar(stream)->sample_rate;
uint32_t bitrate = get_codecpar(stream)->bit_rate;
uint16_t block_align = get_codecpar(stream)->block_align;
uint16_t depth = get_codecpar(stream)->bits_per_coded_sample;
uint32_t codec_data_size = get_codecpar(stream)->extradata_size;
uint8_t *codec_data_pointer = get_codecpar(stream)->extradata;
// type_specific_data
#define WMA_VERSION_1 0x160
#define WMA_VERSION_2_9 0x161
#define WMA_VERSION_9_PRO 0x162
#define WMA_LOSSLESS 0x163
uint16_t codec_id = 0;
switch (get_codecpar(stream)->codec_id)
{
//TODO: What code for lossless ?
case AV_CODEC_ID_WMALOSSLESS:
codec_id = WMA_LOSSLESS;
codec_id = 0x163; // WMA_LOSSLESS
break;
case AV_CODEC_ID_WMAPRO:
codec_id = WMA_VERSION_9_PRO;
codec_id = 0x162; // WMA_VERSION_9_PRO
break;
case AV_CODEC_ID_WMAV2:
codec_id = WMA_VERSION_2_9 ;
codec_id = 0x161; // WMA_VERSION_2_9
break;
case AV_CODEC_ID_WMAV1:
default:
codec_id = WMA_VERSION_1;
codec_id = 0x160; // WMA_VERSION_1
break;
}
#ifdef __sh__
track.aacbuflen = 104 + get_codecpar(stream)->extradata_size;
track.aacbuf = malloc(track.aacbuflen);
memset(track.aacbuf, 0, track.aacbuflen);
@@ -2539,48 +2624,10 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
memcpy(track.aacbuf + 94, &get_codecpar(stream)->extradata_size, 2); //bits_per_sample
memcpy(track.aacbuf + 96, get_codecpar(stream)->extradata, get_codecpar(stream)->extradata_size);
#else
track.aacbuflen = 18 + get_codecpar(stream)->extradata_size;
track.aacbuf = malloc(track.aacbuflen);
memset(track.aacbuf, 0, track.aacbuflen);
uint8_t *data = track.aacbuf;
/* codec tag */
*(data++) = codec_id & 0xff;
*(data++) = (codec_id >> 8) & 0xff;
/* channels */
*(data++) = channels & 0xff;
*(data++) = (channels >> 8) & 0xff;
/* sample rate */
*(data++) = rate & 0xff;
*(data++) = (rate >> 8) & 0xff;
*(data++) = (rate >> 16) & 0xff;
*(data++) = (rate >> 24) & 0xff;
/* byte rate */
bitrate /= 8;
*(data++) = bitrate & 0xff;
*(data++) = (bitrate >> 8) & 0xff;
*(data++) = (bitrate >> 16) & 0xff;
*(data++) = (bitrate >> 24) & 0xff;
/* block align */
*(data++) = block_align & 0xff;
*(data++) = (block_align >> 8) & 0xff;
/* word size */
*(data++) = depth & 0xff;
*(data++) = (depth >> 8) & 0xff;
/* codec data size */
*(data++) = codec_data_size & 0xff;
*(data++) = (codec_data_size >> 8) & 0xff;
memcpy(data, codec_data_pointer, codec_data_size);
#endif
ffmpeg_printf(1, "aacbuf:\n");
//Hexdump(track.aacbuf, track.aacbuflen);
//ffmpeg_printf(1, "priv_data:\n");
//Hexdump(get_codecpar(stream)->priv_data, track.aacbuflen);
track.have_aacheader = 1;
}
#endif
if (context->manager->audio)
{
@@ -2606,12 +2653,16 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
{
if (get_codecpar(stream)->codec_id != AV_CODEC_ID_SSA &&
#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(55, 3, 100)
get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_ASS &&
#endif
get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_WEBVTT)
get_codecpar(stream)->codec_id != AV_CODEC_ID_SUBRIP &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_TEXT &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_SRT &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_WEBVTT &&
((get_codecpar(stream)->codec_id != AV_CODEC_ID_HDMV_PGS_SUBTITLE &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_DVB_SUBTITLE &&
get_codecpar(stream)->codec_id != AV_CODEC_ID_XSUB) ||
!GetGraphicSubPath() || !GetGraphicSubPath()[0]))
{
ffmpeg_printf(10, "subtitle with not supported codec codec_id[%u]\n", (uint32_t)get_codecpar(stream)->codec_id);
}
@@ -2638,10 +2689,6 @@ int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32
ffmpeg_printf(10, "Stream has no duration so we take the duration from context\n");
track.duration = (int64_t) avContext->duration / 1000;
}
track.extraData = get_codecpar(stream)->extradata;
track.extraSize = get_codecpar(stream)->extradata_size;
ffmpeg_printf(1, "subtitle codec %d\n", get_codecpar(stream)->codec_id);
ffmpeg_printf(1, "subtitle width %d\n", get_codecpar(stream)->width);
ffmpeg_printf(1, "subtitle height %d\n", get_codecpar(stream)->height);
@@ -2868,101 +2915,6 @@ static int32_t container_ffmpeg_seek_bytes(off_t pos)
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
#if 0 //unused
/* seeking relative to a given byteposition N seconds ->for reverse playback needed */
static int32_t container_ffmpeg_seek_rel(Context_t *context, off_t pos, int64_t pts, int64_t sec)
{
Track_t *videoTrack = NULL;
Track_t *audioTrack = NULL;
Track_t *current = NULL;
seek_target_flag = 0;
ffmpeg_printf(10, "seeking %" PRId64 " sec relativ to %" PRId64 "\n", sec, pos);
context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack);
context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack);
if (videoTrack != NULL)
{
current = videoTrack;
}
else if (audioTrack != NULL)
{
current = audioTrack;
}
if (current == NULL)
{
ffmpeg_err("no track avaibale to seek\n");
return cERR_CONTAINER_FFMPEG_ERR;
}
if (pos == -1)
{
pos = avio_tell(avContextTab[0]->pb);
}
if (pts == -1)
{
pts = current->pts;
}
if (sec < 0)
{
seek_target_flag |= AVSEEK_FLAG_BACKWARD;
}
ffmpeg_printf(10, "iformat->flags %d\n", avContextTab[0]->iformat->flags);
#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{
if (avContextTab[0]->bit_rate)
{
sec *= avContextTab[0]->bit_rate / 8;
ffmpeg_printf(10, "bit_rate %d\n", avContextTab[0]->bit_rate);
}
else
{
sec *= 180000;
}
pos += sec;
if (pos < 0)
{
ffmpeg_err("end of file reached\n");
releaseMutex(__FILE__, __FUNCTION__, __LINE__);
return cERR_CONTAINER_FFMPEG_END_OF_FILE;
}
ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %f\n", pos, sec);
seek_target_bytes = pos;
do_seek_target_bytes = 1;
return pos;
}
else
#endif
{
sec += pts / 90000;
if (sec < 0)
{
sec = 0;
}
ffmpeg_printf(10, "2. seeking to position %" PRId64 " sec ->time base %f %d\n", sec, av_q2d(((AVStream *) current->stream)->time_base), AV_TIME_BASE);
seek_target_seconds = sec * AV_TIME_BASE;
do_seek_target_seconds = 1;
}
releaseMutex(__FILE__, __FUNCTION__, __LINE__);
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
#endif
static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t absolute)
{
Track_t *videoTrack = NULL;
@@ -3038,50 +2990,8 @@ static int32_t container_ffmpeg_seek(Context_t *context, int64_t sec, uint8_t ab
ffmpeg_printf(10, "iformat->flags 0x%08x\n", avContextTab[0]->iformat->flags);
#if defined(TS_BYTES_SEEKING) && TS_BYTES_SEEKING
if (avContextTab[0]->iformat->flags & AVFMT_TS_DISCONT)
{
/* konfetti: for ts streams seeking frame per seconds does not work (why?).
* I take this algo partly from ffplay.c.
*
* seeking per HTTP does still not work very good. forward seeks everytime
* about 10 seconds, backward does not work.
*/
getMutex(__FILE__, __FUNCTION__, __LINE__);
off_t pos = avio_tell(avContextTab[0]->pb);
releaseMutex(__FILE__, __FUNCTION__, __LINE__);
ffmpeg_printf(10, "pos %" PRId64 " %lld\n", pos, avContextTab[0]->bit_rate);
if (avContextTab[0]->bit_rate)
{
sec *= avContextTab[0]->bit_rate / 8;
ffmpeg_printf(10, "bit_rate %lld\n", avContextTab[0]->bit_rate);
}
else
{
sec *= 180000;
}
pos = sec;
if (pos < 0)
{
pos = 0;
}
ffmpeg_printf(10, "1. seeking to position %" PRId64 " bytes ->sec %lld\n", pos / AV_TIME_BASE, sec / AV_TIME_BASE);
seek_target_bytes = pos / AV_TIME_BASE;
do_seek_target_bytes = 1;
}
else
#endif
{
seek_target_seconds = sec;
do_seek_target_seconds = 1;
}
seek_target_seconds = sec;
do_seek_target_seconds = 1;
return cERR_CONTAINER_FFMPEG_NO_ERROR;
}
@@ -3374,11 +3284,11 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
ffmpeg_printf(50, "Command %d\n", command);
if (command != CONTAINER_SET_BUFFER_SEEK_TIME &&
command != CONTAINER_SET_BUFFER_SIZE &&
command != CONTAINER_GET_BUFFER_SIZE &&
command != CONTAINER_GET_BUFFER_STATUS &&
command != CONTAINER_STOP_BUFFER &&
command != CONTAINER_INIT && !avContextTab[0])
command != CONTAINER_SET_BUFFER_SIZE &&
command != CONTAINER_GET_BUFFER_SIZE &&
command != CONTAINER_GET_BUFFER_STATUS &&
command != CONTAINER_STOP_BUFFER &&
command != CONTAINER_INIT && !avContextTab[0])
{
return cERR_CONTAINER_FFMPEG_ERR;
}
@@ -3476,7 +3386,7 @@ static int32_t Command(Context_t *context, ContainerCmd_t command, void *argumen
return ret;
}
static char *FFMPEG_Capabilities[] = {"aac", "avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv", "wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "ra", "ram", "rm", "3gp", "amr", "webm", "m3u8", "mpd", NULL };
static char *FFMPEG_Capabilities[] = {"aac", "avi", "mkv", "mp4", "ts", "mov", "flv", "flac", "mp3", "mpg", "m2ts", "vob", "evo", "wmv", "wma", "asf", "mp2", "m4v", "m4a", "fla", "divx", "dat", "mpeg", "trp", "mts", "vdr", "ogg", "wav", "wtv", "asx", "mvi", "png", "jpg", "jpeg", "ra", "ram", "rm", "3gp", "amr", "rmvb", "rm", "webm", "opus", "m3u8", "mpd", NULL };
Container_t FFMPEGContainer =
{

View File

@@ -5,7 +5,6 @@
#include "flv2mpeg4/flv2mpeg4.h"
typedef struct
{
flv2mpeg4_CTX *ctx;
@@ -16,7 +15,6 @@ typedef struct
Track_t *track;
} Flv2Mpeg4Context;
static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe __attribute__((unused)), int pts __attribute__((unused)), const uint8_t *buf, int size)
{
Flv2Mpeg4Context *ctx = usr_data;
@@ -26,7 +24,7 @@ static int flv2mpeg4_context_write_packet_cb(void *usr_data, int keyframe __attr
}
AudioVideoOut_t avOut;
avOut.data = (char *)buf;
avOut.data = (unsigned char *)buf;
avOut.len = size;
avOut.pts = ctx->track->pts;
avOut.dts = ctx->track->dts;

View File

@@ -126,7 +126,6 @@ static int mpeg4p2_write_packet(Context_t *ctx, Mpeg4P2Context *mpeg4p2_ctx, Tra
{
ffmpeg_err("bsf setup failed error 0x%x\n", ret);
}
}
else
{

View File

@@ -145,13 +145,13 @@ static AVCodecContext *wrapped_avcodec_get_context(uint32_t cAVIdx, AVStream *st
avCodecCtx = avcodec_alloc_context3(NULL);
if (!avCodecCtx)
{
fprintf(stderr, "context3 alloc for stream %d failed\n", (int)stream->id);
ffmpeg_err("context3 alloc for stream %d failed\n", (int)stream->id);
return NULL;
}
if (avcodec_parameters_to_context(avCodecCtx, stream->codecpar) < 0)
{
fprintf(stderr, "parameters to context for stream %d failed\n", (int)stream->id);
ffmpeg_err("parameters to context for stream %d failed\n", (int)stream->id);
avcodec_free_context(&avCodecCtx);
return NULL;
}