|
|
@@ -327,20 +327,25 @@ void muxer_ffmpeg::on_filter_amix_data(AVFrame *frame, int)
|
|
|
resamples->sample_in = 0;
|
|
|
}
|
|
|
}
|
|
|
- } else { //resample size is channels*frame->linesize[0],for 2 channels
|
|
|
+ } else { // planar: copy each channel plane into contiguous planes in buffer
|
|
|
+ const int channels = ffmpeg_get_frame_channels(frame);
|
|
|
while (remain_len > 0) {
|
|
|
copied_len = min(resamples->size - resamples->sample_in, remain_len);
|
|
|
if (copied_len) {
|
|
|
- memcpy(resamples->buff + resamples->sample_in / 2,
|
|
|
- frame->data[0] + (sample_len - remain_len) / 2,
|
|
|
- copied_len / 2);
|
|
|
- memcpy(resamples->buff + resamples->size / 2 + resamples->sample_in / 2,
|
|
|
- frame->data[1] + (sample_len - remain_len) / 2,
|
|
|
- copied_len / 2);
|
|
|
+ const int copied_per_plane = copied_len / channels;
|
|
|
+ const int written_per_plane = resamples->sample_in / channels;
|
|
|
+ const int plane_size = resamples->size / channels;
|
|
|
+ const int src_offset = (sample_len - remain_len) / channels;
|
|
|
+ for (int ch = 0; ch < channels; ++ch) {
|
|
|
+ memcpy(resamples->buff + ch * plane_size + written_per_plane,
|
|
|
+ frame->data[ch] + src_offset,
|
|
|
+ copied_per_plane);
|
|
|
+ }
|
|
|
resamples->sample_in += copied_len;
|
|
|
remain_len = remain_len - copied_len;
|
|
|
}
|
|
|
|
|
|
+ //got enough pcm to encoder,resample and mix
|
|
|
if (resamples->sample_in == resamples->size) {
|
|
|
_a_stream->a_enc->put(resamples->buff, resamples->size, frame);
|
|
|
|
|
|
@@ -360,7 +365,7 @@ void muxer_ffmpeg::on_filter_aresample_data(AVFrame *frame, int index)
|
|
|
if (_running == false || !_a_stream->a_enc)
|
|
|
return;
|
|
|
|
|
|
- AUDIO_SAMPLE *resamples = _a_stream->a_resamples[0];
|
|
|
+ AUDIO_SAMPLE *resamples = _a_stream->a_resamples[index];
|
|
|
|
|
|
int copied_len = 0;
|
|
|
int sample_len = ffmpeg_get_buffer_size((AVSampleFormat) frame->format,
|
|
|
@@ -394,17 +399,21 @@ void muxer_ffmpeg::on_filter_aresample_data(AVFrame *frame, int index)
|
|
|
resamples->sample_in = 0;
|
|
|
}
|
|
|
}
|
|
|
- } else { //resample size is channels*frame->linesize[0],for 2 channels
|
|
|
+ } else { // planar: copy each channel plane into contiguous planes in buffer
|
|
|
+ const int channels = ffmpeg_get_frame_channels(frame);
|
|
|
while (remain_len > 0) {
|
|
|
copied_len = min(resamples->size - resamples->sample_in, remain_len);
|
|
|
|
|
|
if (copied_len) {
|
|
|
- memcpy(resamples->buff + resamples->sample_in / 2,
|
|
|
- frame->data[0] + (sample_len - remain_len) / 2,
|
|
|
- copied_len / 2);
|
|
|
- memcpy(resamples->buff + resamples->size / 2 + resamples->sample_in / 2,
|
|
|
- frame->data[1] + (sample_len - remain_len) / 2,
|
|
|
- copied_len / 2);
|
|
|
+ const int copied_per_plane = copied_len / channels;
|
|
|
+ const int written_per_plane = resamples->sample_in / channels;
|
|
|
+ const int plane_size = resamples->size / channels;
|
|
|
+ const int src_offset = (sample_len - remain_len) / channels;
|
|
|
+ for (int ch = 0; ch < channels; ++ch) {
|
|
|
+ memcpy(resamples->buff + ch * plane_size + written_per_plane,
|
|
|
+ frame->data[ch] + src_offset,
|
|
|
+ copied_per_plane);
|
|
|
+ }
|
|
|
resamples->sample_in += copied_len;
|
|
|
remain_len = remain_len - copied_len;
|
|
|
}
|
|
|
@@ -937,18 +946,8 @@ int muxer_ffmpeg::write_video(AVPacket *packet)
|
|
|
|
|
|
packet->stream_index = _v_stream->st->index;
|
|
|
|
|
|
- /*packet->pts = av_rescale_q_rnd(packet->pts,
|
|
|
- _v_stream->v_src->get_time_base(),
|
|
|
- { 1,AV_TIME_BASE },
|
|
|
- (AVRounding)(AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX));
|
|
|
-
|
|
|
- // make audio and video use one clock
|
|
|
- if (_v_stream->pre_pts == (uint64_t)-1) {
|
|
|
- _v_stream->pre_pts = packet->pts;
|
|
|
- }*/
|
|
|
-
|
|
|
// scale ts with timebase of base_time
|
|
|
- av_packet_rescale_ts(packet, _v_stream->v_src->get_time_base(), {1, AV_TIME_BASE});
|
|
|
+ av_packet_rescale_ts(packet, _v_stream->v_enc->get_time_base(), {1, AV_TIME_BASE});
|
|
|
|
|
|
// make audio and video use one clock
|
|
|
packet->pts = packet->pts - _base_time;
|
|
|
@@ -975,14 +974,8 @@ int muxer_ffmpeg::write_audio(AVPacket *packet)
|
|
|
std::lock_guard<std::mutex> lock(_mutex);
|
|
|
|
|
|
packet->stream_index = _a_stream->st->index;
|
|
|
-
|
|
|
- AVRational src_timebase = {1, 1};
|
|
|
-
|
|
|
- if (_a_stream->a_filter_amix != nullptr) {
|
|
|
- src_timebase = _a_stream->a_filter_amix->get_time_base();
|
|
|
- } else {
|
|
|
- src_timebase = _a_stream->a_filter_aresample[0]->get_time_base();
|
|
|
- }
|
|
|
+ // 音频包的源时间基应为编码器的 time_base
|
|
|
+ AVRational src_timebase = _a_stream->a_enc->get_time_base();
|
|
|
|
|
|
/*packet->pts = av_rescale_q_rnd(packet->pts,
|
|
|
src_timebase,
|