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@gmx.at>
This commit is contained in:
Michael Niedermayer 2011-11-30 00:21:00 +01:00
parent 31f9032b78
commit ec20fc1581
4 changed files with 48 additions and 5 deletions

View File

@ -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

View File

@ -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},
};

View File

@ -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);
}

View File

@ -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, \