ecb0badb
ming
保存jpg图片
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
#include "FFSaveImg.h"
extern "C"
{
#include <libavcodec/avcodec.h>
#include <libavdevice/avdevice.h>
#include <libavformat/avformat.h>
#include <libavfilter/avfilter.h>
#include <libavutil/avutil.h>
#include <libavutil/pixdesc.h>
#include <libswscale/swscale.h>
#include <libavutil/imgutils.h>
}
int saveJpg(AVFrame *pFrame, const char *out_file) {
int width = pFrame->width;
int height = pFrame->height;
AVCodecContext *pCodecCtx = NULL;
AVFormatContext *pFormatCtx = avformat_alloc_context();
// 设置输出文件格式
pFormatCtx->oformat = av_guess_format("mjpeg", NULL, NULL);
// 创建并初始化输出AVIOContext
if (avio_open(&pFormatCtx->pb, out_file, AVIO_FLAG_READ_WRITE) < 0) {
printf("Couldn't open output file.");
return -1;
}
// 构建一个新stream
AVStream *video_st = avformat_new_stream(pFormatCtx, 0);
if (video_st == NULL) {
return -1;
}
pCodecCtx = video_st->codec;
pCodecCtx->codec_id = pFormatCtx->oformat->video_codec;
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO;
pCodecCtx->pix_fmt = AV_PIX_FMT_YUVJ420P;
pCodecCtx->width = width;
pCodecCtx->height = height;
pCodecCtx->time_base = (AVRational) {1, 25};
AVCodec *pCodec = avcodec_find_encoder(pCodecCtx->codec_id);
if (!pCodec) {
printf("Could not find encoder\n");
return -1;
}
if (avcodec_open2(pCodecCtx, pCodec, NULL) < 0) {
printf("Could not open codec.");
return -1;
}
int ret = avformat_write_header(pFormatCtx, NULL);
if (ret < 0) {
printf("write_header fail\n");
return -1;
}
AVPacket* pkt = av_packet_alloc();
av_init_packet(pkt);
// 编码数据
ret = avcodec_send_frame(pCodecCtx, pFrame);
if (ret < 0) {
printf("Could not avcodec_send_frame.");
return -1;
}
// 得到编码后数据
ret = avcodec_receive_packet(pCodecCtx, pkt);
if (ret < 0) {
printf("Could not avcodec_receive_packet");
return -1;
}
ret = av_write_frame(pFormatCtx, pkt);
if (ret < 0) {
printf("Could not av_write_frame");
return -1;
}
av_frame_free(&pFrame);
av_packet_free(&pkt);
//Write Trailer
av_write_trailer(pFormatCtx);
avcodec_close(pCodecCtx);
avio_close(pFormatCtx->pb);
avformat_free_context(pFormatCtx);
return 0;
}
AVFrame* convert2yuv(int width, int height, unsigned char * rgbbuf, AVPixelFormat src_pix_fmt){
AVPixelFormat dst_pix_fmt = AV_PIX_FMT_YUV420P;
AVFrame *pFrameYUV = av_frame_alloc();
uint8_t *out_buffer = new uint8_t[avpicture_get_size(dst_pix_fmt, width, height)];
avpicture_fill((AVPicture *)pFrameYUV, out_buffer, dst_pix_fmt, width, height);
AVFrame *rgbFrame = av_frame_alloc();
avpicture_fill((AVPicture *)rgbFrame, rgbbuf, src_pix_fmt, width, height);
SwsContext *sws_ctx = sws_getContext(
width, height, src_pix_fmt,
width, height, dst_pix_fmt,
SWS_BILINEAR, NULL, NULL, NULL);
sws_scale(sws_ctx, rgbFrame->data, rgbFrame->linesize, 0, height, pFrameYUV->data, pFrameYUV->linesize);
sws_freeContext(sws_ctx);
av_frame_free(&rgbFrame);
pFrameYUV->width = width;
pFrameYUV->height = height;
pFrameYUV->format = dst_pix_fmt;
return pFrameYUV;
}
void saveJpg(int width, int height, unsigned char * pData, string file_name){
AVFrame *pFrame = convert2yuv(width, height, pData, AV_PIX_FMT_BGR24);
saveJpg(pFrame, file_name.c_str());
}
|