라이브 렌더링 비디오 데이터와 기존 .wav 파일을 mpg 파일로 인코딩합니다.큰 오디오 파일을 .mpg로 인코딩 할 때 av_write_frame이 실패합니다.
먼저 모든 오디오 프레임을 작성한 다음 렌더링 엔진에서 들어오는 비디오 프레임을 작성합니다. 더 작은 .wav 파일 (< 25 초)의 경우 모든 것이 완벽하게 작동합니다. 그러나 더 긴 .wav 파일을 사용하자마자 av_write_frame (오디오 프레임을 쓸 때)은 약 100 프레임을 작성한 후 -1을 반환합니다. 결코 실패하지 않는 프레임과 마지막 프레임이 결코 같은 프레임이 아닙니다. 모든 테스트 파일은 테스트 한 모든 플레이어와 완벽하게 재생할 수 있습니다.
다음은 the muxing example입니다 (다소 차이가 있음).
void write_audio_frame(Cffmpeg_dll * ptr, AVFormatContext *oc, AVStream *st, int16_t sample_val)
{
AVCodecContext *c;
AVPacket pkt = { 0 }; // data and size must be 0;
AVFrame *frame = avcodec_alloc_frame();
int got_packet;
av_init_packet(&pkt);
c = st->codec;
get_audio_frame(ptr, ptr->samples, ptr->audio_input_frame_size, c->channels);
frame->nb_samples = ptr->audio_input_frame_size;
int result = avcodec_fill_audio_frame(frame, c->channels, c->sample_fmt,
(uint8_t *) ptr->samples,
ptr->audio_input_frame_size *
av_get_bytes_per_sample(c->sample_fmt) *
c->channels, 0);
if (result != 0)
{
av_log(c, AV_LOG_ERROR, "Error filling audio frame. Code: %i\n", result);
exit(1);
}
result = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
if (result != 0)
{
av_log(c, AV_LOG_ERROR, "Error encoding audio. Code: %i\n", result);
exit(1);
}
if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, st->time_base);
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index= st->index;
av_log(c, AV_LOG_ERROR, "Got? %i Pts: %i Dts: %i Flags: %i Side Elems: %i Size: %i\n",
got_packet, pkt.pts, pkt.dts, pkt.flags, pkt.side_data_elems, pkt.size);
/* write the compressed frame in the media file */
result = av_write_frame(oc, &pkt);
if (result != 0)
{
av_log(c, AV_LOG_ERROR, "Error while writing audio frame. Result: %i\n", result);
exit(1);
}
}
그래서 :
여기 오디오 프레임을 쓰는 나의 기능입니다. "오류 오디오 프레임을 쓰는 동안 결과 : -1" 내가 항상 어떤 프레임 후에 무엇을 얻을 수 있습니다.void get_audio_frame(Cffmpeg_dll* ptr, int16_t* samples, int frame_size, int nb_channels, int16_t sample_val)
{
fread(samples, sizeof(int16_t), frame_size * nb_channels, ptr->fp_sound_input);
};
그리고 마지막으로, 이것이 내가 모든 오디오 프레임 (I 그 루프 전에 생략는 .WAV 헤더에 대해 걱정하지 마십시오) 작성하는 루프는 다음과 같습니다
그리고 여기 내 get_audio_frame 기능입니다 :
당신이 볼 수 있듯이, 나는 패킷의 거의 모든 것을 출력하고 가능한 오류를 확인하고 있습니다. 더 긴 오디오 파일을 인코딩 할 때 av_write_frame이 실패한 것 외에는 모든 것이 완벽하게 잘된 것 같습니다. 추적중인 모든 패킷 값은 모든 프레임에 대해 100 % 동일합니다 (데이터 포인터 제외). 또한 앞에서 설명한 것처럼 동일한 절차가 짧은 fp_sound_input 파일에서도 완벽하게 작동합니다. avcodec_encode_audio2() 및 avcodec_fill_audio_frame()도 결코 실패하지 않습니다.
인코딩에 사용하는 코덱은 CODEC_ID_MPEG2VIDEO (비디오) 및 CODEC_ID_MP2 (오디오)입니다. .wav 파일은 PCM 16 LE에 저장되며 모두 동일한 인코딩을 사용합니다.
무엇이 잘못 될 수 있습니까? 내가 다시 일을 얻을 때
av_write_frame
의를 사용합니다. 하지만 왜? 모든 오디오 프레임은 하나의 블록에 있습니다. – TheSHEEEP'av_write_frame'을 사용할 때, 패킷은 컨테이너 명세에 따라 정확하게 인터리빙되어야합니다 (MUST). 따라서, 일반적으로'av_interleaved_write_frame'을 사용하는 것이 더 좋습니다. 이 경우 인터리빙 프로세스는 자동입니다. – pogorskiy
그게 다야, 고마워! 왜 작은 오디오 파일로 작동하는지 궁금합니다. ffmpeg의 짜증스러운 마법에 속하는 것 같음) – TheSHEEEP