博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用javacv,解码socket接收的H264码流(byte[]),转为yuv处理,最后再合成转为H264...
阅读量:6714 次
发布时间:2019-06-25

本文共 12807 字,大约阅读时间需要 42 分钟。

其实是一个用java实现录像的功能,还没有实现,但解码和转码已经可以。

1.maven环境,pom.xml配置

1 
2
1.4.1
3
4
3.4.2
5
UTF-8
6
3.1.0
7
8
9
org.bytedeco
10
javacv-platform
11
${javacpp.version}
12
13
14
org.bytedeco
15
javacpp
16
${javacpp.version}
17
18
19
org.bytedeco.javacpp-presets
20
ffmpeg-platform
21
${ffmpeg.version}-${javacpp.version}
22
View Code

2.代码

1 package com.br.test;  2   3 import java.io.ByteArrayOutputStream;  4 import java.io.File;  5 import java.io.FileOutputStream;  6 import java.io.IOException;  7 import java.nio.ByteBuffer;  8 import org.bytedeco.javacpp.*;  9 import static org.bytedeco.javacpp.avcodec.*; 10 import static org.bytedeco.javacpp.avformat.*; 11 import static org.bytedeco.javacpp.avutil.*; 12 import static org.bytedeco.javacpp.swscale.*; 13  14 public class NewTest { 15     // Load only once formats and codecs 16     static { 17         av_register_all(); 18 //        avformat_network_init(); 19         avcodec_register_all(); 20     } 21     public int codec_id; 22     public AVCodecContext m_pCodecCtx = null; // URL中视频解码部分内容 23     public AVFrame m_pFrame = null; // 全局使用帧对象 24     public AVFrame m_pFrameRGB = null; 25     public AVCodec m_pCodec = null; 26     public AVCodecParserContext pCodecParserCtx = null; 27     public AVPacket packet = null; 28     public SwsContext m_pImageConvertCtx = null; // 构造全局对象,供sws_scale切割图片使用 29     public SwsContext img_convert_ctx = null; 30     public Integer count = 0; 31     public int count_size; 32     public BytePointer cur_ptr; 33     public FileOutputStream os; 34     private ByteArrayOutputStream myByteArrayOutputStream = new ByteArrayOutputStream(); 35  36     public NewTest() { 37         System.out.println("init begin"); 38  39         m_pFrame = av_frame_alloc(); 40         codec_id = AV_CODEC_ID_H264; 41         m_pFrameRGB = av_frame_alloc(); 42         m_pCodec = avcodec_find_decoder(codec_id); 43  44         if (m_pCodec == null) { 45             System.out.println("Codec not found\n"); 46         } 47         m_pCodecCtx = avcodec_alloc_context3(m_pCodec); 48         if (m_pCodecCtx == null) { 49             System.out.println("Could not allocate video codec context\n"); 50         } 51  52         pCodecParserCtx = av_parser_init(codec_id); 53         if (pCodecParserCtx == null) { 54             System.out.println("Could not allocate video parser context\n"); 55         } 56  57         if (avcodec_open2(m_pCodecCtx, m_pCodec, (PointerPointer
) null) < 0) { 58 System.out.println("Could not open codec\n"); 59 } 60 img_convert_ctx = sws_getContext(1920, 1088, AV_PIX_FMT_YUV420P, 1920, 1088, AV_PIX_FMT_BGRA, SWS_FAST_BILINEAR, 61 null, null, (DoublePointer) null); 62 63 packet = new AVPacket(); 64 65 packet = av_packet_alloc(); 66 67 av_new_packet(packet, 30000); 68 69 int numBytes = av_image_get_buffer_size(AV_PIX_FMT_BGRA, 1920, 1088, 1); 70 71 BytePointer rgbData = new BytePointer(av_malloc(numBytes)); 72 73 av_image_fill_arrays(m_pFrameRGB.data(), m_pFrameRGB.linesize(), rgbData, AV_PIX_FMT_BGRA, 1920, 1088, 1); 74 75 System.out.println("init end"); 76 } 77 78 public void dec_loop(byte[] H264) { 79 80 ByteBuffer data = ByteBuffer.allocate(H264.length); 81 data.put(H264); 82 int cur_size = H264.length; 83 IntPointer pktSize = new IntPointer(packet.size()); 84 BytePointer temp_bp = new BytePointer(); 85 while (cur_size > 0) { 86 87 data.flip(); 88 int slen = av_parser_parse2(pCodecParserCtx, m_pCodecCtx, temp_bp, pktSize, new BytePointer(data), cur_size, 89 AV_NOPTS_VALUE, AV_NOPTS_VALUE, AV_NOPTS_VALUE); 90 packet = packet.size(pktSize.get()); 91 92 data.position(slen); 93 data = data.compact(); 94 cur_size -= slen; 95 96 if (pktSize.get() == 0) { 97 continue; 98 } 99 packet = packet.data(temp_bp);100 // for(int i = 0;i <5;i++){101 // byte b = packet.data().get(i);102 // System.out.print(byteToHex(b)+" ");103 // }104 // System.out.println("------------------------------!!!!------------------"+packet.size());105 // packet.data().asBuffer();106 107 int asp = avcodec_send_packet(m_pCodecCtx, packet);108 109 if (avcodec_receive_frame(m_pCodecCtx, m_pFrame) == 0) {110 // m_pFrame.data(0);111 // y = m_pFrame->data[0];1920*1088112 // u = m_pFrame->data[1];1920*1088/4113 // v = m_pFrame->data[2];1920*1088/4114 115 System.err.println(116 "->>> decode success " + "width :" + m_pFrame.width() + " " + "height :" + m_pFrame.height());117 118 sws_scale(img_convert_ctx, m_pFrame.data(), m_pFrame.linesize(), 0, m_pCodecCtx.height(),119 m_pFrameRGB.data(), m_pFrameRGB.linesize());120 BytePointer by_bgra_data = m_pFrameRGB.data(0);121 try {122 // String imgName = "C:/Users/user/Desktop/test/test" + count + ".h264";123 // saveImg(m_pFrame, imgName);124 // count++;125 // for (int i = 0; i < 1920 * 1088 * 4; i++) {126 // myByteArrayOutputStream.write(by_bgra_data.get(i));127 // }128 // if (myByteArrayOutputStream.size() == 1920 * 1088 * 4) {129 // File file = new130 // File("C://Users//user//Desktop//test//success.yuv");131 // if (!file.exists()) {132 // file.createNewFile();133 // }134 // FileOutputStream fe = new FileOutputStream(file, true);135 // fe.write(myByteArrayOutputStream.toByteArray());136 // fe.flush();137 // fe.close();138 // myByteArrayOutputStream.reset();139 // }140 } catch (Exception e) {141 e.printStackTrace();142 }143 }144 // av_packet_unref(packet);145 }146 // av_packet_free(packet);147 }148 149 public int saveImg(AVFrame pFrame, String out_file) throws IOException {150 AVCodec codec = null;151 AVPacket pkt = null;152 AVStream pAVStream = null;153 int ret = -1;154 AVDictionary avd = new AVDictionary(null);155 int width = pFrame.width(), height = pFrame.height();156 // 分配AVFormatContext对象157 AVFormatContext pFormatCtx = avformat_alloc_context();158 // 设置输出文件格式159 pFormatCtx.oformat(av_guess_format("h264", null, null));160 if (pFormatCtx.oformat() == null) {161 return -1;162 }163 try {164 // 创建并初始化一个和该url相关的AVIOContext165 AVIOContext pb = new AVIOContext();166 if (avio_open(pb, out_file, AVIO_FLAG_READ_WRITE) < 0) {// dont open167 // file168 return -1;169 }170 pFormatCtx.pb(pb);171 // 构建一个新stream172 pAVStream = avformat_new_stream(pFormatCtx, codec);173 if (pAVStream == null) {174 return -1;175 }176 int codec_id = pFormatCtx.oformat().video_codec();177 // 设置该stream的信息178 AVCodecContext pCodecCtx = pAVStream.codec();179 pCodecCtx.codec_id(codec_id);180 pCodecCtx.codec_type(AVMEDIA_TYPE_VIDEO);181 pCodecCtx.pix_fmt(AV_PIX_FMT_YUV420P);182 pCodecCtx.width(width);183 pCodecCtx.height(height);184 pCodecCtx.time_base().num(1);185 pCodecCtx.time_base().den(25);186 pCodecCtx.qmin(10);187 pCodecCtx.qmax(51);188 pCodecCtx.bit_rate(400000);189 pCodecCtx.gop_size(12);190 pCodecCtx.qcompress(0.6f);191 192 if (pCodecCtx.codec_id() == AV_CODEC_ID_H264) {193 av_dict_set(avd, "preset", "slow", 0);194 av_dict_set(avd, "tune", "zerolatency", 0);195 }196 197 // Begin Output some information198 av_dump_format(pFormatCtx, 0, out_file, 1);199 // End Output some information200 201 // 查找编码器202 AVCodec pCodec = avcodec_find_encoder(pCodecCtx.codec_id());203 if (pCodec == null) {// codec not found204 return -1;205 }206 // 设置pCodecCtx的解码器为pCodec207 if (avcodec_open2(pCodecCtx, pCodec, avd) < 0) {208 System.err.println("Could not open codec.");209 av_dict_free(avd);210 return -1;211 }212 213 // Write Header214 avformat_write_header(pFormatCtx, (PointerPointer
) null);215 216 // 给AVPacket分配足够大的空间217 pkt = new AVPacket();218 int yuvSize = ((width * height) / 2) * 3;219 if (av_new_packet(pkt, yuvSize) < 0) {220 return -1;221 }222 223 int[] got_picture = { 0 };224 // encode225 226 if (avcodec_encode_video2(pCodecCtx, pkt, pFrame, got_picture) >= 0) {227 System.out.println("got_picture[0]:" + got_picture[0]);228 if (got_picture[0] == 1) {229 // flush230 BytePointer pkt_data = pkt.data();231 // 输出pkt数据到文件232 for (int i = 0; i < pkt.size(); i++) {233 myByteArrayOutputStream.write(pkt_data.get(i));234 }235 if (myByteArrayOutputStream.size() == pkt.size()) {236 File file = new File("C://Users//user//Desktop//test//success.h264");237 if (!file.exists()) {238 file.createNewFile();239 }240 FileOutputStream fe = new FileOutputStream(file, true);241 fe.write(myByteArrayOutputStream.toByteArray());242 fe.flush();243 fe.close();244 myByteArrayOutputStream.reset();245 }246 247 if ((ret = av_write_frame(pFormatCtx, pkt)) >= 0) {248 // Write Trailer249 if (av_write_trailer(pFormatCtx) >= 0) {250 System.err.println("->>> Encode Successful. pkt.size():" + pkt.size());251 } else {252 System.err.println("Encode failed.");253 }254 }255 }256 }257 return ret;258 // 结束时销毁259 } finally {260 if (pkt != null) {261 av_free_packet(pkt);262 }263 if (pAVStream != null) {264 avcodec_close(pAVStream.codec());265 }266 if (pFormatCtx != null) {267 avio_close(pFormatCtx.pb());268 avformat_free_context(pFormatCtx);269 }270 }271 }272 273 public static byte[] conver(ByteBuffer byteBuffer) {274 int len = byteBuffer.limit() - byteBuffer.position();275 byte[] bytes = new byte[len];276 277 if (byteBuffer.isReadOnly()) {278 return null;279 } else {280 byteBuffer.get(bytes);281 }282 return bytes;283 }284 285 public static String byteToHex(byte b) {286 String hex = Integer.toHexString(b & 0xFF);287 if (hex.length() < 2) {288 hex = "0" + hex;289 }290 return hex;291 }292 293 public static void main(String[] args) {294 NewTest test = new NewTest();295 }296 297 }
View Code

 

