|
|
@@ -789,45 +789,24 @@ int muxer_ffmpeg::add_audio_stream(const MUX_SETTING_T &setting,
|
|
|
_a_stream->st = st;
|
|
|
|
|
|
_a_stream->setting = setting;
|
|
|
- // 对于RTMP推流,不使用aac_adtstoasc过滤器,保持ADTS格式
|
|
|
- // 检查输出格式是否为FLV(RTMP使用FLV容器)
|
|
|
- if (_fmt_ctx->oformat && strcmp(_fmt_ctx->oformat->name, "flv") == 0) {
|
|
|
- // RTMP推流,不使用过滤器
|
|
|
- _a_stream->filter = nullptr;
|
|
|
- al_debug("RTMP output detected, skipping aac_adtstoasc filter");
|
|
|
- } else {
|
|
|
- // 其他格式(如MP4/RTSP),使用aac_adtstoasc过滤器以去除可能存在的ADTS头
|
|
|
- _a_stream->filter = ffmpeg_bitstream_filter_init("aac_adtstoasc");
|
|
|
- al_debug("Non-RTMP output, using aac_adtstoasc filter");
|
|
|
- }
|
|
|
- if (_fmt_ctx->oformat) {
|
|
|
- const char *ofmt = _fmt_ctx->oformat->name;
|
|
|
- // FLV/RTMP、RTSP、MP4等容器需要原始AAC(无ADTS),因此启用 aac_adtstoasc 过滤器
|
|
|
- if (strcmp(ofmt, "flv") == 0 || strcmp(ofmt, "rtsp") == 0 || strcmp(ofmt, "mp4") == 0
|
|
|
- || strcmp(ofmt, "mov") == 0 || strcmp(ofmt, "matroska") == 0) {
|
|
|
- _a_stream->filter = ffmpeg_bitstream_filter_init("aac_adtstoasc");
|
|
|
- al_debug("Container '%s' requires raw AAC, enabling aac_adtstoasc filter", ofmt);
|
|
|
- } else {
|
|
|
- // 对于期望ADTS的容器(如 mpegts/adts),不使用过滤器
|
|
|
- _a_stream->filter = nullptr;
|
|
|
- al_debug("Container '%s' supports ADTS, skipping aac_adtstoasc filter", ofmt);
|
|
|
- }
|
|
|
- }
|
|
|
+ // 统一关闭 AAC 比特流过滤器:编码器输出原始 AAC(无 ADTS),由容器负责正确封装
|
|
|
+ _a_stream->filter = nullptr;
|
|
|
+ al_debug("AAC bitstream filter disabled; container will handle framing based on extradata");
|
|
|
|
|
|
- } while (0);
|
|
|
+ } while (0);
|
|
|
|
|
|
- return error;
|
|
|
-}
|
|
|
+ return error;
|
|
|
+ }
|
|
|
|
|
|
-int muxer_ffmpeg::open_output(const char *output_file, const MUX_SETTING_T &setting)
|
|
|
-{
|
|
|
- int error = AE_NO;
|
|
|
- int ret = 0;
|
|
|
+ int muxer_ffmpeg::open_output(const char *output_file, const MUX_SETTING_T &setting)
|
|
|
+ {
|
|
|
+ int error = AE_NO;
|
|
|
+ int ret = 0;
|
|
|
|
|
|
- do {
|
|
|
- if (!(_fmt->flags & AVFMT_NOFILE)) {
|
|
|
- ret = avio_open(&_fmt_ctx->pb, output_file, AVIO_FLAG_WRITE);
|
|
|
- if (ret < 0) {
|
|
|
+ do {
|
|
|
+ if (!(_fmt->flags & AVFMT_NOFILE)) {
|
|
|
+ ret = avio_open(&_fmt_ctx->pb, output_file, AVIO_FLAG_WRITE);
|
|
|
+ if (ret < 0) {
|
|
|
error = AE_FFMPEG_OPEN_IO_FAILED;
|
|
|
break;
|
|
|
}
|
|
|
@@ -1044,90 +1023,10 @@ int muxer_ffmpeg::write_audio(AVPacket *packet)
|
|
|
return -1;
|
|
|
}
|
|
|
|
|
|
- // 验证AAC包大小,确保符合RTMP推流要求
|
|
|
- if (packet->size < 7) {
|
|
|
- al_warn("AAC packet size too small: %d bytes (minimum 7 required for ADTS), skipping write", packet->size);
|
|
|
- return -1;
|
|
|
- }
|
|
|
-
|
|
|
- // 检查是否为RTMP推流(FLV格式)
|
|
|
- bool isRtmpStream = (_fmt_ctx->oformat && strcmp(_fmt_ctx->oformat->name, "flv") == 0);
|
|
|
-
|
|
|
- if (isRtmpStream) {
|
|
|
- // RTMP推流需要验证ADTS头部
|
|
|
- if (packet->size >= 2) {
|
|
|
- // 检查ADTS同步字(0xFFF)
|
|
|
- if ((packet->data[0] != 0xFF) || ((packet->data[1] & 0xF0) != 0xF0)) {
|
|
|
- al_warn("Invalid AAC ADTS header for RTMP: 0x%02X%02X, packet may be corrupted",
|
|
|
- packet->data[0], packet->data[1]);
|
|
|
- // 对于RTMP,这可能导致播放问题,但仍然尝试发送
|
|
|
- }
|
|
|
- }
|
|
|
- al_debug("RTMP AAC packet: size=%d, header=0x%02X%02X",
|
|
|
- packet->size, packet->data[0], packet->data[1]);
|
|
|
- }
|
|
|
- // 根据容器判断是否期望ADTS头部
|
|
|
- bool expectsAdts = false;
|
|
|
- if (_fmt_ctx->oformat && _fmt_ctx->oformat->name) {
|
|
|
- const char *ofmt = _fmt_ctx->oformat->name;
|
|
|
- if (strcmp(ofmt, "mpegts") == 0 || strcmp(ofmt, "adts") == 0) {
|
|
|
- expectsAdts = true;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- if (expectsAdts) {
|
|
|
- // 期望ADTS:做最基本校验
|
|
|
- if (packet->size < 7) {
|
|
|
- al_warn("AAC packet too small for ADTS: %d bytes (min 7)", packet->size);
|
|
|
- return -1;
|
|
|
- }
|
|
|
- if (packet->size >= 2 && (packet->data[0] != 0xFF || (packet->data[1] & 0xF0) != 0xF0)) {
|
|
|
- al_warn("Missing ADTS syncword in ADTS-expected container, header=0x%02X%02X",
|
|
|
- packet->data[0],
|
|
|
- packet->data[1]);
|
|
|
- }
|
|
|
- } else {
|
|
|
- // 不期望ADTS(如 RTSP/FLV/MP4 等):如果存在ADTS,仅打印调试信息
|
|
|
- if (packet->size >= 2 && packet->data[0] == 0xFF && (packet->data[1] & 0xF0) == 0xF0) {
|
|
|
- al_debug(
|
|
|
- "ADTS header present but container doesn't require it; filter may strip it later");
|
|
|
- }
|
|
|
- }
|
|
|
+ // 不再强制检查ADTS头部,容器将根据extradata与编码器输出决定封装格式
|
|
|
|
|
|
- // 应用bitstream过滤器(如果存在)
|
|
|
- AVPacket *filtered_packet = packet;
|
|
|
- if (_a_stream->filter) {
|
|
|
- AVPacket *temp_packet = av_packet_alloc();
|
|
|
- if (temp_packet) {
|
|
|
- av_packet_ref(temp_packet, packet);
|
|
|
- int filter_ret = ffmpeg_bitstream_filter_filter(_a_stream->filter, temp_packet);
|
|
|
- if (filter_ret >= 0) {
|
|
|
- // 验证过滤后的包大小
|
|
|
- if (temp_packet->size < 2) {
|
|
|
- al_warn("Filtered AAC packet too small: %d bytes, using original packet",
|
|
|
- temp_packet->size);
|
|
|
- av_packet_free(&temp_packet);
|
|
|
- } else {
|
|
|
- filtered_packet = temp_packet;
|
|
|
- al_debug("Applied aac_adtstoasc filter, original size: %d, filtered size: %d",
|
|
|
- packet->size,
|
|
|
- temp_packet->size);
|
|
|
- }
|
|
|
- } else {
|
|
|
- al_warn("Failed to apply bitstream filter: %d, using original packet", filter_ret);
|
|
|
- av_packet_free(&temp_packet);
|
|
|
- }
|
|
|
- } else {
|
|
|
- al_warn("Failed to allocate temporary packet for filtering");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- int ret = av_interleaved_write_frame(_fmt_ctx, filtered_packet);
|
|
|
-
|
|
|
- // 如果使用了过滤器,需要释放临时包
|
|
|
- if (filtered_packet != packet) {
|
|
|
- av_packet_free(&filtered_packet);
|
|
|
- }
|
|
|
+ // 不应用任何 AAC 比特流过滤器,编码器输出的原始 AAC 数据由容器决定封装
|
|
|
+ int ret = av_interleaved_write_frame(_fmt_ctx, packet);
|
|
|
if (ret != 0) {
|
|
|
al_fatal("write audio frame error:%d", ret);
|
|
|
}
|