[Libav-user] General concat input to stream output questions

Deron deron at pagestream.org
Thu Feb 24 23:26:16 EET 2022


> I would like to stream multiple media files (never ending list) to an 
> mpegts. Concat doesn't work because (I presume) non-incrementing PTS, 
> so I would like to try my hand at an endless video stream and I'd like 
> a little guidance or maybe someone has seen something similar done and 
> can point me to the project? 

Question:

What is the proper way to buffer audio after the filtergraph before 
feeding to avcodec_send_frame?


Details:

Ok, I've played around for awhile and have some code that more or less 
works. I basically took the transcoding.c example (which has a PTS issue 
itself which my code also suffer from but that is for another day when I 
get the errors out first) and rearranged so that the output is opened 
once. The output is hard coded to a fixed desired device/format/codecs 
and has the various muxrate/min/maxrate set. Then in a loop I open each 
input file, generate a new filtergraph and use a close version of the 
transcoding.c examples inner loop.

The current problem I have is that the last audio frame of an input file 
is often truncated (nb_samples < frame_size) but since it is not the 
last frame to the encoder, the encoder complains and dies.

So from what I can tell, I need to buffer the output. I thought I could 
simple allocated an audio frame at init time like this:

     outputAudioFrame = av_frame_alloc();

     outputAudioFrame->nb_samples = enc_ctx->frame_size;
     outputAudioFrame->format = enc_ctx->sample_fmt;
     outputAudioFrame->channel_layout = enc_ctx->channel_layout;

     av_frame_get_buffer(outputAudioFrame, 0);


Then copy the results from the filtergraph audio frame to a buffer:

     memcpy(buffer[writepos], filt_frame->data,
                      filt_frame->nb_samples * filt_frame->channels * 
av_get_bytes_per_sample(filt_frame->format));


Then read the output from the buffer into the outputAudioFrame:

     memcpy(outputAudioFrame->data, buffer[readpos],
                      outputAudioFrame->nb_samples * 
outputAudioFrame->channels * 
av_get_bytes_per_sample(outputAudioFrame->format));

before passing to avcodec_send_frame(enc_stream->enc_ctx, outputAudioFrame);

Which works for the first input file, but for some reason dies on the 
first frame on the second input file when being pushed to the encoder. I 
see it calling pad_last_frame, which I can't even tell why it would be 
calling that as I checked in the calling function and src->nb_samples == 
avctx->frame_size!

Thread 1 "myencoder" received signal SIGSEGV, Segmentation fault.
#0  __memmove_sse2_unaligned_erms () at 
../sysdeps/x86_64/multiarch/memmove-vec-unaligned-erms.S:524
#1  0x00005555564e86c6 in memcpy (__len=2048, __src=<optimized out>, 
__dest=<optimized out>)
     at /usr/include/x86_64-linux-gnu/bits/string_fortified.h:29
#2  av_samples_copy (dst=<optimized out>, src=<optimized out>, 
dst_offset=dst_offset at entry=0, src_offset=src_offset at entry=0,
     nb_samples=<optimized out>, nb_channels=<optimized out>, 
sample_fmt=AV_SAMPLE_FMT_FLTP) at libavutil/samplefmt.c:235
#3  0x0000555555c8cb1f in pad_last_frame (src=0x5555571da780, 
frame=0x5555571c0340, s=0x5555571beec0) at libavcodec/encode.c:128
#4  encode_send_frame_internal (src=0x5555571da780, 
avctx=0x5555571beec0) at libavcodec/encode.c:334
#5  avcodec_send_frame (avctx=0x5555571beec0, frame=0x5555571da780) at 
libavcodec/encode.c:372
#6  0x00005555556f770d in encode_write_frame (encoder=0x7ffff5acd040, 
in_stream_index=1, out_stream_index=1) at myencoder.c:1111
#7  0x00005555556f7a8c in filter_encode_write_frame 
(encoder=0x7ffff5acd040, frame=0x555557267200, in_stream_index=1, 
out_stream_index=1)
     at myencoder.c:1172


Do I need to do something with the audio frame from the filter graph if 
I am not passing it on to avcodec_send_frame?

Thanks!
Deron




More information about the Libav-user mailing list