因为在网上很少有用javacv来解码的例子,只能自己踩坑前行,一点点的测试,所以可能有很多错误或可以优化的地方。

自己项目中用到,以此来记录,便于以后再遇到相同的问题。

转载于:https://www.cnblogs.com/zh-peng/p/10076590.html

你可能感兴趣的文章
微信公众号最新数据解读,三分之一停更成僵尸号
查看>>
《CCNP ROUTE 300-101学习指南》——2.2节构建EIGRP拓扑表
查看>>
《为自己工作——世界顶级设计师成功法则》目录—导读
查看>>
Libreboot 项目向开源社区示好和致歉
查看>>
《CMYK 2.0——设计师色彩管理手册》—第1章1.3节副作用
查看>>
java.util.concurrent.locks.LockSupport
查看>>
红帽加入 Node.js 基金会白金会员
查看>>
《OpenGL编程指南》一2.7 独立的着色器对象
查看>>
Ionic 3.4.2 发布,漂亮的 HTML5 移动应用框架
查看>>
Linux Kernel 4.9-rc8,4.9 分支最后一个候选版
查看>>
想开发 Android 分支?没门!
查看>>
《Web异步与实时交互——iframe AJAX WebSocket开发实战》—— 2.2 相关关键技术及工作原理...
查看>>
《Nmap渗透测试指南》—第1章1.5节Mac OS安
查看>>
重磅,企业实施大数据的路径
查看>>
linux之cp/scp命令+scp命令详解
查看>>
Spark 源码分析 -- BlockStore
查看>>
《C语言编程初学者指南》一1.7 创建并运行第一个C程序
查看>>
学习和使用 PHP 应该注意的10件事
查看>>
《Ember.js实战》——2.5 Ember.js对象模型
查看>>
《响应式Web图形设计》一第13章 响应Web设计中的图像
查看>>