網(wǎng)站首頁 編程語言 正文
在使用ffmpeg的過程中有時(shí)候我們自己的數(shù)據(jù)結(jié)構(gòu)比如yuv數(shù)據(jù)或者壓縮后的H264數(shù)據(jù)想要轉(zhuǎn)為ffmpeg中的AVFrame或者AVPacket結(jié)構(gòu)體,怎么轉(zhuǎn)呢?
這個(gè)在ffmpg的libavcodec的v4l2_buffers.h/.c中有非常好的案例。
下面說說我個(gè)人的理解。
1、下面是我的yuv數(shù)據(jù)結(jié)構(gòu)體
struct Private;
struct MyYUV{
uint8_t *data[8];
int planes[8];
int length;
int width;
int height;
int pix_fmt;
int off_set;
Private *private;
}
1、yuv數(shù)據(jù)轉(zhuǎn)為AVFrame包數(shù)據(jù):
void int MyYUV_2_Avframe(AVFrame *frame, MyYUV *in){
int i , ret;
frame->format = in ->pix_fmt;
for (i = 0; i < in->length; i++) {
ret = buf_to_bufref(in, i, &frame->buf[i]);
if (ret) return ret;
frame->linesize[i] = in->planes[i];
frame->data[i] = frame->buf[i]->data;
}
}
//該函數(shù)主要?jiǎng)?chuàng)建AVBufferRef ,并將相關(guān)數(shù)據(jù)指向其內(nèi)部指針
int buf_to_bufref(MyYUV *in, int plane, AVBufferRef **buf){
int ret;
if (plane >= in->num_planes)
return AVERROR(EINVAL);
/* even though most encoders return 0 in data_offset encoding vp8 does require this value */
//其中my_free_buffer是個(gè)回調(diào)函數(shù),用來釋放yuv數(shù)據(jù)。
*buf = av_buffer_create((char *)in->data[plane] + in->off_set,
in->data[plane] * in->height, my_free_buffer, in, 0);
if (!*buf)
return AVERROR(ENOMEM);
return ret;
}
//下面兩個(gè)函數(shù)是ffmpeg內(nèi)部函數(shù)buffer.c文件中
//通過觀察可以發(fā)現(xiàn),其內(nèi)部并沒有申請(qǐng)數(shù)據(jù)的存儲(chǔ)空間,只是創(chuàng)建了一個(gè)AVBufferRef 和一個(gè)AVBuffer ,然后讓數(shù)據(jù)指針直接淺拷貝過去。
static AVBufferRef *buffer_create(AVBuffer *buf, uint8_t *data, size_t size,
void (*free)(void *opaque, uint8_t *data),
void *opaque, int flags)
{
AVBufferRef *ref = NULL;
buf->data = data;
buf->size = size;
buf->free = free ? free : av_buffer_default_free;
buf->opaque = opaque;
atomic_init(&buf->refcount, 1);
buf->flags = flags;
ref = av_mallocz(sizeof(*ref));
if (!ref)
return NULL;
ref->buffer = buf;
ref->data = data;
ref->size = size;
return ref;
}
AVBufferRef *av_buffer_create(uint8_t *data, size_t size,
void (*free)(void *opaque, uint8_t *data),
void *opaque, int flags)
{
AVBufferRef *ret;
AVBuffer *buf = av_mallocz(sizeof(*buf));
if (!buf)
return NULL;
ret = buffer_create(buf, data, size, free, opaque, flags);
if (!ret) {
av_free(buf);
return NULL;
}
return ret;
}
2、h264數(shù)據(jù)轉(zhuǎn)為AVPacket包數(shù)據(jù):
int mybuf_to_avpkt(AVPacket *pkt, MyYUV *avbuf)
{
int ret;
av_packet_unref(pkt);
//特別注意的是ffmpeg中引用的使用,這里跟上一個(gè)案例是一樣的。
ret = buf_to_bufref(avbuf, 0, &pkt->buf);
if (ret)
return ret;
pkt->size = avbuf->planes[0] * height;
pkt->data = pkt->buf->data;
if (avbuf->buf.flags & BUF_FLAG_KEYFRAME)
pkt->flags |= AV_PKT_FLAG_KEY;
if (avbuf->buf.flags & BUF_FLAG_ERROR) {
av_log(logger(avbuf), AV_LOG_ERROR, "%s driver encode error\n", avbuf->context->name);
pkt->flags |= AV_PKT_FLAG_CORRUPT;
}
pkt->dts = pkt->pts = buf_get_pts(avbuf);
return 0;
}
反著來就很簡單了簡單的數(shù)據(jù)拷貝。
原文鏈接:https://blog.csdn.net/weixin_43360707/article/details/125782672
相關(guān)推薦
- 2022-10-12 Docker開啟遠(yuǎn)程連接并實(shí)現(xiàn)安全通信詳解_docker
- 2022-12-27 一文帶你了解Go語言標(biāo)準(zhǔn)庫strings的常用函數(shù)和方法_Golang
- 2022-09-24 pandas刪除某行或某列數(shù)據(jù)的實(shí)現(xiàn)示例_python
- 2022-10-03 C++深入探究重載重寫覆蓋的區(qū)別_C 語言
- 2022-07-21 配置nacos持久化
- 2022-07-19 Linux 性能監(jiān)測(cè)命令
- 2022-09-10 ELK收集Tomcat日志的實(shí)現(xiàn)_Tomcat
- 2022-11-08 Python?Pandas教程之series?上的轉(zhuǎn)換操作_python
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支