X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=libavformat%2Fflvenc.c;h=d7506c56fbe990be2c1df8d827ce46aaba10edc0;hb=9bbdf5d921ef57e1698f64981e4ea04db7c56fb5;hp=4ca6aea9f7efe84e617fe50f8deb4707dbf859d9;hpb=a81b9c60125f24ae1101be7429b15e74031453e7;p=ffmpeg diff --git a/libavformat/flvenc.c b/libavformat/flvenc.c index 4ca6aea9f7e..d7506c56fbe 100644 --- a/libavformat/flvenc.c +++ b/libavformat/flvenc.c @@ -67,6 +67,8 @@ typedef enum { FLV_AAC_SEQ_HEADER_DETECT = (1 << 0), FLV_NO_SEQUENCE_END = (1 << 1), FLV_ADD_KEYFRAME_INDEX = (1 << 2), + FLV_NO_METADATA = (1 << 3), + FLV_NO_DURATION_FILESIZE = (1 << 4), } FLVFlags; typedef struct FLVFileposition { @@ -268,6 +270,7 @@ static void write_metadata(AVFormatContext *s, unsigned int ts) { AVIOContext *pb = s->pb; FLVContext *flv = s->priv_data; + int write_duration_filesize = !(flv->flags & FLV_NO_DURATION_FILESIZE); int metadata_count = 0; int64_t metadata_count_pos; AVDictionaryEntry *tag = NULL; @@ -291,12 +294,12 @@ static void write_metadata(AVFormatContext *s, unsigned int ts) metadata_count = 4 * !!flv->video_par + 5 * !!flv->audio_par + 1 * !!flv->data_par; - if (pb->seekable) { + if (write_duration_filesize) { metadata_count += 2; // +2 for duration and file size } avio_wb32(pb, metadata_count); - if (pb->seekable) { + if (write_duration_filesize) { put_amf_string(pb, "duration"); flv->duration_offset = avio_tell(pb); // fill in the guessed duration, it'll be corrected later if incorrect @@ -377,7 +380,7 @@ static void write_metadata(AVFormatContext *s, unsigned int ts) metadata_count++; } - if (pb->seekable) { + if (write_duration_filesize) { put_amf_string(pb, "filesize"); flv->filesize_offset = avio_tell(pb); put_amf_double(pb, 0); // delayed write @@ -623,13 +626,15 @@ static int shift_data(AVFormatContext *s) avio_seek(read_pb, flv->keyframes_info_offset, SEEK_SET); pos = avio_tell(read_pb); - /* shift data by chunk of at most keyframe *filepositions* and *times* size */ +#define READ_BLOCK do { \ read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size); \ - read_buf_id ^= 1; - do { + read_buf_id ^= 1; \ +} while (0) - read_size[read_buf_id] = avio_read(read_pb, read_buf[read_buf_id], metadata_size); \ - read_buf_id ^= 1; + /* shift data by chunk of at most keyframe *filepositions* and *times* size */ + READ_BLOCK; + do { + READ_BLOCK; n = read_size[read_buf_id]; if (n < 0) break; @@ -744,7 +749,11 @@ static int flv_write_header(AVFormatContext *s) flv->reserved = 5; } - write_metadata(s, 0); + if (flv->flags & FLV_NO_METADATA) { + pb->seekable = 0; + } else { + write_metadata(s, 0); + } for (i = 0; i < s->nb_streams; i++) { flv_write_codec_header(s, s->streams[i]->codecpar); @@ -839,7 +848,7 @@ end: avio_seek(pb, flv->datasize_offset, SEEK_SET); put_amf_double(pb, flv->datasize); } - if (pb->seekable) { + if (!(flv->flags & FLV_NO_DURATION_FILESIZE)) { /* update information */ if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) { av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); @@ -883,6 +892,10 @@ static int flv_write_packet(AVFormatContext *s, AVPacket *pkt) if (side && side_size > 0 && (side_size != par->extradata_size || memcmp(side, par->extradata, side_size))) { av_free(par->extradata); par->extradata = av_mallocz(side_size + AV_INPUT_BUFFER_PADDING_SIZE); + if (!par->extradata) { + par->extradata_size = 0; + return AVERROR(ENOMEM); + } memcpy(par->extradata, side, side_size); par->extradata_size = side_size; flv_write_codec_header(s, par); @@ -1055,6 +1068,8 @@ static const AVOption options[] = { { "flvflags", "FLV muxer flags", offsetof(FLVContext, flags), AV_OPT_TYPE_FLAGS, {.i64 = 0}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, { "aac_seq_header_detect", "Put AAC sequence header based on stream data", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_AAC_SEQ_HEADER_DETECT}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, { "no_sequence_end", "disable sequence end for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_SEQUENCE_END}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, + { "no_metadata", "disable metadata for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_METADATA}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, + { "no_duration_filesize", "disable duration and filesize zero value metadata for FLV", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_NO_DURATION_FILESIZE}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, { "add_keyframe_index", "Add keyframe index metadata", 0, AV_OPT_TYPE_CONST, {.i64 = FLV_ADD_KEYFRAME_INDEX}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "flvflags" }, { NULL }, };