EasyPlayer支持YUV数据导出功能
2018-02-10 10:44
573 查看
我们可能会遇到这样的功能,播放一个视频的同时,再把这个视频推送出去,或者对视频数据进行智能分析等处理.这样我们就迫切需要得到视频的原始数据.基于这个需求,EasyPlayer增加了获取视频YUV数据的功能.
它的原理是这样的:
Created with Raphaël 2.1.2EasyPlayerClientEasyPlayerClientDecoderDecoderYUVYUV读取媒体流解码,获得YUV数据,导出
一般的播放器在解码之后,直接渲染YUV视频帧,并不做导出处理.因此在实现的时候,我们需要完善第二部分的功能,即解码后的YUV数据导出来.
解码部分需要通过jni来封装给java层调用.
下面代码片段就是解码并返回YUV数据的片段:
下面是调用的片段:
当解码成功后,我们创建一个DirectBuffer,将yuv数据返回到JAVA层.这样,播放器就可以获取到YUV数据了.
注意这里的pYUV数据,是我们在decoder内部开辟的,我们需要在JAVA层使用结束后,主动释放.该函数传入上个函数返回的DirectBuffer,在底层会获取到其对应的YUV 数据块,然后再释放它.
释放YUV:
最后,我们看看上层的调用:
EasyPlayer:https://github.com/EasyDSS/EasyPlayer
点击链接加入群【EasyPlayer】:544917793
它的原理是这样的:
Created with Raphaël 2.1.2EasyPlayerClientEasyPlayerClientDecoderDecoderYUVYUV读取媒体流解码,获得YUV数据,导出
一般的播放器在解码之后,直接渲染YUV视频帧,并不做导出处理.因此在实现的时候,我们需要完善第二部分的功能,即解码后的YUV数据导出来.
解码部分需要通过jni来封装给java层调用.
下面代码片段就是解码并返回YUV数据的片段:
nRet = avcodec_decode_video2(pComponent->pCodecCtx, pComponent->pFrame, &got_picture, &packet); av_free_packet(&packet); if (nRet < 0) { char av_error[AV_ERROR_MAX_STRING_SIZE] = { 0 }; LOGI("avcodec_decode_video2 result %d %s \r\n", nRet, av_make_error_string(av_error, AV_ERROR_MAX_STRING_SIZE, nRet)); return nRet; } if( got_picture) // 解出一个视频帧了. { width = pComponent->pFrame->width; height = pComponent->pFrame->height; int size = avpicture_get_size((AVPixelFormat)pComponent->pFrame->format, width, height); uint8_t* buffer = NULL; if (*pYUV == NULL){ buffer = (uint8_t*)av_malloc(size); }else{ buffer = (uint8_t *)*pYUV; } unsigned int y = width * pComponent->pFrame->height; unsigned int u = width/2 * pComponent->pFrame->height / 2; unsigned int v = width/2 * pComponent->pFrame->height / 2; for (int l = 0;l<height;l++){ memcpy(buffer + l*width, pComponent->pFrame->data[0] + pComponent->pFrame->linesize[0] * l, width); } for (int l = 0;l<height/2;l++){ memcpy(buffer + y + l*width/2, pComponent->pFrame->data[1] + pComponent->pFrame->linesize[1] * l, width/2); memcpy(buffer + y + u + l*width/2, pComponent->pFrame->data[2] + pComponent->pFrame->linesize[2] * l, width/2); } // 将视频帧付给YUV buffer. *pYUV = buffer; }
下面是调用的片段:
unsigned char *pYUV = NULL; unsigned int width; unsigned int height; VIDEO_HANDLE *vh =(VIDEO_HANDLE*) handle; int r = h264_decoder_decode(vh->handle_h264, (unsigned char *)(pBuffer + offset), size, &pYUV, width, height); jobject buf = NULL; if (r > 0){ buf = pEnv->NewDirectByteBuffer(pYUV, width*height * 3/2); } return buf;
当解码成功后,我们创建一个DirectBuffer,将yuv数据返回到JAVA层.这样,播放器就可以获取到YUV数据了.
注意这里的pYUV数据,是我们在decoder内部开辟的,我们需要在JAVA层使用结束后,主动释放.该函数传入上个函数返回的DirectBuffer,在底层会获取到其对应的YUV 数据块,然后再释放它.
释放YUV:
JNIEXPORT void JNICALL Java_org_easydarwin_video_VideoCodec_releaseYUV( JNIEnv *pEnv, jclass jobj, jobject buffer) { void *pYUV = pEnv->GetDirectBufferAddress(buffer); h264_decoder_release((unsigned char *)pYUV); }
最后,我们看看上层的调用:
// 解码 ByteBuffer buf = mDecoder.decodeFrameYUV(frameInfo, size); // 将YUV buffer 回调给上层. if (i420callback != null && buf != null) i420callback.onI420Data(buf); // 释放YUV buffer if (buf != null) mDecoder.releaseBuffer(buf);
关于EasyPlayer流媒体播放器
An elegant, simple, fast android RTSP/RTMP/HLS/HTTP Player.EasyPlayer support RTSP(RTP over TCP/UDP)version & Pro version,cover all kinds of streaming media!EasyPlayer是一款精炼、高效、稳定的流媒体播放器,分为RTSP版、RTMP版和Pro版三个版本,支持各种各样的流媒体音视频协议和文件的播放,在安防、互联网、教育、录播、IPTV等多个领域大放异彩,广泛应用!EasyPlayer:https://github.com/EasyDSS/EasyPlayer
点击链接加入群【EasyPlayer】:544917793
相关文章推荐
- 具有强大构建强大的Word报表,支持XAML数据绑定,文档格式转换,导出为PDF等功能的控件TX Text Control .NET for WPF介绍
- 功能齐全、效率一流的免费开源数据库导入导出工具(c#开发,支持SQL server、SQLite、ACCESS三种数据库),每月借此处理数据5G以上
- 利用itext操作pdf从数据库导出大量数据--功能汇总(一)
- 如何自己做Zabbix数据导出功能(下)
- SQL2005 SSMSE管理器里没有数据导入导出功能,怎么办?
- ALV标准导出EXCEL 2010功能无数据
- GridView数据导出功能
- POI Struts数据导出支持分页
- [转]SQL Server 2008支持将数据导出为脚本
- 将dev gridControl表中原形数据导出到excel功能写法
- 怎么MSSQL 2005 的导入导出功能没有“在Sql Server数据库之间复制对象和数据”一项?
- 重写GridView支持数据筛选和自动排序功能
- Java处理数据导出功能
- (DevExpress2011控件教程)ASPxGridView 范例4 :ASPxGridView 行选择、多表头设计、数据导出、主表细表等功能实现
- smarty制作数据库的数据导出及其,怎样从数据库读出数据,并修改数据库信息等功能后台管理系统
- MyReport数据导出引擎——MyReport的好帮手,支持Excel导出
- php利用phpexcel插件实现数据的导入和导出(支持csv\xls\xlsx格式和超过26个字段列)
- .NET WinForm下一个支持更新ProgressBar进度的DataGridView导出数据到Excel的类
- 快速导出数据到Excel(三):利用Excel内置功能
- SQL Server 2008支持将数据导出为脚本