[FFmpeg-devel] [PATCH 1/4] lavf: add write_uncoded_frame() API.
Nicolas George
george at nsup.org
Wed Jan 1 13:27:05 CET 2014
Signed-off-by: Nicolas George <george at nsup.org>
---
libavformat/avformat.h | 44 ++++++++++++++++++++++++++++++++++++++++++++
libavformat/mux.c | 43 ++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 86 insertions(+), 1 deletion(-)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 6d719d7..9b25bff 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -453,6 +453,14 @@ typedef struct AVOutputFormat {
void (*get_output_timestamp)(struct AVFormatContext *s, int stream,
int64_t *dts, int64_t *wall);
+
+ /**
+ * Write an uncoded AVFrame
+ *
+ * See av_write_uncoded_frame() for details.
+ */
+ int (*write_uncoded_frame)(struct AVFormatContext *, int stream_index,
+ AVFrame *frame, unsigned flags);
} AVOutputFormat;
/**
* @}
@@ -1908,6 +1916,42 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt);
int av_interleaved_write_frame(AVFormatContext *s, AVPacket *pkt);
/**
+ * Write a uncoded frame to an output media file
+ *
+ * If the muxer supports it, this function allows to write an AVFrame
+ * structure directly, without encoding it into a packet.
+ * It is mostly useful for devices and similar special muxers that use raw
+ * video or PCM data and will not serialize it into a byte stream.
+ *
+ * To test whether it is possible to use it with a given muxer and stream,
+ * use the AV_WRITE_UNCODED_FRAME_QUERY flag with frame = NULL.
+ *
+ * The caller keeps ownership of the frame and is responsible for freeing
+ * it.
+ *
+ * @return >=0 for success, a negative code on error
+ */
+int av_write_uncoded_frame(AVFormatContext *s, int stream_index,
+ AVFrame *frame, unsigned flags);
+
+enum AVWriteUncodedFrameFlags {
+
+ /**
+ * Query whether the feature is possible on this stream.
+ * The frame argument is ignored.
+ */
+ AV_WRITE_UNCODED_FRAME_QUERY = 0x0001,
+
+ /**
+ * Do not queue packets for interleaving.
+ * If this flag is set, the application is responsible for interleaving.
+ */
+ AV_WRITE_UNCODED_FRAME_NO_INTERLEAVE = 0x0002,
+
+};
+
+
+/**
* Write the stream trailer to an output media file and free the
* file private data.
*
diff --git a/libavformat/mux.c b/libavformat/mux.c
index f01b82b..0ea7dfc 100644
--- a/libavformat/mux.c
+++ b/libavformat/mux.c
@@ -414,6 +414,8 @@ int avformat_write_header(AVFormatContext *s, AVDictionary **options)
return 0;
}
+#define AV_PKT_FLAG_UNCODED_FRAME 0x2000
+
//FIXME merge with compute_pkt_fields
static int compute_pkt_fields2(AVFormatContext *s, AVStream *st, AVPacket *pkt)
{
@@ -536,7 +538,13 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt)
}
did_split = av_packet_split_side_data(pkt);
- ret = s->oformat->write_packet(s, pkt);
+ if ((pkt->flags & AV_PKT_FLAG_UNCODED_FRAME)) {
+ av_assert0(pkt->size == sizeof(AVFrame));
+ ret = s->oformat->write_uncoded_frame(s, pkt->stream_index,
+ (AVFrame *)pkt->data, 0);
+ } else {
+ ret = s->oformat->write_packet(s, pkt);
+ }
if (s->flush_packets && s->pb && ret >= 0 && s->flags & AVFMT_FLAG_FLUSH_PACKETS)
avio_flush(s->pb);
@@ -871,3 +879,36 @@ int ff_write_chained(AVFormatContext *dst, int dst_stream, AVPacket *pkt,
dst->streams[dst_stream]->time_base);
return av_write_frame(dst, &local_pkt);
}
+
+int av_write_uncoded_frame(AVFormatContext *s, int stream_index,
+ AVFrame *frame, unsigned flags)
+{
+ AVPacket pkt, *pktp;
+
+ av_assert0(s->oformat);
+ if (!s->oformat->write_uncoded_frame)
+ return AVERROR(ENOSYS);
+ if ((flags & AV_WRITE_UNCODED_FRAME_QUERY))
+ return s->oformat->write_uncoded_frame(s, stream_index, NULL, flags);
+
+ if (!frame) {
+ pktp = NULL;
+ } else {
+ pktp = &pkt;
+ av_init_packet(&pkt);
+ pkt.data = (void *)frame;
+ /* Note: using sizeof(AVFrame) from outside lavu is unsafe in
+ geneal, but it is only being used internally to this file as a
+ consistency check. */
+ pkt.size = sizeof(*frame);
+ pkt.pts = frame->pts != AV_NOPTS_VALUE ? frame->pts : frame->pkt_pts;
+ pkt.dts = frame->pkt_dts;
+ pkt.duration = av_frame_get_pkt_duration(frame);
+ pkt.stream_index = stream_index;
+ pkt.flags |= AV_PKT_FLAG_UNCODED_FRAME;
+ }
+
+ return (flags & AV_WRITE_UNCODED_FRAME_NO_INTERLEAVE) ?
+ av_write_frame(s, pktp) :
+ av_interleaved_write_frame(s, pktp);
+}
--
1.7.10.4
More information about the ffmpeg-devel
mailing list