summaryrefslogtreecommitdiff
path: root/libavformat
diff options
context:
space:
mode:
Diffstat (limited to 'libavformat')
-rw-r--r--libavformat/internal.h3
-rw-r--r--libavformat/mux.c35
-rw-r--r--libavformat/segment.c4
3 files changed, 27 insertions, 15 deletions
diff --git a/libavformat/internal.h b/libavformat/internal.h
index 4fc1154b9d..9d7312c0e2 100644
--- a/libavformat/internal.h
+++ b/libavformat/internal.h
@@ -506,7 +506,8 @@ void ff_sdp_write_media(char *buff, int size, AVStream *st, int idx,
*
* @param dst the muxer to write the packet to
* @param dst_stream the stream index within dst to write the packet to
- * @param pkt the packet to be written
+ * @param pkt the packet to be written. It will be returned blank when
+ * av_interleaved_write_frame() is used, unchanged otherwise.
* @param src the muxer the packet originally was intended for
* @param interleave 0->use av_write_frame, 1->av_interleaved_write_frame
* @return the value av_write_frame returned
diff --git a/libavformat/mux.c b/libavformat/mux.c
index b1ad0dd561..6ba1306f2b 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -643,12 +643,12 @@ static void guess_pkt_duration(AVFormatContext *s, AVStream *st, AVPacket *pkt)
*/
static int write_packet(AVFormatContext *s, AVPacket *pkt)
{
+ AVStream *const st = s->streams[pkt->stream_index];
int ret;
// If the timestamp offsetting below is adjusted, adjust
// ff_interleaved_peek similarly.
if (s->output_ts_offset) {
- AVStream *st = s->streams[pkt->stream_index];
int64_t offset = av_rescale_q(s->output_ts_offset, AV_TIME_BASE_Q, st->time_base);
if (pkt->dts != AV_NOPTS_VALUE)
@@ -658,7 +658,6 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (s->avoid_negative_ts > 0) {
- AVStream *st = s->streams[pkt->stream_index];
int64_t offset = st->internal->mux_ts_offset;
int64_t ts = s->internal->avoid_negative_ts_use_pts ? pkt->pts : pkt->dts;
@@ -719,7 +718,7 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
}
if (ret >= 0)
- s->streams[pkt->stream_index]->nb_frames++;
+ st->nb_frames++;
return ret;
}
@@ -1192,6 +1191,7 @@ int av_write_frame(AVFormatContext *s, AVPacket *in)
pkt = in;
} else {
/* We don't own in, so we have to make sure not to modify it.
+ * (ff_write_chained() relies on this fact.)
* The following avoids copying in's data unnecessarily.
* Copying side data is unavoidable as a bitstream filter
* may change it, e.g. free it on errors. */
@@ -1291,21 +1291,30 @@ int av_get_output_timestamp(struct AVFormatContext *s, int stream,
int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
AVFormatContext *src, int interleave)
{
- AVPacket local_pkt;
+ int64_t pts = pkt->pts, dts = pkt->dts, duration = pkt->duration;
+ int stream_index = pkt->stream_index;
+ AVRational time_base = pkt->time_base;
int ret;
- local_pkt = *pkt;
- local_pkt.stream_index = dst_stream;
+ pkt->stream_index = dst_stream;
- av_packet_rescale_ts(&local_pkt,
- src->streams[pkt->stream_index]->time_base,
+ av_packet_rescale_ts(pkt,
+ src->streams[stream_index]->time_base,
dst->streams[dst_stream]->time_base);
- if (interleave) ret = av_interleaved_write_frame(dst, &local_pkt);
- else ret = av_write_frame(dst, &local_pkt);
- pkt->buf = local_pkt.buf;
- pkt->side_data = local_pkt.side_data;
- pkt->side_data_elems = local_pkt.side_data_elems;
+ if (!interleave) {
+ ret = av_write_frame(dst, pkt);
+ /* We only have to backup and restore the fields that
+ * we changed ourselves, because av_write_frame() does not
+ * modify the packet given to it. */
+ pkt->pts = pts;
+ pkt->dts = dts;
+ pkt->duration = duration;
+ pkt->stream_index = stream_index;
+ pkt->time_base = time_base;
+ } else
+ ret = av_interleaved_write_frame(dst, pkt);
+
return ret;
}
diff --git a/libavformat/segment.c b/libavformat/segment.c
index ed671353d0..7c171b6fa4 100644
--- a/libavformat/segment.c
+++ b/libavformat/segment.c
@@ -952,7 +952,9 @@ calc_times:
seg->initial_offset || seg->reset_timestamps || seg->avf->oformat->interleave_packet);
fail:
- if (pkt->stream_index == seg->reference_stream_index) {
+ /* Use st->index here as the packet returned from ff_write_chained()
+ * is blank if interleaving has been used. */
+ if (st->index == seg->reference_stream_index) {
seg->frame_count++;
seg->segment_frame_count++;
}