sdk-hwV1.3/external/eyesee-mpp/system/private/rtsp/IPCProgram/encodeH264.c

229 lines
7.3 KiB
C
Raw Normal View History

2024-05-07 10:09:20 +00:00
/*
* encode.c
*
* Created on: 2014-8-16
* Author: liu
*/
#include <signal.h>
#include "camer.h"
#include "encode.h"
#include "libavformat/avformat.h"
//static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base,
// AVStream *st, AVPacket *pkt) {
// /* rescale output packet timestamp values from codec to stream timebase */
// pkt->pts = av_rescale_q_rnd(pkt->pts, *time_base, st->time_base,
// AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
// pkt->dts = av_rescale_q_rnd(pkt->dts, *time_base, st->time_base,
// AV_ROUND_NEAR_INF | AV_ROUND_PASS_MINMAX);
// pkt->duration = av_rescale_q(pkt->duration, *time_base, st->time_base);
// pkt->stream_index = st->index;
// /* Write the compressed frame to the media file. */
//// log_packet(fmt_ctx, pkt);
// return av_interleaved_write_frame(fmt_ctx, pkt);
//}
int flush_encoder(Encode* encode, unsigned int stream_index)
{
int ret;
int got_frame;
AVPacket enc_pkt;
while (1) {
printf("Flushing stream #%u encoder\n", stream_index);
//ret = encode_write_frame(NULL, stream_index, &got_frame);
enc_pkt.data = NULL;
enc_pkt.size = 0;
av_init_packet(&enc_pkt);
ret = avcodec_encode_video2(encode->pCodecCtx, &enc_pkt, NULL, &got_frame);
av_frame_free(NULL);
if (ret < 0) break;
if (!got_frame) {
printf("缓存数据编码成功1帧\n");
ret = 0;
break;
}
}
return ret;
}
int ffmpeg_init(Encode* encode)
{
int ret = 0;
avcodec_register_all();
encode->pCodec = avcodec_find_encoder(AV_CODEC_ID_H264);
if (!encode->pCodec) {
printf("没有找到合适的编码器!\n");
exit(1);
}
encode->pCodecCtx = avcodec_alloc_context3(encode->pCodec);
encode->pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P;
encode->pCodecCtx->width = encode->in_w;
encode->pCodecCtx->height = encode->in_h;
encode->pCodecCtx->time_base.num = 1;
encode->pCodecCtx->time_base.den = 10;
printf("encode %dx%d, and the time_base num: %d den: %d\n", encode->in_w, encode->in_h,
encode->pCodecCtx->time_base.num, encode->pCodecCtx->time_base.den);
encode->pCodecCtx->bit_rate = 200000;
encode->pCodecCtx->gop_size = 20;
encode->pCodecCtx->max_b_frames = 0;
//H264
//encode->pCodecCtx->me_range = 16;
//encode->pCodecCtx->max_qdiff = 4;
// encode->pCodecCtx->qmin = 8;
// encode->pCodecCtx->qmax = 31;
//encode->pCodecCtx->qcompress = 0.6;
// av_opt_set(encode->pCodecCtx->priv_data, "preset", "slow", 0);
av_opt_set(encode->pCodecCtx->priv_data, "profile", "baseline", 0);
av_opt_set(encode->pCodecCtx->priv_data, "preset", "superfast", 0);
av_opt_set(encode->pCodecCtx->priv_data, "tune", "zerolatency", 0);
//swscale init
enum AVPixelFormat sws_fmt = AV_PIX_FMT_YUYV422;
encode->sws_ctx =
sws_getContext(encode->pCodecCtx->width, encode->pCodecCtx->height, sws_fmt, encode->pCodecCtx->width,
encode->pCodecCtx->height, encode->pCodecCtx->pix_fmt, SWS_BILINEAR, NULL, NULL, NULL);
if ((encode->src_size = av_image_alloc(encode->src_data, encode->src_linesize, encode->pCodecCtx->width,
encode->pCodecCtx->height, sws_fmt, 1)) < 0) {
fprintf(stderr, "Could not allocate source image\n");
return -1;
}
printf("========== src_size: %d\n", encode->src_size);
printf("========== src_height: %d\n", encode->pCodecCtx->height);
printf("========== src_width: %d\n", encode->pCodecCtx->width);
printf("========== src_linesize[0]: %d\n", encode->src_linesize[0]);
printf("========== src_linesize[1]: %d\n", encode->src_linesize[1]);
printf("========== src_linesize[2]: %d\n", encode->src_linesize[2]);
printf("========== src_linesize[3]: %d\n", encode->src_linesize[3]);
encode->bsfc = av_bitstream_filter_init("h264_mp4toannexb");
if (!encode->bsfc) {
printf("bitstream_filter_init failed!\n");
av_bitstream_filter_close(encode->bsfc);
encode->bsfc = NULL;
}
if (avcodec_open2(encode->pCodecCtx, encode->pCodec, NULL) < 0) {
printf("编码器打开失败!\n");
return -1;
}
encode->picture = av_frame_alloc();
encode->picture->format = encode->pCodecCtx->pix_fmt;
encode->picture->width = encode->pCodecCtx->width;
encode->picture->height = encode->pCodecCtx->height;
ret = av_image_alloc(encode->picture->data, encode->picture->linesize, encode->pCodecCtx->width,
encode->pCodecCtx->height, encode->pCodecCtx->pix_fmt, 32);
if (ret < 0) {
fprintf(stderr, "could not allow raw picture buffer\n");
exit(1);
}
return 0;
}
int ffmpeg_encode_end(Encode* encode)
{
//Flush Encoder
int ret = flush_encoder(encode, 0);
if (ret < 0) {
printf("Flushing encoder failed\n");
return -1;
}
//编码器相关资源清理
av_bitstream_filter_close(encode->bsfc);
avcodec_close(encode->pCodecCtx);
avcodec_free_context(&(encode->pCodecCtx));
av_free(encode->picture);
// avformat_free_context(encode->pFormatCtx);
//swscale格式转换相关资源释放
av_freep(&encode->src_data[0]);
sws_freeContext(encode->sws_ctx);
return 0;
}
static int is_stop;
static void encode_stop(int signo)
{
printf("\nloops! stop!!!\n");
is_stop = 1;
}
//
//int main(int argc, char* argv[]) {
// int got_picture = 0;
//
// signal(SIGINT, encode_stop);
// Encode ecd, *encode;
// encode = &ecd;
// Camera *camera_s, cam;
// camera_s = &cam;
//
// camera_s = calloc_camera();
// camera_s->width = 640;
// camera_s->height = 480;
// camera_s->type = V4L2_PIX_FMT_YUYV;
//// sleep(1);
// encode->in_w = camera_s->width;
// encode->in_h = camera_s->height; //宽高
// int i;
//// encode->out_file = "src01.h264"; //输出文件路径
//
// captureInit(camera_s);
// ffmpeg_init(encode);
// encode->tmp_file_fd = fopen("tmp", "w");
//
// for (i = 0; !is_stop; i++) {
// av_init_packet(&encode->pkt);
// encode->pkt.data = NULL;
// encode->pkt.size = 0;
// //读入YUV
// usleep(10000);
// while (read_frame(camera_s, encode->src_data[0]))
// ;
// sws_scale(encode->sws_ctx, (const uint8_t * const *) (encode->src_data),
// encode->src_linesize, 0, encode->pCodecCtx->height,
// encode->picture->data, encode->picture->linesize);
// //PTS
// encode->picture->pts = i;
// //编码
// int ret = avcodec_encode_video2(encode->pCodecCtx, &encode->pkt,
// encode->picture, &got_picture);
// if (ret < 0) {
// fprintf(stderr, "编码错误!\n");
// return -1;
// }
// if (got_picture == 1) {
// printf("编码成功1帧\n");
//// fwrite(encode->pkt.data, 1, encode->pkt.size, encode->tmp_file_fd);
// uint8_t *poutbuf;
// int poutbuf_size;
//
// int a = av_bitstream_filter_filter(encode->bsfc, encode->pCodecCtx,
// NULL, &poutbuf, &poutbuf_size, encode->pkt.data, encode->pkt.size,
// 0);
// if (a < 0) {
// fprintf(stderr, "bitstream_filter failed!\n");
// } else {
// fwrite(poutbuf, 1, poutbuf_size, encode->tmp_file_fd);
// }
//
// av_free_packet(&encode->pkt);
// }
// }
//
// ffmpeg_encode_end(encode);
// stop_capturing(camera_s);
// av_bitstream_filter_close(encode->bsfc);
// fclose(encode->tmp_file_fd);
//
// return 0;
//}