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->gop_size = 30;
priv->vdec_ctx->max_b_frames = 2;
priv->vdec_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
s->time_base = priv->vdec_ctx->time_base;
return ret;
}
+ priv->vpkt = av_packet_alloc();
+ if (!priv->vpkt)
+ return -ENOMEM;
+
return 0;
}
return ret;
}
+ priv->afifo = av_audio_fifo_alloc(AV_SAMPLE_FMT_FLTP, 2, 1024);
+ if (!priv->afifo)
+ return -ENOMEM;
+
+ priv->apkt = av_packet_alloc();
+ if (!priv->apkt)
+ return -ENOMEM;
+
+ priv->aframe = av_frame_alloc();
+ if (!priv->aframe)
+ return -ENOMEM;
+
+ priv->aframe->format = AV_SAMPLE_FMT_FLTP;
+ priv->aframe->channels = 2;
+ priv->aframe->nb_samples = 1024;
+
+ if (av_frame_get_buffer(priv->aframe, 1) < 0)
+ return -ENOMEM;
+
return 0;
}
if (priv->adec_ctx)
avcodec_close(priv->adec_ctx);
+ if (priv->afifo)
+ av_audio_fifo_free(priv->afifo);
+
free(priv);
return ret;
}
io->exit = 1;
while (-1 != io->tid) {
pthread_cond_signal(&io->cond);
- pthread_cond_signal(&io->cond);
+ pthread_cond_wait(&io->cond, &io->mutex);
}
pthread_mutex_unlock(&io->mutex);
if (priv->adec_ctx)
avcodec_close(priv->adec_ctx);
+ if (priv->afifo)
+ av_audio_fifo_free(priv->afifo);
+
if (priv->vframe)
av_frame_free(&priv->vframe);
return 0;
}
-static int __ffmpeg_decode(simp_avio_t* io, AVCodecContext* dec_ctx, AVPacket* pkt, AVFrame* frame, scf_list_t* h)
+static int __ffmpeg_encode(simp_avio_t* io, AVCodecContext* c, AVPacket* pkt, AVFrame* frame)
{
- int ret = avcodec_send_packet(dec_ctx, pkt);
+ simp_ffmpeg_t* priv = io->priv;
+ simp_frame_t* f;
+ AVStream* s;
+
+ int ret = avcodec_send_frame(c, frame);
if (ret < 0) {
- scf_loge("avcodec_send_packet error, ret: %s\n", av_err2str(ret));
+ scf_loge("avcodec_send_frame error, ret: %s\n", av_err2str(ret));
return ret;
}
while (ret >= 0) {
- ret = avcodec_receive_frame(dec_ctx, frame);
+ ret = avcodec_receive_packet(c, pkt);
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));
+ scf_loge("avcodec_receive_packet error, ret: %s\n", av_err2str(ret));
return ret;
}
- frame->pts = frame->best_effort_timestamp;
-
- simp_frame_t* f = simp_frame_alloc();
- if (!f)
- return -ENOMEM;
+ ret = av_write_frame(priv->fmt_ctx, pkt);
+ av_packet_unref(pkt);
- ret = av_frame_copy(f->frame, frame);
- if (ret < 0)
+ if (ret < 0) {
+ scf_loge("av_write_frame error, ret: %s\n", av_err2str(ret));
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;
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;
+ simp_frame_t* f;
+ scf_list_t* l;
while (!io->exit) {
pthread_mutex_lock(&io->mutex);
- pthread_mutex_unlock(&io->mutex);
+ if (!scf_list_empty(&io->vout)) {
+ l = scf_list_head(&io->vout);
+ f = scf_list_data(l, simp_frame_t, list);
+
+ scf_list_del(&f->list);
+ pthread_mutex_unlock(&io->mutex);
+
+ int ret = __ffmpeg_encode(io, priv->vdec_ctx, priv->vpkt, f->frame);
+
+ simp_frame_free(f);
+ f = NULL;
+
+ if (ret < 0) {
+ io->error = ret;
+ goto end;
+ }
+
+ } else if (!scf_list_empty(&io->aout)) {
+ l = scf_list_head(&io->aout);
+ f = scf_list_data(l, simp_frame_t, list);
+
+ scf_list_del(&f->list);
+ pthread_mutex_unlock(&io->mutex);
+
+ int ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples);
+
+ simp_frame_free(f);
+ f = NULL;
+
+ if (ret < 0) {
+ io->error = ret;
+ goto end;
+ }
+
+ while (av_audio_fifo_size(priv->afifo) >= 1024) {
+
+ ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024);
+ if (ret < 0) {
+ io->error = ret;
+ goto end;
+
+ } else if (1024 != ret) {
+ io->error = -1;
+ goto end;
+ }
+
+ ret = __ffmpeg_encode(io, priv->adec_ctx, priv->apkt, priv->aframe);
+ if (ret < 0) {
+ io->error = ret;
+ goto end;
+ }
+ }
+ } else {
+ pthread_cond_wait(&io->cond, &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);