mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2025-01-08 13:22:53 +02:00
Merge commit '3f7fd59d151a2773f0e2e93e56b6b13ec6e5334b'
* commit '3f7fd59d151a2773f0e2e93e56b6b13ec6e5334b': avformat: fix typo in avformat_close_input mp3enc: write Xing TOC mp3enc: support MPEG-2 and MPEG-2.5 in Xing header. mp3enc: downgrade some errors in writing Xing frame to warnings lavf: flush the output AVIOContext in av_write_trailer(). lavf: cosmetics, reformat av_write_trailer(). avio: flush the internal buffer in avio_close() Enhance doc on asyncts audiofilter cmdutils: avoid setting data pointers to invalid values in alloc_buffer() libavcodec: remove av_destruct_packet_nofree() Conflicts: libavcodec/avpacket.c libavformat/mp3enc.c libavformat/nutenc.c libavformat/utils.c libavformat/version.h tests/ref/lavf/voc tests/ref/lavf/voc_s16 Merged-by: Michael Niedermayer <michaelni@gmx.at>
This commit is contained in:
commit
f276a490f0
@ -738,14 +738,17 @@ The filter accepts the following named parameters:
|
||||
@table @option
|
||||
|
||||
@item compensate
|
||||
Enable stretching/squeezing the data to make it match the timestamps.
|
||||
Enable stretching/squeezing the data to make it match the timestamps. Disabled
|
||||
by default. When disabled, time gaps are covered with silence.
|
||||
|
||||
@item min_delta
|
||||
Minimum difference between timestamps and audio data (in seconds) to trigger
|
||||
adding/dropping samples.
|
||||
adding/dropping samples. Default value is 0.1. If you get non-perfect sync with
|
||||
this filter, try setting this parameter to 0.
|
||||
|
||||
@item max_comp
|
||||
Maximum compensation in samples per second.
|
||||
Maximum compensation in samples per second. Relevant only with compensate=1.
|
||||
Default value 500.
|
||||
|
||||
@item first_pts
|
||||
Assume the first pts should be this value.
|
||||
|
@ -3618,11 +3618,6 @@ void avsubtitle_free(AVSubtitle *sub);
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* @deprecated use NULL instead
|
||||
*/
|
||||
attribute_deprecated void av_destruct_packet_nofree(AVPacket *pkt);
|
||||
|
||||
/**
|
||||
* Default packet destructor.
|
||||
*/
|
||||
|
@ -27,14 +27,6 @@
|
||||
#include "bytestream.h"
|
||||
#include "internal.h"
|
||||
|
||||
void av_destruct_packet_nofree(AVPacket *pkt)
|
||||
{
|
||||
pkt->data = NULL;
|
||||
pkt->size = 0;
|
||||
pkt->side_data = NULL;
|
||||
pkt->side_data_elems = 0;
|
||||
}
|
||||
|
||||
void ff_packet_free_side_data(AVPacket *pkt)
|
||||
{
|
||||
int i;
|
||||
@ -137,8 +129,7 @@ int av_dup_packet(AVPacket *pkt)
|
||||
{
|
||||
AVPacket tmp_pkt;
|
||||
|
||||
if (((pkt->destruct == av_destruct_packet_nofree) ||
|
||||
(pkt->destruct == NULL)) && pkt->data) {
|
||||
if (pkt->destruct == NULL && pkt->data) {
|
||||
tmp_pkt = *pkt;
|
||||
|
||||
pkt->data = NULL;
|
||||
|
@ -893,7 +893,6 @@ static int asf_write_trailer(AVFormatContext *s)
|
||||
asf_write_header1(s, file_size, data_size - asf->data_offset);
|
||||
}
|
||||
|
||||
avio_flush(s->pb);
|
||||
av_free(asf->index_ptr);
|
||||
return 0;
|
||||
}
|
||||
|
@ -72,8 +72,6 @@ static int write_trailer(AVFormatContext *s)
|
||||
avio_write(s->pb, avctx->extradata + ass->extra_index,
|
||||
avctx->extradata_size - ass->extra_index);
|
||||
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -635,7 +635,6 @@ static int avi_write_trailer(AVFormatContext *s)
|
||||
avi_write_counters(s, avi->riff_id);
|
||||
}
|
||||
}
|
||||
avio_flush(pb);
|
||||
|
||||
for (i=0; i<s->nb_streams; i++) {
|
||||
AVIStream *avist= s->streams[i]->priv_data;
|
||||
|
@ -50,7 +50,7 @@ static int crc_write_trailer(struct AVFormatContext *s)
|
||||
|
||||
snprintf(buf, sizeof(buf), "CRC=0x%08x\n", crc->crcval);
|
||||
avio_write(s->pb, buf, strlen(buf));
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -225,15 +225,12 @@ static int ffm_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
static int ffm_write_trailer(AVFormatContext *s)
|
||||
{
|
||||
AVIOContext *pb = s->pb;
|
||||
FFMContext *ffm = s->priv_data;
|
||||
|
||||
/* flush packets */
|
||||
if (ffm->packet_ptr > ffm->packet)
|
||||
flush_packet(s);
|
||||
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -80,8 +80,6 @@ static int write_trailer(AVFormatContext *s)
|
||||
write_tags(s->pb, ch->metadata);
|
||||
}
|
||||
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -67,7 +67,7 @@ static int write_trailer(AVFormatContext *s)
|
||||
avio_wb16(pb, 1/av_q2d(st->codec->time_base));
|
||||
for (i = 0; i < 16; i++)
|
||||
avio_w8(pb, 0x00); // reserved
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -347,7 +347,7 @@ static int gif_write_trailer(AVFormatContext *s)
|
||||
AVIOContext *pb = s->pb;
|
||||
|
||||
avio_w8(pb, 0x3b);
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -92,8 +92,6 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
avio_write(pb[0], pkt->data , ysize);
|
||||
avio_write(pb[1], pkt->data + ysize, (pkt->size - ysize)/2);
|
||||
avio_write(pb[2], pkt->data + ysize +(pkt->size - ysize)/2, (pkt->size - ysize)/2);
|
||||
avio_flush(pb[1]);
|
||||
avio_flush(pb[2]);
|
||||
avio_close(pb[1]);
|
||||
avio_close(pb[2]);
|
||||
}else{
|
||||
|
@ -1289,7 +1289,7 @@ static int mkv_write_trailer(AVFormatContext *s)
|
||||
av_freep(&mkv->cues->entries);
|
||||
av_freep(&mkv->cues);
|
||||
av_destruct_packet(&mkv->cur_audio_pkt);
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -3682,8 +3682,6 @@ static int mov_write_trailer(AVFormatContext *s)
|
||||
|
||||
}
|
||||
|
||||
avio_flush(pb);
|
||||
|
||||
av_freep(&mov->tracks);
|
||||
|
||||
return res;
|
||||
|
@ -79,21 +79,25 @@ static int id3v1_create_tag(AVFormatContext *s, uint8_t *buf)
|
||||
return count;
|
||||
}
|
||||
|
||||
#define VBR_NUM_BAGS 400
|
||||
#define VBR_TOC_SIZE 100
|
||||
#define XING_NUM_BAGS 400
|
||||
#define XING_TOC_SIZE 100
|
||||
// maximum size of the xing frame: offset/Xing/flags/frames/size/TOC
|
||||
#define XING_MAX_SIZE (32 + 4 + 4 + 4 + 4 + XING_TOC_SIZE)
|
||||
|
||||
typedef struct MP3Context {
|
||||
const AVClass *class;
|
||||
ID3v2EncContext id3;
|
||||
int id3v2_version;
|
||||
int write_id3v1;
|
||||
int64_t frames_offset;
|
||||
|
||||
/* xing header */
|
||||
int64_t xing_offset;
|
||||
int32_t frames;
|
||||
int32_t size;
|
||||
uint32_t want;
|
||||
uint32_t seen;
|
||||
uint32_t pos;
|
||||
uint64_t bag[VBR_NUM_BAGS];
|
||||
uint64_t bag[XING_NUM_BAGS];
|
||||
int initial_bitrate;
|
||||
int has_variable_bitrate;
|
||||
|
||||
@ -106,7 +110,7 @@ typedef struct MP3Context {
|
||||
AVPacketList *queue, *queue_end;
|
||||
} MP3Context;
|
||||
|
||||
static const int64_t xing_offtbl[2][2] = {{32, 17}, {17,9}};
|
||||
static const uint8_t xing_offtbl[2][2] = {{32, 17}, {17, 9}};
|
||||
|
||||
/*
|
||||
* Write an empty XING header and initialize respective data.
|
||||
@ -118,7 +122,7 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
int bitrate_idx;
|
||||
int best_bitrate_idx = -1;
|
||||
int best_bitrate_error= INT_MAX;
|
||||
int64_t xing_offset;
|
||||
int xing_offset;
|
||||
int32_t header, mask;
|
||||
MPADecodeHeader c;
|
||||
int srate_idx, ver = 0, i, channels;
|
||||
@ -130,10 +134,12 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
|
||||
for (i = 0; i < FF_ARRAY_ELEMS(avpriv_mpa_freq_tab); i++) {
|
||||
const uint16_t base_freq = avpriv_mpa_freq_tab[i];
|
||||
|
||||
if (codec->sample_rate == base_freq) ver = 0x3; // MPEG 1
|
||||
else if (codec->sample_rate == base_freq / 2) ver = 0x2; // MPEG 2
|
||||
else if (codec->sample_rate == base_freq / 4) ver = 0x0; // MPEG 2.5
|
||||
else continue;
|
||||
|
||||
srate_idx = i;
|
||||
break;
|
||||
}
|
||||
@ -145,7 +151,9 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
switch (codec->channels) {
|
||||
case 1: channels = MPA_MONO; break;
|
||||
case 2: channels = MPA_STEREO; break;
|
||||
default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, not writing Xing header.\n"); return -1;
|
||||
default: av_log(s, AV_LOG_WARNING, "Unsupported number of channels, "
|
||||
"not writing Xing header.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* dummy MPEG audio header */
|
||||
@ -178,7 +186,7 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
+ 4 // frames/size/toc flags
|
||||
+ 4 // frames
|
||||
+ 4 // size
|
||||
+ VBR_TOC_SIZE // toc
|
||||
+ XING_TOC_SIZE // toc
|
||||
+ 24
|
||||
;
|
||||
|
||||
@ -188,11 +196,12 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
}
|
||||
|
||||
avio_wb32(s->pb, header);
|
||||
ffio_fill(s->pb, 0, xing_offset);
|
||||
avio_wb32(s->pb, MKBETAG('X', 'i', 'n', 'g'));
|
||||
avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames/size/toc
|
||||
|
||||
mp3->frames_offset = avio_tell(s->pb);
|
||||
ffio_fill(s->pb, 0, xing_offset);
|
||||
mp3->xing_offset = avio_tell(s->pb);
|
||||
ffio_wfourcc(s->pb, "Xing");
|
||||
avio_wb32(s->pb, 0x01 | 0x02 | 0x04); // frames / size / TOC
|
||||
|
||||
mp3->size = c.frame_size;
|
||||
mp3->want=1;
|
||||
mp3->seen=0;
|
||||
@ -202,8 +211,8 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
avio_wb32(s->pb, 0); // size
|
||||
|
||||
// toc
|
||||
for (i = 0; i < VBR_TOC_SIZE; ++i)
|
||||
avio_w8(s->pb, (uint8_t)(255 * i / VBR_TOC_SIZE));
|
||||
for (i = 0; i < XING_TOC_SIZE; ++i)
|
||||
avio_w8(s->pb, (uint8_t)(255 * i / XING_TOC_SIZE));
|
||||
|
||||
for (i = 0; i < strlen(vendor); ++i)
|
||||
avio_w8(s->pb, vendor[i]);
|
||||
@ -212,7 +221,6 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
avio_wb24(s->pb, FFMAX(codec->delay - 528 - 1, 0)<<12);
|
||||
|
||||
ffio_fill(s->pb, 0, c.frame_size - needed);
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -221,70 +229,63 @@ static int mp3_write_xing(AVFormatContext *s)
|
||||
* Add a frame to XING data.
|
||||
* Following lame's "VbrTag.c".
|
||||
*/
|
||||
static void mp3_xing_add_frame(AVFormatContext *s, AVPacket *pkt)
|
||||
static void mp3_xing_add_frame(MP3Context *mp3, AVPacket *pkt)
|
||||
{
|
||||
MP3Context *mp3 = s->priv_data;
|
||||
int i;
|
||||
|
||||
++mp3->frames;
|
||||
mp3->frames++;
|
||||
mp3->seen++;
|
||||
mp3->size += pkt->size;
|
||||
|
||||
if (mp3->want == ++mp3->seen) {
|
||||
if (mp3->want == mp3->seen) {
|
||||
mp3->bag[mp3->pos] = mp3->size;
|
||||
|
||||
if (VBR_NUM_BAGS == ++mp3->pos) {
|
||||
if (XING_NUM_BAGS == ++mp3->pos) {
|
||||
/* shrink table to half size by throwing away each second bag. */
|
||||
for (i = 1; i < VBR_NUM_BAGS; i += 2)
|
||||
for (i = 1; i < XING_NUM_BAGS; i += 2)
|
||||
mp3->bag[i >> 1] = mp3->bag[i];
|
||||
|
||||
/* double wanted amount per bag. */
|
||||
mp3->want <<= 1;
|
||||
mp3->want *= 2;
|
||||
/* adjust current position to half of table size. */
|
||||
mp3->pos >>= 1;
|
||||
mp3->pos = XING_NUM_BAGS / 2;
|
||||
}
|
||||
|
||||
mp3->seen = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static void mp3_fix_xing(AVFormatContext *s)
|
||||
static void mp3_update_xing(AVFormatContext *s)
|
||||
{
|
||||
MP3Context *mp3 = s->priv_data;
|
||||
int i;
|
||||
|
||||
avio_flush(s->pb);
|
||||
|
||||
/* replace "Xing" identification string with "Info" for CBR files. */
|
||||
if (!mp3->has_variable_bitrate) {
|
||||
int64_t tag_offset = mp3->frames_offset
|
||||
- 4 // frames/size/toc flags
|
||||
- 4; // xing tag
|
||||
avio_seek(s->pb, tag_offset, SEEK_SET);
|
||||
avio_wb32(s->pb, MKBETAG('I', 'n', 'f', 'o'));
|
||||
avio_seek(s->pb, mp3->xing_offset, SEEK_SET);
|
||||
ffio_wfourcc(s->pb, "Info");
|
||||
}
|
||||
|
||||
avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
|
||||
avio_seek(s->pb, mp3->xing_offset + 8, SEEK_SET);
|
||||
avio_wb32(s->pb, mp3->frames);
|
||||
avio_wb32(s->pb, mp3->size);
|
||||
|
||||
avio_w8(s->pb, 0); // first toc entry has to be zero.
|
||||
|
||||
for (i = 1; i < VBR_TOC_SIZE; ++i) {
|
||||
int j = i * mp3->pos / VBR_TOC_SIZE;
|
||||
for (i = 1; i < XING_TOC_SIZE; ++i) {
|
||||
int j = i * mp3->pos / XING_TOC_SIZE;
|
||||
int seek_point = 256LL * mp3->bag[j] / mp3->size;
|
||||
avio_w8(s->pb, FFMIN(seek_point, 255));
|
||||
}
|
||||
|
||||
avio_flush(s->pb);
|
||||
avio_seek(s->pb, 0, SEEK_END);
|
||||
}
|
||||
|
||||
static int mp3_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
|
||||
static int mp3_write_audio_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
{
|
||||
if (! pkt || ! pkt->data || pkt->size < 4)
|
||||
return ff_raw_write_packet(s, pkt);
|
||||
else {
|
||||
MP3Context *mp3 = s->priv_data;
|
||||
MP3Context *mp3 = s->priv_data;
|
||||
|
||||
if (pkt && pkt->data && pkt->size >= 4) {
|
||||
MPADecodeHeader c;
|
||||
int av_unused base;
|
||||
|
||||
@ -292,10 +293,8 @@ static int mp3_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
|
||||
|
||||
if (!mp3->initial_bitrate)
|
||||
mp3->initial_bitrate = c.bit_rate;
|
||||
if (!mp3->has_variable_bitrate) {
|
||||
if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
|
||||
mp3->has_variable_bitrate = 1;
|
||||
}
|
||||
if ((c.bit_rate == 0) || (mp3->initial_bitrate != c.bit_rate))
|
||||
mp3->has_variable_bitrate = 1;
|
||||
|
||||
#ifdef FILTER_VBR_HEADERS
|
||||
/* filter out XING and INFO headers. */
|
||||
@ -315,11 +314,11 @@ static int mp3_write_packet_internal(AVFormatContext *s, AVPacket *pkt)
|
||||
return 0;
|
||||
#endif
|
||||
|
||||
if (mp3->frames_offset)
|
||||
mp3_xing_add_frame(s, pkt);
|
||||
|
||||
return ff_raw_write_packet(s, pkt);
|
||||
if (mp3->xing_offset)
|
||||
mp3_xing_add_frame(mp3, pkt);
|
||||
}
|
||||
|
||||
return ff_raw_write_packet(s, pkt);
|
||||
}
|
||||
|
||||
static int mp3_queue_flush(AVFormatContext *s)
|
||||
@ -332,7 +331,7 @@ static int mp3_queue_flush(AVFormatContext *s)
|
||||
mp3_write_xing(s);
|
||||
|
||||
while ((pktl = mp3->queue)) {
|
||||
if (write && (ret = mp3_write_packet_internal(s, &pktl->pkt)) < 0)
|
||||
if (write && (ret = mp3_write_audio_packet(s, &pktl->pkt)) < 0)
|
||||
write = 0;
|
||||
av_free_packet(&pktl->pkt);
|
||||
mp3->queue = pktl->next;
|
||||
@ -347,26 +346,24 @@ static int mp2_write_trailer(struct AVFormatContext *s)
|
||||
uint8_t buf[ID3v1_TAG_SIZE];
|
||||
MP3Context *mp3 = s->priv_data;
|
||||
|
||||
if (mp3 && mp3->pics_to_write) {
|
||||
if (mp3->pics_to_write) {
|
||||
av_log(s, AV_LOG_WARNING, "No packets were sent for some of the "
|
||||
"attached pictures.\n");
|
||||
mp3_queue_flush(s);
|
||||
}
|
||||
|
||||
/* write the id3v1 tag */
|
||||
if (mp3 && mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
|
||||
if (mp3->write_id3v1 && id3v1_create_tag(s, buf) > 0) {
|
||||
avio_write(s->pb, buf, ID3v1_TAG_SIZE);
|
||||
}
|
||||
|
||||
/* write number of frames */
|
||||
if (mp3 && mp3->frames_offset) {
|
||||
avio_seek(s->pb, mp3->frames_offset, SEEK_SET);
|
||||
if (mp3->xing_offset) {
|
||||
avio_seek(s->pb, mp3->xing_offset+8, SEEK_SET);
|
||||
avio_wb32(s->pb, s->streams[mp3->audio_stream_idx]->nb_frames);
|
||||
avio_seek(s->pb, 0, SEEK_END);
|
||||
}
|
||||
|
||||
avio_flush(s->pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -390,7 +387,6 @@ AVOutputFormat ff_mp2_muxer = {
|
||||
.audio_codec = AV_CODEC_ID_MP2,
|
||||
.video_codec = AV_CODEC_ID_NONE,
|
||||
.write_packet = ff_raw_write_packet,
|
||||
.write_trailer = mp2_write_trailer,
|
||||
.flags = AVFMT_NOTIMESTAMPS,
|
||||
};
|
||||
#endif
|
||||
@ -432,7 +428,7 @@ static int mp3_write_packet(AVFormatContext *s, AVPacket *pkt)
|
||||
mp3->queue = pktl;
|
||||
mp3->queue_end = pktl;
|
||||
} else
|
||||
return mp3_write_packet_internal(s, pkt);
|
||||
return mp3_write_audio_packet(s, pkt);
|
||||
} else {
|
||||
int ret;
|
||||
|
||||
@ -510,8 +506,8 @@ static int mp3_write_trailer(AVFormatContext *s)
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
if (mp3->frames_offset)
|
||||
mp3_fix_xing(s);
|
||||
if (mp3->xing_offset)
|
||||
mp3_update_xing(s);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -2075,8 +2075,6 @@ static int mxf_write_footer(AVFormatContext *s)
|
||||
}
|
||||
}
|
||||
|
||||
avio_flush(pb);
|
||||
|
||||
ff_audio_interleave_close(s);
|
||||
|
||||
av_freep(&mxf->index_entries);
|
||||
|
@ -930,7 +930,6 @@ static int nut_write_trailer(AVFormatContext *s){
|
||||
put_packet(nut, bc, dyn_bc, 1, INDEX_STARTCODE);
|
||||
}
|
||||
|
||||
avio_flush(bc);
|
||||
ff_nut_free_sp(nut);
|
||||
for(i=0; i<s->nb_streams; i++)
|
||||
av_freep(&nut->stream[i].keyframe_pts);
|
||||
|
@ -460,7 +460,7 @@ static int rm_write_trailer(AVFormatContext *s)
|
||||
avio_wb32(pb, 0);
|
||||
avio_wb32(pb, 0);
|
||||
}
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -95,8 +95,6 @@ static int rso_write_trailer(AVFormatContext *s)
|
||||
avio_wb16(pb, coded_file_size);
|
||||
avio_seek(pb, file_size, SEEK_SET);
|
||||
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -130,7 +130,6 @@ static int smjpeg_write_trailer(AVFormatContext *s)
|
||||
}
|
||||
|
||||
avio_wl32(pb, SMJPEG_DONE);
|
||||
avio_flush(pb);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -486,8 +486,6 @@ static int swf_write_trailer(AVFormatContext *s)
|
||||
put_swf_tag(s, TAG_END);
|
||||
put_swf_end_tag(s);
|
||||
|
||||
avio_flush(s->pb);
|
||||
|
||||
/* patch file size and number of frames if not streamed */
|
||||
if (s->pb->seekable && video_enc) {
|
||||
file_size = avio_tell(pb);
|
||||
|
@ -3056,8 +3056,11 @@ void av_close_input_file(AVFormatContext *s)
|
||||
void avformat_close_input(AVFormatContext **ps)
|
||||
{
|
||||
AVFormatContext *s = *ps;
|
||||
AVIOContext *pb = (s->iformat && (s->iformat->flags & AVFMT_NOFILE)) || (s->flags & AVFMT_FLAG_CUSTOM_IO) ?
|
||||
NULL : s->pb;
|
||||
AVIOContext *pb = s->pb;
|
||||
|
||||
if ((s->iformat && s->iformat->flags & AVFMT_NOFILE) ||
|
||||
(s->flags & AVFMT_FLAG_CUSTOM_IO))
|
||||
pb = NULL;
|
||||
|
||||
flush_packet_queue(s);
|
||||
|
||||
@ -3761,34 +3764,38 @@ int av_write_trailer(AVFormatContext *s)
|
||||
{
|
||||
int ret, i;
|
||||
|
||||
for(;;){
|
||||
for (;;) {
|
||||
AVPacket pkt;
|
||||
ret= interleave_packet(s, &pkt, NULL, 1);
|
||||
if(ret<0) //FIXME cleanup needed for ret<0 ?
|
||||
ret = interleave_packet(s, &pkt, NULL, 1);
|
||||
if (ret < 0) //FIXME cleanup needed for ret<0 ?
|
||||
goto fail;
|
||||
if(!ret)
|
||||
if (!ret)
|
||||
break;
|
||||
|
||||
ret= s->oformat->write_packet(s, &pkt);
|
||||
ret = s->oformat->write_packet(s, &pkt);
|
||||
if (ret >= 0)
|
||||
s->streams[pkt.stream_index]->nb_frames++;
|
||||
|
||||
av_free_packet(&pkt);
|
||||
|
||||
if(ret<0)
|
||||
if (ret < 0)
|
||||
goto fail;
|
||||
if(s->pb && s->pb->error)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if(s->oformat->write_trailer)
|
||||
if (s->oformat->write_trailer)
|
||||
ret = s->oformat->write_trailer(s);
|
||||
|
||||
if (!(s->oformat->flags & AVFMT_NOFILE))
|
||||
avio_flush(s->pb);
|
||||
|
||||
fail:
|
||||
if (s->pb)
|
||||
avio_flush(s->pb);
|
||||
if(ret == 0)
|
||||
if (ret == 0)
|
||||
ret = s->pb ? s->pb->error : 0;
|
||||
for(i=0;i<s->nb_streams;i++) {
|
||||
for (i = 0; i < s->nb_streams; i++) {
|
||||
av_freep(&s->streams[i]->priv_data);
|
||||
av_freep(&s->streams[i]->index_entries);
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
|
||||
#define LIBAVFORMAT_VERSION_MAJOR 54
|
||||
#define LIBAVFORMAT_VERSION_MINOR 27
|
||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||
#define LIBAVFORMAT_VERSION_MICRO 101
|
||||
|
||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||
LIBAVFORMAT_VERSION_MINOR, \
|
||||
|
Loading…
Reference in New Issue
Block a user