ffmpeg3 rgb编码为h264文件


#include "stdafx.h"  

#include <stdio.h>  

#include <stdlib.h>  

#include <string.h>  

 

extern "C"

{

#include <libavcodec\avcodec.h>    

#include <libavformat\avformat.h>    

#include <libswscale\swscale.h>    

#include <libavutil\pixfmt.h>    

#include <libavutil\imgutils.h>    

#include <libavutil/opt.h>  

#include "libavutil/time.h"

}

 

 

static AVCodecContext *c = NULL;

 

static AVFrame *frame;

 

static AVPacket pkt;

 

static FILE *file;

 

struct SwsContext *sws_context = NULL;

 

 

 

static void ffmpeg_encoder_set_frame_yuv_from_rgb(uint8_t *rgb) {

 

const int in_linesize[1] = { 3 * c->width };

 

sws_context = sws_getCachedContext(sws_context,

 

c->width, c->height, AV_PIX_FMT_RGB24,

 

c->width, c->height, AV_PIX_FMT_YUV420P,

 

0, 0, 0, 0);

 

sws_scale(sws_context, (const uint8_t * const *)&rgb, in_linesize, 0,

 

c->height, frame->data, frame->linesize);

 

}

 

 

 

uint8_t* generate_rgb(int width, int height, int pts, uint8_t *rgb) {

 

int x, y, cur;

 

rgb = (uint8_t *)realloc(rgb, 3 * sizeof(uint8_t) * height * width);

 

for (y = 0; y < height; y++) {

 

for (x = 0; x < width; x++) {

 

cur = 3 * (y * width + x);

 

rgb[cur + 0] = 0;

 

rgb[cur + 1] = 0;

 

rgb[cur + 2] = 0;

 

if ((frame->pts / 25) % 2 == 0) {

 

if (y < height / 2) {

 

if (x < width / 2) {

 

/* Black. */

 

}

 

else {

 

rgb[cur + 0] = 255;

 

}

 

}

 

else {

 

if (x < width / 2) {

 

rgb[cur + 1] = 255;

 

}

 

else {

 

rgb[cur + 2] = 255;

 

}

 

}

 

}

 

else {

 

if (y < height / 2) {

 

rgb[cur + 0] = 255;

 

if (x < width / 2) {

 

rgb[cur + 1] = 255;

 

}

 

else {

 

rgb[cur + 2] = 255;

 

}

 

}

 

else {

 

if (x < width / 2) {

 

rgb[cur + 1] = 255;

 

rgb[cur + 2] = 255;

 

}

 

else {

 

rgb[cur + 0] = 255;

 

rgb[cur + 1] = 255;

 

rgb[cur + 2] = 255;

 

}

 

}

 

}

 

}

 

}

 

return rgb;

 

}

 

 

 

/* Allocate resources and write header data to the output file. */

 

void ffmpeg_encoder_start(const char *filename, int codec_id, int fps, int width, int height) {

 

AVCodec *codec;

 

int ret;

 

 

 

codec = avcodec_find_encoder((AVCodecID)codec_id);

 

if (!codec) {

 

fprintf(stderr, "Codec not found\n");

 

exit(1);

 

}

 

c = avcodec_alloc_context3(codec);

 

if (!c) {

 

fprintf(stderr, "Could not allocate video codec context\n");

 

exit(1);

 

}

 

c->bit_rate = 400000;

 

c->width = width;

 

c->height = height;

 

c->time_base.num = 1;

 

c->time_base.den = fps;

 

c->keyint_min = 600;

 

c->pix_fmt = AV_PIX_FMT_YUV420P;

 

if (codec_id == AV_CODEC_ID_H264)

 

av_opt_set(c->priv_data, "preset", "slow", 0);

 

if (avcodec_open2(c, codec, NULL) < 0) {

 

fprintf(stderr, "Could not open codec\n");

 

exit(1);

 

}

 

file = fopen(filename, "wb");

 

if (!file) {

 

fprintf(stderr, "Could not open %s\n", filename);

 

exit(1);

 

}

 

frame = av_frame_alloc();

 

if (!frame) {

 

fprintf(stderr, "Could not allocate video frame\n");

 

exit(1);

 

}

 

frame->format = c->pix_fmt;

 

frame->width = c->width;

 

frame->height = c->height;

 

ret = av_image_alloc(frame->data, frame->linesize, c->width, c->height, c->pix_fmt, 32);

 

if (ret < 0) {

 

fprintf(stderr, "Could not allocate raw picture buffer\n");

 

exit(1);

 

}

 

}

 

 

 

/*

 

Write trailing data to the output file

 

and free resources allocated by ffmpeg_encoder_start.

 

*/

 

void ffmpeg_encoder_finish(void) {

 

uint8_t endcode[] = { 0, 0, 1, 0xb7 };

 

int got_output, ret;

 

do {

 

fflush(stdout);

 

ret = avcodec_encode_video2(c, &pkt, NULL, &got_output);

 

if (ret < 0) {

 

fprintf(stderr, "Error encoding frame\n");

 

exit(1);

 

}

 

if (got_output) {

 

fwrite(pkt.data, 1, pkt.size, file);

 

av_packet_unref(&pkt);

 

}

 

} while (got_output);

 

fwrite(endcode, 1, sizeof(endcode), file);

 

fclose(file);

 

avcodec_close(c);

 

av_free(c);

 

av_freep(&frame->data[0]);

 

av_frame_free(&frame);

 

}

 

 

 

/*

 

Encode one frame from an RGB24 input and save it to the output file.

 

Must be called after ffmpeg_encoder_start, and ffmpeg_encoder_finish

 

must be called after the last call to this function.

 

*/

 

void ffmpeg_encoder_encode_frame(uint8_t *rgb) {

 

int ret, got_output;

 

ffmpeg_encoder_set_frame_yuv_from_rgb(rgb);

 

av_init_packet(&pkt);

 

pkt.data = NULL;

 

pkt.size = 0;

 

if (frame->pts == 1) {

 

frame->key_frame = 1;

 

frame->pict_type = AV_PICTURE_TYPE_I;

 

}

 

else {

 

frame->key_frame = 0;

 

frame->pict_type = AV_PICTURE_TYPE_P;

 

}

 

ret = avcodec_encode_video2(c, &pkt, frame, &got_output);

 

if (ret < 0) {

 

fprintf(stderr, "Error encoding frame\n");

 

exit(1);

 

}

 

if (got_output) {

 

fwrite(pkt.data, 1, pkt.size, file);

 

av_packet_unref(&pkt);

 

}

 

}

 

 

int main(void) {

  av_register_all();

av_log_set_level(AV_LOG_INFO);
avformat_network_init();
avcodec_register_all();

 char *filename = "tmp.h264";

 int pts;

 int width = 320;

 int height = 240;

 uint8_t *rgb = NULL;

 ffmpeg_encoder_start(filename, AV_CODEC_ID_H264, 25, width, height);

 for (pts = 0; pts < 1000; pts++) {

 frame->pts = pts;

 rgb = generate_rgb(width, height, pts, rgb);

 ffmpeg_encoder_encode_frame(rgb);

 }

 ffmpeg_encoder_finish();

//encode_example("tmp.mpg", AV_CODEC_ID_MPEG1VIDEO);

 return 0;

 }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AI算法网奇

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值