#define DIV_ROUND_UP(s,v) (((s) + ((v)-1)) / (v))
+#define GST_AVI_KEYFRAME 1
+#define ENTRY_IS_KEYFRAME(e) ((e)->flags == GST_AVI_KEYFRAME)
+#define ENTRY_SET_KEYFRAME(e) ((e)->flags = GST_AVI_KEYFRAME)
+#define ENTRY_UNSET_KEYFRAME(e) ((e)->flags = 0)
+
+
GST_DEBUG_CATEGORY_STATIC (avidemux_debug);
#define GST_CAT_DEFAULT avidemux_debug
if (before) {
if (entry) {
+ gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &val);
GST_DEBUG_OBJECT (avi, "stream %d, previous entry at %"
G_GUINT64_FORMAT, i, val);
- gst_index_entry_assoc_map (entry, GST_FORMAT_BYTES, &val);
if (val < min)
min = val;
}
if (before) {
if (entry) {
+ val = stream->index[index].offset;
GST_DEBUG_OBJECT (avi,
"stream %d, previous entry at %" G_GUINT64_FORMAT, i, val);
- val = stream->index[index].offset;
if (val < min)
min = val;
}
GST_DEBUG_OBJECT (element, "marking video as VBR, res %d", res);
break;
case GST_RIFF_FCC_auds:
- stream->is_vbr = (stream->strh->samplesize == 0)
- && stream->strh->scale > 1;
res =
gst_riff_parse_strf_auds (element, sub, &stream->strf.auds,
&stream->extradata);
+ stream->is_vbr = (stream->strh->samplesize == 0)
+ && stream->strh->scale > 1
+ && stream->strf.auds->blockalign != 1;
sub = NULL;
GST_DEBUG_OBJECT (element, "marking audio as VBR:%d, res %d",
stream->is_vbr, res);
/* we need these or we have no way to come up with timestamps */
- if ((stream->is_vbr && !stream->strf.auds->av_bps) ||
- (!stream->is_vbr && (!stream->strh->scale ||
+ if ((!stream->is_vbr && !stream->strf.auds->av_bps) ||
+ (stream->is_vbr && (!stream->strh->scale ||
!stream->strh->rate))) {
GST_WARNING_OBJECT (element,
"invalid audio header, ignoring stream");
goto fail;
}
+ /* some more sanity checks */
+ if (stream->is_vbr) {
+ if (stream->strf.auds->blockalign <= 4) {
+ /* that would mean (too) many frames per chunk,
+ * so not likely set as expected */
+ GST_DEBUG_OBJECT (element,
+ "suspicious blockalign %d for VBR audio; "
+ "overriding to 1 frame per chunk",
+ stream->strf.auds->blockalign);
+ /* this should top any likely value */
+ stream->strf.auds->blockalign = (1 << 12);
+ }
+ }
break;
case GST_RIFF_FCC_iavs:
stream->is_vbr = TRUE;
GST_DEBUG ("will parse index chunk size %u for tag %"
GST_FOURCC_FORMAT, GST_BUFFER_SIZE (buf), GST_FOURCC_ARGS (tag));
- avi->offset = avi->first_movi_offset - 8;
+ avi->offset = avi->first_movi_offset;
gst_avi_demux_parse_index (avi, buf);
#ifndef GST_DISABLE_GST_DEBUG
* through the whole file */
if (avi->abort_buffering) {
avi->abort_buffering = FALSE;
- gst_adapter_flush (avi->adapter, 8);
+ if (size) {
+ gst_adapter_flush (avi->adapter, 8);
+ return GST_FLOW_OK;
+ }
+ } else {
+ return GST_FLOW_OK;
}
- return GST_FLOW_OK;
}
GST_DEBUG ("chunk ID %" GST_FOURCC_FORMAT ", size %u",
GST_FOURCC_ARGS (tag), size);
if (saw_desired_kf) {
gst_adapter_flush (avi->adapter, 8);
/* get buffer */
- buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
- /* patch the size */
- GST_BUFFER_SIZE (buf) = size;
+ if (size) {
+ buf = gst_adapter_take_buffer (avi->adapter, GST_ROUND_UP_2 (size));
+ /* patch the size */
+ GST_BUFFER_SIZE (buf) = size;
+ } else {
+ buf = NULL;
+ }
} else {
GST_DEBUG_OBJECT (avi,
"Desired keyframe not yet reached, flushing chunk");
stream->discont = FALSE;
}
res = gst_pad_push (stream->pad, buf);
+ buf = NULL;
/* combine flows */
res = gst_avi_demux_combine_flows (avi, stream, res);
switch (transition) {
case GST_STATE_CHANGE_PAUSED_TO_READY:
+ avi->have_index = FALSE;
gst_avi_demux_reset (avi);
break;
default: