Я пытаюсь записать звук из dshow с помощью ffmpeg, заново сэмплировать его и записать в файл mp4.
Открытие потоков и codecContext должно работать как чудо. Большая проблема для меня - это повторная выборка и правильный набор точек и точек.
На данный момент мой код выглядит следующим образом
//int flag;
int frameFinished; //when you decode a single packet, you still don't have information enough to have a frame [depending on the type of codec, some of them //you do], when you decode a GROUP of packets that represents a frame, then you have a picture! that's why frameFinished will let //you know you decoded enough to have a frame. int value;
AVPacket* inPacket = av_packet_alloc();//(AVPacket*)av_malloc(sizeof(AVPacket));
AVFrame* inFrame = av_frame_alloc();
//av_init_packet(inPacket);
int got_frame;
SwrContext* swrCtx_ = nullptr;
while (threading)
{
if (av_read_frame(screenInformation->inAVFormatContext, inPacket) >= 0) {
if (inPacket->stream_index == screenInformation->videoSteamIndex)
{
int len = avcodec_decode_audio4(screenInformation->inAVCodecContext, inFrame, &got_frame, inPacket);
if (len < 0) {
fprintf(stderr, "Error while decoding\n");
exit(1);
}
if (got_frame) {
/* if a frame has been decoded, output it */
int data_size = av_get_bytes_per_sample(screenInformation->outAVCodecContext->sample_fmt);
if (data_size < 0) {
/* This should not occur, checking just for paranoia */
fprintf(stderr, "Failed to calculate data size\n");
exit(1);
}
if (swrCtx_ == nullptr) {
/*
swsCtx_ = sws_getCachedContext(swsCtx_,
screenInformation->inAVCodecContext->width, screenInformation->inAVCodecContext->height,
screenInformation->inAVCodecContext->pix_fmt,
screenInformation->outAVCodecContext->width, screenInformation-outAVCodecContext->height,
screenInformation->outAVCodecContext->pix_fmt,
SWS_BICUBIC, NULL, NULL, NULL);
*/
swrCtx_ = swr_alloc_set_opts(NULL,
screenInformation->outAVCodecContext->channel_layout,
screenInformation->outAVCodecContext->sample_fmt,
screenInformation->outAVCodecContext->sample_rate,
AV_CH_LAYOUT_MONO, //screenInformation->inAVCodecContext->channel_layout,
screenInformation->inAVCodecContext->sample_fmt,
screenInformation->inAVCodecContext->sample_rate,
0, NULL
);
swr_init(swrCtx_);
}
AVFrame* outFrame = av_frame_alloc();//Allocate an AVFrame and set its fields to default values.
if (!outFrame)
{
cout << "\nunable to release the avframe resources for outframe";
exit(1);
}
av_frame_copy_props(outFrame, inFrame);
outFrame->channel_layout = screenInformation->outAVCodecContext->channel_layout;
outFrame->format = screenInformation->outAVCodecContext->sample_fmt;
outFrame->sample_rate = screenInformation->outAVCodecContext->sample_rate;
swr_convert_frame(swrCtx_, outFrame, inFrame);
AVPacket* outPacket = av_packet_alloc();
int got_packet_ptr;
avcodec_encode_audio2(screenInformation->outAVCodecContext, outPacket, outFrame, &got_packet_ptr);
if (got_packet_ptr) {
if (av_interleaved_write_frame(outAVFormatContext, outPacket) != 0)
{
cout << "\nerror in writing audio frame";
}
}
}
}
}
}// End of while-loop
Я знаю, что этот код не подходит для большинства Проблема в том, что это единственное решение для проверки этого.
Для pts и dts я пробовал код из примера декодирования / кодирования. Но это не работает вообще. Также я не могу запустить видео, которое должно содержать аудио.
С уважением, Себастьян