Hi, I've been trying to write compressed audio frames to a container with av_interleaved_frame and I am seeing strange results. The source audio is a single tone of constant amplitude, mono, which I can see I am decompressing fine when I plot all the values to a graph.
Depending on the format/codec combo I see: - a monotone signal randomly interspersed with noise or silence. - a short playback of a distorted tone - correct length playback of a monotone with varying amplitude For the section of code where I compress and write a frame to a container, it works perfectly for video. The ffmpeg library does not produce any messages during writing. I have searched on what could be the cause of this and the topic of correctly setting packet->pts/dts comes up regularly. However, I believe I am doing the correct thing. Could anyone give me any pointers? Kind regards Jon Noble Here is the relevant snippet of code from https://github.com/jonno85uk/mediahandling/blob/Issue4_encoding/ffmpeg/ffmpegstream.cpp bool FFMpegStream::writeFrame(MediaFramePtr sample) { bool okay = true; std::call_once(setup_encoder_, [&] { okay = setupEncoder(); }); if (!okay) { logMessage(LogType::CRITICAL, "Failed to setup encoder"); return false; } if ( (sink_codec_ctx_ == nullptr) || (sink_frame_ == nullptr) ) { logMessage(LogType::CRITICAL, "Stream has not been configured correctly for writing"); return false; } // send frame to encoder if (sample) { const auto data = sample->data(); assert(data.data_); for (auto ix = 0; ix < AV_NUM_DATA_POINTERS; ++ix) { sink_frame_->data[ix] = data.data_[ix]; } if (data.sample_count_ >= 0) { sink_frame_->pts = audio_samples_; audio_samples_ += data.sample_count_; } else { sink_frame_->pts++; } auto ret = avcodec_send_frame(sink_codec_ctx_.get(), sink_frame_.get()); if (ret < 0) { av_strerror(ret, err.data(), ERR_LEN); const auto msg = fmt::format("Failed to send frame to encoder: {}", err.data()); logMessage(LogType::CRITICAL, msg); return false; } } else { const auto ret = avcodec_send_frame(sink_codec_ctx_.get(), nullptr); if (ret < 0) { av_strerror(ret, err.data(), ERR_LEN); const auto msg = fmt::format("Failed to send frame to encoder: {}", err.data()); logMessage(LogType::CRITICAL, msg); return false; } } // Retrieve packet from encoder int ret = 0; while (ret >= 0) { ret = avcodec_receive_packet(sink_codec_ctx_.get(), pkt_); if (ret == AVERROR(EAGAIN)) { return true; } else if (ret < 0) { if (ret != AVERROR_EOF) { av_strerror(ret, err.data(), ERR_LEN); const auto msg = fmt::format("Failed to receive packet from encoder, msg={}", err.data()); logMessage(LogType::CRITICAL, msg); return false; } return true; } pkt_->stream_index = stream_->index; av_packet_rescale_ts(pkt_, sink_codec_ctx_->time_base, stream_->time_base); // Send packet to container writer ret = av_interleaved_write_frame(&sink_->formatContext(), pkt_); av_packet_unref(pkt_); if (ret < 0 ){ av_strerror(ret, err.data(), ERR_LEN); const auto msg = fmt::format("Failed to write frame to container, msg={}", err.data()); logMessage(LogType::CRITICAL, msg); return false; } av_packet_unref(pkt_); } return true; }
_______________________________________________ Libav-user mailing list [email protected] https://ffmpeg.org/mailman/listinfo/libav-user To unsubscribe, visit link above, or email [email protected] with subject "unsubscribe".
