当前位置:网站首页>Conversion of player's actual 10 pixel format and size
Conversion of player's actual 10 pixel format and size
2022-06-12 14:08:00 【Sister Suo】
SwsContext* vctx = NULL;
Create a context for format and size conversion , The assignment is NULL,
for (;;)// Every time I receive packet Go through it receive
{
// once send May correspond to multiple times receive, Because once send Of packet It may contain multiple frames of information
// Therefore, it is necessary to receive multiple times , Until you can't get it
re= avcodec_receive_frame(av, frame);//frame Application method and packet Agreement , But more than packet The space is much larger
if (re != 0)break;
cout << "recv frame" << frame->format << " " << frame->linesize[0] << endl;// The value of the video is one line ,why?
// The size and format are processed after decoding
if (av ==vc)
{
vctx = sws_getCachedContext(
vctx,// Pass on NULL Will be newly created
frame->width,frame->height, (AVPixelFormat)frame->format,// Input width, height and format
frame->width, frame->height, AV_PIX_FMT_RGBA,// Output width, height and format
SWS_BILINEAR,0,0,0
);// If there is a difference between the original and the target vctx Empty and recreate , Same handle vctx out
if (vctx)
cout << " Format and size conversion succeeded " << endl;
else
cout << " Format and size conversion failed " << endl;
}
}
In traversing each packet Of receive Used in the cycle of sws_getCachedContext
First determine whether the decoder context is video , Only video frames can use format and size conversion , This function is for context variables vctx The initialization , It stores the information of pixel format and size conversion , stay sws_scale() In order to carry out the real transformation ,
To do a cast
Because I gave it to vctx The assignment is null, Here we pass null to the function vctx Will create a new vctx, The following is the input width, height and format , Output width, height and format , If there is a difference between the original and the target vctx Empty and recreate , Same handle vctx out
give the result as follows , You can see only video frames vctx If it is not empty, it will be printed successfully 
if (vctx)
{
if (!rgb)
rgb = new unsigned char[frame->width * frame->height * 4];//rgba 32 position ,4 Bytes
uint8_t* data[2] = {
0 };// Namely unsigned char
data[0] = rgb;
int lines[2] = {
0 };
lines[0] = frame->width * 4;
cout << " Format and size conversion succeeded " << endl;
re=sws_scale(
vctx,
frame->data,// input data
frame->linesize, 0,// Enter row size , To align
frame->height,// Enter the height , Traverse all of linesize
data,// Output data and size
lines
);
cout << "sws_scale=" << re << endl;
}
else
cout << " Format and size conversion failed " << endl;
}
int sws_scale(struct SwsContext *c, const uint8_t *const srcSlice[],
const int srcStride[], int srcSliceY, int srcSliceH,
uint8_t *const dst[], const int dstStride[]);
The function parameters are described in detail below :
1. Parameters SwsContext *c, Context of conversion format . That is to say sws_getContext The result returned by the function .
2. Parameters const uint8_t *const srcSlice[], Enter the data pointer for each color channel of the image . It's actually decoded AVFrame Medium data[] Array . Because different pixels have different storage formats , therefore srcSlice[] dimension
It could be different .
With YUV420P For example , It is planar Format , Its memory is arranged as follows :
YYYYYYYY UUUU VVVV
Use FFmpeg Decoded and stored in AVFrame Of data[] In the array :
data[0]——-Y component , Y1, Y2, Y3, Y4, Y5, Y6, Y7, Y8……
data[1]——-U component , U1, U2, U3, U4……
data[2]——-V component , V1, V2, V3, V4……
linesize[] The data width of the corresponding channel is saved in the array ,
linesize[0]——-Y The width of the component
linesize[1]——-U The width of the component
linesize[2]——-V The width of the component
and RGB24, It is packed Format , It's in data[] There is only one dimension in the array , It is stored as follows :
data[0]: R1, G1, B1, R2, G2, B2, R3, G3, B3, R4, G4, B4……
Special attention should be paid here ,linesize[0] The value of is not necessarily equal to the width of the picture , Sometimes in order to align the decoders CPU, The actual size will be larger than the width of the picture , This is when we program ( such as OpengGL Hardware conversion / Rendering ) Pay special attention to , Otherwise, the decoded image will be abnormal .
3. Parameters const int srcStride[], Enter the span of each color channel of the image .. That is, the number of bytes per channel , Corresponding to the decoded AVFrame Medium linesize[] Array . According to it, you can determine the starting position of the next line , however stride and width Not necessarily the same , This is because :
a. Due to the alignment of data frame storage , It is possible to add some padding bytes after each line, so stride = width + N;
b.packet In color space , Several channels of data per pixel are mixed together , for example RGBA, Every pixel 3 Bytes are stored continuously , Therefore, the position of the next line needs to be skipped 3*width byte .
4. Parameters int srcSliceY, int srcSliceH, Define the processing area on the input image ,srcSliceY It's the starting position ,srcSliceH How many lines are processed . If srcSliceY=0,srcSliceH=height, Indicates that a complete image is processed at one time . This setting is for multithreading parallelism , For example, you can create two threads , The first thread handles [0, h/2-1] That's ok , The second thread handles [h/2, h-1] That's ok . Parallel processing speeds up .
5. Parameters uint8_t *const dst[], const int dstStride[] Define the output image information ( Data pointer of each color channel output , Number of bytes per color channel row )
Reference resources :https://www.cnblogs.com/yongdaimi/p/10715830.html
边栏推荐
- TestEngine with ID ‘junit-vintage‘ failed to discover tests
- 3. Hidden processes under the ring
- SystemC:SC_ Thread and SC_ METHOD
- 280 weeks /2171 Take out the least number of magic beans
- 618 entered the second half of the period, apple occupied the high-end market, and the domestic mobile phones finally undercut the price competition
- 初学者入门阿里云haas510开板式DTU(2.0版本)--510-AS
- Void pointer (void*) usage
- Paw advanced user guide
- 2022版Redis数据删除策略
- Write policy of cache
猜你喜欢

【mysql进阶】索引分类及索引优化方案(五)

通过loganalyzer展示数据库中的日志

阿里云开发板HaaS510解析串口JSON数据并发送属性

拆改廣告機---業餘解壓

When the byte jumps, the Chinese 996 is output in the United States

Des File Encryptor based on MFC framework

What is automatic bidding? What are its advantages?

Alicloud development board vscode development environment setup

Display logs in the database through loganalyzer
![[advanced MySQL] evolution of MySQL index data structure (IV)](/img/eb/e32387b172eb4c3a4152dbc3b0cb8f.png)
[advanced MySQL] evolution of MySQL index data structure (IV)
随机推荐
atomic and exclusive operation
高考回忆录
Lua callinfo structure, stkid structure resolution
IAT hook hijacking process API call
什么是自动出价?它的优势是什么?
My resume.
Compile and install lamp architecture of WordPress and discuz for multi virtual hosts based on fastcgi mode
Cmake basic tutorial - 02 b-hello-cmake
280 weeks /2171 Take out the least number of magic beans
NotePad 常用设置
Crack WinRAR to ad pop-up window
工具笔记 —— 常用自定义工具类(正则,随机数等)
[video lesson] a full set of tutorials on the design and production of Android studio Internet of things app -- all mastered during the National Day
公司运营中更注重转化的出价策略,如何实现? —Google sem
Cmake basic tutorial - 01 a-hello-cmake
Running phase of SystemC
2021-05-28
单总线温度传感器18B20数据上云(阿里云)
PostgreSQL14安装使用教程
3. Hidden processes under the ring