static int filter_encode_write_frame(AVFrame *frame, unsigned int stream_index) { int ret; AVFrame *filt_frame; av_log(NULL, AV_LOG_INFO, "Pushing decoded frame to filters\n"); /* push the decoded frame into the filtergraph */ ret = av_buffersrc_add_frame_flags(filter_ctx[stream_index].buffersrc_ctx, frame, 0); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error while feeding the filtergraph\n"); return ret; } /* pull filtered frames from the filtergraph */ while (1) { filt_frame = av_frame_alloc(); if (!filt_frame) { ret = AVERROR(ENOMEM); break; } av_log(NULL, AV_LOG_INFO, "Pulling filtered frame from filters\n"); ret = av_buffersink_get_frame(filter_ctx[stream_index].buffersink_ctx, filt_frame); if (ret < 0) { /* if no more frames for output - returns AVERROR(EAGAIN) * if flushed and no more frames for output - returns AVERROR_EOF * rewrite retcode to 0 to show it as normal procedure completion */ if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF) ret = 0; av_frame_free(&filt_frame); break; } filt_frame->pict_type = AV_PICTURE_TYPE_NONE; ret = encode_write_frame(filt_frame, stream_index, NULL); if (ret < 0) break; } return ret; }
static int flush_encoder(unsigned int stream_index) { int ret; int got_frame; if (!(ofmt_ctx->streams[stream_index]->codec->codec->capabilities & CODEC_CAP_DELAY)) return 0; while (1) { av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", stream_index); ret = encode_write_frame(NULL, stream_index, &got_frame); if (ret < 0) break; if (!got_frame) return 0; } return ret; }
int flush_encoder(unsigned int streamIdx) { int ret; int got_frame; if (!(ofmt_ctx->streams[streamIdx]->codec->codec->capabilities & CODEC_CAP_DELAY)) return 0; while (1) { ret = encode_write_frame(NULL, streamIdx, &got_frame); if (ret < 0) break; if (!got_frame) return 0; //av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder %d \n", streamIdx, frame_use); frame_use++; } return ret; }
int main() { int ret=0, check_yuv = 0; AVPacket pkt; AVFrame *frame = NULL; enum AVMediaType mediaType; unsigned int streamIdx; unsigned int i; int gotFrame; check_yuv = check_file(); //inititialize all the registers av_register_all(); if (open_input_file(check_yuv) < 0) exit(1); if (open_output_file() < 0) exit(1); //initialize packet, set data to NULL av_init_packet(&pkt); pkt.data = NULL; pkt.size = 0; //read all packets while (av_read_frame(inFmtCtx, &pkt) >= 0) { streamIdx = pkt.stream_index; mediaType = inFmtCtx->streams[streamIdx]->codec->codec_type; av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", streamIdx); av_log(NULL, AV_LOG_DEBUG, "Going to reencode \n"); frame = av_frame_alloc(); if (!frame) { ret = AVERROR(ENOMEM); break; } av_packet_rescale_ts(&pkt,inFmtCtx->streams[streamIdx]->time_base, inFmtCtx->streams[streamIdx]->codec->time_base); if (mediaType == AVMEDIA_TYPE_VIDEO) { ret = avcodec_decode_video2(inFmtCtx->streams[streamIdx]->codec, frame, &gotFrame, &pkt); if (ret < 0) { av_frame_free(&frame); av_log(NULL, AV_LOG_ERROR, "Decoding failed\n"); break; } } if (gotFrame) { frame->pts = av_frame_get_best_effort_timestamp(frame); ret = encode_write_frame(frame, streamIdx, &gotFrame); //av_frame_free(&frame); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Error Encoding Frame"); exit(1); } } else av_frame_free(&frame); av_free_packet(&pkt); } //flush encoders for (i = 0; i < inFmtCtx->nb_streams; i++) { if (inFmtCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) { ret = flush_encoder(i); if (ret < 0) { av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n"); exit(1); } } } //free all av_write_trailer(outFmtCtx); av_free_packet(&pkt); //av_frame_free(&frame); for (i = 0; i < inFmtCtx->nb_streams; i++) { avcodec_close(inFmtCtx->streams[i]->codec); if (outFmtCtx && outFmtCtx->nb_streams > i && outFmtCtx->streams[i] && outFmtCtx->streams[i]->codec) avcodec_close(outFmtCtx->streams[i]->codec); } avformat_close_input(&inFmtCtx); if (outFmtCtx && !(outFmtCtx->oformat->flags & AVFMT_NOFILE)) avio_closep(&outFmtCtx->pb); avformat_free_context(outFmtCtx); if (ret < 0) av_log(NULL, AV_LOG_ERROR, "Error occurred \n"); return 0; }