early-access version 1680

This commit is contained in:
pineappleEA
2021-05-13 11:45:27 +02:00
parent 1434d96e7d
commit 66ed389c6f
311 changed files with 6452 additions and 2597 deletions
+1
View File
@@ -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
View File
@@ -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
View File
@@ -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;
+5 -1
View File
@@ -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
View File
@@ -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);
+8 -3
View File
@@ -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);
+7 -11
View File
@@ -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;
+2 -2
View File
@@ -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
View File
@@ -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,
+3
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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 },
};
+75 -55
View File
@@ -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");
+3 -2
View File
@@ -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;
}
+58 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
}
+8 -10
View File
@@ -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;
+14
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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)
+139 -19
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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",
};
-2
View File
@@ -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;
+103 -114
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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);
+1 -1
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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,
};
+4
View File
@@ -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.
+2 -2
View File
@@ -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
View File
@@ -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
View File
@@ -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;