Файл не может быть восстановлен. воспроизводится с помощью проигрывателя Windows Media или ffplay, и когда я пытаюсь ffprobe полученный файл, появляются следующие сообщения об ошибках:
[h264 @ 0000015060d8f5c0] No start code is found.
Last message repeated 1 times
[h264 @ 0000015060d8f5c0] non-existing PPS 0 referenced
Last message repeated 1 times
[h264 @ 0000015060d8f5c0] decode_slice_header error
[h264 @ 0000015060d8f5c0] no frame!
[h264 @ 0000015060d8f5c0] non-existing PPS 0 referenced
Last message repeated 1 times
[h264 @ 0000015060d8f5c0] decode_slice_header error
[h264 @ 0000015060d8f5c0] no frame!
[h264 @ 0000015060d8f5c0] non-existing PPS 0 referenced
Last message repeated 1 times
# [...]
# this continues for a long time
Я выполнил другие шаги по устранению неполадок при кодировании h264 в Matroska, но ни один из них, похоже, не помог мне:
- Настройка AV_CODEC_FLAG_GLOBAL_HEADER: неверные данные при создании контейнера MKV с потоком h264, поскольку дополнительные данные имеют значение NULL.
- Выделение некоторого места для дополнительных данных: инициализация выходного файла для мультиплексирования MKV с помощью FFmpeg
Код инициализации (C++):
auto format = av_guess_format("matroska", (recording_base_path + full_file_path_).c_str(), NULL);
avformat_alloc_output_context2(&format_context_, format, NULL, (recording_base_path + full_file_path_).c_str());
// initialize ffmpeg codec context
const AVCodec* codec = avcodec_find_encoder_by_name("libx264");
video_stream_ = avformat_new_stream(format_context_, NULL);
codec_context_ = avcodec_alloc_context3(codec);
codec_context_->width = output_size_.Width;
codec_context_->height = output_size_.Height;
codec_context_->time_base = av_make_q(1, 90000);
codec_context_->gop_size = 1;
codec_context_->max_b_frames = 1;
codec_context_->pix_fmt = AV_PIX_FMT_YUV420P;
codec_context_->profile = FF_PROFILE_H264_MAIN;
codec_context_->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
codec_context_->extradata = (uint8_t*)av_mallocz(1024 * 1024);
codec_context_->extradata_size = 1024 * 1024;
avcodec_parameters_from_context(video_stream_->codecpar, codec_context_);
avcodec_open2(codec_context_, codec, NULL);
avio_open(&format_context_->pb, full_file_path_.c_str(), AVIO_FLAG_WRITE);
avformat_write_header(format_context_, nullptr);
Кодирование кадра и запись его в контейнер:
// Allocate input frame and copy data from mappedTex.pData
AVFrame *input_frame = av_frame_alloc();
input_frame->data[0] = (uint8_t *)mappedTex.pData;
input_frame->linesize[0] = mappedTex.RowPitch;
// Output frame
AVFrame *avFrame = av_frame_alloc();
avFrame->format = AV_PIX_FMT_YUV420P;
avFrame->width = codec_context_->width;
avFrame->height = codec_context_->height;
std::chrono::microseconds time_since_segment_start = std::chrono::duration_cast(frame.SystemRelativeTime() - started_at_);
avFrame->pts = av_rescale_q(time_since_segment_start.count(), AVRational{1,1000000}, codec_context_->time_base);
av_frame_get_buffer(avFrame, 0);
// Convert input_frame from RGB to YUV and save it into avFrame
sws_scale(sws_ctx_, input_frame->data, input_frame->linesize, 0,
frame.ContentSize().Height, avFrame->data,
avFrame->linesize);
av_frame_free(&input_frame);
auto ret = avcodec_send_frame(codec_context_, avFrame);
AVPacket* packet = av_packet_alloc();
while (true) {
ret = avcodec_receive_packet(codec_context_, packet);
if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) {
break;
} else if (ret < 0) {
std::cout time_base);
// TODO: try to write something to packet->side_data!
ret = av_interleaved_write_frame(format_context_, packet);
//ret = av_write_frame(format_context_, packet);
if (ret < 0) {
std::cout
Подробнее здесь: https://stackoverflow.com/questions/781 ... eates-corr