From bba7faf12c272ef6d24642ae9998106b17f698db Mon Sep 17 00:00:00 2001 From: "yu.dongliang" <18588496441@163.com> Date: Thu, 6 Apr 2023 22:54:44 +0800 Subject: [PATCH] tmp --- simp_ffmpeg_output.c | 268 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 268 insertions(+) create mode 100644 simp_ffmpeg_output.c diff --git a/simp_ffmpeg_output.c b/simp_ffmpeg_output.c new file mode 100644 index 0000000..447c007 --- /dev/null +++ b/simp_ffmpeg_output.c @@ -0,0 +1,268 @@ +#include"simp_ffmpeg.h" +#include"scf_log.h" + +static int _video_init(simp_ffmpeg_t* priv) +{ + AVStream* s; + AVCodec* c; + + c = avcodec_find_encoder(priv->fmt_ctx->oformat->video_codec); + if (!c) + return -EINVAL; + + s = avformat_new_stream(priv->fmt_ctx, c); + if (!s) + return -ENOMEM; + + s->id = priv->fmt_ctx->nb_streams - 1; + priv->vidx = s->id; + + priv->vdec_ctx = avcodec_alloc_context3(c); + if (!priv->vdec_ctx) + return -1; + + priv->vdec_ctx->codec_id = c->codec_id; + priv->vdec_ctx->bit_rate = 1024 * 1024; + priv->vdec_ctx->width = 1920; + priv->vdec_ctx->height = 1080; + priv->vdec_ctx->time_base = (AVRational){1, 25}; + priv->vdec_ctx->gop_size = 20; + priv->vdec_ctx->max_b_frames = 2; + priv->vdec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; + s->time_base = priv->vdec_ctx->time_base; + + if (priv->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) + priv->vdec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + int ret = avcodec_open2(priv->vdec_ctx, c, NULL); + if (ret < 0) { + printf("avcodec_parameters_to_context error, ret: %d, %s\n", ret, av_err2str(ret)); + return ret; + } + + return 0; +} + +static int _audio_init(simp_ffmpeg_t* priv) +{ + AVStream* s; + AVCodec* c; + + c = avcodec_find_encoder(priv->fmt_ctx->oformat->audio_codec); + if (!c) + return -EINVAL; + + s = avformat_new_stream(priv->fmt_ctx, c); + if (!s) + return -ENOMEM; + + s->id = priv->fmt_ctx->nb_streams - 1; + priv->aidx = s->id; + + priv->adec_ctx = avcodec_alloc_context3(c); + if (!priv->adec_ctx) + return -1; + + priv->adec_ctx->codec_id = c->codec_id; + priv->adec_ctx->bit_rate = 64 * 1024; + priv->adec_ctx->sample_rate = 44100; + priv->adec_ctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + priv->adec_ctx->channels = 2; + priv->adec_ctx->channel_layout = av_get_default_channel_layout(priv->adec_ctx->channels); + priv->adec_ctx->time_base = (AVRational){1, priv->adec_ctx->sample_rate}; + s->time_base = priv->adec_ctx->time_base; + + if (priv->fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER) + priv->adec_ctx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER; + + int ret = avcodec_open2(priv->adec_ctx, c, NULL); + if (ret < 0) { + printf("avcodec_parameters_to_context error, ret: %d, %s\n", ret, av_err2str(ret)); + return ret; + } + + return 0; +} + +static int _ffmpeg_open(simp_avio_t* io, const char* path) +{ + simp_ffmpeg_t* priv; + AVStream* s; + + int ret; + int i; + + priv = calloc(1, sizeof(simp_ffmpeg_t)); + if (!priv) + return -ENOMEM; + + priv->vidx = -1; + priv->aidx = -1; + + avformat_alloc_output_context2(&priv->fmt_ctx, NULL, NULL, path); + if (!priv->fmt_ctx) { + scf_loge("\n"); + goto error; + } + + if (priv->fmt_ctx->oformat->video_codec != AV_CODEC_ID_NONE) { + + ret = _video_init(priv); + if (ret < 0) + goto error; + } + + if (priv->fmt_ctx->oformat->audio_codec != AV_CODEC_ID_NONE) { + + ret = _audio_init(priv); + if (ret < 0) + goto error; + } + + + io->priv = priv; + return 0; + +error: + if (priv->fmt_ctx) + avformat_close_output(&priv->fmt_ctx); + + if (priv->vdec_ctx) + avcodec_close(priv->vdec_ctx); + + if (priv->adec_ctx) + avcodec_close(priv->adec_ctx); + + free(priv); + return ret; +} + +static int _ffmpeg_close(simp_avio_t* io) +{ + simp_ffmpeg_t* priv; + + if (io) { + pthread_mutex_lock(&io->mutex); + io->exit = 1; + while (-1 != io->tid) { + pthread_cond_signal(&io->cond); + pthread_cond_signal(&io->cond); + } + pthread_mutex_unlock(&io->mutex); + + priv = io->priv; + + if (priv) { + if (priv->fmt_ctx) + avformat_close_output(&priv->fmt_ctx); + + if (priv->vdec_ctx) + avcodec_close(priv->vdec_ctx); + + if (priv->adec_ctx) + avcodec_close(priv->adec_ctx); + + if (priv->vframe) + av_frame_free(&priv->vframe); + + if (priv->aframe) + av_frame_free(&priv->aframe); + + free(priv); + } + } + + return 0; +} + +int __ffmpeg_decode(simp_avio_t* io, AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame, scf_list_t* h) +{ + int ret = avcodec_send_packet(dec_ctx, pkt); + if (ret < 0) { + scf_loge("avcodec_send_packet error, ret: %s\n", av_err2str(ret)); + return ret; + } + + while (ret >= 0) { + ret = avcodec_receive_frame(dec_ctx, frame); + + if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) + break; + else if (ret < 0) { + printf("avcodec_receive_frame error, ret: %d, %s\n", ret, av_err2str(ret)); + return ret; + } + + frame->pts = frame->best_effort_timestamp; + + simp_frame_t* f = simp_frame_alloc(); + if (!f) + return -ENOMEM; + + ret = av_frame_copy(f->frame, frame); + if (ret < 0) + return ret; + + pthread_mutex_lock(&io->mutex); + scf_list_add_tail(h, &f->list); + pthread_cond_signal(&io->cond); + pthread_mutex_unlock(&io->mutex); + } + + return 0; +} + +void* __ffmpeg_run(void* arg) +{ + simp_avio_t* io = arg; + simp_ffmpeg_t* priv = io->priv; + AVPacket* pkt = NULL; + + simp_frame_t* vf; + simp_frame_t* af; + scf_list_t* vl; + scf_list_t* al; + + pkt = av_packet_alloc(); + if (!pkt) + goto end; + + while (!priv->exit) { + pthread_mutex_lock(&io->mutex); + + pthread_mutex_unlock(&io->mutex); + + + + } + +end: + if (pkt) + av_packet_free(&pkt); + + pthread_mutex_lock(&io->mutex); + io->tid = -1; + pthread_cond_signal(&io->cond); + pthread_mutex_unlock(&io->mutex); + + return NULL; +} + +static int _ffmpeg_run(simp_avio_t* io) +{ + if (pthread_create(&io->tid, NULL, __ffmpeg_run, io)) { + scf_loge("\n"); + return -1; + } + + return 0; +} + +simp_avio_ops_t simp_avio_ffmpeg_output = +{ + .type = "ffmpeg_output", + .open = _ffmpeg_open, + .close = _ffmpeg_close, + .run = _ffmpeg_run, +}; + -- 2.25.1