網站首頁 編程語言 正文
在使用ffmpeg的過程中有時候我們自己的數據結構比如yuv數據或者壓縮后的H264數據想要轉為ffmpeg中的AVFrame或者AVPacket結構體,怎么轉呢?
這個在ffmpg的libavcodec的v4l2_buffers.h/.c中有非常好的案例。
下面說說我個人的理解。
1、下面是我的yuv數據結構體
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數據轉為AVFrame包數據:
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;
}
}
//該函數主要創建AVBufferRef ,并將相關數據指向其內部指針
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是個回調函數,用來釋放yuv數據。
*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;
}
//下面兩個函數是ffmpeg內部函數buffer.c文件中
//通過觀察可以發現,其內部并沒有申請數據的存儲空間,只是創建了一個AVBufferRef 和一個AVBuffer ,然后讓數據指針直接淺拷貝過去。
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數據轉為AVPacket包數據:
int mybuf_to_avpkt(AVPacket *pkt, MyYUV *avbuf)
{
int ret;
av_packet_unref(pkt);
//特別注意的是ffmpeg中引用的使用,這里跟上一個案例是一樣的。
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;
}
反著來就很簡單了簡單的數據拷貝。
原文鏈接:https://blog.csdn.net/weixin_43360707/article/details/125782672
相關推薦
- 2022-10-01 使用flask如何獲取post請求參數_python
- 2022-03-18 docker?創建容器時指定容器ip的實現示例_docker
- 2023-03-01 kotlin?object關鍵字單例模式實現示例詳解_Android
- 2022-11-20 更強大的React?狀態管理庫Zustand使用詳解_React
- 2023-10-10 Promise同時獲取n個接口數據的幾種方式
- 2023-12-25 Spring @Cacheable緩存注解
- 2022-09-18 ASP.NET?Core實現文件上傳和下載_實用技巧
- 2022-06-22 使用pyinstaller打包.exe文件的詳細教程_python
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支