early-access version 1680
This commit is contained in:
+1
@@ -303,6 +303,7 @@ OBJS-$(CONFIG_MATROSKA_MUXER) += matroskaenc.o matroska.o \
|
||||
av1.o avc.o hevc.o \
|
||||
flacenc_header.o avlanguage.o \
|
||||
vorbiscomment.o wv.o
|
||||
OBJS-$(CONFIG_MCC_DEMUXER) += mccdec.o subtitles.o
|
||||
OBJS-$(CONFIG_MD5_MUXER) += hashenc.o
|
||||
OBJS-$(CONFIG_MGSTS_DEMUXER) += mgsts.o
|
||||
OBJS-$(CONFIG_MICRODVD_DEMUXER) += microdvddec.o subtitles.o
|
||||
|
||||
+1
-1
@@ -169,7 +169,7 @@ static int adts_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return 0;
|
||||
if (!par->extradata_size) {
|
||||
uint8_t *side_data;
|
||||
int side_data_size = 0, ret;
|
||||
int side_data_size, ret;
|
||||
|
||||
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
|
||||
&side_data_size);
|
||||
|
||||
+2
@@ -230,6 +230,7 @@ extern AVInputFormat ff_lvf_demuxer;
|
||||
extern AVInputFormat ff_lxf_demuxer;
|
||||
extern AVInputFormat ff_m4v_demuxer;
|
||||
extern AVOutputFormat ff_m4v_muxer;
|
||||
extern AVInputFormat ff_mcc_demuxer;
|
||||
extern AVOutputFormat ff_md5_muxer;
|
||||
extern AVInputFormat ff_matroska_demuxer;
|
||||
extern AVOutputFormat ff_matroska_muxer;
|
||||
@@ -487,6 +488,7 @@ extern AVInputFormat ff_image_pbm_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_pcx_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_pgmyuv_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_pgm_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_pgx_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_pictor_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_png_pipe_demuxer;
|
||||
extern AVInputFormat ff_image_ppm_pipe_demuxer;
|
||||
|
||||
Vendored
+5
-1
@@ -29,6 +29,7 @@
|
||||
#define APM_VS12_CHUNK_SIZE 76
|
||||
#define APM_MAX_READ_SIZE 4096
|
||||
|
||||
#define APM_TAG_CODEC 0x2000
|
||||
#define APM_TAG_VS12 MKTAG('v', 's', '1', '2')
|
||||
#define APM_TAG_DATA MKTAG('D', 'A', 'T', 'A')
|
||||
|
||||
@@ -74,6 +75,9 @@ static void apm_parse_vs12(APMVS12Chunk *vs12, const uint8_t *buf)
|
||||
|
||||
static int apm_probe(const AVProbeData *p)
|
||||
{
|
||||
if (AV_RL16(p->buf) != APM_TAG_CODEC)
|
||||
return 0;
|
||||
|
||||
if (p->buf_size < 100)
|
||||
return 0;
|
||||
|
||||
@@ -103,7 +107,7 @@ static int apm_read_header(AVFormatContext *s)
|
||||
if (st->codecpar->bits_per_coded_sample != 4)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
if (st->codecpar->codec_tag != 0x2000)
|
||||
if (st->codecpar->codec_tag != APM_TAG_CODEC)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
/* ff_get_wav_header() does most of the work, but we need to fix a few things. */
|
||||
|
||||
+1
-1
@@ -119,7 +119,7 @@ static int flush_packet(AVFormatContext *format_context, AVPacket *packet)
|
||||
AVIOContext *io_context = format_context->pb;
|
||||
AVStream *codec_stream = format_context->streams[0];
|
||||
uint8_t *side_data = NULL;
|
||||
int side_data_size = 0;
|
||||
int side_data_size;
|
||||
|
||||
av_assert0(apng->prev_packet);
|
||||
|
||||
|
||||
Vendored
+8
-3
@@ -81,7 +81,7 @@ static int au_read_annotation(AVFormatContext *s, int size)
|
||||
AVBPrint bprint;
|
||||
char * key = NULL;
|
||||
char * value = NULL;
|
||||
int i;
|
||||
int ret, i;
|
||||
|
||||
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
@@ -92,7 +92,9 @@ static int au_read_annotation(AVFormatContext *s, int size)
|
||||
if (c == '\0') {
|
||||
state = PARSE_FINISHED;
|
||||
} else if (c == '=') {
|
||||
av_bprint_finalize(&bprint, &key);
|
||||
ret = av_bprint_finalize(&bprint, &key);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
av_bprint_init(&bprint, 64, AV_BPRINT_SIZE_UNLIMITED);
|
||||
state = PARSE_VALUE;
|
||||
} else {
|
||||
@@ -143,6 +145,7 @@ static int au_read_header(AVFormatContext *s)
|
||||
int bps, ba = 0;
|
||||
enum AVCodecID codec;
|
||||
AVStream *st;
|
||||
int ret;
|
||||
|
||||
tag = avio_rl32(pb);
|
||||
if (tag != MKTAG('.', 's', 'n', 'd'))
|
||||
@@ -161,7 +164,9 @@ static int au_read_header(AVFormatContext *s)
|
||||
|
||||
if (size > 24) {
|
||||
/* parse annotation field to get metadata */
|
||||
au_read_annotation(s, size - 24);
|
||||
ret = au_read_annotation(s, size - 24);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
codec = ff_codec_get_id(codec_au_tags, id);
|
||||
|
||||
Vendored
+7
-11
@@ -363,11 +363,11 @@ int ff_av1_parse_seq_header(AV1SequenceParameters *seq, const uint8_t *buf, int
|
||||
|
||||
int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
|
||||
{
|
||||
AVIOContext *seq_pb = NULL, *meta_pb = NULL;
|
||||
AVIOContext *meta_pb;
|
||||
AV1SequenceParameters seq_params;
|
||||
PutBitContext pbc;
|
||||
uint8_t header[4];
|
||||
uint8_t *seq, *meta;
|
||||
uint8_t header[4], *meta;
|
||||
const uint8_t *seq;
|
||||
int64_t obu_size;
|
||||
int start_pos, type, temporal_id, spatial_id;
|
||||
int ret, nb_seq = 0, seq_size, meta_size;
|
||||
@@ -375,12 +375,9 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
|
||||
if (size <= 0)
|
||||
return AVERROR_INVALIDDATA;
|
||||
|
||||
ret = avio_open_dyn_buf(&seq_pb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = avio_open_dyn_buf(&meta_pb);
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
return ret;
|
||||
|
||||
while (size > 0) {
|
||||
int len = parse_obu_header(buf, size, &obu_size, &start_pos,
|
||||
@@ -401,7 +398,8 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
|
||||
avio_write(seq_pb, buf, len);
|
||||
seq = buf;
|
||||
seq_size = len;
|
||||
break;
|
||||
case AV1_OBU_METADATA:
|
||||
if (!obu_size) {
|
||||
@@ -417,8 +415,7 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
|
||||
buf += len;
|
||||
}
|
||||
|
||||
seq_size = avio_get_dyn_buf(seq_pb, &seq);
|
||||
if (!seq_size) {
|
||||
if (!nb_seq) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto fail;
|
||||
}
|
||||
@@ -447,7 +444,6 @@ int ff_isom_write_av1c(AVIOContext *pb, const uint8_t *buf, int size)
|
||||
avio_write(pb, meta, meta_size);
|
||||
|
||||
fail:
|
||||
ffio_free_dyn_buf(&seq_pb);
|
||||
ffio_free_dyn_buf(&meta_pb);
|
||||
|
||||
return ret;
|
||||
|
||||
Vendored
+2
-2
@@ -27,7 +27,7 @@
|
||||
#include "avc.h"
|
||||
#include "avio_internal.h"
|
||||
|
||||
static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
|
||||
static const uint8_t *avc_find_startcode_internal(const uint8_t *p, const uint8_t *end)
|
||||
{
|
||||
const uint8_t *a = p + 4 - ((intptr_t)p & 3);
|
||||
|
||||
@@ -65,7 +65,7 @@ static const uint8_t *ff_avc_find_startcode_internal(const uint8_t *p, const uin
|
||||
}
|
||||
|
||||
const uint8_t *ff_avc_find_startcode(const uint8_t *p, const uint8_t *end){
|
||||
const uint8_t *out= ff_avc_find_startcode_internal(p, end);
|
||||
const uint8_t *out = avc_find_startcode_internal(p, end);
|
||||
if(p<out && out<end && !out[-1]) out--;
|
||||
return out;
|
||||
}
|
||||
|
||||
+2
-1
@@ -2189,7 +2189,8 @@ uint8_t *av_stream_new_side_data(AVStream *stream,
|
||||
*
|
||||
* @param stream stream
|
||||
* @param type desired side information type
|
||||
* @param size pointer for side information size to store (optional)
|
||||
* @param size If supplied, *size will be set to the size of the side data
|
||||
* or to zero if the desired side data is not present.
|
||||
* @return pointer to data if present or NULL otherwise
|
||||
*/
|
||||
uint8_t *av_stream_get_side_data(const AVStream *stream,
|
||||
|
||||
Vendored
+3
@@ -67,7 +67,10 @@ const AVClass ffurl_context_class = {
|
||||
.option = options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.child_next = urlcontext_child_next,
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
.child_class_next = ff_urlcontext_child_class_next,
|
||||
#endif
|
||||
.child_class_iterate = ff_urlcontext_child_class_iterate,
|
||||
};
|
||||
/*@}*/
|
||||
|
||||
|
||||
+30
-17
@@ -48,10 +48,19 @@ static void *ff_avio_child_next(void *obj, void *prev)
|
||||
return prev ? NULL : s->opaque;
|
||||
}
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
static const AVClass *ff_avio_child_class_next(const AVClass *prev)
|
||||
{
|
||||
return prev ? NULL : &ffurl_context_class;
|
||||
}
|
||||
#endif
|
||||
|
||||
static const AVClass *child_class_iterate(void **iter)
|
||||
{
|
||||
const AVClass *c = *iter ? NULL : &ffurl_context_class;
|
||||
*iter = (void*)(uintptr_t)c;
|
||||
return c;
|
||||
}
|
||||
|
||||
#define OFFSET(x) offsetof(AVIOContext,x)
|
||||
#define E AV_OPT_FLAG_ENCODING_PARAM
|
||||
@@ -67,7 +76,10 @@ const AVClass ff_avio_class = {
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.option = ff_avio_options,
|
||||
.child_next = ff_avio_child_next,
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
.child_class_next = ff_avio_child_class_next,
|
||||
#endif
|
||||
.child_class_iterate = child_class_iterate,
|
||||
};
|
||||
|
||||
static void fill_buffer(AVIOContext *s);
|
||||
@@ -696,7 +708,7 @@ int avio_read_partial(AVIOContext *s, unsigned char *buf, int size)
|
||||
int len;
|
||||
|
||||
if (size < 0)
|
||||
return -1;
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if (s->read_packet && s->write_flag) {
|
||||
len = read_packet_wrapper(s, buf, size);
|
||||
@@ -1272,22 +1284,21 @@ typedef struct DynBuffer {
|
||||
static int dyn_buf_write(void *opaque, uint8_t *buf, int buf_size)
|
||||
{
|
||||
DynBuffer *d = opaque;
|
||||
unsigned new_size, new_allocated_size;
|
||||
unsigned new_size;
|
||||
|
||||
/* reallocate buffer if needed */
|
||||
new_size = (unsigned)d->pos + buf_size;
|
||||
new_allocated_size = d->allocated_size;
|
||||
if (new_size < d->pos || new_size > INT_MAX/2)
|
||||
return -1;
|
||||
while (new_size > new_allocated_size) {
|
||||
if (!new_allocated_size)
|
||||
new_allocated_size = new_size;
|
||||
else
|
||||
new_allocated_size += new_allocated_size / 2 + 1;
|
||||
}
|
||||
|
||||
if (new_allocated_size > d->allocated_size) {
|
||||
if (new_size < d->pos || new_size > INT_MAX)
|
||||
return AVERROR(ERANGE);
|
||||
if (new_size > d->allocated_size) {
|
||||
unsigned new_allocated_size = d->allocated_size ? d->allocated_size
|
||||
: new_size;
|
||||
int err;
|
||||
while (new_size > new_allocated_size)
|
||||
new_allocated_size += new_allocated_size / 2 + 1;
|
||||
|
||||
new_allocated_size = FFMIN(new_allocated_size, INT_MAX);
|
||||
|
||||
if ((err = av_reallocp(&d->buffer, new_allocated_size)) < 0) {
|
||||
d->allocated_size = 0;
|
||||
d->size = 0;
|
||||
@@ -1325,8 +1336,10 @@ static int64_t dyn_buf_seek(void *opaque, int64_t offset, int whence)
|
||||
offset += d->pos;
|
||||
else if (whence == SEEK_END)
|
||||
offset += d->size;
|
||||
if (offset < 0 || offset > 0x7fffffffLL)
|
||||
return -1;
|
||||
if (offset < 0)
|
||||
return AVERROR(EINVAL);
|
||||
if (offset > INT_MAX)
|
||||
return AVERROR(ERANGE);
|
||||
d->pos = offset;
|
||||
return 0;
|
||||
}
|
||||
@@ -1337,7 +1350,7 @@ static int url_open_dyn_buf_internal(AVIOContext **s, int max_packet_size)
|
||||
unsigned io_buffer_size = max_packet_size ? max_packet_size : 1024;
|
||||
|
||||
if (sizeof(DynBuffer) + io_buffer_size < io_buffer_size)
|
||||
return -1;
|
||||
return AVERROR(ERANGE);
|
||||
d = av_mallocz(sizeof(DynBuffer) + io_buffer_size);
|
||||
if (!d)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -1361,7 +1374,7 @@ int avio_open_dyn_buf(AVIOContext **s)
|
||||
int ffio_open_dyn_packet_buf(AVIOContext **s, int max_packet_size)
|
||||
{
|
||||
if (max_packet_size <= 0)
|
||||
return -1;
|
||||
return AVERROR(EINVAL);
|
||||
return url_open_dyn_buf_internal(s, max_packet_size);
|
||||
}
|
||||
|
||||
|
||||
+14
@@ -2001,6 +2001,20 @@ static int open_demux_for_component(AVFormatContext *s, struct representation *p
|
||||
st->id = i;
|
||||
avcodec_parameters_copy(st->codecpar, ist->codecpar);
|
||||
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
|
||||
|
||||
// copy disposition
|
||||
st->disposition = ist->disposition;
|
||||
|
||||
// copy side data
|
||||
for (int i = 0; i < ist->nb_side_data; i++) {
|
||||
const AVPacketSideData *sd_src = &ist->side_data[i];
|
||||
uint8_t *dst_data;
|
||||
|
||||
dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
|
||||
if (!dst_data)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(dst_data, sd_src->data, sd_src->size);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
+25
-11
@@ -115,6 +115,7 @@ typedef struct OutputStream {
|
||||
int64_t last_dts, last_pts;
|
||||
int last_flags;
|
||||
int bit_rate;
|
||||
int first_segment_bit_rate;
|
||||
SegmentType segment_type; /* segment type selected for this particular stream */
|
||||
const char *format_name;
|
||||
const char *extension_name;
|
||||
@@ -171,6 +172,7 @@ typedef struct DASHContext {
|
||||
const char *user_agent;
|
||||
AVDictionary *http_opts;
|
||||
int hls_playlist;
|
||||
const char *hls_master_name;
|
||||
int http_persistent;
|
||||
int master_playlist_created;
|
||||
AVIOContext *mpd_out;
|
||||
@@ -196,6 +198,7 @@ typedef struct DASHContext {
|
||||
int target_latency_refid;
|
||||
AVRational min_playback_rate;
|
||||
AVRational max_playback_rate;
|
||||
int64_t update_period;
|
||||
} DASHContext;
|
||||
|
||||
static struct codec_string {
|
||||
@@ -839,8 +842,12 @@ static int write_adaptation_set(AVFormatContext *s, AVIOContext *out, int as_ind
|
||||
continue;
|
||||
|
||||
if (os->bit_rate > 0)
|
||||
snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"",
|
||||
os->bit_rate);
|
||||
snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->bit_rate);
|
||||
else if (final) {
|
||||
int average_bit_rate = os->pos * 8 * AV_TIME_BASE / c->total_duration;
|
||||
snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", average_bit_rate);
|
||||
} else if (os->first_segment_bit_rate > 0)
|
||||
snprintf(bandwidth_str, sizeof(bandwidth_str), " bandwidth=\"%d\"", os->first_segment_bit_rate);
|
||||
|
||||
if (as->media_type == AVMEDIA_TYPE_VIDEO) {
|
||||
avio_printf(out, "\t\t\t<Representation id=\"%d\" mimeType=\"video/%s\" codecs=\"%s\"%s width=\"%d\" height=\"%d\"",
|
||||
@@ -1178,6 +1185,8 @@ static int write_manifest(AVFormatContext *s, int final)
|
||||
char now_str[100];
|
||||
if (c->use_template && !c->use_timeline)
|
||||
update_period = 500;
|
||||
if (c->update_period)
|
||||
update_period = c->update_period;
|
||||
avio_printf(out, "\tminimumUpdatePeriod=\"PT%"PRId64"S\"\n", update_period);
|
||||
if (!c->ldash)
|
||||
avio_printf(out, "\tsuggestedPresentationDelay=\"PT%"PRId64"S\"\n", c->last_duration / AV_TIME_BASE);
|
||||
@@ -1261,9 +1270,9 @@ static int write_manifest(AVFormatContext *s, int final)
|
||||
return 0;
|
||||
|
||||
if (*c->dirname)
|
||||
snprintf(filename_hls, sizeof(filename_hls), "%smaster.m3u8", c->dirname);
|
||||
snprintf(filename_hls, sizeof(filename_hls), "%s%s", c->dirname, c->hls_master_name);
|
||||
else
|
||||
snprintf(filename_hls, sizeof(filename_hls), "master.m3u8");
|
||||
snprintf(filename_hls, sizeof(filename_hls), "%s", c->hls_master_name);
|
||||
|
||||
snprintf(temp_filename, sizeof(temp_filename), use_rename ? "%s.tmp" : "%s", filename_hls);
|
||||
|
||||
@@ -1304,7 +1313,13 @@ static int write_manifest(AVFormatContext *s, int final)
|
||||
OutputStream *os = &c->streams[i];
|
||||
char *agroup = NULL;
|
||||
char *codec_str_ptr = NULL;
|
||||
int stream_bitrate = st->codecpar->bit_rate + os->muxer_overhead;
|
||||
int stream_bitrate = os->muxer_overhead;
|
||||
if (os->bit_rate > 0)
|
||||
stream_bitrate += os->bit_rate;
|
||||
else if (final)
|
||||
stream_bitrate += os->pos * 8 * AV_TIME_BASE / c->total_duration;
|
||||
else if (os->first_segment_bit_rate > 0)
|
||||
stream_bitrate += os->first_segment_bit_rate;
|
||||
if (st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO)
|
||||
continue;
|
||||
if (os->segment_type != SEGMENT_TYPE_MP4)
|
||||
@@ -1957,11 +1972,8 @@ static int dash_flush(AVFormatContext *s, int final, int stream)
|
||||
os->total_pkt_size = 0;
|
||||
os->total_pkt_duration = 0;
|
||||
|
||||
if (!os->bit_rate) {
|
||||
// calculate average bitrate of first segment
|
||||
int64_t bitrate = (int64_t) range_length * 8 * (c->use_timeline ? os->ctx->streams[0]->time_base.den : AV_TIME_BASE) / duration;
|
||||
if (bitrate >= 0)
|
||||
os->bit_rate = bitrate;
|
||||
if (!os->bit_rate && !os->first_segment_bit_rate) {
|
||||
os->first_segment_bit_rate = (int64_t) range_length * 8 * AV_TIME_BASE / duration;
|
||||
}
|
||||
add_segment(os, os->filename, os->start_pts, os->max_pts - os->start_pts, os->pos, range_length, index_length, next_exp_index);
|
||||
av_log(s, AV_LOG_VERBOSE, "Representation %d media segment %d written to: %s\n", i, os->segment_index, os->full_path);
|
||||
@@ -2292,7 +2304,7 @@ static int dash_write_trailer(AVFormatContext *s)
|
||||
|
||||
if (c->hls_playlist && c->master_playlist_created) {
|
||||
char filename[1024];
|
||||
snprintf(filename, sizeof(filename), "%smaster.m3u8", c->dirname);
|
||||
snprintf(filename, sizeof(filename), "%s%s", c->dirname, c->hls_master_name);
|
||||
dashenc_delete_file(s, filename);
|
||||
}
|
||||
}
|
||||
@@ -2349,6 +2361,7 @@ static const AVOption options[] = {
|
||||
{ "http_user_agent", "override User-Agent field in HTTP header", OFFSET(user_agent), AV_OPT_TYPE_STRING, {.str = NULL}, 0, 0, E},
|
||||
{ "http_persistent", "Use persistent HTTP connections", OFFSET(http_persistent), AV_OPT_TYPE_BOOL, {.i64 = 0 }, 0, 1, E },
|
||||
{ "hls_playlist", "Generate HLS playlist files(master.m3u8, media_%d.m3u8)", OFFSET(hls_playlist), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
|
||||
{ "hls_master_name", "HLS master playlist name", OFFSET(hls_master_name), AV_OPT_TYPE_STRING, {.str = "master.m3u8"}, 0, 0, E },
|
||||
{ "streaming", "Enable/Disable streaming mode of output. Each frame will be moof fragment", OFFSET(streaming), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
|
||||
{ "timeout", "set timeout for socket I/O operations", OFFSET(timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT_MAX, .flags = E },
|
||||
{ "index_correction", "Enable/Disable segment index correction logic", OFFSET(index_correction), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
|
||||
@@ -2370,6 +2383,7 @@ static const AVOption options[] = {
|
||||
{ "target_latency", "Set desired target latency for Low-latency dash", OFFSET(target_latency), AV_OPT_TYPE_DURATION, { .i64 = 0 }, 0, INT_MAX, E },
|
||||
{ "min_playback_rate", "Set desired minimum playback rate", OFFSET(min_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
|
||||
{ "max_playback_rate", "Set desired maximum playback rate", OFFSET(max_playback_rate), AV_OPT_TYPE_RATIONAL, { .dbl = 1.0 }, 0.5, 1.5, E },
|
||||
{ "update_period", "Set the mpd update interval", OFFSET(update_period), AV_OPT_TYPE_INT64, {.i64 = 0}, 0, INT64_MAX, E},
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
||||
Vendored
+75
-55
@@ -131,10 +131,10 @@ static void print_fps(double d, const char *postfix)
|
||||
av_log(NULL, AV_LOG_INFO, "%1.0fk %s", d / 1000, postfix);
|
||||
}
|
||||
|
||||
static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
|
||||
static void dump_metadata(void *ctx, const AVDictionary *m, const char *indent)
|
||||
{
|
||||
if (m && !(av_dict_count(m) == 1 && av_dict_get(m, "language", NULL, 0))) {
|
||||
AVDictionaryEntry *tag = NULL;
|
||||
const AVDictionaryEntry *tag = NULL;
|
||||
|
||||
av_log(ctx, AV_LOG_INFO, "%sMetadata:\n", indent);
|
||||
while ((tag = av_dict_get(m, "", tag, AV_DICT_IGNORE_SUFFIX)))
|
||||
@@ -158,7 +158,7 @@ static void dump_metadata(void *ctx, AVDictionary *m, const char *indent)
|
||||
}
|
||||
|
||||
/* param change side data*/
|
||||
static void dump_paramchange(void *ctx, AVPacketSideData *sd)
|
||||
static void dump_paramchange(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
int size = sd->size;
|
||||
const uint8_t *data = sd->data;
|
||||
@@ -211,7 +211,7 @@ static void dump_paramchange(void *ctx, AVPacketSideData *sd)
|
||||
|
||||
return;
|
||||
fail:
|
||||
av_log(ctx, AV_LOG_ERROR, "unknown param");
|
||||
av_log(ctx, AV_LOG_ERROR, "unknown param\n");
|
||||
}
|
||||
|
||||
/* replaygain side data*/
|
||||
@@ -235,15 +235,15 @@ static void print_peak(void *ctx, const char *str, uint32_t peak)
|
||||
av_log(ctx, AV_LOG_INFO, ", ");
|
||||
}
|
||||
|
||||
static void dump_replaygain(void *ctx, AVPacketSideData *sd)
|
||||
static void dump_replaygain(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
AVReplayGain *rg;
|
||||
const AVReplayGain *rg;
|
||||
|
||||
if (sd->size < sizeof(*rg)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data");
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data\n");
|
||||
return;
|
||||
}
|
||||
rg = (AVReplayGain*)sd->data;
|
||||
rg = (const AVReplayGain *)sd->data;
|
||||
|
||||
print_gain(ctx, "track gain", rg->track_gain);
|
||||
print_peak(ctx, "track peak", rg->track_peak);
|
||||
@@ -251,16 +251,16 @@ static void dump_replaygain(void *ctx, AVPacketSideData *sd)
|
||||
print_peak(ctx, "album peak", rg->album_peak);
|
||||
}
|
||||
|
||||
static void dump_stereo3d(void *ctx, AVPacketSideData *sd)
|
||||
static void dump_stereo3d(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
AVStereo3D *stereo;
|
||||
const AVStereo3D *stereo;
|
||||
|
||||
if (sd->size < sizeof(*stereo)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data");
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
stereo = (AVStereo3D *)sd->data;
|
||||
stereo = (const AVStereo3D *)sd->data;
|
||||
|
||||
av_log(ctx, AV_LOG_INFO, "%s", av_stereo3d_type_name(stereo->type));
|
||||
|
||||
@@ -268,12 +268,12 @@ static void dump_stereo3d(void *ctx, AVPacketSideData *sd)
|
||||
av_log(ctx, AV_LOG_INFO, " (inverted)");
|
||||
}
|
||||
|
||||
static void dump_audioservicetype(void *ctx, AVPacketSideData *sd)
|
||||
static void dump_audioservicetype(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
enum AVAudioServiceType *ast = (enum AVAudioServiceType *)sd->data;
|
||||
const enum AVAudioServiceType *ast = (const enum AVAudioServiceType *)sd->data;
|
||||
|
||||
if (sd->size < sizeof(*ast)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data");
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -311,12 +311,12 @@ static void dump_audioservicetype(void *ctx, AVPacketSideData *sd)
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_cpb(void *ctx, AVPacketSideData *sd)
|
||||
static void dump_cpb(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
AVCPBProperties *cpb = (AVCPBProperties *)sd->data;
|
||||
const AVCPBProperties *cpb = (const AVCPBProperties *)sd->data;
|
||||
|
||||
if (sd->size < sizeof(*cpb)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data");
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -334,8 +334,10 @@ static void dump_cpb(void *ctx, AVPacketSideData *sd)
|
||||
av_log(ctx, AV_LOG_INFO, "vbv_delay: %"PRIu64"", cpb->vbv_delay);
|
||||
}
|
||||
|
||||
static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
|
||||
AVMasteringDisplayMetadata* metadata = (AVMasteringDisplayMetadata*)sd->data;
|
||||
static void dump_mastering_display_metadata(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
const AVMasteringDisplayMetadata *metadata =
|
||||
(const AVMasteringDisplayMetadata *)sd->data;
|
||||
av_log(ctx, AV_LOG_INFO, "Mastering Display Metadata, "
|
||||
"has_primaries:%d has_luminance:%d "
|
||||
"r(%5.4f,%5.4f) g(%5.4f,%5.4f) b(%5.4f %5.4f) wp(%5.4f, %5.4f) "
|
||||
@@ -351,21 +353,23 @@ static void dump_mastering_display_metadata(void *ctx, AVPacketSideData* sd) {
|
||||
av_q2d(metadata->min_luminance), av_q2d(metadata->max_luminance));
|
||||
}
|
||||
|
||||
static void dump_content_light_metadata(void *ctx, AVPacketSideData* sd)
|
||||
static void dump_content_light_metadata(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
AVContentLightMetadata* metadata = (AVContentLightMetadata*)sd->data;
|
||||
const AVContentLightMetadata *metadata =
|
||||
(const AVContentLightMetadata *)sd->data;
|
||||
av_log(ctx, AV_LOG_INFO, "Content Light Level Metadata, "
|
||||
"MaxCLL=%d, MaxFALL=%d",
|
||||
metadata->MaxCLL, metadata->MaxFALL);
|
||||
}
|
||||
|
||||
static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *sd)
|
||||
static void dump_spherical(void *ctx, const AVCodecParameters *par,
|
||||
const AVPacketSideData *sd)
|
||||
{
|
||||
AVSphericalMapping *spherical = (AVSphericalMapping *)sd->data;
|
||||
const AVSphericalMapping *spherical = (const AVSphericalMapping *)sd->data;
|
||||
double yaw, pitch, roll;
|
||||
|
||||
if (sd->size < sizeof(*spherical)) {
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data");
|
||||
av_log(ctx, AV_LOG_ERROR, "invalid data\n");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -388,9 +392,10 @@ static void dump_spherical(void *ctx, AVCodecParameters *par, AVPacketSideData *
|
||||
}
|
||||
}
|
||||
|
||||
static void dump_dovi_conf(void *ctx, AVPacketSideData* sd)
|
||||
static void dump_dovi_conf(void *ctx, const AVPacketSideData *sd)
|
||||
{
|
||||
AVDOVIDecoderConfigurationRecord *dovi = (AVDOVIDecoderConfigurationRecord *)sd->data;
|
||||
const AVDOVIDecoderConfigurationRecord *dovi =
|
||||
(const AVDOVIDecoderConfigurationRecord *)sd->data;
|
||||
|
||||
av_log(ctx, AV_LOG_INFO, "version: %d.%d, profile: %d, level: %d, "
|
||||
"rpu flag: %d, el flag: %d, bl flag: %d, compatibility id: %d",
|
||||
@@ -402,7 +407,7 @@ static void dump_dovi_conf(void *ctx, AVPacketSideData* sd)
|
||||
dovi->dv_bl_signal_compatibility_id);
|
||||
}
|
||||
|
||||
static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
|
||||
static void dump_sidedata(void *ctx, const AVStream *st, const char *indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
@@ -410,10 +415,10 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
|
||||
av_log(ctx, AV_LOG_INFO, "%sSide data:\n", indent);
|
||||
|
||||
for (i = 0; i < st->nb_side_data; i++) {
|
||||
AVPacketSideData sd = st->side_data[i];
|
||||
const AVPacketSideData *sd = &st->side_data[i];
|
||||
av_log(ctx, AV_LOG_INFO, "%s ", indent);
|
||||
|
||||
switch (sd.type) {
|
||||
switch (sd->type) {
|
||||
case AV_PKT_DATA_PALETTE:
|
||||
av_log(ctx, AV_LOG_INFO, "palette");
|
||||
break;
|
||||
@@ -422,55 +427,55 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
|
||||
break;
|
||||
case AV_PKT_DATA_PARAM_CHANGE:
|
||||
av_log(ctx, AV_LOG_INFO, "paramchange: ");
|
||||
dump_paramchange(ctx, &sd);
|
||||
dump_paramchange(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_H263_MB_INFO:
|
||||
av_log(ctx, AV_LOG_INFO, "H.263 macroblock info");
|
||||
break;
|
||||
case AV_PKT_DATA_REPLAYGAIN:
|
||||
av_log(ctx, AV_LOG_INFO, "replaygain: ");
|
||||
dump_replaygain(ctx, &sd);
|
||||
dump_replaygain(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_DISPLAYMATRIX:
|
||||
av_log(ctx, AV_LOG_INFO, "displaymatrix: rotation of %.2f degrees",
|
||||
av_display_rotation_get((int32_t *)sd.data));
|
||||
av_display_rotation_get((const int32_t *)sd->data));
|
||||
break;
|
||||
case AV_PKT_DATA_STEREO3D:
|
||||
av_log(ctx, AV_LOG_INFO, "stereo3d: ");
|
||||
dump_stereo3d(ctx, &sd);
|
||||
dump_stereo3d(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_AUDIO_SERVICE_TYPE:
|
||||
av_log(ctx, AV_LOG_INFO, "audio service type: ");
|
||||
dump_audioservicetype(ctx, &sd);
|
||||
dump_audioservicetype(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_QUALITY_STATS:
|
||||
av_log(ctx, AV_LOG_INFO, "quality factor: %"PRId32", pict_type: %c",
|
||||
AV_RL32(sd.data), av_get_picture_type_char(sd.data[4]));
|
||||
AV_RL32(sd->data), av_get_picture_type_char(sd->data[4]));
|
||||
break;
|
||||
case AV_PKT_DATA_CPB_PROPERTIES:
|
||||
av_log(ctx, AV_LOG_INFO, "cpb: ");
|
||||
dump_cpb(ctx, &sd);
|
||||
dump_cpb(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_MASTERING_DISPLAY_METADATA:
|
||||
dump_mastering_display_metadata(ctx, &sd);
|
||||
dump_mastering_display_metadata(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_SPHERICAL:
|
||||
av_log(ctx, AV_LOG_INFO, "spherical: ");
|
||||
dump_spherical(ctx, st->codecpar, &sd);
|
||||
dump_spherical(ctx, st->codecpar, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_CONTENT_LIGHT_LEVEL:
|
||||
dump_content_light_metadata(ctx, &sd);
|
||||
dump_content_light_metadata(ctx, sd);
|
||||
break;
|
||||
case AV_PKT_DATA_ICC_PROFILE:
|
||||
av_log(ctx, AV_LOG_INFO, "ICC Profile");
|
||||
break;
|
||||
case AV_PKT_DATA_DOVI_CONF:
|
||||
av_log(ctx, AV_LOG_INFO, "DOVI configuration record: ");
|
||||
dump_dovi_conf(ctx, &sd);
|
||||
dump_dovi_conf(ctx, sd);
|
||||
break;
|
||||
default:
|
||||
av_log(ctx, AV_LOG_INFO,
|
||||
"unknown side data type %d (%d bytes)", sd.type, sd.size);
|
||||
"unknown side data type %d (%d bytes)", sd->type, sd->size);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -479,14 +484,14 @@ static void dump_sidedata(void *ctx, AVStream *st, const char *indent)
|
||||
}
|
||||
|
||||
/* "user interface" functions */
|
||||
static void dump_stream_format(AVFormatContext *ic, int i,
|
||||
static void dump_stream_format(const AVFormatContext *ic, int i,
|
||||
int index, int is_output)
|
||||
{
|
||||
char buf[256];
|
||||
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
|
||||
AVStream *st = ic->streams[i];
|
||||
AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
char *separator = ic->dump_separator;
|
||||
const AVStream *st = ic->streams[i];
|
||||
const AVDictionaryEntry *lang = av_dict_get(st->metadata, "language", NULL, 0);
|
||||
const char *separator = ic->dump_separator;
|
||||
AVCodecContext *avctx;
|
||||
int ret;
|
||||
|
||||
@@ -500,6 +505,8 @@ static void dump_stream_format(AVFormatContext *ic, int i,
|
||||
return;
|
||||
}
|
||||
|
||||
#if FF_API_LAVF_AVCTX
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
// Fields which are missing from AVCodecParameters need to be taken from the AVCodecContext
|
||||
avctx->properties = st->codec->properties;
|
||||
avctx->codec = st->codec->codec;
|
||||
@@ -507,6 +514,8 @@ static void dump_stream_format(AVFormatContext *ic, int i,
|
||||
avctx->qmax = st->codec->qmax;
|
||||
avctx->coded_width = st->codec->coded_width;
|
||||
avctx->coded_height = st->codec->coded_height;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
if (separator)
|
||||
av_opt_set(avctx, "dump_separator", separator, 0);
|
||||
@@ -541,7 +550,13 @@ static void dump_stream_format(AVFormatContext *ic, int i,
|
||||
int fps = st->avg_frame_rate.den && st->avg_frame_rate.num;
|
||||
int tbr = st->r_frame_rate.den && st->r_frame_rate.num;
|
||||
int tbn = st->time_base.den && st->time_base.num;
|
||||
#if FF_API_LAVF_AVCTX
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
int tbc = st->codec->time_base.den && st->codec->time_base.num;
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#else
|
||||
int tbc = 0;
|
||||
#endif
|
||||
|
||||
if (fps || tbr || tbn || tbc)
|
||||
av_log(NULL, AV_LOG_INFO, "%s", separator);
|
||||
@@ -552,8 +567,12 @@ static void dump_stream_format(AVFormatContext *ic, int i,
|
||||
print_fps(av_q2d(st->r_frame_rate), tbn || tbc ? "tbr, " : "tbr");
|
||||
if (tbn)
|
||||
print_fps(1 / av_q2d(st->time_base), tbc ? "tbn, " : "tbn");
|
||||
#if FF_API_LAVF_AVCTX
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
if (tbc)
|
||||
print_fps(1 / av_q2d(st->codec->time_base), "tbc");
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
}
|
||||
|
||||
if (st->disposition & AV_DISPOSITION_DEFAULT)
|
||||
@@ -647,7 +666,7 @@ void av_dump_format(AVFormatContext *ic, int index,
|
||||
}
|
||||
|
||||
for (i = 0; i < ic->nb_chapters; i++) {
|
||||
AVChapter *ch = ic->chapters[i];
|
||||
const AVChapter *ch = ic->chapters[i];
|
||||
av_log(NULL, AV_LOG_INFO, " Chapter #%d:%d: ", index, i);
|
||||
av_log(NULL, AV_LOG_INFO,
|
||||
"start %f, ", ch->start * av_q2d(ch->time_base));
|
||||
@@ -660,17 +679,18 @@ void av_dump_format(AVFormatContext *ic, int index,
|
||||
if (ic->nb_programs) {
|
||||
int j, k, total = 0;
|
||||
for (j = 0; j < ic->nb_programs; j++) {
|
||||
AVDictionaryEntry *name = av_dict_get(ic->programs[j]->metadata,
|
||||
"name", NULL, 0);
|
||||
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
|
||||
const AVProgram *program = ic->programs[j];
|
||||
const AVDictionaryEntry *name = av_dict_get(program->metadata,
|
||||
"name", NULL, 0);
|
||||
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", program->id,
|
||||
name ? name->value : "");
|
||||
dump_metadata(NULL, ic->programs[j]->metadata, " ");
|
||||
for (k = 0; k < ic->programs[j]->nb_stream_indexes; k++) {
|
||||
dump_stream_format(ic, ic->programs[j]->stream_index[k],
|
||||
dump_metadata(NULL, program->metadata, " ");
|
||||
for (k = 0; k < program->nb_stream_indexes; k++) {
|
||||
dump_stream_format(ic, program->stream_index[k],
|
||||
index, is_output);
|
||||
printed[ic->programs[j]->stream_index[k]] = 1;
|
||||
printed[program->stream_index[k]] = 1;
|
||||
}
|
||||
total += ic->programs[j]->nb_stream_indexes;
|
||||
total += program->nb_stream_indexes;
|
||||
}
|
||||
if (total < ic->nb_streams)
|
||||
av_log(NULL, AV_LOG_INFO, " No Program\n");
|
||||
|
||||
Vendored
+3
-2
@@ -406,9 +406,10 @@ static int dv_write_packet(struct AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
fsize = dv_assemble_frame(s, s->priv_data, s->streams[pkt->stream_index],
|
||||
pkt->data, pkt->size, &frame);
|
||||
if (fsize > 0) {
|
||||
avio_write(s->pb, frame, fsize);
|
||||
if (fsize < 0) {
|
||||
return fsize;
|
||||
}
|
||||
avio_write(s->pb, frame, fsize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+58
-1
@@ -19,6 +19,8 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include <stdatomic.h>
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/opt.h"
|
||||
#include "libavutil/time.h"
|
||||
@@ -77,6 +79,9 @@ typedef struct FifoContext {
|
||||
/* Value > 0 signals queue overflow */
|
||||
volatile uint8_t overflow_flag;
|
||||
|
||||
atomic_int_least64_t queue_duration;
|
||||
int64_t last_sent_dts;
|
||||
int64_t timeshift;
|
||||
} FifoContext;
|
||||
|
||||
typedef struct FifoThreadContext {
|
||||
@@ -98,9 +103,12 @@ typedef struct FifoThreadContext {
|
||||
* so finalization by calling write_trailer and ff_io_close must be done
|
||||
* before exiting / reinitialization of underlying muxer */
|
||||
uint8_t header_written;
|
||||
|
||||
int64_t last_received_dts;
|
||||
} FifoThreadContext;
|
||||
|
||||
typedef enum FifoMessageType {
|
||||
FIFO_NOOP,
|
||||
FIFO_WRITE_HEADER,
|
||||
FIFO_WRITE_PACKET,
|
||||
FIFO_FLUSH_OUTPUT
|
||||
@@ -159,6 +167,15 @@ static int fifo_thread_flush_output(FifoThreadContext *ctx)
|
||||
return av_write_frame(avf2, NULL);
|
||||
}
|
||||
|
||||
static int64_t next_duration(AVFormatContext *avf, AVPacket *pkt, int64_t *last_dts)
|
||||
{
|
||||
AVStream *st = avf->streams[pkt->stream_index];
|
||||
int64_t dts = av_rescale_q(pkt->dts, st->time_base, AV_TIME_BASE_Q);
|
||||
int64_t duration = (*last_dts == AV_NOPTS_VALUE ? 0 : dts - *last_dts);
|
||||
*last_dts = dts;
|
||||
return duration;
|
||||
}
|
||||
|
||||
static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
|
||||
{
|
||||
AVFormatContext *avf = ctx->avf;
|
||||
@@ -167,6 +184,9 @@ static int fifo_thread_write_packet(FifoThreadContext *ctx, AVPacket *pkt)
|
||||
AVRational src_tb, dst_tb;
|
||||
int ret, s_idx;
|
||||
|
||||
if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
|
||||
atomic_fetch_sub_explicit(&fifo->queue_duration, next_duration(avf, pkt, &ctx->last_received_dts), memory_order_relaxed);
|
||||
|
||||
if (ctx->drop_until_keyframe) {
|
||||
if (pkt->flags & AV_PKT_FLAG_KEY) {
|
||||
ctx->drop_until_keyframe = 0;
|
||||
@@ -209,6 +229,9 @@ static int fifo_thread_dispatch_message(FifoThreadContext *ctx, FifoMessage *msg
|
||||
{
|
||||
int ret = AVERROR(EINVAL);
|
||||
|
||||
if (msg->type == FIFO_NOOP)
|
||||
return 0;
|
||||
|
||||
if (!ctx->header_written) {
|
||||
ret = fifo_thread_write_header(ctx);
|
||||
if (ret < 0)
|
||||
@@ -390,12 +413,13 @@ static void *fifo_consumer_thread(void *data)
|
||||
AVFormatContext *avf = data;
|
||||
FifoContext *fifo = avf->priv_data;
|
||||
AVThreadMessageQueue *queue = fifo->queue;
|
||||
FifoMessage msg = {FIFO_WRITE_HEADER, {0}};
|
||||
FifoMessage msg = {fifo->timeshift ? FIFO_NOOP : FIFO_WRITE_HEADER, {0}};
|
||||
int ret;
|
||||
|
||||
FifoThreadContext fifo_thread_ctx;
|
||||
memset(&fifo_thread_ctx, 0, sizeof(FifoThreadContext));
|
||||
fifo_thread_ctx.avf = avf;
|
||||
fifo_thread_ctx.last_received_dts = AV_NOPTS_VALUE;
|
||||
|
||||
while (1) {
|
||||
uint8_t just_flushed = 0;
|
||||
@@ -429,6 +453,10 @@ static void *fifo_consumer_thread(void *data)
|
||||
if (just_flushed)
|
||||
av_log(avf, AV_LOG_INFO, "FIFO queue flushed\n");
|
||||
|
||||
if (fifo->timeshift)
|
||||
while (atomic_load_explicit(&fifo->queue_duration, memory_order_relaxed) < fifo->timeshift)
|
||||
av_usleep(10000);
|
||||
|
||||
ret = av_thread_message_queue_recv(queue, &msg, 0);
|
||||
if (ret < 0) {
|
||||
av_thread_message_queue_set_err_send(queue, ret);
|
||||
@@ -488,6 +516,8 @@ static int fifo_init(AVFormatContext *avf)
|
||||
" only when drop_pkts_on_overflow is also turned on\n");
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
atomic_init(&fifo->queue_duration, 0);
|
||||
fifo->last_sent_dts = AV_NOPTS_VALUE;
|
||||
|
||||
oformat = av_guess_format(fifo->format, avf->url, NULL);
|
||||
if (!oformat) {
|
||||
@@ -563,6 +593,9 @@ static int fifo_write_packet(AVFormatContext *avf, AVPacket *pkt)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (fifo->timeshift && pkt->dts != AV_NOPTS_VALUE)
|
||||
atomic_fetch_add_explicit(&fifo->queue_duration, next_duration(avf, pkt, &fifo->last_sent_dts), memory_order_relaxed);
|
||||
|
||||
return ret;
|
||||
fail:
|
||||
if (pkt)
|
||||
@@ -576,6 +609,27 @@ static int fifo_write_trailer(AVFormatContext *avf)
|
||||
int ret;
|
||||
|
||||
av_thread_message_queue_set_err_recv(fifo->queue, AVERROR_EOF);
|
||||
if (fifo->timeshift) {
|
||||
int64_t now = av_gettime_relative();
|
||||
int64_t elapsed = 0;
|
||||
FifoMessage msg = {FIFO_NOOP};
|
||||
do {
|
||||
int64_t delay = av_gettime_relative() - now;
|
||||
if (delay < 0) { // Discontinuity?
|
||||
delay = 10000;
|
||||
now = av_gettime_relative();
|
||||
} else {
|
||||
now += delay;
|
||||
}
|
||||
atomic_fetch_add_explicit(&fifo->queue_duration, delay, memory_order_relaxed);
|
||||
elapsed += delay;
|
||||
if (elapsed > fifo->timeshift)
|
||||
break;
|
||||
av_usleep(10000);
|
||||
ret = av_thread_message_queue_send(fifo->queue, &msg, AV_THREAD_MESSAGE_NONBLOCK);
|
||||
} while (ret >= 0 || ret == AVERROR(EAGAIN));
|
||||
atomic_store(&fifo->queue_duration, INT64_MAX);
|
||||
}
|
||||
|
||||
ret = pthread_join(fifo->writer_thread, NULL);
|
||||
if (ret < 0) {
|
||||
@@ -630,6 +684,9 @@ static const AVOption options[] = {
|
||||
{"recover_any_error", "Attempt recovery regardless of type of the error", OFFSET(recover_any_error),
|
||||
AV_OPT_TYPE_BOOL, {.i64 = 0}, 0, 1, AV_OPT_FLAG_ENCODING_PARAM},
|
||||
|
||||
{"timeshift", "Delay fifo output", OFFSET(timeshift),
|
||||
AV_OPT_TYPE_DURATION, {.i64 = 0}, 0, INT64_MAX, AV_OPT_FLAG_ENCODING_PARAM},
|
||||
|
||||
{NULL},
|
||||
};
|
||||
|
||||
|
||||
+10
-15
@@ -514,8 +514,7 @@ static int amf_parse_object(AVFormatContext *s, AVStream *astream,
|
||||
if (key &&
|
||||
(ioc->seekable & AVIO_SEEKABLE_NORMAL) &&
|
||||
!strcmp(KEYFRAMES_TAG, key) && depth == 1)
|
||||
if (parse_keyframes_index(s, ioc,
|
||||
max_pos) < 0)
|
||||
if (parse_keyframes_index(s, ioc, max_pos) < 0)
|
||||
av_log(s, AV_LOG_ERROR, "Keyframe index parsing failed\n");
|
||||
else
|
||||
add_keyframes_index(s);
|
||||
@@ -732,8 +731,7 @@ static int flv_read_metabody(AVFormatContext *s, int64_t next_pos)
|
||||
astream = stream;
|
||||
if (flv->last_keyframe_stream_index == -1)
|
||||
flv->last_keyframe_stream_index = i;
|
||||
}
|
||||
else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||
} else if (stream->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE)
|
||||
dstream = stream;
|
||||
}
|
||||
|
||||
@@ -1058,8 +1056,7 @@ retry:
|
||||
if (type == 0 && dts == 0 || type < 0) {
|
||||
if (type < 0 && flv->validate_count &&
|
||||
flv->validate_index[0].pos > next &&
|
||||
flv->validate_index[0].pos - 4 < next
|
||||
) {
|
||||
flv->validate_index[0].pos - 4 < next) {
|
||||
av_log(s, AV_LOG_WARNING, "Adjusting next position due to index mismatch\n");
|
||||
next = flv->validate_index[0].pos - 4;
|
||||
}
|
||||
@@ -1120,7 +1117,6 @@ skip:
|
||||
st = create_stream(s, stream_types[stream_type]);
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
}
|
||||
av_log(s, AV_LOG_TRACE, "%d %X %d \n", stream_type, flags, st->discard);
|
||||
|
||||
@@ -1133,10 +1129,9 @@ skip:
|
||||
stream_type == FLV_STREAM_TYPE_AUDIO))
|
||||
av_add_index_entry(st, pos, dts, size, 0, AVINDEX_KEYFRAME);
|
||||
|
||||
if ( (st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || (stream_type == FLV_STREAM_TYPE_AUDIO)))
|
||||
||(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && (stream_type == FLV_STREAM_TYPE_VIDEO)))
|
||||
|| st->discard >= AVDISCARD_ALL
|
||||
) {
|
||||
if ((st->discard >= AVDISCARD_NONKEY && !((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY || stream_type == FLV_STREAM_TYPE_AUDIO)) ||
|
||||
(st->discard >= AVDISCARD_BIDIR && ((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_DISP_INTER && stream_type == FLV_STREAM_TYPE_VIDEO)) ||
|
||||
st->discard >= AVDISCARD_ALL) {
|
||||
avio_seek(s->pb, next, SEEK_SET);
|
||||
ret = FFERROR_REDO;
|
||||
goto leave;
|
||||
@@ -1299,10 +1294,10 @@ retry_duration:
|
||||
ff_add_param_change(pkt, channels, 0, sample_rate, 0, 0);
|
||||
}
|
||||
|
||||
if ( stream_type == FLV_STREAM_TYPE_AUDIO ||
|
||||
((flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY) ||
|
||||
stream_type == FLV_STREAM_TYPE_SUBTITLE ||
|
||||
stream_type == FLV_STREAM_TYPE_DATA)
|
||||
if (stream_type == FLV_STREAM_TYPE_AUDIO ||
|
||||
(flags & FLV_VIDEO_FRAMETYPE_MASK) == FLV_FRAME_KEY ||
|
||||
stream_type == FLV_STREAM_TYPE_SUBTITLE ||
|
||||
stream_type == FLV_STREAM_TYPE_DATA)
|
||||
pkt->flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
leave:
|
||||
|
||||
+1
-1
@@ -902,7 +902,7 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
if (par->codec_id == AV_CODEC_ID_AAC || par->codec_id == AV_CODEC_ID_H264
|
||||
|| par->codec_id == AV_CODEC_ID_MPEG4) {
|
||||
int side_size = 0;
|
||||
int side_size;
|
||||
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
||||
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
|
||||
ret = ff_alloc_extradata(par, side_size);
|
||||
|
||||
+1
-1
@@ -144,7 +144,7 @@ static int gif_read_header(AVFormatContext *s)
|
||||
AVBPrint bp;
|
||||
int block_size;
|
||||
|
||||
av_bprint_init(&bp, 0, -1);
|
||||
av_bprint_init(&bp, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
while ((block_size = avio_r8(pb)) != 0) {
|
||||
avio_read_to_bprint(pb, &bp, block_size);
|
||||
}
|
||||
|
||||
Vendored
+8
-10
@@ -1068,29 +1068,27 @@ int ff_hevc_annexb2mp4_buf(const uint8_t *buf_in, uint8_t **buf_out,
|
||||
int ff_isom_write_hvcc(AVIOContext *pb, const uint8_t *data,
|
||||
int size, int ps_array_completeness)
|
||||
{
|
||||
int ret = 0;
|
||||
uint8_t *buf, *end, *start = NULL;
|
||||
HEVCDecoderConfigurationRecord hvcc;
|
||||
|
||||
hvcc_init(&hvcc);
|
||||
uint8_t *buf, *end, *start;
|
||||
int ret;
|
||||
|
||||
if (size < 6) {
|
||||
/* We can't write a valid hvcC from the provided data */
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto end;
|
||||
return AVERROR_INVALIDDATA;
|
||||
} else if (*data == 1) {
|
||||
/* Data is already hvcC-formatted */
|
||||
avio_write(pb, data, size);
|
||||
goto end;
|
||||
return 0;
|
||||
} else if (!(AV_RB24(data) == 1 || AV_RB32(data) == 1)) {
|
||||
/* Not a valid Annex B start code prefix */
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto end;
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ret = ff_avc_parse_nal_units_buf(data, &start, &size);
|
||||
if (ret < 0)
|
||||
goto end;
|
||||
return ret;
|
||||
|
||||
hvcc_init(&hvcc);
|
||||
|
||||
buf = start;
|
||||
end = start + size;
|
||||
|
||||
Vendored
+14
@@ -1768,6 +1768,20 @@ static int set_stream_info_from_input_stream(AVStream *st, struct playlist *pls,
|
||||
else
|
||||
avpriv_set_pts_info(st, ist->pts_wrap_bits, ist->time_base.num, ist->time_base.den);
|
||||
|
||||
// copy disposition
|
||||
st->disposition = ist->disposition;
|
||||
|
||||
// copy side data
|
||||
for (int i = 0; i < ist->nb_side_data; i++) {
|
||||
const AVPacketSideData *sd_src = &ist->side_data[i];
|
||||
uint8_t *dst_data;
|
||||
|
||||
dst_data = av_stream_new_side_data(st, sd_src->type, sd_src->size);
|
||||
if (!dst_data)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(dst_data, sd_src->data, sd_src->size);
|
||||
}
|
||||
|
||||
st->internal->need_context_update = 1;
|
||||
|
||||
return 0;
|
||||
|
||||
+12
-14
@@ -365,11 +365,11 @@ fail:
|
||||
static int replace_str_data_in_filename(char **s, const char *filename, char placeholder, const char *datastring)
|
||||
{
|
||||
const char *p;
|
||||
char *new_filename;
|
||||
char c;
|
||||
int addchar_count;
|
||||
int found_count = 0;
|
||||
AVBPrint buf;
|
||||
int ret;
|
||||
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
@@ -395,22 +395,21 @@ static int replace_str_data_in_filename(char **s, const char *filename, char pla
|
||||
}
|
||||
if (!av_bprint_is_complete(&buf)) {
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
return -1;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
|
||||
return -1;
|
||||
*s = new_filename;
|
||||
if ((ret = av_bprint_finalize(&buf, s)) < 0)
|
||||
return ret;
|
||||
return found_count;
|
||||
}
|
||||
|
||||
static int replace_int_data_in_filename(char **s, const char *filename, char placeholder, int64_t number)
|
||||
{
|
||||
const char *p;
|
||||
char *new_filename;
|
||||
char c;
|
||||
int nd, addchar_count;
|
||||
int found_count = 0;
|
||||
AVBPrint buf;
|
||||
int ret;
|
||||
|
||||
av_bprint_init(&buf, 0, AV_BPRINT_SIZE_UNLIMITED);
|
||||
|
||||
@@ -444,11 +443,10 @@ static int replace_int_data_in_filename(char **s, const char *filename, char pla
|
||||
}
|
||||
if (!av_bprint_is_complete(&buf)) {
|
||||
av_bprint_finalize(&buf, NULL);
|
||||
return -1;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (av_bprint_finalize(&buf, &new_filename) < 0 || !new_filename)
|
||||
return -1;
|
||||
*s = new_filename;
|
||||
if ((ret = av_bprint_finalize(&buf, s)) < 0)
|
||||
return ret;
|
||||
return found_count;
|
||||
}
|
||||
|
||||
@@ -2392,7 +2390,7 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
&& (hls->flags & HLS_TEMP_FILE);
|
||||
}
|
||||
|
||||
if ((hls->max_seg_size > 0 && (vs->size >= hls->max_seg_size)) || !byterange_mode) {
|
||||
if ((hls->max_seg_size > 0 && (vs->size + vs->start_pos >= hls->max_seg_size)) || !byterange_mode) {
|
||||
AVDictionary *options = NULL;
|
||||
char *filename = NULL;
|
||||
if (hls->key_info_file || hls->encrypt) {
|
||||
@@ -2487,14 +2485,15 @@ static int hls_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
if (hls->flags & HLS_SINGLE_FILE) {
|
||||
vs->start_pos += vs->size;
|
||||
} else if (hls->max_seg_size > 0) {
|
||||
vs->start_pos = new_start_pos;
|
||||
if (vs->size >= hls->max_seg_size) {
|
||||
if (vs->size + vs->start_pos >= hls->max_seg_size) {
|
||||
vs->sequence++;
|
||||
sls_flag_file_rename(hls, vs, old_filename);
|
||||
ret = hls_start(s, vs);
|
||||
vs->start_pos = 0;
|
||||
/* When split segment by byte, the duration is short than hls_time,
|
||||
* so it is not enough one segment duration as hls_time, */
|
||||
} else {
|
||||
vs->start_pos = new_start_pos;
|
||||
}
|
||||
} else {
|
||||
vs->start_pos = new_start_pos;
|
||||
@@ -2631,7 +2630,6 @@ static int hls_write_trailer(struct AVFormatContext *s)
|
||||
goto failed;
|
||||
|
||||
vs->size = range_length;
|
||||
hlsenc_io_close(s, &vs->out, filename);
|
||||
ret = hlsenc_io_close(s, &vs->out, filename);
|
||||
if (ret < 0) {
|
||||
av_log(s, AV_LOG_WARNING, "upload segment failed, will retry with a new http session.\n");
|
||||
|
||||
+5
-1
@@ -43,6 +43,7 @@ typedef struct IcecastContext {
|
||||
int public;
|
||||
char *url;
|
||||
char *user_agent;
|
||||
int tls;
|
||||
} IcecastContext;
|
||||
|
||||
#define DEFAULT_ICE_USER "source"
|
||||
@@ -62,6 +63,7 @@ static const AVOption options[] = {
|
||||
{ "password", "set password", OFFSET(pass), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
|
||||
{ "content_type", "set content-type, MUST be set if not audio/mpeg", OFFSET(content_type), AV_OPT_TYPE_STRING, { .str = NULL }, 0, 0, E },
|
||||
{ "legacy_icecast", "use legacy SOURCE method, for Icecast < v2.4", OFFSET(legacy_icecast), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
|
||||
{ "tls", "use a TLS connection", OFFSET(tls), AV_OPT_TYPE_BOOL, { .i64 = 0 }, 0, 1, E },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -162,7 +164,9 @@ static int icecast_open(URLContext *h, const char *uri, int flags)
|
||||
}
|
||||
|
||||
// Build new URI for passing to http protocol
|
||||
ff_url_join(h_url, sizeof(h_url), "http", auth, host, port, "%s", path);
|
||||
ff_url_join(h_url, sizeof(h_url),
|
||||
s->tls ? "https" : "http",
|
||||
auth, host, port, "%s", path);
|
||||
// Finally open http proto handler
|
||||
ret = ffurl_open_whitelist(&s->hd, h_url, AVIO_FLAG_READ_WRITE, NULL,
|
||||
&opt_dict, h->protocol_whitelist, h->protocol_blacklist, h);
|
||||
|
||||
+9
@@ -1000,6 +1000,14 @@ static int pgmyuv_probe(const AVProbeData *p) // custom FFmpeg format recognized
|
||||
return ret && av_match_ext(p->filename, "pgmyuv") ? ret : 0;
|
||||
}
|
||||
|
||||
static int pgx_probe(const AVProbeData *p)
|
||||
{
|
||||
const uint8_t *b = p->buf;
|
||||
if (!memcmp(b, "PG ML ", 6))
|
||||
return AVPROBE_SCORE_EXTENSION + 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ppm_probe(const AVProbeData *p)
|
||||
{
|
||||
return pnm_magic_check(p, 3) || pnm_magic_check(p, 6) ? pnm_probe(p) : 0;
|
||||
@@ -1094,6 +1102,7 @@ IMAGEAUTO_DEMUXER(pbm, AV_CODEC_ID_PBM)
|
||||
IMAGEAUTO_DEMUXER(pcx, AV_CODEC_ID_PCX)
|
||||
IMAGEAUTO_DEMUXER(pgm, AV_CODEC_ID_PGM)
|
||||
IMAGEAUTO_DEMUXER(pgmyuv, AV_CODEC_ID_PGMYUV)
|
||||
IMAGEAUTO_DEMUXER(pgx, AV_CODEC_ID_PGX)
|
||||
IMAGEAUTO_DEMUXER(pictor, AV_CODEC_ID_PICTOR)
|
||||
IMAGEAUTO_DEMUXER(png, AV_CODEC_ID_PNG)
|
||||
IMAGEAUTO_DEMUXER(ppm, AV_CODEC_ID_PPM)
|
||||
|
||||
Vendored
+139
-19
@@ -395,25 +395,145 @@ const AVCodecTag ff_codec_movdata_tags[] = {
|
||||
/* http://developer.apple.com/documentation/mac/Text/Text-368.html */
|
||||
/* deprecated by putting the code as 3*5 bits ASCII */
|
||||
static const char mov_mdhd_language_map[][4] = {
|
||||
/* 0-9 */
|
||||
"eng", "fra", "ger", "ita", "dut", "sve", "spa", "dan", "por", "nor",
|
||||
"heb", "jpn", "ara", "fin", "gre", "ice", "mlt", "tur", "hr "/*scr*/, "chi"/*ace?*/,
|
||||
"urd", "hin", "tha", "kor", "lit", "pol", "hun", "est", "lav", "",
|
||||
"fo ", "", "rus", "chi", "", "iri", "alb", "ron", "ces", "slk",
|
||||
"slv", "yid", "sr ", "mac", "bul", "ukr", "bel", "uzb", "kaz", "aze",
|
||||
/*?*/
|
||||
"aze", "arm", "geo", "mol", "kir", "tgk", "tuk", "mon", "", "pus",
|
||||
"kur", "kas", "snd", "tib", "nep", "san", "mar", "ben", "asm", "guj",
|
||||
"pa ", "ori", "mal", "kan", "tam", "tel", "", "bur", "khm", "lao",
|
||||
/* roman? arabic? */
|
||||
"vie", "ind", "tgl", "may", "may", "amh", "tir", "orm", "som", "swa",
|
||||
/*==rundi?*/
|
||||
"", "run", "", "mlg", "epo", "", "", "", "", "",
|
||||
/* 100 */
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "", "",
|
||||
"", "", "", "", "", "", "", "", "wel", "baq",
|
||||
"cat", "lat", "que", "grn", "aym", "tat", "uig", "dzo", "jav"
|
||||
"eng", /* 0 English */
|
||||
"fra", /* 1 French */
|
||||
"ger", /* 2 German */
|
||||
"ita", /* 3 Italian */
|
||||
"dut", /* 4 Dutch */
|
||||
"sve", /* 5 Swedish */
|
||||
"spa", /* 6 Spanish */
|
||||
"dan", /* 7 Danish */
|
||||
"por", /* 8 Portuguese */
|
||||
"nor", /* 9 Norwegian */
|
||||
"heb", /* 10 Hebrew */
|
||||
"jpn", /* 11 Japanese */
|
||||
"ara", /* 12 Arabic */
|
||||
"fin", /* 13 Finnish */
|
||||
"gre", /* 14 Greek */
|
||||
"ice", /* 15 Icelandic */
|
||||
"mlt", /* 16 Maltese */
|
||||
"tur", /* 17 Turkish */
|
||||
"hr ", /* 18 Croatian */
|
||||
"chi", /* 19 Traditional Chinese */
|
||||
"urd", /* 20 Urdu */
|
||||
"hin", /* 21 Hindi */
|
||||
"tha", /* 22 Thai */
|
||||
"kor", /* 23 Korean */
|
||||
"lit", /* 24 Lithuanian */
|
||||
"pol", /* 25 Polish */
|
||||
"hun", /* 26 Hungarian */
|
||||
"est", /* 27 Estonian */
|
||||
"lav", /* 28 Latvian */
|
||||
"", /* 29 Sami */
|
||||
"fo ", /* 30 Faroese */
|
||||
"", /* 31 Farsi */
|
||||
"rus", /* 32 Russian */
|
||||
"chi", /* 33 Simplified Chinese */
|
||||
"", /* 34 Flemish */
|
||||
"iri", /* 35 Irish */
|
||||
"alb", /* 36 Albanian */
|
||||
"ron", /* 37 Romanian */
|
||||
"ces", /* 38 Czech */
|
||||
"slk", /* 39 Slovak */
|
||||
"slv", /* 40 Slovenian */
|
||||
"yid", /* 41 Yiddish */
|
||||
"sr ", /* 42 Serbian */
|
||||
"mac", /* 43 Macedonian */
|
||||
"bul", /* 44 Bulgarian */
|
||||
"ukr", /* 45 Ukrainian */
|
||||
"bel", /* 46 Belarusian */
|
||||
"uzb", /* 47 Uzbek */
|
||||
"kaz", /* 48 Kazakh */
|
||||
"aze", /* 49 Azerbaijani */
|
||||
"aze", /* 50 AzerbaijanAr */
|
||||
"arm", /* 51 Armenian */
|
||||
"geo", /* 52 Georgian */
|
||||
"mol", /* 53 Moldavian */
|
||||
"kir", /* 54 Kirghiz */
|
||||
"tgk", /* 55 Tajiki */
|
||||
"tuk", /* 56 Turkmen */
|
||||
"mon", /* 57 Mongolian */
|
||||
"", /* 58 MongolianCyr */
|
||||
"pus", /* 59 Pashto */
|
||||
"kur", /* 60 Kurdish */
|
||||
"kas", /* 61 Kashmiri */
|
||||
"snd", /* 62 Sindhi */
|
||||
"tib", /* 63 Tibetan */
|
||||
"nep", /* 64 Nepali */
|
||||
"san", /* 65 Sanskrit */
|
||||
"mar", /* 66 Marathi */
|
||||
"ben", /* 67 Bengali */
|
||||
"asm", /* 68 Assamese */
|
||||
"guj", /* 69 Gujarati */
|
||||
"pa ", /* 70 Punjabi */
|
||||
"ori", /* 71 Oriya */
|
||||
"mal", /* 72 Malayalam */
|
||||
"kan", /* 73 Kannada */
|
||||
"tam", /* 74 Tamil */
|
||||
"tel", /* 75 Telugu */
|
||||
"", /* 76 Sinhala */
|
||||
"bur", /* 77 Burmese */
|
||||
"khm", /* 78 Khmer */
|
||||
"lao", /* 79 Lao */
|
||||
"vie", /* 80 Vietnamese */
|
||||
"ind", /* 81 Indonesian */
|
||||
"tgl", /* 82 Tagalog */
|
||||
"may", /* 83 MalayRoman */
|
||||
"may", /* 84 MalayArabic */
|
||||
"amh", /* 85 Amharic */
|
||||
"tir", /* 86 Galla */
|
||||
"orm", /* 87 Oromo */
|
||||
"som", /* 88 Somali */
|
||||
"swa", /* 89 Swahili */
|
||||
"", /* 90 Kinyarwanda */
|
||||
"run", /* 91 Rundi */
|
||||
"", /* 92 Nyanja */
|
||||
"mlg", /* 93 Malagasy */
|
||||
"epo", /* 94 Esperanto */
|
||||
"", /* 95 */
|
||||
"", /* 96 */
|
||||
"", /* 97 */
|
||||
"", /* 98 */
|
||||
"", /* 99 */
|
||||
"", /* 100 */
|
||||
"", /* 101 */
|
||||
"", /* 102 */
|
||||
"", /* 103 */
|
||||
"", /* 104 */
|
||||
"", /* 105 */
|
||||
"", /* 106 */
|
||||
"", /* 107 */
|
||||
"", /* 108 */
|
||||
"", /* 109 */
|
||||
"", /* 110 */
|
||||
"", /* 111 */
|
||||
"", /* 112 */
|
||||
"", /* 113 */
|
||||
"", /* 114 */
|
||||
"", /* 115 */
|
||||
"", /* 116 */
|
||||
"", /* 117 */
|
||||
"", /* 118 */
|
||||
"", /* 119 */
|
||||
"", /* 120 */
|
||||
"", /* 121 */
|
||||
"", /* 122 */
|
||||
"", /* 123 */
|
||||
"", /* 124 */
|
||||
"", /* 125 */
|
||||
"", /* 126 */
|
||||
"", /* 127 */
|
||||
"wel", /* 128 Welsh */
|
||||
"baq", /* 129 Basque */
|
||||
"cat", /* 130 Catalan */
|
||||
"lat", /* 131 Latin */
|
||||
"que", /* 132 Quechua */
|
||||
"grn", /* 133 Guarani */
|
||||
"aym", /* 134 Aymara */
|
||||
"tat", /* 135 Tatar */
|
||||
"uig", /* 136 Uighur */
|
||||
"dzo", /* 137 Dzongkha */
|
||||
"jav", /* 138 JavaneseRom */
|
||||
};
|
||||
|
||||
int ff_mov_iso639_to_lang(const char lang[4], int mp4)
|
||||
|
||||
+1
-1
@@ -165,7 +165,7 @@ static int latm_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return ff_raw_write_packet(s, pkt);
|
||||
else {
|
||||
uint8_t *side_data;
|
||||
int side_data_size = 0, ret;
|
||||
int side_data_size, ret;
|
||||
|
||||
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
|
||||
&side_data_size);
|
||||
|
||||
+5
-1
@@ -39,6 +39,7 @@ typedef struct AMQPContext {
|
||||
int pkt_size;
|
||||
int64_t connection_timeout;
|
||||
int pkt_size_overflow;
|
||||
int delivery_mode;
|
||||
} AMQPContext;
|
||||
|
||||
#define STR_LEN 1024
|
||||
@@ -52,6 +53,9 @@ static const AVOption options[] = {
|
||||
{ "exchange", "Exchange to send/read packets", OFFSET(exchange), AV_OPT_TYPE_STRING, { .str = "amq.direct" }, 0, 0, .flags = D | E },
|
||||
{ "routing_key", "Key to filter streams", OFFSET(routing_key), AV_OPT_TYPE_STRING, { .str = "amqp" }, 0, 0, .flags = D | E },
|
||||
{ "connection_timeout", "Initial connection timeout", OFFSET(connection_timeout), AV_OPT_TYPE_DURATION, { .i64 = -1 }, -1, INT64_MAX, .flags = D | E},
|
||||
{ "delivery_mode", "Delivery mode", OFFSET(delivery_mode), AV_OPT_TYPE_INT, { .i64 = AMQP_DELIVERY_PERSISTENT }, 1, 2, .flags = E, "delivery_mode"},
|
||||
{ "persistent", "Persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_PERSISTENT }, 0, 0, E, "delivery_mode" },
|
||||
{ "non-persistent", "Non-persistent delivery mode", 0, AV_OPT_TYPE_CONST, { .i64 = AMQP_DELIVERY_NONPERSISTENT }, 0, 0, E, "delivery_mode" },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
@@ -222,7 +226,7 @@ static int amqp_proto_write(URLContext *h, const unsigned char *buf, int size)
|
||||
|
||||
props._flags = AMQP_BASIC_CONTENT_TYPE_FLAG | AMQP_BASIC_DELIVERY_MODE_FLAG;
|
||||
props.content_type = amqp_cstring_bytes("octet/stream");
|
||||
props.delivery_mode = 2; /* persistent delivery mode */
|
||||
props.delivery_mode = s->delivery_mode;
|
||||
|
||||
ret = amqp_basic_publish(s->conn, DEFAULT_CHANNEL, amqp_cstring_bytes(s->exchange),
|
||||
amqp_cstring_bytes(s->routing_key), 0, 0,
|
||||
|
||||
+2
-4
@@ -2007,7 +2007,7 @@ static int mkv_write_block(AVFormatContext *s, AVIOContext *pb,
|
||||
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
||||
mkv_track *track = &mkv->tracks[pkt->stream_index];
|
||||
uint8_t *data = NULL, *side_data = NULL;
|
||||
int err = 0, offset = 0, size = pkt->size, side_data_size = 0;
|
||||
int err = 0, offset = 0, size = pkt->size, side_data_size;
|
||||
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
||||
uint64_t additional_id;
|
||||
int64_t discard_padding = 0;
|
||||
@@ -2122,12 +2122,10 @@ static int mkv_write_vtt_blocks(AVFormatContext *s, AVIOContext *pb, const AVPac
|
||||
int64_t ts = track->write_dts ? pkt->dts : pkt->pts;
|
||||
const int flags = 0;
|
||||
|
||||
id_size = 0;
|
||||
id = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_IDENTIFIER,
|
||||
&id_size);
|
||||
id = id ? id : "";
|
||||
|
||||
settings_size = 0;
|
||||
settings = av_packet_get_side_data(pkt, AV_PKT_DATA_WEBVTT_SETTINGS,
|
||||
&settings_size);
|
||||
settings = settings ? settings : "";
|
||||
@@ -2184,7 +2182,7 @@ static int mkv_check_new_extra_data(AVFormatContext *s, const AVPacket *pkt)
|
||||
mkv_track *track = &mkv->tracks[pkt->stream_index];
|
||||
AVCodecParameters *par = s->streams[pkt->stream_index]->codecpar;
|
||||
uint8_t *side_data;
|
||||
int side_data_size = 0, ret;
|
||||
int side_data_size, ret;
|
||||
|
||||
side_data = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA,
|
||||
&side_data_size);
|
||||
|
||||
+238
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* MCC subtitle demuxer
|
||||
* Copyright (c) 2020 Paul B Mahol
|
||||
*
|
||||
* This file is part of FFmpeg.
|
||||
*
|
||||
* FFmpeg is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* FFmpeg is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with FFmpeg; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
#include "avformat.h"
|
||||
#include "internal.h"
|
||||
#include "subtitles.h"
|
||||
#include "libavutil/avstring.h"
|
||||
#include "libavutil/bprint.h"
|
||||
#include "libavutil/intreadwrite.h"
|
||||
|
||||
typedef struct MCCContext {
|
||||
FFDemuxSubtitlesQueue q;
|
||||
} MCCContext;
|
||||
|
||||
static int mcc_probe(const AVProbeData *p)
|
||||
{
|
||||
char buf[28];
|
||||
FFTextReader tr;
|
||||
|
||||
ff_text_init_buf(&tr, p->buf, p->buf_size);
|
||||
|
||||
while (ff_text_peek_r8(&tr) == '\r' || ff_text_peek_r8(&tr) == '\n')
|
||||
ff_text_r8(&tr);
|
||||
|
||||
ff_text_read(&tr, buf, sizeof(buf));
|
||||
|
||||
if (!memcmp(buf, "File Format=MacCaption_MCC V", 28))
|
||||
return AVPROBE_SCORE_MAX;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert(uint8_t x)
|
||||
{
|
||||
if (x >= 'a')
|
||||
x -= 87;
|
||||
else if (x >= 'A')
|
||||
x -= 55;
|
||||
else
|
||||
x -= '0';
|
||||
return x;
|
||||
}
|
||||
|
||||
typedef struct alias {
|
||||
uint8_t key;
|
||||
int len;
|
||||
const char *value;
|
||||
} alias;
|
||||
|
||||
static const alias aliases[20] = {
|
||||
{ .key = 16, .len = 3, .value = "\xFA\x0\x0", },
|
||||
{ .key = 17, .len = 6, .value = "\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 18, .len = 9, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 19, .len = 12, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 20, .len = 15, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 21, .len = 18, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 22, .len = 21, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 23, .len = 24, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 24, .len = 27, .value = "\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0\xFA\x0\x0", },
|
||||
{ .key = 25, .len = 3, .value = "\xFB\x80\x80", },
|
||||
{ .key = 26, .len = 3, .value = "\xFC\x80\x80", },
|
||||
{ .key = 27, .len = 3, .value = "\xFD\x80\x80", },
|
||||
{ .key = 28, .len = 2, .value = "\x96\x69", },
|
||||
{ .key = 29, .len = 2, .value = "\x61\x01", },
|
||||
{ .key = 30, .len = 3, .value = "\xFC\x80\x80", },
|
||||
{ .key = 31, .len = 3, .value = "\xFC\x80\x80", },
|
||||
{ .key = 32, .len = 4, .value = "\xE1\x00\x00\x00", },
|
||||
{ .key = 33, .len = 0, .value = NULL, },
|
||||
{ .key = 34, .len = 0, .value = NULL, },
|
||||
{ .key = 35, .len = 1, .value = "\x0", },
|
||||
};
|
||||
|
||||
static int mcc_read_header(AVFormatContext *s)
|
||||
{
|
||||
MCCContext *mcc = s->priv_data;
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
AVRational rate;
|
||||
int64_t ts, pos;
|
||||
uint8_t out[4096];
|
||||
char line[4096];
|
||||
FFTextReader tr;
|
||||
int ret = 0;
|
||||
|
||||
ff_text_init_avio(s, &tr, s->pb);
|
||||
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
||||
st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
|
||||
avpriv_set_pts_info(st, 64, 1, 30);
|
||||
|
||||
while (!ff_text_eof(&tr)) {
|
||||
int hh, mm, ss, fs, i = 0, j = 0;
|
||||
int start = 12, count = 0;
|
||||
AVPacket *sub;
|
||||
char *lline;
|
||||
|
||||
ff_subtitles_read_line(&tr, line, sizeof(line));
|
||||
if (!strncmp(line, "File Format=MacCaption_MCC V", 28))
|
||||
continue;
|
||||
if (!strncmp(line, "//", 2))
|
||||
continue;
|
||||
if (!strncmp(line, "Time Code Rate=", 15)) {
|
||||
char *rate_str = line + 15;
|
||||
char *df = NULL;
|
||||
int num = -1, den = -1;
|
||||
|
||||
if (rate_str[0]) {
|
||||
num = strtol(rate_str, &df, 10);
|
||||
den = 1;
|
||||
if (df && !av_strncasecmp(df, "DF", 2)) {
|
||||
num *= 1000;
|
||||
den = 1001;
|
||||
}
|
||||
}
|
||||
|
||||
if (num > 0 && den > 0) {
|
||||
rate = av_make_q(num, den);
|
||||
avpriv_set_pts_info(st, 64, rate.den, rate.num);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (av_sscanf(line, "%d:%d:%d:%d", &hh, &mm, &ss, &fs) != 4)
|
||||
continue;
|
||||
|
||||
ts = av_rescale(hh * 3600LL + mm * 60LL + ss, rate.num, rate.den) + fs;
|
||||
|
||||
lline = (char *)&line;
|
||||
lline += 12;
|
||||
pos = ff_text_pos(&tr);
|
||||
|
||||
while (lline[i]) {
|
||||
uint8_t v = convert(lline[i]);
|
||||
|
||||
if (v >= 16 && v <= 35) {
|
||||
int idx = v - 16;
|
||||
if (aliases[idx].len) {
|
||||
if (j >= sizeof(out) - 1 - aliases[idx].len) {
|
||||
j = 0;
|
||||
break;
|
||||
}
|
||||
memcpy(out + j, aliases[idx].value, aliases[idx].len);
|
||||
j += aliases[idx].len;
|
||||
}
|
||||
} else {
|
||||
uint8_t vv;
|
||||
|
||||
if (i + 13 >= sizeof(line) - 1)
|
||||
break;
|
||||
vv = convert(lline[i + 1]);
|
||||
if (j >= sizeof(out) - 1) {
|
||||
j = 0;
|
||||
break;
|
||||
}
|
||||
out[j++] = vv | (v << 4);
|
||||
i++;
|
||||
}
|
||||
|
||||
i++;
|
||||
}
|
||||
out[j] = 0;
|
||||
|
||||
if (out[7] & 0x80)
|
||||
start += 4;
|
||||
count = (out[11] & 0x1f) * 3;
|
||||
if (j < start + count + 1)
|
||||
continue;
|
||||
|
||||
if (!count)
|
||||
continue;
|
||||
sub = ff_subtitles_queue_insert(&mcc->q, out + start, count, 0);
|
||||
if (!sub)
|
||||
goto fail;
|
||||
|
||||
sub->pos = pos;
|
||||
sub->pts = ts;
|
||||
sub->duration = 1;
|
||||
}
|
||||
|
||||
ff_subtitles_queue_finalize(s, &mcc->q);
|
||||
|
||||
return ret;
|
||||
fail:
|
||||
ff_subtitles_queue_clean(&mcc->q);
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
static int mcc_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
MCCContext *mcc = s->priv_data;
|
||||
return ff_subtitles_queue_read_packet(&mcc->q, pkt);
|
||||
}
|
||||
|
||||
static int mcc_read_seek(AVFormatContext *s, int stream_index,
|
||||
int64_t min_ts, int64_t ts, int64_t max_ts, int flags)
|
||||
{
|
||||
MCCContext *mcc = s->priv_data;
|
||||
return ff_subtitles_queue_seek(&mcc->q, s, stream_index,
|
||||
min_ts, ts, max_ts, flags);
|
||||
}
|
||||
|
||||
static int mcc_read_close(AVFormatContext *s)
|
||||
{
|
||||
MCCContext *mcc = s->priv_data;
|
||||
ff_subtitles_queue_clean(&mcc->q);
|
||||
return 0;
|
||||
}
|
||||
|
||||
AVInputFormat ff_mcc_demuxer = {
|
||||
.name = "mcc",
|
||||
.long_name = NULL_IF_CONFIG_SMALL("MacCaption"),
|
||||
.priv_data_size = sizeof(MCCContext),
|
||||
.read_probe = mcc_probe,
|
||||
.read_header = mcc_read_header,
|
||||
.read_packet = mcc_read_packet,
|
||||
.read_seek2 = mcc_read_seek,
|
||||
.read_close = mcc_read_close,
|
||||
.extensions = "mcc",
|
||||
};
|
||||
Vendored
-2
@@ -175,8 +175,6 @@ static int read_packet(AVFormatContext *s,
|
||||
return 0;
|
||||
|
||||
case MM_TYPE_AUDIO :
|
||||
if (s->nb_streams < 2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if ((ret = av_get_packet(s->pb, pkt, length)) < 0)
|
||||
return ret;
|
||||
pkt->stream_index = 1;
|
||||
|
||||
Vendored
+103
-114
@@ -181,7 +181,6 @@ static int mov_read_mac_string(MOVContext *c, AVIOContext *pb, int len,
|
||||
|
||||
static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
|
||||
{
|
||||
AVPacket pkt;
|
||||
AVStream *st;
|
||||
MOVStreamContext *sc;
|
||||
enum AVCodecID id;
|
||||
@@ -205,12 +204,12 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
|
||||
return AVERROR(ENOMEM);
|
||||
st->priv_data = sc;
|
||||
|
||||
ret = av_get_packet(pb, &pkt, len);
|
||||
ret = av_get_packet(pb, &st->attached_pic, len);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (pkt.size >= 8 && id != AV_CODEC_ID_BMP) {
|
||||
if (AV_RB64(pkt.data) == 0x89504e470d0a1a0a) {
|
||||
if (st->attached_pic.size >= 8 && id != AV_CODEC_ID_BMP) {
|
||||
if (AV_RB64(st->attached_pic.data) == 0x89504e470d0a1a0a) {
|
||||
id = AV_CODEC_ID_PNG;
|
||||
} else {
|
||||
id = AV_CODEC_ID_MJPEG;
|
||||
@@ -219,7 +218,6 @@ static int mov_read_covr(MOVContext *c, AVIOContext *pb, int type, int len)
|
||||
|
||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC;
|
||||
|
||||
st->attached_pic = pkt;
|
||||
st->attached_pic.stream_index = st->index;
|
||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
||||
|
||||
@@ -646,7 +644,7 @@ static int mov_read_dref(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
avio_skip(pb, 16);
|
||||
|
||||
for (type = 0; type != -1 && avio_tell(pb) < next; ) {
|
||||
if(avio_feof(pb))
|
||||
if (avio_feof(pb))
|
||||
return AVERROR_EOF;
|
||||
type = avio_rb16(pb);
|
||||
len = avio_rb16(pb);
|
||||
@@ -859,26 +857,20 @@ static int mov_read_dec3(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
|
||||
static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
{
|
||||
const uint32_t ddts_size = 20;
|
||||
#define DDTS_SIZE 20
|
||||
uint8_t buf[DDTS_SIZE + AV_INPUT_BUFFER_PADDING_SIZE];
|
||||
AVStream *st = NULL;
|
||||
uint8_t *buf = NULL;
|
||||
uint32_t frame_duration_code = 0;
|
||||
uint32_t channel_layout_code = 0;
|
||||
GetBitContext gb;
|
||||
int ret;
|
||||
|
||||
buf = av_malloc(ddts_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!buf) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if (avio_read(pb, buf, ddts_size) < ddts_size) {
|
||||
av_free(buf);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if ((ret = ffio_read_size(pb, buf, DDTS_SIZE)) < 0)
|
||||
return ret;
|
||||
|
||||
init_get_bits(&gb, buf, 8*ddts_size);
|
||||
init_get_bits(&gb, buf, 8 * DDTS_SIZE);
|
||||
|
||||
if (c->fc->nb_streams < 1) {
|
||||
av_free(buf);
|
||||
return 0;
|
||||
}
|
||||
st = c->fc->streams[c->fc->nb_streams-1];
|
||||
@@ -886,7 +878,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
st->codecpar->sample_rate = get_bits_long(&gb, 32);
|
||||
if (st->codecpar->sample_rate <= 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Invalid sample rate %d\n", st->codecpar->sample_rate);
|
||||
av_free(buf);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
skip_bits_long(&gb, 32); /* max bitrate */
|
||||
@@ -914,7 +905,6 @@ static int mov_read_ddts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
((channel_layout_code & 0x8) ? AV_CH_LOW_FREQUENCY : 0);
|
||||
|
||||
st->codecpar->channels = av_get_channel_layout_nb_channels(st->codecpar->channel_layout);
|
||||
av_free(buf);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1318,7 +1308,7 @@ static int update_frag_index(MOVContext *c, int64_t offset)
|
||||
&c->frag_index.allocated_size,
|
||||
(c->frag_index.nb_items + 1) *
|
||||
sizeof(*c->frag_index.item));
|
||||
if(!item)
|
||||
if (!item)
|
||||
return -1;
|
||||
c->frag_index.item = item;
|
||||
|
||||
@@ -1402,7 +1392,7 @@ static int mov_read_moof(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
static void mov_metadata_creation_time(AVDictionary **metadata, int64_t time, void *logctx)
|
||||
{
|
||||
if (time) {
|
||||
if(time >= 2082844800)
|
||||
if (time >= 2082844800)
|
||||
time -= 2082844800; /* seconds between 1904-01-01 and Epoch */
|
||||
|
||||
if ((int64_t)(time * 1000000ULL) / 1000000 != time) {
|
||||
@@ -1576,8 +1566,7 @@ static int mov_read_colr(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
ret = ffio_read_size(pb, icc_profile, atom.size - 4);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
color_primaries = avio_rb16(pb);
|
||||
color_trc = avio_rb16(pb);
|
||||
color_matrix = avio_rb16(pb);
|
||||
@@ -1730,7 +1719,7 @@ static int mov_read_dpxe(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
static int mov_read_avid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
{
|
||||
int ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_AVUI);
|
||||
if(ret == 0)
|
||||
if (!ret)
|
||||
ret = mov_read_extradata(c, pb, atom, AV_CODEC_ID_DNXHD);
|
||||
return ret;
|
||||
}
|
||||
@@ -2342,18 +2331,15 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
uint32_t format = AV_RB32(st->codecpar->extradata + 22);
|
||||
if (format == AV_RB32("name") && (int64_t)size >= (int64_t)len + 18) {
|
||||
uint16_t str_size = AV_RB16(st->codecpar->extradata + 26); /* string length */
|
||||
if (str_size > 0 && size >= (int)str_size + 30) {
|
||||
if (str_size > 0 && size >= (int)str_size + 30 &&
|
||||
st->codecpar->extradata[30] /* Don't add empty string */) {
|
||||
char *reel_name = av_malloc(str_size + 1);
|
||||
if (!reel_name)
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(reel_name, st->codecpar->extradata + 30, str_size);
|
||||
reel_name[str_size] = 0; /* Add null terminator */
|
||||
/* don't add reel_name if emtpy string */
|
||||
if (*reel_name == 0) {
|
||||
av_free(reel_name);
|
||||
} else {
|
||||
av_dict_set(&st->metadata, "reel_name", reel_name, AV_DICT_DONT_STRDUP_VAL);
|
||||
}
|
||||
av_dict_set(&st->metadata, "reel_name", reel_name,
|
||||
AV_DICT_DONT_STRDUP_VAL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2550,11 +2536,8 @@ int ff_mov_read_stsd_entries(MOVContext *c, AVIOContext *pb, int entries)
|
||||
|
||||
/* Move the current stream extradata to the stream context one. */
|
||||
sc->extradata_size[pseudo_stream_id] = extra_size;
|
||||
sc->extradata[pseudo_stream_id] = av_malloc(extra_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
if (!sc->extradata[pseudo_stream_id])
|
||||
return AVERROR(ENOMEM);
|
||||
memcpy(sc->extradata[pseudo_stream_id], st->codecpar->extradata, extra_size);
|
||||
av_freep(&st->codecpar->extradata);
|
||||
sc->extradata[pseudo_stream_id] = st->codecpar->extradata;
|
||||
st->codecpar->extradata = NULL;
|
||||
st->codecpar->extradata_size = 0;
|
||||
}
|
||||
sc->stsd_count++;
|
||||
@@ -2781,8 +2764,7 @@ static int mov_read_stss(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
|
||||
av_log(c->fc, AV_LOG_TRACE, "keyframe_count = %u\n", entries);
|
||||
|
||||
if (!entries)
|
||||
{
|
||||
if (!entries) {
|
||||
sc->keyframe_absent = 1;
|
||||
if (!st->need_parsing && st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
|
||||
st->need_parsing = AVSTREAM_PARSE_HEADERS;
|
||||
@@ -2910,8 +2892,8 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
AVStream *st;
|
||||
MOVStreamContext *sc;
|
||||
unsigned int i, entries, alloc_size = 0;
|
||||
int64_t duration=0;
|
||||
int64_t total_sample_count=0;
|
||||
int64_t duration = 0;
|
||||
int64_t total_sample_count = 0;
|
||||
|
||||
if (c->fc->nb_streams < 1)
|
||||
return 0;
|
||||
@@ -2946,7 +2928,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
sc->stts_count = min_entries;
|
||||
sc->stts_data = stts_data;
|
||||
|
||||
sample_count=avio_rb32(pb);
|
||||
sample_count = avio_rb32(pb);
|
||||
sample_duration = avio_rb32(pb);
|
||||
|
||||
sc->stts_data[i].count= sample_count;
|
||||
@@ -2963,8 +2945,7 @@ static int mov_read_stts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
|
||||
if (duration > 0 &&
|
||||
duration <= INT64_MAX - sc->duration_for_fps &&
|
||||
total_sample_count <= INT_MAX - sc->nb_frames_for_fps
|
||||
) {
|
||||
total_sample_count <= INT_MAX - sc->nb_frames_for_fps) {
|
||||
sc->duration_for_fps += duration;
|
||||
sc->nb_frames_for_fps += total_sample_count;
|
||||
}
|
||||
@@ -3053,8 +3034,8 @@ static int mov_read_ctts(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
for (i = 0; i < entries && !pb->eof_reached; i++) {
|
||||
int count =avio_rb32(pb);
|
||||
int duration =avio_rb32(pb);
|
||||
int count = avio_rb32(pb);
|
||||
int duration = avio_rb32(pb);
|
||||
|
||||
if (count <= 0) {
|
||||
av_log(c->fc, AV_LOG_TRACE,
|
||||
@@ -3294,13 +3275,13 @@ static int64_t add_index_entry(AVStream *st, int64_t pos, int64_t timestamp,
|
||||
FFMAX(min_size_needed, 2 * st->index_entries_allocated_size) :
|
||||
min_size_needed;
|
||||
|
||||
if((unsigned)st->nb_index_entries + 1 >= UINT_MAX / sizeof(AVIndexEntry))
|
||||
if (st->nb_index_entries + 1U >= UINT_MAX / sizeof(AVIndexEntry))
|
||||
return -1;
|
||||
|
||||
entries = av_fast_realloc(st->index_entries,
|
||||
&st->index_entries_allocated_size,
|
||||
requested_size);
|
||||
if(!entries)
|
||||
if (!entries)
|
||||
return -1;
|
||||
|
||||
st->index_entries= entries;
|
||||
@@ -3345,12 +3326,12 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
|
||||
FFMAX(min_size_needed, 2 * (*allocated_size)) :
|
||||
min_size_needed;
|
||||
|
||||
if((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
|
||||
if ((unsigned)(*ctts_count) >= UINT_MAX / sizeof(MOVStts) - 1)
|
||||
return -1;
|
||||
|
||||
ctts_buf_new = av_fast_realloc(*ctts_data, allocated_size, requested_size);
|
||||
|
||||
if(!ctts_buf_new)
|
||||
if (!ctts_buf_new)
|
||||
return -1;
|
||||
|
||||
*ctts_data = ctts_buf_new;
|
||||
@@ -3363,7 +3344,8 @@ static int64_t add_ctts_entry(MOVStts** ctts_data, unsigned int* ctts_count, uns
|
||||
}
|
||||
|
||||
#define MAX_REORDER_DELAY 16
|
||||
static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
|
||||
static void mov_estimate_video_delay(MOVContext *c, AVStream* st)
|
||||
{
|
||||
MOVStreamContext *msc = st->priv_data;
|
||||
int ind;
|
||||
int ctts_ind = 0;
|
||||
@@ -3378,7 +3360,7 @@ static void mov_estimate_video_delay(MOVContext *c, AVStream* st) {
|
||||
if (st->codecpar->video_delay <= 0 && msc->ctts_data &&
|
||||
st->codecpar->codec_id == AV_CODEC_ID_H264) {
|
||||
st->codecpar->video_delay = 0;
|
||||
for(ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
|
||||
for (ind = 0; ind < st->nb_index_entries && ctts_ind < msc->ctts_count; ++ind) {
|
||||
// Point j to the last elem of the buffer and insert the current pts there.
|
||||
j = buf_start;
|
||||
buf_start = (buf_start + 1);
|
||||
@@ -4176,10 +4158,10 @@ static int mov_open_dref(MOVContext *c, AVIOContext **pb, const char *src, MOVDr
|
||||
return AVERROR(ENOENT);
|
||||
}
|
||||
|
||||
if(strstr(ref->path + l + 1, "..") ||
|
||||
strstr(ref->path + l + 1, ":") ||
|
||||
(ref->nlvl_from > 1 && same_origin < 0) ||
|
||||
(filename[0] == '/' && src_path == src))
|
||||
if (strstr(ref->path + l + 1, "..") ||
|
||||
strstr(ref->path + l + 1, ":") ||
|
||||
(ref->nlvl_from > 1 && same_origin < 0) ||
|
||||
(filename[0] == '/' && src_path == src))
|
||||
return AVERROR(ENOENT);
|
||||
}
|
||||
|
||||
@@ -4813,8 +4795,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
if (flags & MOV_TRUN_FIRST_SAMPLE_FLAGS) first_sample_flags = avio_rb32(pb);
|
||||
|
||||
frag_stream_info = get_current_frag_stream_info(&c->frag_index);
|
||||
if (frag_stream_info)
|
||||
{
|
||||
if (frag_stream_info) {
|
||||
if (frag_stream_info->next_trun_dts != AV_NOPTS_VALUE) {
|
||||
dts = frag_stream_info->next_trun_dts - sc->time_offset;
|
||||
} else if (frag_stream_info->first_tfra_pts != AV_NOPTS_VALUE &&
|
||||
@@ -4863,7 +4844,7 @@ static int mov_read_trun(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
new_entries = av_fast_realloc(st->index_entries,
|
||||
&st->index_entries_allocated_size,
|
||||
requested_size);
|
||||
if(!new_entries)
|
||||
if (!new_entries)
|
||||
return AVERROR(ENOMEM);
|
||||
st->index_entries= new_entries;
|
||||
|
||||
@@ -5773,12 +5754,9 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
st = c->fc->streams[c->fc->nb_streams - 1];
|
||||
sc = st->priv_data;
|
||||
|
||||
ret = avio_read(pb, uuid, sizeof(uuid));
|
||||
if (ret < 0) {
|
||||
ret = ffio_read_size(pb, uuid, sizeof(uuid));
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
} else if (ret != sizeof(uuid)) {
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
if (!memcmp(uuid, uuid_isml_manifest, sizeof(uuid))) {
|
||||
uint8_t *buffer, *ptr;
|
||||
char *endptr;
|
||||
@@ -5794,13 +5772,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
if (!buffer) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
ret = avio_read(pb, buffer, len);
|
||||
ret = ffio_read_size(pb, buffer, len);
|
||||
if (ret < 0) {
|
||||
av_free(buffer);
|
||||
return ret;
|
||||
} else if (ret != len) {
|
||||
av_free(buffer);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
ptr = buffer;
|
||||
@@ -5831,13 +5806,10 @@ static int mov_read_uuid(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
if (!buffer) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
ret = avio_read(pb, buffer, len);
|
||||
ret = ffio_read_size(pb, buffer, len);
|
||||
if (ret < 0) {
|
||||
av_free(buffer);
|
||||
return ret;
|
||||
} else if (ret != len) {
|
||||
av_free(buffer);
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
buffer[len] = '\0';
|
||||
av_dict_set(&c->fc->metadata, "xmp",
|
||||
@@ -5981,7 +5953,7 @@ static int get_current_encryption_info(MOVContext *c, MOVEncryptionIndex **encry
|
||||
|
||||
static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVStreamContext *sc, AVEncryptionInfo **sample, int use_subsamples)
|
||||
{
|
||||
int i;
|
||||
int i, ret;
|
||||
unsigned int subsample_count;
|
||||
AVSubsampleEncryptionInfo *subsamples;
|
||||
|
||||
@@ -5995,11 +5967,11 @@ static int mov_read_sample_encryption_info(MOVContext *c, AVIOContext *pb, MOVSt
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (sc->cenc.per_sample_iv_size != 0) {
|
||||
if (avio_read(pb, (*sample)->iv, sc->cenc.per_sample_iv_size) != sc->cenc.per_sample_iv_size) {
|
||||
if ((ret = ffio_read_size(pb, (*sample)->iv, sc->cenc.per_sample_iv_size)) < 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "failed to read the initialization vector\n");
|
||||
av_encryption_info_free(*sample);
|
||||
*sample = NULL;
|
||||
return AVERROR_INVALIDDATA;
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6367,9 +6339,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
if (!info)
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
if (avio_read(pb, info->system_id, 16) != 16) {
|
||||
if ((ret = ffio_read_size(pb, info->system_id, 16)) < 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Failed to read the system id\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
@@ -6397,9 +6368,8 @@ static int mov_read_pssh(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
}
|
||||
info->num_key_ids = i + 1;
|
||||
|
||||
if (avio_read(pb, info->key_ids[i], 16) != 16) {
|
||||
if ((ret = ffio_read_size(pb, info->key_ids[i], 16)) < 0) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Failed to read the key id\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
@@ -6618,15 +6588,13 @@ static int cenc_decrypt(MOVContext *c, MOVStreamContext *sc, AVEncryptionInfo *s
|
||||
|
||||
av_aes_ctr_set_full_iv(sc->cenc.aes_ctr, sample->iv);
|
||||
|
||||
if (!sample->subsample_count)
|
||||
{
|
||||
if (!sample->subsample_count) {
|
||||
/* decrypt the whole packet */
|
||||
av_aes_ctr_crypt(sc->cenc.aes_ctr, input, input, size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < sample->subsample_count; i++)
|
||||
{
|
||||
for (i = 0; i < sample->subsample_count; i++) {
|
||||
if (sample->subsamples[i].bytes_of_clear_data + sample->subsamples[i].bytes_of_protected_data > size) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "subsample size exceeds the packet size left\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
@@ -6988,10 +6956,9 @@ static int mov_read_default(MOVContext *c, AVIOContext *pb, MOVAtom atom)
|
||||
}
|
||||
}
|
||||
if (atom.type != MKTAG('r','o','o','t') &&
|
||||
atom.type != MKTAG('m','o','o','v'))
|
||||
{
|
||||
if (a.type == MKTAG('t','r','a','k') || a.type == MKTAG('m','d','a','t'))
|
||||
{
|
||||
atom.type != MKTAG('m','o','o','v')) {
|
||||
if (a.type == MKTAG('t','r','a','k') ||
|
||||
a.type == MKTAG('m','d','a','t')) {
|
||||
av_log(c->fc, AV_LOG_ERROR, "Broken file, trak/mdat not at top-level\n");
|
||||
avio_skip(pb, -8);
|
||||
c->atom_depth --;
|
||||
@@ -7131,25 +7098,26 @@ static int mov_probe(const AVProbeData *p)
|
||||
offset = FFMAX(4, AV_RB32(p->buf+offset)) + offset;
|
||||
}
|
||||
}
|
||||
if(score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
|
||||
if (score > AVPROBE_SCORE_MAX - 50 && moov_offset != -1) {
|
||||
/* moov atom in the header - we should make sure that this is not a
|
||||
* MOV-packed MPEG-PS */
|
||||
offset = moov_offset;
|
||||
|
||||
while(offset < (p->buf_size - 16)){ /* Sufficient space */
|
||||
while (offset < (p->buf_size - 16)) { /* Sufficient space */
|
||||
/* We found an actual hdlr atom */
|
||||
if(AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
|
||||
AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
|
||||
AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')){
|
||||
if (AV_RL32(p->buf + offset ) == MKTAG('h','d','l','r') &&
|
||||
AV_RL32(p->buf + offset + 8) == MKTAG('m','h','l','r') &&
|
||||
AV_RL32(p->buf + offset + 12) == MKTAG('M','P','E','G')) {
|
||||
av_log(NULL, AV_LOG_WARNING, "Found media data tag MPEG indicating this is a MOV-packed MPEG-PS.\n");
|
||||
/* We found a media handler reference atom describing an
|
||||
* MPEG-PS-in-MOV, return a
|
||||
* low score to force expanding the probe window until
|
||||
* mpegps_probe finds what it needs */
|
||||
return 5;
|
||||
}else
|
||||
} else {
|
||||
/* Keep looking */
|
||||
offset+=2;
|
||||
offset += 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7186,17 +7154,15 @@ static void mov_read_chapters(AVFormatContext *s)
|
||||
st->disposition |= AV_DISPOSITION_ATTACHED_PIC | AV_DISPOSITION_TIMED_THUMBNAILS;
|
||||
if (st->nb_index_entries) {
|
||||
// Retrieve the first frame, if possible
|
||||
AVPacket pkt;
|
||||
AVIndexEntry *sample = &st->index_entries[0];
|
||||
if (avio_seek(sc->pb, sample->pos, SEEK_SET) != sample->pos) {
|
||||
av_log(s, AV_LOG_ERROR, "Failed to retrieve first frame\n");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (av_get_packet(sc->pb, &pkt, sample->size) < 0)
|
||||
if (av_get_packet(sc->pb, &st->attached_pic, sample->size) < 0)
|
||||
goto finish;
|
||||
|
||||
st->attached_pic = pkt;
|
||||
st->attached_pic.stream_index = st->index;
|
||||
st->attached_pic.flags |= AV_PKT_FLAG_KEY;
|
||||
}
|
||||
@@ -7627,7 +7593,8 @@ static int mov_read_header(AVFormatContext *s)
|
||||
AVStream *st = s->streams[i];
|
||||
MOVStreamContext *sc = st->priv_data;
|
||||
fix_timescale(mov, sc);
|
||||
if(st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO && st->codecpar->codec_id == AV_CODEC_ID_AAC) {
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
st->codecpar->codec_id == AV_CODEC_ID_AAC) {
|
||||
st->skip_samples = sc->start_pad;
|
||||
}
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO && sc->nb_frames_for_fps > 0 && sc->duration_for_fps > 0)
|
||||
@@ -7645,8 +7612,7 @@ static int mov_read_header(AVFormatContext *s)
|
||||
}
|
||||
if (mov->handbrake_version &&
|
||||
mov->handbrake_version <= 1000000*0 + 1000*10 + 2 && // 0.10.2
|
||||
st->codecpar->codec_id == AV_CODEC_ID_MP3
|
||||
) {
|
||||
st->codecpar->codec_id == AV_CODEC_ID_MP3) {
|
||||
av_log(s, AV_LOG_VERBOSE, "Forcing full parsing for mp3 stream\n");
|
||||
st->need_parsing = AVSTREAM_PARSE_FULL;
|
||||
}
|
||||
@@ -7700,9 +7666,8 @@ static int mov_read_header(AVFormatContext *s)
|
||||
switch (st->codecpar->codec_type) {
|
||||
case AVMEDIA_TYPE_AUDIO:
|
||||
err = ff_replaygain_export(st, s->metadata);
|
||||
if (err < 0) {
|
||||
if (err < 0)
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
case AVMEDIA_TYPE_VIDEO:
|
||||
if (sc->display_matrix) {
|
||||
@@ -7856,6 +7821,27 @@ static int mov_change_extradata(MOVStreamContext *sc, AVPacket *pkt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int get_eia608_packet(AVIOContext *pb, AVPacket *pkt, int size)
|
||||
{
|
||||
int new_size, ret;
|
||||
|
||||
if (size <= 8)
|
||||
return AVERROR_INVALIDDATA;
|
||||
new_size = ((size - 8) / 2) * 3;
|
||||
ret = av_new_packet(pkt, new_size);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
avio_skip(pb, 8);
|
||||
for (int j = 0; j < new_size; j += 3) {
|
||||
pkt->data[j] = 0xFC;
|
||||
pkt->data[j+1] = avio_r8(pb);
|
||||
pkt->data[j+2] = avio_r8(pb);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
MOVContext *mov = s->priv_data;
|
||||
@@ -7895,12 +7881,15 @@ static int mov_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
|
||||
if( st->discard == AVDISCARD_NONKEY && 0==(sample->flags & AVINDEX_KEYFRAME) ) {
|
||||
if (st->discard == AVDISCARD_NONKEY && !(sample->flags & AVINDEX_KEYFRAME)) {
|
||||
av_log(mov->fc, AV_LOG_DEBUG, "Nonkey frame from stream %d discarded due to AVDISCARD_NONKEY\n", sc->ffindex);
|
||||
goto retry;
|
||||
}
|
||||
|
||||
ret = av_get_packet(sc->pb, pkt, sample->size);
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_EIA_608 && sample->size > 8)
|
||||
ret = get_eia608_packet(sc->pb, pkt, sample->size);
|
||||
else
|
||||
ret = av_get_packet(sc->pb, pkt, sample->size);
|
||||
if (ret < 0) {
|
||||
if (should_retry(sc->pb, ret)) {
|
||||
mov_current_sample_dec(sc);
|
||||
@@ -8056,17 +8045,17 @@ static int mov_seek_stream(AVFormatContext *s, AVStream *st, int64_t timestamp,
|
||||
|
||||
/* adjust stsd index */
|
||||
if (sc->chunk_count) {
|
||||
time_sample = 0;
|
||||
for (i = 0; i < sc->stsc_count; i++) {
|
||||
int64_t next = time_sample + mov_get_stsc_samples(sc, i);
|
||||
if (next > sc->current_sample) {
|
||||
sc->stsc_index = i;
|
||||
sc->stsc_sample = sc->current_sample - time_sample;
|
||||
break;
|
||||
time_sample = 0;
|
||||
for (i = 0; i < sc->stsc_count; i++) {
|
||||
int64_t next = time_sample + mov_get_stsc_samples(sc, i);
|
||||
if (next > sc->current_sample) {
|
||||
sc->stsc_index = i;
|
||||
sc->stsc_sample = sc->current_sample - time_sample;
|
||||
break;
|
||||
}
|
||||
av_assert0(next == (int)next);
|
||||
time_sample = next;
|
||||
}
|
||||
av_assert0(next == (int)next);
|
||||
time_sample = next;
|
||||
}
|
||||
}
|
||||
|
||||
return sample;
|
||||
|
||||
+48
-14
@@ -4798,28 +4798,40 @@ static int mov_write_tfra_tag(AVIOContext *pb, MOVTrack *track)
|
||||
|
||||
static int mov_write_mfra_tag(AVIOContext *pb, MOVMuxContext *mov)
|
||||
{
|
||||
int64_t pos = avio_tell(pb);
|
||||
int i;
|
||||
AVIOContext *mfra_pb;
|
||||
int i, ret, sz;
|
||||
uint8_t *buf;
|
||||
|
||||
avio_wb32(pb, 0); /* size placeholder */
|
||||
ffio_wfourcc(pb, "mfra");
|
||||
ret = avio_open_dyn_buf(&mfra_pb);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
avio_wb32(mfra_pb, 0); /* size placeholder */
|
||||
ffio_wfourcc(mfra_pb, "mfra");
|
||||
/* An empty mfra atom is enough to indicate to the publishing point that
|
||||
* the stream has ended. */
|
||||
if (mov->flags & FF_MOV_FLAG_ISML)
|
||||
return update_size(pb, pos);
|
||||
goto done_mfra;
|
||||
|
||||
for (i = 0; i < mov->nb_streams; i++) {
|
||||
MOVTrack *track = &mov->tracks[i];
|
||||
if (track->nb_frag_info)
|
||||
mov_write_tfra_tag(pb, track);
|
||||
mov_write_tfra_tag(mfra_pb, track);
|
||||
}
|
||||
|
||||
avio_wb32(pb, 16);
|
||||
ffio_wfourcc(pb, "mfro");
|
||||
avio_wb32(pb, 0); /* version + flags */
|
||||
avio_wb32(pb, avio_tell(pb) + 4 - pos);
|
||||
avio_wb32(mfra_pb, 16);
|
||||
ffio_wfourcc(mfra_pb, "mfro");
|
||||
avio_wb32(mfra_pb, 0); /* version + flags */
|
||||
avio_wb32(mfra_pb, avio_tell(mfra_pb) + 4);
|
||||
|
||||
return update_size(pb, pos);
|
||||
done_mfra:
|
||||
|
||||
sz = update_size(mfra_pb, 0);
|
||||
ret = avio_get_dyn_buf(mfra_pb, &buf);
|
||||
avio_write(pb, buf, ret);
|
||||
ffio_free_dyn_buf(&mfra_pb);
|
||||
|
||||
return sz;
|
||||
}
|
||||
|
||||
static int mov_write_mdat_tag(AVIOContext *pb, MOVMuxContext *mov)
|
||||
@@ -4875,7 +4887,7 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
|
||||
{
|
||||
MOVMuxContext *mov = s->priv_data;
|
||||
int64_t pos = avio_tell(pb);
|
||||
int has_h264 = 0, has_video = 0;
|
||||
int has_h264 = 0, has_av1 = 0, has_video = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
@@ -4886,6 +4898,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
|
||||
has_video = 1;
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_H264)
|
||||
has_h264 = 1;
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_AV1)
|
||||
has_av1 = 1;
|
||||
}
|
||||
|
||||
avio_wb32(pb, 0); /* size */
|
||||
@@ -4909,6 +4923,8 @@ static int mov_write_ftyp_tag(AVIOContext *pb, AVFormatContext *s)
|
||||
ffio_wfourcc(pb, "cmfc");
|
||||
if (mov->flags & FF_MOV_FLAG_FRAGMENT && !(mov->flags & FF_MOV_FLAG_NEGATIVE_CTS_OFFSETS))
|
||||
ffio_wfourcc(pb, "iso6");
|
||||
if (has_av1)
|
||||
ffio_wfourcc(pb, "av01");
|
||||
} else {
|
||||
if (mov->flags & FF_MOV_FLAG_FRAGMENT)
|
||||
ffio_wfourcc(pb, "iso6");
|
||||
@@ -5582,6 +5598,22 @@ int ff_mov_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
goto end;
|
||||
avio_write(pb, pkt->data, size);
|
||||
#endif
|
||||
} else if (par->codec_id == AV_CODEC_ID_EIA_608) {
|
||||
size = 8;
|
||||
|
||||
for (int i = 0; i < pkt->size; i += 3) {
|
||||
if (pkt->data[i] == 0xFC) {
|
||||
size += 2;
|
||||
}
|
||||
}
|
||||
avio_wb32(pb, size);
|
||||
ffio_wfourcc(pb, "cdat");
|
||||
for (int i = 0; i < pkt->size; i += 3) {
|
||||
if (pkt->data[i] == 0xFC) {
|
||||
avio_w8(pb, pkt->data[i + 1]);
|
||||
avio_w8(pb, pkt->data[i + 2]);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (trk->cenc.aes_ctr) {
|
||||
if (par->codec_id == AV_CODEC_ID_H264 && par->extradata_size > 4) {
|
||||
@@ -5768,7 +5800,7 @@ static int mov_write_single_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
trk->par->codec_id == AV_CODEC_ID_AAC ||
|
||||
trk->par->codec_id == AV_CODEC_ID_AV1 ||
|
||||
trk->par->codec_id == AV_CODEC_ID_FLAC) {
|
||||
int side_size = 0;
|
||||
int side_size;
|
||||
uint8_t *side = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &side_size);
|
||||
if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) {
|
||||
void *newextra = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE);
|
||||
@@ -6967,7 +6999,9 @@ static int mov_write_trailer(AVFormatContext *s)
|
||||
}
|
||||
if (!(mov->flags & FF_MOV_FLAG_SKIP_TRAILER)) {
|
||||
avio_write_marker(s->pb, AV_NOPTS_VALUE, AVIO_DATA_MARKER_TRAILER);
|
||||
mov_write_mfra_tag(pb, mov);
|
||||
res = mov_write_mfra_tag(pb, mov);
|
||||
if (res < 0)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -354,7 +354,7 @@ static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
if (mp3->xing_offset) {
|
||||
uint8_t *side_data = NULL;
|
||||
int side_data_size = 0;
|
||||
int side_data_size;
|
||||
|
||||
mp3_xing_add_frame(mp3, pkt);
|
||||
mp3->audio_size += pkt->size;
|
||||
|
||||
+7
@@ -137,6 +137,13 @@
|
||||
#define STREAM_TYPE_AUDIO_TRUEHD 0x83
|
||||
#define STREAM_TYPE_AUDIO_EAC3 0x87
|
||||
|
||||
/* ISO/IEC 13818-1 Table 2-22 */
|
||||
#define STREAM_ID_PRIVATE_STREAM_1 0xbd
|
||||
#define STREAM_ID_AUDIO_STREAM_0 0xc0
|
||||
#define STREAM_ID_VIDEO_STREAM_0 0xe0
|
||||
#define STREAM_ID_METADATA_STREAM 0xfc
|
||||
#define STREAM_ID_EXTENDED_STREAM_ID 0xfd
|
||||
|
||||
typedef struct MpegTSContext MpegTSContext;
|
||||
|
||||
MpegTSContext *avpriv_mpegts_parse_open(AVFormatContext *s);
|
||||
|
||||
+8
-8
@@ -1382,28 +1382,28 @@ static void mpegts_write_pes(AVFormatContext *s, AVStream *st,
|
||||
is_dvb_teletext = 0;
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_DIRAC)
|
||||
*q++ = 0xfd;
|
||||
*q++ = STREAM_ID_EXTENDED_STREAM_ID;
|
||||
else
|
||||
*q++ = 0xe0;
|
||||
*q++ = STREAM_ID_VIDEO_STREAM_0;
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
(st->codecpar->codec_id == AV_CODEC_ID_MP2 ||
|
||||
st->codecpar->codec_id == AV_CODEC_ID_MP3 ||
|
||||
st->codecpar->codec_id == AV_CODEC_ID_AAC)) {
|
||||
*q++ = 0xc0;
|
||||
*q++ = STREAM_ID_AUDIO_STREAM_0;
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_AUDIO &&
|
||||
st->codecpar->codec_id == AV_CODEC_ID_AC3 &&
|
||||
ts->m2ts_mode) {
|
||||
*q++ = 0xfd;
|
||||
*q++ = STREAM_ID_EXTENDED_STREAM_ID;
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA &&
|
||||
st->codecpar->codec_id == AV_CODEC_ID_TIMED_ID3) {
|
||||
*q++ = 0xbd;
|
||||
*q++ = STREAM_ID_PRIVATE_STREAM_1;
|
||||
} else if (st->codecpar->codec_type == AVMEDIA_TYPE_DATA) {
|
||||
*q++ = stream_id != -1 ? stream_id : 0xfc;
|
||||
*q++ = stream_id != -1 ? stream_id : STREAM_ID_METADATA_STREAM;
|
||||
|
||||
if (stream_id == 0xbd) /* asynchronous KLV */
|
||||
if (stream_id == STREAM_ID_PRIVATE_STREAM_1) /* asynchronous KLV */
|
||||
pts = dts = AV_NOPTS_VALUE;
|
||||
} else {
|
||||
*q++ = 0xbd;
|
||||
*q++ = STREAM_ID_PRIVATE_STREAM_1;
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_SUBTITLE) {
|
||||
if (st->codecpar->codec_id == AV_CODEC_ID_DVB_SUBTITLE) {
|
||||
is_dvb_subtitle = 1;
|
||||
|
||||
+1
-2
@@ -83,7 +83,6 @@ static int mpl2_read_header(AVFormatContext *s)
|
||||
{
|
||||
MPL2Context *mpl2 = s->priv_data;
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
int res = 0;
|
||||
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -122,7 +121,7 @@ static int mpl2_read_header(AVFormatContext *s)
|
||||
}
|
||||
|
||||
ff_subtitles_queue_finalize(s, &mpl2->q);
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int mpl2_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
+64
@@ -21,6 +21,7 @@
|
||||
#include "avio_internal.h"
|
||||
#include "internal.h"
|
||||
|
||||
#include "libavutil/avassert.h"
|
||||
#include "libavutil/internal.h"
|
||||
#include "libavutil/opt.h"
|
||||
|
||||
@@ -53,6 +54,8 @@ static void *format_child_next(void *obj, void *prev)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
FF_DISABLE_DEPRECATION_WARNINGS
|
||||
static const AVClass *format_child_class_next(const AVClass *prev)
|
||||
{
|
||||
AVInputFormat *ifmt = NULL;
|
||||
@@ -80,6 +83,64 @@ static const AVClass *format_child_class_next(const AVClass *prev)
|
||||
|
||||
return NULL;
|
||||
}
|
||||
FF_ENABLE_DEPRECATION_WARNINGS
|
||||
#endif
|
||||
|
||||
enum {
|
||||
CHILD_CLASS_ITER_AVIO = 0,
|
||||
CHILD_CLASS_ITER_MUX,
|
||||
CHILD_CLASS_ITER_DEMUX,
|
||||
CHILD_CLASS_ITER_DONE,
|
||||
|
||||
};
|
||||
|
||||
#define ITER_STATE_SHIFT 16
|
||||
|
||||
static const AVClass *format_child_class_iterate(void **iter)
|
||||
{
|
||||
// we use the low 16 bits of iter as the value to be passed to
|
||||
// av_(de)muxer_iterate()
|
||||
void *val = (void*)(((uintptr_t)*iter) & ((1 << ITER_STATE_SHIFT) - 1));
|
||||
unsigned int state = ((uintptr_t)*iter) >> ITER_STATE_SHIFT;
|
||||
const AVClass *ret = NULL;
|
||||
|
||||
if (state == CHILD_CLASS_ITER_AVIO) {
|
||||
ret = &ff_avio_class;
|
||||
state++;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (state == CHILD_CLASS_ITER_MUX) {
|
||||
const AVOutputFormat *ofmt;
|
||||
|
||||
while ((ofmt = av_muxer_iterate(&val))) {
|
||||
ret = ofmt->priv_class;
|
||||
if (ret)
|
||||
goto finish;
|
||||
}
|
||||
|
||||
val = NULL;
|
||||
state++;
|
||||
}
|
||||
|
||||
if (state == CHILD_CLASS_ITER_DEMUX) {
|
||||
const AVInputFormat *ifmt;
|
||||
|
||||
while ((ifmt = av_demuxer_iterate(&val))) {
|
||||
ret = ifmt->priv_class;
|
||||
if (ret)
|
||||
goto finish;
|
||||
}
|
||||
val = NULL;
|
||||
state++;
|
||||
}
|
||||
|
||||
finish:
|
||||
// make sure none av_(de)muxer_iterate does not set the high bits of val
|
||||
av_assert0(!((uintptr_t)val >> ITER_STATE_SHIFT));
|
||||
*iter = (void*)((uintptr_t)val | (state << ITER_STATE_SHIFT));
|
||||
return ret;
|
||||
}
|
||||
|
||||
static AVClassCategory get_category(void *ptr)
|
||||
{
|
||||
@@ -94,7 +155,10 @@ static const AVClass av_format_context_class = {
|
||||
.option = avformat_options,
|
||||
.version = LIBAVUTIL_VERSION_INT,
|
||||
.child_next = format_child_next,
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
.child_class_next = format_child_class_next,
|
||||
#endif
|
||||
.child_class_iterate = format_child_class_iterate,
|
||||
.category = AV_CLASS_CATEGORY_MUXER,
|
||||
.get_category = get_category,
|
||||
};
|
||||
|
||||
+1
-2
@@ -67,7 +67,6 @@ static int pjs_read_header(AVFormatContext *s)
|
||||
{
|
||||
PJSContext *pjs = s->priv_data;
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
int res = 0;
|
||||
|
||||
if (!st)
|
||||
return AVERROR(ENOMEM);
|
||||
@@ -105,7 +104,7 @@ static int pjs_read_header(AVFormatContext *s)
|
||||
}
|
||||
|
||||
ff_subtitles_queue_finalize(s, &pjs->q);
|
||||
return res;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int pjs_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
+16
@@ -73,6 +73,7 @@ extern const URLProtocol ff_libzmq_protocol;
|
||||
|
||||
#include "libavformat/protocol_list.c"
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
const AVClass *ff_urlcontext_child_class_next(const AVClass *prev)
|
||||
{
|
||||
int i;
|
||||
@@ -91,7 +92,22 @@ const AVClass *ff_urlcontext_child_class_next(const AVClass *prev)
|
||||
return url_protocols[i]->priv_data_class;
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
const AVClass *ff_urlcontext_child_class_iterate(void **iter)
|
||||
{
|
||||
const AVClass *ret = NULL;
|
||||
uintptr_t i;
|
||||
|
||||
for (i = (uintptr_t)*iter; url_protocols[i]; i++) {
|
||||
ret = url_protocols[i]->priv_data_class;
|
||||
if (ret)
|
||||
break;
|
||||
}
|
||||
|
||||
*iter = (void*)(uintptr_t)(url_protocols[i] ? i + 1 : i);
|
||||
return ret;
|
||||
}
|
||||
|
||||
const char *avio_enum_protocols(void **opaque, int output)
|
||||
{
|
||||
|
||||
+1
-1
@@ -589,7 +589,7 @@ static int rtp_write_packet(AVFormatContext *s1, AVPacket *pkt)
|
||||
break;
|
||||
case AV_CODEC_ID_H263:
|
||||
if (s->flags & FF_RTP_FLAG_RFC2190) {
|
||||
int mb_info_size = 0;
|
||||
int mb_info_size;
|
||||
const uint8_t *mb_info =
|
||||
av_packet_get_side_data(pkt, AV_PKT_DATA_H263_MB_INFO,
|
||||
&mb_info_size);
|
||||
|
||||
+65
-45
@@ -63,10 +63,9 @@ static int scc_read_header(AVFormatContext *s)
|
||||
{
|
||||
SCCContext *scc = s->priv_data;
|
||||
AVStream *st = avformat_new_stream(s, NULL);
|
||||
char line[4096], line2[4096];
|
||||
int64_t ts_start, ts_end;
|
||||
int count = 0, ret = 0;
|
||||
ptrdiff_t len2, len;
|
||||
char line2[4096], line[4096];
|
||||
int64_t pos, ts, next_ts = AV_NOPTS_VALUE;
|
||||
ptrdiff_t len;
|
||||
uint8_t out[4096];
|
||||
FFTextReader tr;
|
||||
|
||||
@@ -78,83 +77,104 @@ static int scc_read_header(AVFormatContext *s)
|
||||
st->codecpar->codec_type = AVMEDIA_TYPE_SUBTITLE;
|
||||
st->codecpar->codec_id = AV_CODEC_ID_EIA_608;
|
||||
|
||||
while (!ff_text_eof(&tr)) {
|
||||
int64_t current_pos, next_pos;
|
||||
while (!ff_text_eof(&tr) || next_ts == AV_NOPTS_VALUE || line2[0]) {
|
||||
char *saveptr = NULL, *lline;
|
||||
int hh1, mm1, ss1, fs1, i;
|
||||
int hh2, mm2, ss2, fs2;
|
||||
int hh, mm, ss, fs, i;
|
||||
AVPacket *sub;
|
||||
|
||||
if (count == 0) {
|
||||
current_pos = ff_text_pos(&tr);
|
||||
if (next_ts == AV_NOPTS_VALUE) {
|
||||
while (!ff_text_eof(&tr)) {
|
||||
len = ff_subtitles_read_line(&tr, line, sizeof(line));
|
||||
if (len > 13)
|
||||
if (len <= 13)
|
||||
continue;
|
||||
if (!strncmp(line, "Scenarist_SCC V1.0", 18))
|
||||
continue;
|
||||
if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
|
||||
break;
|
||||
}
|
||||
|
||||
ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33;
|
||||
|
||||
while (!ff_text_eof(&tr)) {
|
||||
len = ff_subtitles_read_line(&tr, line2, sizeof(line2));
|
||||
if (len <= 13)
|
||||
continue;
|
||||
|
||||
if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
memmove(line, line2, sizeof(line));
|
||||
line2[0] = 0;
|
||||
|
||||
while (!ff_text_eof(&tr)) {
|
||||
len = ff_subtitles_read_line(&tr, line2, sizeof(line2));
|
||||
if (len <= 13)
|
||||
continue;
|
||||
|
||||
if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh, &mm, &ss, &fs) == 4)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!strncmp(line, "Scenarist_SCC V1.0", 18))
|
||||
continue;
|
||||
if (av_sscanf(line, "%d:%d:%d%*[:;]%d", &hh1, &mm1, &ss1, &fs1) != 4)
|
||||
continue;
|
||||
next_ts = (hh * 3600LL + mm * 60LL + ss) * 1000LL + fs * 33;
|
||||
|
||||
ts_start = (hh1 * 3600LL + mm1 * 60LL + ss1) * 1000LL + fs1 * 33;
|
||||
|
||||
next_pos = ff_text_pos(&tr);
|
||||
while (!ff_text_eof(&tr)) {
|
||||
len2 = ff_subtitles_read_line(&tr, line2, sizeof(line2));
|
||||
if (len2 > 13)
|
||||
break;
|
||||
}
|
||||
if (av_sscanf(line2, "%d:%d:%d%*[:;]%d", &hh2, &mm2, &ss2, &fs2) != 4)
|
||||
continue;
|
||||
|
||||
ts_end = (hh2 * 3600LL + mm2 * 60LL + ss2) * 1000LL + fs2 * 33;
|
||||
count++;
|
||||
|
||||
try_again:
|
||||
pos = ff_text_pos(&tr);
|
||||
lline = (char *)&line;
|
||||
lline += 12;
|
||||
|
||||
for (i = 0; i < 4095; i += 3) {
|
||||
char *ptr = av_strtok(lline, " ", &saveptr);
|
||||
char c1, c2, c3, c4;
|
||||
uint8_t o1, o2;
|
||||
|
||||
if (!ptr)
|
||||
break;
|
||||
|
||||
if (av_sscanf(ptr, "%c%c%c%c", &c1, &c2, &c3, &c4) != 4)
|
||||
break;
|
||||
o1 = convert(c2) | (convert(c1) << 4);
|
||||
o2 = convert(c4) | (convert(c3) << 4);
|
||||
|
||||
lline = NULL;
|
||||
|
||||
if (i > 12 && o1 == 0x94 && o2 == 0x20 && saveptr &&
|
||||
(av_strncasecmp(saveptr, "942f", 4) && !av_strncasecmp(saveptr, "942c", 4))) {
|
||||
|
||||
out[i] = 0;
|
||||
|
||||
sub = ff_subtitles_queue_insert(&scc->q, out, i, 0);
|
||||
if (!sub)
|
||||
goto fail;
|
||||
|
||||
sub->pos = pos;
|
||||
pos += i;
|
||||
sub->pts = ts;
|
||||
sub->duration = i * 11;
|
||||
ts += sub->duration;
|
||||
i = 0;
|
||||
}
|
||||
|
||||
out[i+0] = 0xfc;
|
||||
out[i+1] = convert(c2) | (convert(c1) << 4);
|
||||
out[i+2] = convert(c4) | (convert(c3) << 4);
|
||||
out[i+1] = o1;
|
||||
out[i+2] = o2;
|
||||
}
|
||||
|
||||
out[i] = 0;
|
||||
|
||||
sub = ff_subtitles_queue_insert(&scc->q, out, i, 0);
|
||||
if (!sub)
|
||||
goto fail;
|
||||
|
||||
sub->pos = current_pos;
|
||||
sub->pts = ts_start;
|
||||
sub->duration = ts_end - ts_start;
|
||||
memmove(line, line2, sizeof(line));
|
||||
current_pos = next_pos;
|
||||
line2[0] = 0;
|
||||
}
|
||||
|
||||
if (line[0]) {
|
||||
ts_start = ts_end;
|
||||
ts_end += 1200;
|
||||
goto try_again;
|
||||
sub->pos = pos;
|
||||
sub->pts = ts;
|
||||
sub->duration = next_ts - ts;
|
||||
ts = next_ts;
|
||||
}
|
||||
|
||||
ff_subtitles_queue_finalize(s, &scc->q);
|
||||
|
||||
return ret;
|
||||
return 0;
|
||||
fail:
|
||||
ff_subtitles_queue_clean(&scc->q);
|
||||
return AVERROR(ENOMEM);
|
||||
|
||||
Vendored
+1
-1
@@ -212,7 +212,7 @@ static char *extradata2psets(AVFormatContext *s, AVCodecParameters *par)
|
||||
p += strlen(p);
|
||||
r = r1;
|
||||
}
|
||||
if (sps && sps_end - sps >= 4 && p - psets <= MAX_PSET_SIZE - strlen(profile_string) - 7) {
|
||||
if (sps && sps_end - sps >= 4) {
|
||||
memcpy(p, profile_string, strlen(profile_string));
|
||||
p += strlen(p);
|
||||
ff_data_to_hex(p, sps + 1, 3, 0);
|
||||
|
||||
+1
-1
@@ -873,7 +873,7 @@ static int seg_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
return AVERROR(EINVAL);
|
||||
|
||||
if (!st->codecpar->extradata_size) {
|
||||
int pkt_extradata_size = 0;
|
||||
int pkt_extradata_size;
|
||||
uint8_t *pkt_extradata = av_packet_get_side_data(pkt, AV_PKT_DATA_NEW_EXTRADATA, &pkt_extradata_size);
|
||||
if (pkt_extradata && pkt_extradata_size > 0) {
|
||||
ret = ff_alloc_extradata(st->codecpar, pkt_extradata_size);
|
||||
|
||||
+88
-113
@@ -48,16 +48,16 @@ typedef struct SmackerContext {
|
||||
uint32_t *frm_size;
|
||||
uint8_t *frm_flags;
|
||||
/* internal variables */
|
||||
int64_t next_frame_pos;
|
||||
int cur_frame;
|
||||
/* current frame for demuxing */
|
||||
uint8_t pal[768];
|
||||
int indexes[7];
|
||||
int videoindex;
|
||||
uint8_t *bufs[7];
|
||||
int buf_sizes[7];
|
||||
int stream_id[7];
|
||||
int curstream;
|
||||
int64_t nextpos;
|
||||
int indexes[7];
|
||||
/* current frame for demuxing */
|
||||
uint32_t frame_size;
|
||||
int flags;
|
||||
int next_audio_index;
|
||||
int new_palette;
|
||||
uint8_t pal[768];
|
||||
int64_t aud_pts[7];
|
||||
} SmackerContext;
|
||||
|
||||
@@ -205,85 +205,75 @@ static int smacker_read_header(AVFormatContext *s)
|
||||
avio_rl32(pb); /* padding */
|
||||
|
||||
/* setup data */
|
||||
smk->frm_size = av_malloc_array(smk->frames, sizeof(*smk->frm_size));
|
||||
smk->frm_flags = av_malloc(smk->frames);
|
||||
if (!smk->frm_size || !smk->frm_flags) {
|
||||
av_freep(&smk->frm_size);
|
||||
av_freep(&smk->frm_flags);
|
||||
st->priv_data = av_malloc_array(smk->frames, sizeof(*smk->frm_size) +
|
||||
sizeof(*smk->frm_flags));
|
||||
if (!st->priv_data)
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
smk->frm_size = st->priv_data;
|
||||
smk->frm_flags = (void*)(smk->frm_size + smk->frames);
|
||||
|
||||
/* read frame info */
|
||||
for (i = 0; i < smk->frames; i++) {
|
||||
smk->frm_size[i] = avio_rl32(pb);
|
||||
}
|
||||
for (i = 0; i < smk->frames; i++) {
|
||||
smk->frm_flags[i] = avio_r8(pb);
|
||||
if ((ret = ffio_read_size(pb, smk->frm_flags, smk->frames)) < 0 ||
|
||||
/* load trees to extradata, they will be unpacked by decoder */
|
||||
(ret = ffio_read_size(pb, par->extradata + 16,
|
||||
par->extradata_size - 16)) < 0) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* load trees to extradata, they will be unpacked by decoder */
|
||||
ret = avio_read(pb, par->extradata + 16, par->extradata_size - 16);
|
||||
if (ret != par->extradata_size - 16) {
|
||||
av_freep(&smk->frm_size);
|
||||
av_freep(&smk->frm_flags);
|
||||
return AVERROR(EIO);
|
||||
}
|
||||
|
||||
smk->curstream = -1;
|
||||
smk->nextpos = avio_tell(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
SmackerContext *smk = s->priv_data;
|
||||
int flags;
|
||||
int ret;
|
||||
int i;
|
||||
int frame_size = 0;
|
||||
int palchange = 0;
|
||||
|
||||
if (avio_feof(s->pb) || smk->cur_frame >= smk->frames)
|
||||
return AVERROR_EOF;
|
||||
|
||||
/* if we demuxed all streams, pass another frame */
|
||||
if(smk->curstream < 0) {
|
||||
avio_seek(s->pb, smk->nextpos, 0);
|
||||
frame_size = smk->frm_size[smk->cur_frame] & (~3);
|
||||
if (!smk->next_audio_index) {
|
||||
smk->frame_size = smk->frm_size[smk->cur_frame] & (~3);
|
||||
smk->next_frame_pos = avio_tell(s->pb) + smk->frame_size;
|
||||
flags = smk->frm_flags[smk->cur_frame];
|
||||
smk->flags = flags >> 1;
|
||||
/* handle palette change event */
|
||||
if(flags & SMACKER_PAL){
|
||||
if (flags & SMACKER_PAL) {
|
||||
int size, sz, t, off, j, pos;
|
||||
uint8_t *pal = smk->pal;
|
||||
uint8_t oldpal[768];
|
||||
|
||||
memcpy(oldpal, pal, 768);
|
||||
size = avio_r8(s->pb);
|
||||
size = size * 4 - 1;
|
||||
if(size + 1 > frame_size)
|
||||
return AVERROR_INVALIDDATA;
|
||||
frame_size -= size;
|
||||
frame_size--;
|
||||
size = size * 4;
|
||||
if (size > smk->frame_size) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto next_frame;
|
||||
}
|
||||
smk->frame_size -= size--;
|
||||
sz = 0;
|
||||
pos = avio_tell(s->pb) + size;
|
||||
while(sz < 256){
|
||||
while (sz < 256) {
|
||||
t = avio_r8(s->pb);
|
||||
if(t & 0x80){ /* skip palette entries */
|
||||
sz += (t & 0x7F) + 1;
|
||||
if (t & 0x80) { /* skip palette entries */
|
||||
sz += (t & 0x7F) + 1;
|
||||
pal += ((t & 0x7F) + 1) * 3;
|
||||
} else if(t & 0x40){ /* copy with offset */
|
||||
} else if (t & 0x40) { /* copy with offset */
|
||||
off = avio_r8(s->pb);
|
||||
j = (t & 0x3F) + 1;
|
||||
if (off + j > 0x100) {
|
||||
av_log(s, AV_LOG_ERROR,
|
||||
"Invalid palette update, offset=%d length=%d extends beyond palette size\n",
|
||||
off, j);
|
||||
return AVERROR_INVALIDDATA;
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto next_frame;
|
||||
}
|
||||
off *= 3;
|
||||
while(j-- && sz < 256) {
|
||||
while (j-- && sz < 256) {
|
||||
*pal++ = oldpal[off + 0];
|
||||
*pal++ = oldpal[off + 1];
|
||||
*pal++ = oldpal[off + 2];
|
||||
@@ -298,79 +288,65 @@ static int smacker_read_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
}
|
||||
}
|
||||
avio_seek(s->pb, pos, 0);
|
||||
palchange |= 1;
|
||||
smk->new_palette = 1;
|
||||
}
|
||||
flags >>= 1;
|
||||
smk->curstream = -1;
|
||||
/* if audio chunks are present, put them to stack and retrieve later */
|
||||
for(i = 0; i < 7; i++) {
|
||||
if(flags & 1) {
|
||||
uint32_t size;
|
||||
int err;
|
||||
|
||||
size = avio_rl32(s->pb) - 4;
|
||||
if (!size || size + 4LL > frame_size) {
|
||||
av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
|
||||
return AVERROR_INVALIDDATA;
|
||||
}
|
||||
frame_size -= size;
|
||||
frame_size -= 4;
|
||||
smk->curstream++;
|
||||
if ((err = av_reallocp(&smk->bufs[smk->curstream], size)) < 0) {
|
||||
smk->buf_sizes[smk->curstream] = 0;
|
||||
return err;
|
||||
}
|
||||
smk->buf_sizes[smk->curstream] = size;
|
||||
ret = avio_read(s->pb, smk->bufs[smk->curstream], size);
|
||||
if(ret != size)
|
||||
return AVERROR(EIO);
|
||||
smk->stream_id[smk->curstream] = smk->indexes[i];
|
||||
}
|
||||
flags >>= 1;
|
||||
}
|
||||
if (frame_size < 0 || frame_size >= INT_MAX/2)
|
||||
return AVERROR_INVALIDDATA;
|
||||
if ((ret = av_new_packet(pkt, frame_size + 769)) < 0)
|
||||
return ret;
|
||||
if(smk->frm_size[smk->cur_frame] & 1)
|
||||
palchange |= 2;
|
||||
pkt->data[0] = palchange;
|
||||
memcpy(pkt->data + 1, smk->pal, 768);
|
||||
ret = avio_read(s->pb, pkt->data + 769, frame_size);
|
||||
if(ret != frame_size)
|
||||
return AVERROR(EIO);
|
||||
pkt->stream_index = smk->videoindex;
|
||||
pkt->pts = smk->cur_frame;
|
||||
pkt->size = ret + 769;
|
||||
smk->cur_frame++;
|
||||
smk->nextpos = avio_tell(s->pb);
|
||||
} else {
|
||||
if (smk->stream_id[smk->curstream] < 0 || !smk->bufs[smk->curstream])
|
||||
return AVERROR_INVALIDDATA;
|
||||
if ((ret = av_new_packet(pkt, smk->buf_sizes[smk->curstream])) < 0)
|
||||
return ret;
|
||||
memcpy(pkt->data, smk->bufs[smk->curstream], smk->buf_sizes[smk->curstream]);
|
||||
pkt->size = smk->buf_sizes[smk->curstream];
|
||||
pkt->stream_index = smk->stream_id[smk->curstream];
|
||||
pkt->pts = smk->aud_pts[smk->curstream];
|
||||
smk->aud_pts[smk->curstream] += AV_RL32(pkt->data);
|
||||
smk->curstream--;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
for (int i = smk->next_audio_index; i < 7; i++) {
|
||||
if (smk->flags & (1 << i)) {
|
||||
uint32_t size;
|
||||
|
||||
static int smacker_read_close(AVFormatContext *s)
|
||||
{
|
||||
SmackerContext *smk = s->priv_data;
|
||||
int i;
|
||||
size = avio_rl32(s->pb);
|
||||
if ((int)size < 8 || size > smk->frame_size) {
|
||||
av_log(s, AV_LOG_ERROR, "Invalid audio part size\n");
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto next_frame;
|
||||
}
|
||||
smk->frame_size -= size;
|
||||
size -= 4;
|
||||
|
||||
for(i = 0; i < 7; i++)
|
||||
av_freep(&smk->bufs[i]);
|
||||
av_freep(&smk->frm_size);
|
||||
av_freep(&smk->frm_flags);
|
||||
if (smk->indexes[i] < 0) {
|
||||
avio_skip(s->pb, size);
|
||||
continue;
|
||||
}
|
||||
if ((ret = av_get_packet(s->pb, pkt, size)) != size) {
|
||||
ret = ret < 0 ? ret : AVERROR_INVALIDDATA;
|
||||
goto next_frame;
|
||||
}
|
||||
pkt->stream_index = smk->indexes[i];
|
||||
pkt->pts = smk->aud_pts[i];
|
||||
smk->aud_pts[i] += AV_RL32(pkt->data);
|
||||
smk->next_audio_index = i + 1;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (smk->frame_size >= INT_MAX/2) {
|
||||
ret = AVERROR_INVALIDDATA;
|
||||
goto next_frame;
|
||||
}
|
||||
if ((ret = av_new_packet(pkt, smk->frame_size + 769)) < 0)
|
||||
goto next_frame;
|
||||
flags = smk->new_palette;
|
||||
if (smk->frm_size[smk->cur_frame] & 1)
|
||||
flags |= 2;
|
||||
pkt->data[0] = flags;
|
||||
memcpy(pkt->data + 1, smk->pal, 768);
|
||||
ret = ffio_read_size(s->pb, pkt->data + 769, smk->frame_size);
|
||||
if (ret < 0)
|
||||
goto next_frame;
|
||||
pkt->stream_index = smk->videoindex;
|
||||
pkt->pts = smk->cur_frame;
|
||||
smk->next_audio_index = 0;
|
||||
smk->new_palette = 0;
|
||||
smk->cur_frame++;
|
||||
|
||||
return 0;
|
||||
next_frame:
|
||||
avio_seek(s->pb, smk->next_frame_pos, SEEK_SET);
|
||||
smk->next_audio_index = 0;
|
||||
smk->cur_frame++;
|
||||
return ret;
|
||||
}
|
||||
|
||||
AVInputFormat ff_smacker_demuxer = {
|
||||
@@ -380,5 +356,4 @@ AVInputFormat ff_smacker_demuxer = {
|
||||
.read_probe = smacker_probe,
|
||||
.read_header = smacker_read_header,
|
||||
.read_packet = smacker_read_packet,
|
||||
.read_close = smacker_read_close,
|
||||
};
|
||||
|
||||
+18
-31
@@ -49,7 +49,6 @@ typedef struct Fragment {
|
||||
|
||||
typedef struct OutputStream {
|
||||
AVFormatContext *ctx;
|
||||
int ctx_inited;
|
||||
char dirname[1024];
|
||||
uint8_t iobuf[32768];
|
||||
URLContext *out; // Current output stream where all output is written
|
||||
@@ -173,8 +172,6 @@ static void ism_free(AVFormatContext *s)
|
||||
ffurl_closep(&os->out);
|
||||
ffurl_closep(&os->out2);
|
||||
ffurl_closep(&os->tail_out);
|
||||
if (os->ctx && os->ctx_inited)
|
||||
av_write_trailer(os->ctx);
|
||||
if (os->ctx && os->ctx->pb)
|
||||
avio_context_free(&os->ctx->pb);
|
||||
avformat_free_context(os->ctx);
|
||||
@@ -289,21 +286,18 @@ static int ism_write_header(AVFormatContext *s)
|
||||
ff_const59 AVOutputFormat *oformat;
|
||||
|
||||
if (mkdir(s->url, 0777) == -1 && errno != EEXIST) {
|
||||
ret = AVERROR(errno);
|
||||
av_log(s, AV_LOG_ERROR, "mkdir failed\n");
|
||||
goto fail;
|
||||
return AVERROR(errno);
|
||||
}
|
||||
|
||||
oformat = av_guess_format("ismv", NULL, NULL);
|
||||
if (!oformat) {
|
||||
ret = AVERROR_MUXER_NOT_FOUND;
|
||||
goto fail;
|
||||
return AVERROR_MUXER_NOT_FOUND;
|
||||
}
|
||||
|
||||
c->streams = av_mallocz_array(s->nb_streams, sizeof(*c->streams));
|
||||
if (!c->streams) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
@@ -321,22 +315,21 @@ static int ism_write_header(AVFormatContext *s)
|
||||
}
|
||||
|
||||
if (mkdir(os->dirname, 0777) == -1 && errno != EEXIST) {
|
||||
ret = AVERROR(errno);
|
||||
av_log(s, AV_LOG_ERROR, "mkdir failed\n");
|
||||
goto fail;
|
||||
return AVERROR(errno);
|
||||
}
|
||||
|
||||
os->ctx = ctx = avformat_alloc_context();
|
||||
if (!ctx || ff_copy_whiteblacklists(ctx, s) < 0) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
if (!ctx) {
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
if ((ret = ff_copy_whiteblacklists(ctx, s)) < 0)
|
||||
return ret;
|
||||
ctx->oformat = oformat;
|
||||
ctx->interrupt_callback = s->interrupt_callback;
|
||||
|
||||
if (!(st = avformat_new_stream(ctx, NULL))) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
avcodec_parameters_copy(st->codecpar, s->streams[i]->codecpar);
|
||||
st->sample_aspect_ratio = s->streams[i]->sample_aspect_ratio;
|
||||
@@ -344,8 +337,7 @@ static int ism_write_header(AVFormatContext *s)
|
||||
|
||||
ctx->pb = avio_alloc_context(os->iobuf, sizeof(os->iobuf), AVIO_FLAG_WRITE, os, NULL, ism_write, ism_seek);
|
||||
if (!ctx->pb) {
|
||||
ret = AVERROR(ENOMEM);
|
||||
goto fail;
|
||||
return AVERROR(ENOMEM);
|
||||
}
|
||||
|
||||
av_dict_set_int(&opts, "ism_lookahead", c->lookahead_count, 0);
|
||||
@@ -353,9 +345,8 @@ static int ism_write_header(AVFormatContext *s)
|
||||
ret = avformat_write_header(ctx, &opts);
|
||||
av_dict_free(&opts);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
return ret;
|
||||
}
|
||||
os->ctx_inited = 1;
|
||||
avio_flush(ctx->pb);
|
||||
s->streams[i]->time_base = st->time_base;
|
||||
if (st->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
|
||||
@@ -367,8 +358,7 @@ static int ism_write_header(AVFormatContext *s)
|
||||
os->fourcc = "WVC1";
|
||||
} else {
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported video codec\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
} else {
|
||||
c->has_audio = 1;
|
||||
@@ -381,8 +371,7 @@ static int ism_write_header(AVFormatContext *s)
|
||||
os->audio_tag = 0x0162;
|
||||
} else {
|
||||
av_log(s, AV_LOG_ERROR, "Unsupported audio codec\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
os->packet_size = st->codecpar->block_align ? st->codecpar->block_align : 4;
|
||||
}
|
||||
@@ -391,15 +380,13 @@ static int ism_write_header(AVFormatContext *s)
|
||||
|
||||
if (!c->has_video && c->min_frag_duration <= 0) {
|
||||
av_log(s, AV_LOG_WARNING, "no video stream and no min frag duration set\n");
|
||||
ret = AVERROR(EINVAL);
|
||||
goto fail;
|
||||
return AVERROR(EINVAL);
|
||||
}
|
||||
ret = write_manifest(s, 0);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
fail:
|
||||
if (ret)
|
||||
ism_free(s);
|
||||
return ret;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_fragment(AVFormatContext *s, const char *filename, int64_t *start_ts, int64_t *duration, int64_t *moof_size, int64_t size)
|
||||
@@ -628,7 +615,6 @@ static int ism_write_trailer(AVFormatContext *s)
|
||||
rmdir(s->url);
|
||||
}
|
||||
|
||||
ism_free(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -661,5 +647,6 @@ AVOutputFormat ff_smoothstreaming_muxer = {
|
||||
.write_header = ism_write_header,
|
||||
.write_packet = ism_write_packet,
|
||||
.write_trailer = ism_write_trailer,
|
||||
.deinit = ism_free,
|
||||
.priv_class = &ism_class,
|
||||
};
|
||||
|
||||
Vendored
+4
@@ -322,7 +322,11 @@ void ff_make_absolute_url(char *buf, int size, const char *base,
|
||||
*/
|
||||
AVIODirEntry *ff_alloc_dir_entry(void);
|
||||
|
||||
#if FF_API_CHILD_CLASS_NEXT
|
||||
const AVClass *ff_urlcontext_child_class_next(const AVClass *prev);
|
||||
#endif
|
||||
|
||||
const AVClass *ff_urlcontext_child_class_iterate(void **iter);
|
||||
|
||||
/**
|
||||
* Construct a list of protocols matching a given whitelist and/or blacklist.
|
||||
|
||||
Vendored
+2
-2
@@ -4132,8 +4132,8 @@ FF_ENABLE_DEPRECATION_WARNINGS
|
||||
avcodec_string(buf, sizeof(buf), st->internal->avctx, 0);
|
||||
av_log(ic, AV_LOG_WARNING,
|
||||
"Could not find codec parameters for stream %d (%s): %s\n"
|
||||
"Consider increasing the value for the 'analyzeduration' and 'probesize' options\n",
|
||||
i, buf, errmsg);
|
||||
"Consider increasing the value for the 'analyzeduration' (%"PRId64") and 'probesize' (%"PRId64") options\n",
|
||||
i, buf, errmsg, ic->max_analyze_duration, ic->probesize);
|
||||
} else {
|
||||
ret = 0;
|
||||
}
|
||||
|
||||
+1
-1
@@ -32,7 +32,7 @@
|
||||
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
|
||||
// Also please add any ticket numbers that you believe might be affected here
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 58
|
||||
#define LIBAVFORMAT_VERSION_MINOR 45
|
||||
#define LIBAVFORMAT_VERSION_MINOR 48
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
|
||||
+1
-1
@@ -125,7 +125,7 @@ static int webvtt_read_header(AVFormatContext *s)
|
||||
break;
|
||||
|
||||
/* optional cue settings */
|
||||
p += strcspn(p, "\n\t ");
|
||||
p += strcspn(p, "\n\r\t ");
|
||||
while (*p == '\t' || *p == ' ')
|
||||
p++;
|
||||
settings = p;
|
||||
|
||||
Reference in New Issue
Block a user