mirror of https://git.ffmpeg.org/ffmpeg.git
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:
parent
31f9032b78
commit
ec20fc1581
|
@ -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
|
||||
|
|
|
@ -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},
|
||||
};
|
||||
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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, \
|
||||
|
|
Loading…
Reference in New Issue