sleep(1);
}
- simp_filter_close(f);
+ simp_filter_close(f, 1);
printf("main quit ok\n");
return 0;
if (io->ops && io->ops->close)
io->ops->close(io);
+ scf_list_clear(&io->vin, simp_frame_t, list, simp_frame_free);
+ scf_list_clear(&io->ain, simp_frame_t, list, simp_frame_free);
+ scf_list_clear(&io->vout, simp_frame_t, list, simp_frame_free);
+ scf_list_clear(&io->aout, simp_frame_t, list, simp_frame_free);
+
free(io);
}
return 0;
int error;
int exit;
+ int flush;
pthread_t tid;
pthread_mutex_t mutex;
pthread_cond_t cond;
int simp_avio_stop (simp_avio_t* io);
int simp_filter_open (simp_filter_t** pf);
-int simp_filter_close (simp_filter_t* f);
+int simp_filter_close (simp_filter_t* f, int flush);
int simp_filter_run (simp_filter_t* f);
int simp_filter_add_input (simp_filter_t* f, simp_avio_t* input);
if (priv->aframe)
av_frame_free(&priv->aframe);
+ if (priv->vpkt)
+ av_packet_free(&priv->vpkt);
+
+ if (priv->apkt)
+ av_packet_free(&priv->apkt);
+
free(priv);
}
}
ret = avio_open(&priv->fmt_ctx->pb, priv->fmt_ctx->url, AVIO_FLAG_WRITE);
if (ret < 0) {
scf_loge("Could not open output file '%s'", priv->fmt_ctx->url);
+ io->error = ret;
goto end;
}
}
ret = avformat_write_header(priv->fmt_ctx, NULL);
if (ret < 0) {
scf_loge("avformat_write_header error, ret: %s\n", av_err2str(ret));
+ io->error = ret;
goto end;
}
}
- if (io->flush) {
- pthread_mutex_lock(&io->mutex);
- while(!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_lock(&io->mutex);
+ while(!scf_list_empty(&io->vout)) {
+ l = scf_list_head(&io->vout);
+ f = scf_list_data(l, simp_frame_t, list);
- scf_logd("priv->vidx: %d, frame->pts: %ld\n", priv->vidx, f->frame->pts);
+ scf_list_del(&f->list);
- if (0 == io->error) {
+ scf_logd("priv->vidx: %d, frame->pts: %ld\n", priv->vidx, f->frame->pts);
- ret = __ffmpeg_encode(io, priv->vcodec_ctx, priv->vpkt, f->frame, priv->vidx);
- if (ret < 0)
- scf_loge("ret: %d, frame->pts: %ld\n", ret, f->frame->pts);
+ if (0 == io->error && io->flush) {
- io->error = ret;
- }
+ ret = __ffmpeg_encode(io, priv->vcodec_ctx, priv->vpkt, f->frame, priv->vidx);
+ if (ret < 0)
+ scf_loge("ret: %d, frame->pts: %ld\n", ret, f->frame->pts);
- simp_frame_free(f);
- f = NULL;
+ io->error = ret;
}
- while (!scf_list_empty(&io->aout)) {
- l = scf_list_head(&io->aout);
- f = scf_list_data(l, simp_frame_t, list);
+ simp_frame_free(f);
+ f = NULL;
+ }
- scf_list_del(&f->list);
+ while (!scf_list_empty(&io->aout)) {
+ l = scf_list_head(&io->aout);
+ f = scf_list_data(l, simp_frame_t, list);
- if (0 == io->error) {
- ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples);
- if (ret < 0)
- scf_loge("ret: %d\n", ret);
+ scf_list_del(&f->list);
- io->error = ret;
- }
+ if (0 == io->error && io->flush) {
- simp_frame_free(f);
- f = NULL;
+ ret = av_audio_fifo_write(priv->afifo, (void**)f->frame->data, f->frame->nb_samples);
+ if (ret < 0)
+ scf_loge("ret: %d\n", ret);
+
+ io->error = ret;
}
- while (av_audio_fifo_size(priv->afifo) > 0) {
+ simp_frame_free(f);
+ f = NULL;
+ }
- if (0 == io->error) {
- ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024);
- if (ret < 0) {
- scf_loge("ret: %d\n", ret);
- io->error = ret;
- break;
- }
+ while (av_audio_fifo_size(priv->afifo) > 0) {
- priv->nb_samples += priv->aframe->nb_samples;
- priv->aframe->pts = priv->nb_samples;
+ if (0 == io->error && io->flush) {
- scf_logd("aframe->pts: %ld\n", priv->aframe->pts);
+ ret = av_audio_fifo_read(priv->afifo, (void**)priv->aframe->data, 1024);
+ if (ret < 0) {
+ scf_loge("ret: %d\n", ret);
+ io->error = ret;
+ break;
+ }
- ret = __ffmpeg_encode(io, priv->acodec_ctx, priv->apkt, priv->aframe, priv->aidx);
- if (ret < 0) {
- scf_loge("ret: %d\n", ret);
- io->error = ret;
- break;
- }
+ priv->nb_samples += priv->aframe->nb_samples;
+ priv->aframe->pts = priv->nb_samples;
+
+ scf_logd("aframe->pts: %ld\n", priv->aframe->pts);
+
+ ret = __ffmpeg_encode(io, priv->acodec_ctx, priv->apkt, priv->aframe, priv->aidx);
+ if (ret < 0) {
+ scf_loge("ret: %d\n", ret);
+ io->error = ret;
+ break;
}
}
- pthread_mutex_unlock(&io->mutex);
}
+ pthread_mutex_unlock(&io->mutex);
end:
+ ret = av_write_trailer(priv->fmt_ctx);
+ if (ret < 0) {
+ io->error = ret;
+ scf_loge("av_write_trailer error, ret: %s\n", av_err2str(ret));
+ }
+
pthread_mutex_lock(&io->mutex);
io->tid = -1;
pthread_cond_signal(&io->cond);
return 0;
}
-int simp_filter_close(simp_filter_t* f)
+int simp_filter_close(simp_filter_t* f, int flush)
{
- scf_loge("\n");
- return -1;
+ simp_avio_t* io;
+ scf_list_t* l;
+
+ if (!f)
+ return -EINVAL;
+
+ pthread_mutex_lock(&f->mutex);
+ if (flush)
+ f->flush = 1;
+ else
+ f->exit = 1;
+
+ while (-1 != f->tid) {
+ pthread_cond_signal(&f->cond);
+ pthread_cond_wait(&f->cond, &f->mutex);
+ }
+ pthread_mutex_unlock(&f->mutex);
+
+ avfilter_graph_free(&f->vgraph);
+ avfilter_graph_free(&f->agraph);
+
+ f->abuffersink_ctx = NULL;
+ f->vbuffersink_ctx = NULL;
+
+ av_frame_free(&f->vframe);
+ av_frame_free(&f->aframe);
+
+ for (l = scf_list_head(&f->inputs); l != scf_list_sentinel(&f->inputs); ) {
+ io = scf_list_data(l, simp_avio_t, list);
+ l = scf_list_next(l);
+
+ scf_list_del(&io->list);
+
+ io->abuffersrc_ctx = NULL;
+ io->vbuffersrc_ctx = NULL;
+
+ simp_avio_close(io);
+ io = NULL;
+ }
+
+ for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); ) {
+ io = scf_list_data(l, simp_avio_t, list);
+ l = scf_list_next(l);
+
+ scf_list_del(&io->list);
+ simp_avio_close(io);
+ io = NULL;
+ }
+
+ return 0;
}
static int _filter_add_video(simp_avio_t* io)
goto error;
}
+ int flushed = 0;
+
while (!f->exit) {
- int vn = 0;
- int an = 0;
usleep(500 * 1000);
if (io->start_time == 0)
io->start_time = gettime();
+ if (f->flush)
+ simp_avio_stop(io);
+
if (io->vopen) {
f->error = _filter_add_video(io);
if (f->error < 0)
goto error;
+
+ if (f->flush) {
+ flushed++;
+
+ pthread_mutex_lock(&io->mutex);
+ if (scf_list_empty(&io->vin))
+ flushed--;
+ pthread_mutex_unlock(&io->mutex);
+ }
}
if (io->aopen) {
f->error = _filter_add_audio(io);
if (f->error < 0)
goto error;
+
+ if (f->flush) {
+ flushed++;
+
+ pthread_mutex_lock(&io->mutex);
+ if (scf_list_empty(&io->ain))
+ flushed--;
+ pthread_mutex_unlock(&io->mutex);
+ }
}
}
+ if (f->flush && 0 == flushed)
+ f->exit = 1;
+
while (1) {
int ret = av_buffersink_get_frame(f->vbuffersink_ctx, f->vframe);
for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l = scf_list_next(l)) {
io = scf_list_data(l, simp_avio_t, list);
- vf = calloc(1, sizeof(simp_frame_t));
- if (!vf) {
- f->error = -ENOMEM;
- goto error;
- }
+ if (io->vopen) {
+ vf = calloc(1, sizeof(simp_frame_t));
+ if (!vf) {
+ f->error = -ENOMEM;
+ goto error;
+ }
- vf->frame = av_frame_clone(f->vframe);
- if (!vf->frame) {
- simp_frame_free(vf);
- vf = NULL;
+ vf->frame = av_frame_clone(f->vframe);
+ if (!vf->frame) {
+ simp_frame_free(vf);
+ vf = NULL;
- f->error = -ENOMEM;
- goto error;
- }
+ f->error = -ENOMEM;
+ goto error;
+ }
- scf_logd("vf->frame->pts: %ld\n", vf->frame->pts);
+ scf_logd("vf->frame->pts: %ld\n", vf->frame->pts);
- pthread_mutex_lock(&io->mutex);
- scf_list_add_tail(&io->vout, &vf->list);
- pthread_cond_signal(&io->cond);
- pthread_mutex_unlock(&io->mutex);
- vf = NULL;
+ pthread_mutex_lock(&io->mutex);
+ scf_list_add_tail(&io->vout, &vf->list);
+ pthread_cond_signal(&io->cond);
+ pthread_mutex_unlock(&io->mutex);
+ vf = NULL;
+ }
}
av_frame_unref(f->vframe);
for (l = scf_list_head(&f->outputs); l != scf_list_sentinel(&f->outputs); l = scf_list_next(l)) {
io = scf_list_data(l, simp_avio_t, list);
- af = calloc(1, sizeof(simp_frame_t));
- if (!af) {
- f->error = -ENOMEM;
- goto error;
- }
+ if (io->aopen) {
+ af = calloc(1, sizeof(simp_frame_t));
+ if (!af) {
+ f->error = -ENOMEM;
+ goto error;
+ }
- af->frame = av_frame_clone(f->aframe);
- if (!af->frame) {
- simp_frame_free(af);
- af = NULL;
+ af->frame = av_frame_clone(f->aframe);
+ if (!af->frame) {
+ simp_frame_free(af);
+ af = NULL;
- f->error = -ENOMEM;
- goto error;
- }
+ f->error = -ENOMEM;
+ goto error;
+ }
+
+ scf_logd("af->frame->pts: %ld\n", af->frame->pts);
- scf_logd("af->frame->pts: %ld\n", af->frame->pts);
+ pthread_mutex_lock(&io->mutex);
+ scf_list_add_tail(&io->aout, &af->list);
+ pthread_cond_signal(&io->cond);
+ pthread_mutex_unlock(&io->mutex);
+ af = NULL;
+ }
- pthread_mutex_lock(&io->mutex);
- scf_list_add_tail(&io->aout, &af->list);
- pthread_cond_signal(&io->cond);
- pthread_mutex_unlock(&io->mutex);
- af = NULL;
+ if (f->flush)
+ io->flush = 1;
}
av_frame_unref(f->aframe);
}
error:
+ pthread_mutex_lock(&f->mutex);
+ f->tid = -1;
+ pthread_cond_signal(&f->cond);
+ pthread_mutex_unlock(&f->mutex);
return NULL;
}