On Sun, 26 Feb 2012, Justin Ruggles wrote:
For encoding, frame_size is the number of input samples to send to the
encoder and is not necessarily the same as the duration of all output
packets.
---
libavformat/movenc.c | 56 ++++++++++++++++++++++++++++++++++---------------
1 files changed, 39 insertions(+), 17 deletions(-)
Looks good in general, but IMO needs a bit of splitting.
diff --git a/libavformat/movenc.c b/libavformat/movenc.c
index 2c6a6e1..5ad82d7 100644
--- a/libavformat/movenc.c
+++ b/libavformat/movenc.c
@@ -551,6 +551,40 @@ static int mov_get_lpcm_flags(enum CodecID codec_id)
}
}
+static int get_cluster_duration(MOVTrack *track, int cluster_idx)
+{
+ int64_t next_dts;
+
+ if (cluster_idx >= track->entry)
+ return 0;
+
+ if (cluster_idx + 1 == track->entry)
+ next_dts = track->track_duration + track->start_dts;
+ else
+ next_dts = track->cluster[cluster_idx + 1].dts;
+
+ return next_dts - track->cluster[cluster_idx].dts;
+}
This, and the usage of it below would be one patch - just pure
factorization.
+static int get_samples_per_packet(MOVTrack *track)
+{
+ int i, first_duration;
+
+ /* use 1 for raw PCM */
+ if (!track->audio_vbr)
+ return 1;
+
+ /* check to see if duration is constant for all clusters */
+ if (!track->entry)
+ return 0;
+ first_duration = get_cluster_duration(track, 0);
+ for (i = 1; i < track->entry; i++) {
+ if (get_cluster_duration(track, i) != first_duration)
+ return 0;
+ }
+ return first_duration;
+}
+
This and the usage of it is another.
static int mov_write_audio_tag(AVIOContext *pb, MOVTrack *track)
{
int64_t pos = avio_tell(pb);
@@ -587,7 +621,7 @@ static int mov_write_audio_tag(AVIOContext *pb, MOVTrack
*track)
avio_wb32(pb, av_get_bits_per_sample(track->enc->codec_id));
avio_wb32(pb, mov_get_lpcm_flags(track->enc->codec_id));
avio_wb32(pb, track->sample_size);
- avio_wb32(pb, track->audio_vbr ? track->enc->frame_size : 1);
+ avio_wb32(pb, get_samples_per_packet(track));
} else {
/* reserved for mp4/3gp */
avio_wb16(pb, 2);
@@ -1107,9 +1141,7 @@ static int mov_write_stts_tag(AVIOContext *pb, MOVTrack
*track)
av_malloc(track->entry * sizeof(*stts_entries)) : /*
worst case */
NULL;
for (i=0; i<track->entry; i++) {
- int64_t duration = i + 1 == track->entry ?
- track->track_duration - track->cluster[i].dts +
track->start_dts : /* readjusting */
- track->cluster[i+1].dts - track->cluster[i].dts;
+ int duration = get_cluster_duration(track, i);
if (i && duration == stts_entries[entries].duration) {
stts_entries[entries].count++; /* compress */
} else {
This changes the data type of duration fron int64_t to int, but I guess it
shouldn't make any difference (int makes more sense).
@@ -2202,7 +2234,7 @@ static int mov_write_tfhd_tag(AVIOContext *pb, MOVTrack
*track,
if (flags & MOV_TFHD_BASE_DATA_OFFSET)
avio_wb64(pb, moof_offset);
if (flags & MOV_TFHD_DEFAULT_DURATION) {
- track->default_duration = track->audio_vbr ? track->enc->frame_size :
1;
+ track->default_duration = track->audio_vbr ?
get_cluster_duration(track, 0) : 1;
avio_wb32(pb, track->default_duration);
}
if (flags & MOV_TFHD_DEFAULT_SIZE) {
This belongs to the second one (or a completely different one), since the
first one would be a pure factorization.
@@ -2235,10 +2267,7 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack
*track)
int i;
for (i = 0; i < track->entry; i++) {
- int64_t duration = i + 1 == track->entry ?
- track->track_duration - track->cluster[i].dts + track->start_dts :
- track->cluster[i + 1].dts - track->cluster[i].dts;
- if (duration != track->default_duration)
+ if (get_cluster_duration(track, i) != track->default_duration)
flags |= MOV_TRUN_SAMPLE_DURATION;
if (track->cluster[i].size != track->default_size)
flags |= MOV_TRUN_SAMPLE_SIZE;
@@ -2262,11 +2291,8 @@ static int mov_write_trun_tag(AVIOContext *pb, MOVTrack
*track)
avio_wb32(pb, get_sample_flags(track, &track->cluster[0]));
for (i = 0; i < track->entry; i++) {
- int64_t duration = i + 1 == track->entry ?
- track->track_duration - track->cluster[i].dts + track->start_dts :
- track->cluster[i + 1].dts - track->cluster[i].dts;
if (flags & MOV_TRUN_SAMPLE_DURATION)
- avio_wb32(pb, duration);
+ avio_wb32(pb, get_cluster_duration(track, i));
if (flags & MOV_TRUN_SAMPLE_SIZE)
avio_wb32(pb, track->cluster[i].size);
if (flags & MOV_TRUN_SAMPLE_FLAGS)
@@ -3105,10 +3131,6 @@ static int mov_write_header(AVFormatContext *s)
}
/* set audio_vbr for compressed audio */
if (av_get_bits_per_sample(st->codec->codec_id) < 8) {
- if (!st->codec->frame_size && track->mode == MODE_MOV) {
- av_log(s, AV_LOG_ERROR, "track %d: codec frame size is not
set\n", i);
- goto error;
- }
track->audio_vbr = 1;
}
if (track->mode != MODE_MOV) {
--
1.7.1
// Martin
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel