FFmpeg之音画同步与资源释放
前面使用FFmpeg完成了视频和音频的播放,但是项目跑起来后发现视频和画面并不一致,也就是说我们从队列中取出数据进行播放时是没有对画面和音频时间进行同步处理的,所以出现了问题。同时播放完成以及错误或者退出时要进行相关的资源释放工作。
音画同步的处理
保证画面和音频同步其实很简单,就是尽量保证二者进行输出播放时的时刻尽最大可能进行接近处理。
也就是说也以某个为基准去同步另一个,那么我们应该以哪个为基准呢,一般都是以音频为基准的,因为人对声音的敏感度要大于画面的敏感度。
在视频播放中进行时间的同步处理
| 1 | void VideoChannel::video_play() { | 
这样也就尽量保证了画面和视频的同步输出播放。
资源的释放
- AVFormatContext的释放 - 1 
 2
 3
 4
 5- if(formatContext){ 
 avformat_close_input(&formatContext);
 avformat_free_context(formatContext);
 formatContext = nullptr;
 }
- Audio与Video的处理释放 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13- void VideoChannel::stop(){ 
 LOGD("VideoChannel prepare stop");
 isPlaying = false;
 pthread_join(pid_video_decode, nullptr);
 pthread_join(pid_video_play, nullptr);
 packets.setWork(0);
 frames.setWork(0);
 packets.clear();
 frames.clear();
 LOGD("VideoChannel stop");
 }
- AVPacket与AVFrame的释放 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15- static void releaseAVPacket(AVPacket ** p){ 
 if(p){
 av_packet_unref(*p);
 av_packet_free(p);
 *p = nullptr;
 }
 }
 static void releaseAVFrame(AVFrame ** f){
 if(f){
 av_frame_unref(*f);
 av_frame_free(f);
 *f = nullptr;
 }
 }
- ANativeWindow的释放 - 1 
 2
 3
 4
 5
 6
 7
 8
 9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23- extern "C" 
 JNIEXPORT void JNICALL
 Java_cn_jiajunhui_lib_jjhplayer_JJHPlayer_nativeRelease(JNIEnv
 * env,
 jobject thiz
 ) {
 LOGD("native-lib prepare release");
 pthread_mutex_lock(&mutex);
 // 先释放之前的显示窗口
 if (window) {
 ANativeWindow_release(window);
 window = nullptr;
 }
 pthread_mutex_unlock(&mutex);
 if(player)
 player->release();
 DELETE(player);
 DELETE(vm);
 LOGD("native-lib release");
 }