[FFmpeg-cvslog] lavf: allow grouping packets in chunks of a user specified size and duration.
Michael Niedermayer
git at videolan.org
Thu Dec 1 04:26:08 CET 2011
ffmpeg | branch: master | Michael Niedermayer <michaelni at gmx.at> | Wed Nov 30 00:21:00 2011 +0100| [ec20fc15818598aaf83232db3df2c85b1752c49a] | committer: Michael Niedermayer
lavf: allow grouping packets in chunks of a user specified size and duration.
This is similar to MP4Boxs -inter
Signed-off-by: Michael Niedermayer <michaelni at gmx.at>
> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ec20fc15818598aaf83232db3df2c85b1752c49a
---
libavformat/avformat.h | 19 +++++++++++++++++++
libavformat/options.c | 2 ++
libavformat/utils.c | 30 ++++++++++++++++++++++++++----
libavformat/version.h | 2 +-
4 files changed, 48 insertions(+), 5 deletions(-)
diff --git a/libavformat/avformat.h b/libavformat/avformat.h
index 156e83c..f1c701d 100644
--- a/libavformat/avformat.h
+++ b/libavformat/avformat.h
@@ -700,6 +700,9 @@ typedef struct AVStream {
*/
int stream_identifier;
+ int64_t interleaver_chunk_size;
+ int64_t interleaver_chunk_duration;
+
/**
* Stream informations used internally by av_find_stream_info()
*/
@@ -1086,6 +1089,22 @@ typedef struct AVFormatContext {
*/
int audio_preload;
+ /**
+ * Max chunk time in microseconds.
+ * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+ * - encoding: Set by user via AVOptions (NO direct access)
+ * - decoding: unused
+ */
+ int max_chunk_duration;
+
+ /**
+ * Max chunk size in bytes
+ * Note, not all formats support this and unpredictable things may happen if it is used when not supported.
+ * - encoding: Set by user via AVOptions (NO direct access)
+ * - decoding: unused
+ */
+ int max_chunk_size;
+
/*****************************************************************
* All fields below this line are not part of the public API. They
* may not be used outside of libavformat and can be changed and
diff --git a/libavformat/options.c b/libavformat/options.c
index 144aa1a..2584153 100644
--- a/libavformat/options.c
+++ b/libavformat/options.c
@@ -117,6 +117,8 @@ static const AVOption options[]={
{"explode", "abort decoding on error recognition", 0, AV_OPT_TYPE_CONST, {.dbl = FF_ER_EXPLODE }, INT_MIN, INT_MAX, D, "fer"},
{"fpsprobesize", "number of frames used to probe fps", OFFSET(fps_probe_size), AV_OPT_TYPE_INT, {.dbl = -1}, -1, INT_MAX-1, D},
{"audio_preload", "microseconds by which audio packets should be interleaved earlier", OFFSET(audio_preload), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX-1, E},
+{"chunk_duration", "microseconds for each chunk", OFFSET(max_chunk_duration), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX-1, E},
+{"chunk_size", "size in bytes for each chunk", OFFSET(max_chunk_size), AV_OPT_TYPE_INT, {.dbl = 0}, 0, INT_MAX-1, E},
{NULL},
};
diff --git a/libavformat/utils.c b/libavformat/utils.c
index 5a4b364..1493f27 100644
--- a/libavformat/utils.c
+++ b/libavformat/utils.c
@@ -3263,10 +3263,14 @@ int av_write_frame(AVFormatContext *s, AVPacket *pkt)
return ret;
}
+#define CHUNK_START 0x1000
+
int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
int (*compare)(AVFormatContext *, AVPacket *, AVPacket *))
{
AVPacketList **next_point, *this_pktl;
+ AVStream *st= s->streams[pkt->stream_index];
+ int chunked= s->max_chunk_size || s->max_chunk_duration;
this_pktl = av_mallocz(sizeof(AVPacketList));
if (!this_pktl)
@@ -3276,16 +3280,34 @@ int ff_interleave_add_packet(AVFormatContext *s, AVPacket *pkt,
av_dup_packet(&this_pktl->pkt); // duplicate the packet if it uses non-alloced memory
if(s->streams[pkt->stream_index]->last_in_packet_buffer){
- next_point = &(s->streams[pkt->stream_index]->last_in_packet_buffer->next);
- }else
+ next_point = &(st->last_in_packet_buffer->next);
+ }else{
next_point = &s->packet_buffer;
+ }
if(*next_point){
+ if(chunked){
+ uint64_t max= av_rescale_q(s->max_chunk_duration, AV_TIME_BASE_Q, st->time_base);
+ if( st->interleaver_chunk_size + pkt->size <= s->max_chunk_size-1U
+ && st->interleaver_chunk_duration + pkt->duration <= max-1U){
+ st->interleaver_chunk_size += pkt->size;
+ st->interleaver_chunk_duration += pkt->duration;
+ goto next_non_null;
+ }else{
+ st->interleaver_chunk_size =
+ st->interleaver_chunk_duration = 0;
+ this_pktl->pkt.flags |= CHUNK_START;
+ }
+ }
+
if(compare(s, &s->packet_buffer_end->pkt, pkt)){
- while(!compare(s, &(*next_point)->pkt, pkt)){
+ while( *next_point
+ && ((chunked && !((*next_point)->pkt.flags&CHUNK_START))
+ || !compare(s, &(*next_point)->pkt, pkt))){
next_point= &(*next_point)->next;
}
- goto next_non_null;
+ if(*next_point)
+ goto next_non_null;
}else{
next_point = &(s->packet_buffer_end->next);
}
diff --git a/libavformat/version.h b/libavformat/version.h
index 73acf6c..844cd64 100644
--- a/libavformat/version.h
+++ b/libavformat/version.h
@@ -24,7 +24,7 @@
#include "libavutil/avutil.h"
#define LIBAVFORMAT_VERSION_MAJOR 53
-#define LIBAVFORMAT_VERSION_MINOR 23
+#define LIBAVFORMAT_VERSION_MINOR 24
#define LIBAVFORMAT_VERSION_MICRO 0
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
More information about the ffmpeg-cvslog
mailing list