avformat/flvenc: do not attempt to write duration and filesize when not seekable

Its impossible to update the filesize & duration values if seekback is not
possible as with live streams

Signed-off-by: Michael Niedermayer <michael@niedermayer.cc>
This commit is contained in:
Steven Liu 2016-10-12 18:11:41 +08:00 committed by Michael Niedermayer
parent c0e2846dcd
commit 5702416c57
1 changed files with 28 additions and 21 deletions

View File

@ -234,16 +234,18 @@ static void write_metadata(AVFormatContext *s, unsigned int ts)
metadata_count_pos = avio_tell(pb); metadata_count_pos = avio_tell(pb);
metadata_count = 4 * !!flv->video_par + metadata_count = 4 * !!flv->video_par +
5 * !!flv->audio_par + 5 * !!flv->audio_par +
1 * !!flv->data_par + 1 * !!flv->data_par;
2; // +2 for duration and file size if (pb->seekable) {
metadata_count += 2; // +2 for duration and file size
}
avio_wb32(pb, metadata_count); avio_wb32(pb, metadata_count);
put_amf_string(pb, "duration"); if (pb->seekable) {
flv->duration_offset = avio_tell(pb); put_amf_string(pb, "duration");
flv->duration_offset = avio_tell(pb);
// fill in the guessed duration, it'll be corrected later if incorrect // fill in the guessed duration, it'll be corrected later if incorrect
put_amf_double(pb, s->duration / AV_TIME_BASE); put_amf_double(pb, s->duration / AV_TIME_BASE);
}
if (flv->video_par) { if (flv->video_par) {
put_amf_string(pb, "width"); put_amf_string(pb, "width");
@ -319,9 +321,11 @@ static void write_metadata(AVFormatContext *s, unsigned int ts)
metadata_count++; metadata_count++;
} }
put_amf_string(pb, "filesize"); if (pb->seekable) {
flv->filesize_offset = avio_tell(pb); put_amf_string(pb, "filesize");
put_amf_double(pb, 0); // delayed write flv->filesize_offset = avio_tell(pb);
put_amf_double(pb, 0); // delayed write
}
put_amf_string(pb, ""); put_amf_string(pb, "");
avio_w8(pb, AMF_END_OF_OBJECT); avio_w8(pb, AMF_END_OF_OBJECT);
@ -543,16 +547,19 @@ static int flv_write_trailer(AVFormatContext *s)
file_size = avio_tell(pb); file_size = avio_tell(pb);
/* update information */ if (pb->seekable) {
if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) /* update information */
av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n"); if (avio_seek(pb, flv->duration_offset, SEEK_SET) < 0) {
else av_log(s, AV_LOG_WARNING, "Failed to update header with correct duration.\n");
put_amf_double(pb, flv->duration / (double)1000); } else {
if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) put_amf_double(pb, flv->duration / (double)1000);
av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n"); }
else if (avio_seek(pb, flv->filesize_offset, SEEK_SET) < 0) {
put_amf_double(pb, file_size); av_log(s, AV_LOG_WARNING, "Failed to update header with correct filesize.\n");
} else {
put_amf_double(pb, file_size);
}
}
avio_seek(pb, file_size, SEEK_SET); avio_seek(pb, file_size, SEEK_SET);
return 0; return 0;
} }