package com.java110.gateway.sip.remux;
import org.bytedeco.javacpp.*;
import org.bytedeco.javacv.FFmpegFrameRecorder;
import org.bytedeco.javacv.FFmpegLockCallback;
import org.bytedeco.javacv.Frame;
import org.bytedeco.javacv.FrameRecorder;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.nio.*;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import static org.bytedeco.javacpp.avcodec.*;
import static org.bytedeco.javacpp.avdevice.avdevice_register_all;
import static org.bytedeco.javacpp.avformat.*;
import static org.bytedeco.javacpp.avutil.*;
import static org.bytedeco.javacpp.swresample.*;
import static org.bytedeco.javacpp.swscale.*;
/**
* 自定义FFmpegFrameRecorder
* 修改recordPacket函数,支持传入设置pts/dts
* @author yangjie
* 2020年3月23日
*/
@SuppressWarnings("all")
public class CustomFFmpegFrameRecorder extends FrameRecorder {
public static CustomFFmpegFrameRecorder createDefault(File f, int w, int h) throws Exception { return new CustomFFmpegFrameRecorder(f, w, h); }
public static CustomFFmpegFrameRecorder createDefault(String f, int w, int h) throws Exception { return new CustomFFmpegFrameRecorder(f, w, h); }
private static Exception loadingException = null;
public static void tryLoad() throws Exception {
if (loadingException != null) {
throw loadingException;
} else {
try {
Loader.load(org.bytedeco.javacpp.avutil.class);
Loader.load(org.bytedeco.javacpp.swresample.class);
Loader.load(org.bytedeco.javacpp.avcodec.class);
Loader.load(org.bytedeco.javacpp.avformat.class);
Loader.load(org.bytedeco.javacpp.swscale.class);
/* initialize libavcodec, and register all codecs and formats */
av_jni_set_java_vm(Loader.getJavaVM(), null);
avcodec_register_all();
av_register_all();
avformat_network_init();
Loader.load(org.bytedeco.javacpp.avdevice.class);
avdevice_register_all();
} catch (Throwable t) {
if (t instanceof Exception) {
throw loadingException = (Exception)t;
} else {
throw loadingException = new Exception("Failed to load " + FFmpegFrameRecorder.class, t);
}
}
}
}
static {
try {
tryLoad();
FFmpegLockCallback.init();
} catch (Exception ex) { }
}
public CustomFFmpegFrameRecorder(File file, int audioChannels) {
this(file, 0, 0, audioChannels);
}
public CustomFFmpegFrameRecorder(String filename, int audioChannels) {
this(filename, 0, 0, audioChannels);
}
public CustomFFmpegFrameRecorder(File file, int imageWidth, int imageHeight) {
this(file, imageWidth, imageHeight, 0);
}
public CustomFFmpegFrameRecorder(String filename, int imageWidth, int imageHeight) {
this(filename, imageWidth, imageHeight, 0);
}
public CustomFFmpegFrameRecorder(File file, int imageWidth, int imageHeight, int audioChannels) {
this(file.getAbsolutePath(), imageWidth, imageHeight, audioChannels);
}
public CustomFFmpegFrameRecorder(String filename, int imageWidth, int imageHeight, int audioChannels) {
this.filename = filename;
this.imageWidth = imageWidth;
this.imageHeight = imageHeight;
this.audioChannels = audioChannels;
this.pixelFormat = AV_PIX_FMT_NONE;
this.videoCodec = AV_CODEC_ID_NONE;
this.videoBitrate = 400000;
this.frameRate = 30;
this.sampleFormat = AV_SAMPLE_FMT_NONE;
this.audioCodec = AV_CODEC_ID_NONE;
this.audioBitrate = 64000;
this.sampleRate = 44100;
this.interleaved = true;
this.video_pkt = new AVPacket();
this.audio_pkt = new AVPacket();
}
public CustomFFmpegFrameRecorder(OutputStream outputStream, int audioChannels) {
this(outputStream.toString(), audioChannels);
this.outputStream = outputStream;
}
public CustomFFmpegFrameRecorder(OutputStream outputStream, int imageWidth, int imageHeight) {
this(outputStream.toString(), imageWidth, imageHeight);
this.outputStream = outputStream;
}
public CustomFFmpegFrameRecorder(OutputStream outputStream, int imageWidth, int imageHeight, int audioChannels) {
this(outputStream.toString(), imageWidth, imageHeight, audioChannels);
this.outputStream = outputStream;
}
public void release() throws Exception {
// synchronized (org.bytedeco.javacpp.avcodec.class) {
releaseUnsafe();
// }
}
void releaseUnsafe() throws Exception {
/* close each codec */
if (video_c != null) {
avcodec_free_context(video_c);
video_c = null;
}
if (audio_c != null) {
avcodec_free_context(audio_c);
audio_c = null;
}
if (picture_buf != null) {
av_free(picture_buf);
picture_buf = null;
}
if (picture != null) {
av_frame_free(picture);
picture = null;
}
if (tmp_picture != null) {
av_frame_free(tmp_picture);
tmp_picture = null;
}
if (video_outbuf != null) {
av_free(video_outbuf);
video_outbuf = null;
}
if (frame != null) {
av_frame_free(frame);
frame = null;
}
if (samples_out != null) {
for (int i = 0; i < samples_out.length; i++) {
av_free(samples_out[i].position(0));
}
samples_out = null;
}
if (audio_outbuf != null) {
av_free(audio_outbuf);
audio_outbuf = null;
}
if (video_st != null && video_st.metadata() != null) {
av_dict_free(video_st.metadata());
video_st.metadata(null);
}
if (audio_st != null && audio_st.metadata() != null) {
av_dict_free(audio_st.metadata());
audio_st.metadata(null);
}
video_st = null;
audio_st = null;
filename = null;
AVFormatContext outputStreamKey = oc;
if (oc != null && !oc.isNull()) {
if (outputStream == null && (oformat.flags() & AVFMT_NOFILE) == 0) {
/* close the output file */
avio_close(oc.pb());
}
/* free the streams */
int nb_streams = oc.nb_streams();
for(int i = 0; i < nb_streams; i++) {
av_free(oc.streams(i).codec());
av_free(oc.streams(i));
}
/* free metadata */
if (oc.metadata() != null) {
av_dict_free(oc.metadata());
oc.metadata(null);
}
/* free the stream */
av_free(oc);
oc = null;
}
if (img_convert_ctx != null) {
sws_freeContext(img_convert_ctx);
img_convert_ctx = null;
}
if (samples_convert_ctx != null) {
swr_free(samples_convert_ctx);
samples_convert_ctx = null;
}
if (outputStream != null) {
try {
outputStream.close();
} catch (IOException ex) {
throw new Exception("Error on OutputStream.close(): ", ex);
} finally {
outputStream = null;
outputStreams.remove(outputStreamKey);
if (avio != null) {
if (avio.buffer() != null) {
av_free(avio.buffer());
avio.buffer(null);
}
av_free(avio);
avio = null;
}
}
}
}
@Override protected void finalize() throws Throwable {
super.finalize();
release();
}
static Map<Pointer,OutputStream> outputStreams = Collections.synchronizedMap(new HashMap<Pointer,OutputStream>());
static class WriteCallback extends Write_packet_Pointer_BytePointer_int {
@Override public int call(Pointer opaque, BytePointer buf, int buf_size) {
try {
byte[] b = new byte[buf_size];
OutputStream os = outputStreams.get(opaque);
buf.get(b, 0, buf_size);
os.write(b, 0, buf_size);
return buf_size;
}
catch (Throwable t) {
System.err.println("Error on OutputStream.write(): " + t);
return -1;
}
}
}
static WriteCallback writeCallback = new WriteCallback();
static {
PointerScope s = PointerScope.getInnerScope();
if (s != null) {
s.detach(writeCallback);
}
}
private OutputStream outputStream;
private AVIOContext avio;
private String filename;
private AVFrame picture, tmp_picture;
private BytePointer picture_buf;
private BytePointer video_outbuf;
private int video_outbuf_size;
private AVFrame frame;
private Pointer[] samples_in;
private BytePointer[] samples_out;
private PointerPointer samples_in_ptr;
private PointerPointer samples_out_ptr;
private BytePointer audio_outbuf;
private int audio_outbuf_size;
private in

知一NN
- 粉丝: 42
- 资源: 4157
最新资源
- 微信小程序蚂蚁项目.zip
- 基于Vuforia和OpenGL设计的AR安卓应用,可以显示化学分子AR模型(毕业设计项目).zip
- 宠物寄养网站(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- 宠物领养系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- 基于EggJS + MySQL + Sequelize 技术的一套地摊引流商城后端服务。这是一套移动端地摊引流电子商城系统后端服务,轻量无支付,无需注册支付平台即可使用
- Qt-基于VLC设计的流媒体播放器.zip
- 基于SSM开发框架的线上单元考试系统,分为学生,教师,管理员三个用户,包括考试中心,试卷回顾,试题管理,学生管理,教师管理和试卷管理等等.zip
- Comsol等离子体仿真揭秘空气棒板电晕放电及空气反应中的潜在世界探索之旅!,Comsol等离子体仿真:空气棒板电晕放电及23种精简空气反应研究,Comsol等离子体仿真,空气棒板电晕放电,23种精简
- 大学生心理健康管理系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- 大学生社团管理系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- 大学生心理健康评测系统(源码+数据库+论文+ppt)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- 基于Java开发的综合性心理咨询平台后端设计源码
- 软件工程导论期末作业展示用网页.zip
- 安卓项目-天气的android端.zip
- 电影评论网站(源码+数据库+论文)java开发springboot框架javaweb,可做计算机毕业设计或课程设计
- Comsol等离子体仿真:探究Ar棒板粗通道流注放电的三维电场强度与电子温度研究(版本信息附注),Comsol 5.5与6.0版本中的等离子体仿真:探究电子密度、电子温度、三维视图与电场强度在Ar棒板
资源上传下载、课程学习等过程中有任何疑问或建议,欢迎提出宝贵意见哦~我们会及时处理!
点击此处反馈


