[Libav-user] I there a way to prevent format guessing on the mpegts demuxer?

Jesper Taxbøl jesper at taxboel.dk
Sun May 24 01:29:25 EEST 2020


I am working on a streaming video application with a client and a server.

My transport stream contains HEVC, AAC and a customdata track.

In the server I am using these settings on the data stream.

codec_type = AVMEDIA_TYPE_DATA;
codec_id = AV_CODEC_ID_BIN_DATA;

The data is a small byte chunk sent for every frame with some
parameters relating to the video. Fixed size 38bytes. Video, audio and data
pass through the demuxer unharmed.

But, I am experiencing that my AVFormatContext returns the first ~20
packages within rrecieving the first 18000 bytes. Then it stalls for almost
2.8MB before returning the following packages.

It must be noted that I use an AVIOContext to feed the data into the

When debugging I have tried some changes and found that;

If I dont inject the actual data packets there is much less delay. So I
suspect my problem has something to do with me triggering some analysis of
the stream with my data packets.

Is there a way to tell the AVFormatContext what the contents of the stream
is, so I can get data from the stream with as little delay as posible?

I have added my test setup below, where the socket is replaced with a
chunkwise data feeder.

kind regards


#include <stdio.h>
#include <queue>

using namespace std;


extern "C" {
#include <libavutil/avassert.h>
#include <libavutil/channel_layout.h>
#include <libavutil/opt.h>
#include <libavutil/mathematics.h>
#include <libavutil/timestamp.h>
#include <libavformat/avformat.h>
#include <libswscale/swscale.h>
#include <libswresample/swresample.h>
#include <libavutil/file.h>

struct Packet{
uint8_t* data;
uint64_t len;

queue<Packet*> Q;
static int x = 0;
uint64_t bc = 0;
static int read_packet(void *opaque, uint8_t *buf, int buf_size)
int r = 0;

//printf("x:%d %llu\r\n", x++, bc);
if(x == 35)
int x;
x = 2;
if(Q.size() > 0)
Packet* p = Q.front();
if(p->len > buf_size)
memcpy(buf, p->data, buf_size);
p->len -= buf_size;
uint8_t* new_data = (uint8_t*)malloc(p->len);
memcpy(new_data, &p->data[buf_size], p->len);
p->data = new_data;
r = buf_size;
memcpy(buf, p->data, p->len);
r = p->len;

bc += r;
return r;

int main(int argc, char* argv[])
printf("Hello world...\r\n");

static AVFormatContext *fmt_ctx = NULL;
//fmt_ctx->flags |= AVFMT_FLA

//Read file data into queue packets
FILE* f = fopen("customdata.ts", "rb");
#define BUF_SIZE 1000
uint8_t b[BUF_SIZE];
int l = fread(b, 1, BUF_SIZE, f);
if(l <= 0)
Packet* p = (Packet*)malloc(sizeof(Packet));
p->data = (uint8_t*)malloc(l);
memcpy((void*)p->data, (void*)b, l);
p->len = l;
printf("File read into %d chunks\r\n", Q.size());

if (!(fmt_ctx = avformat_alloc_context())) {
fprintf(stderr, "Could not allocate fmt_ctx\n");

size_t avio_ctx_buffer_size = 4096;

uint8_t* avio_ctx_buffer = (uint8_t*)av_malloc(avio_ctx_buffer_size);
if (!avio_ctx_buffer) {
printf("error allocating avio_ctx_buffer\r\n");

AVIOContext* avio_ctx = avio_alloc_context(avio_ctx_buffer,
avio_ctx_buffer_size, 0, NULL, &read_packet, NULL, NULL);

if (!avio_ctx) {
printf("error allocating avio_ctx\r\n");
fmt_ctx->pb = avio_ctx;

AVInputFormat *inputFormat = av_find_input_format("mpegts");
AVDictionary *inOptions = NULL;
av_dict_set(&inOptions, "test","test", 0);
if (avformat_open_input(&fmt_ctx, NULL, inputFormat, &inOptions) < 0)
fprintf(stderr, "Could not open source file \r\n");

AVPacket pkt;
pkt.data = NULL;
pkt.size = 0;
int framecounter = 0;
while(av_read_frame(fmt_ctx, &pkt) >= 0)
printf("index %d %llu %d\r\n", framecounter, bc, pkt.stream_index);
if(framecounter == 22)
printf("now somethin funny start\r\n");
if(framecounter++ > 100)

return 0;
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://ffmpeg.org/pipermail/libav-user/attachments/20200524/295db633/attachment.html>

More information about the Libav-user mailing list