[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