Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <libavformat/avformat.h>
- #include <libavcodec/avcodec.h>
- #include <libavdevice/avdevice.h>
- #include <libswscale/swscale.h>
- // filters
- #include <libavfilter/avfilter.h>
- #include <libavfilter/avfiltergraph.h>
- #include <libavfilter/buffersink.h>
- #include <libavfilter/avcodec.h>
- int main(int argc, char **argv)
- {
- if (argc < 3) {
- fprintf(stderr,"usage: %s input-file format\n",argv[0]);
- exit(1);
- }
- // Prepare ffmpeg library
- av_register_all();
- avdevice_register_all();
- avfilter_register_all();
- avformat_network_init();
- // Open video stream
- AVInputFormat *pIFormat = av_find_input_format(argv[2]);
- AVDictionary *params = NULL;
- if (strcmp(argv[2],"video4linux") == 0) {
- av_dict_set(¶ms,"video_size","640x240",0);
- av_dict_set(¶ms,"standard","ntsc",0);
- }
- AVFormatContext *pIFormatCtx = NULL;
- int bRet = avformat_open_input(&pIFormatCtx, argv[1], pIFormat, ¶ms);
- if (bRet != 0) {
- fprintf(stderr, "Could not open file\n");
- return 1;
- }
- /* Retrieve stream information */
- if (avformat_find_stream_info(pIFormatCtx,NULL) < 0) {
- fprintf(stderr, "No stream info\n");
- return 1;
- }
- /* Find the first video stream */
- int ixInputStream = -1;
- int ix;
- for (ix = 0; ix < pIFormatCtx->nb_streams; ix++) {
- if (pIFormatCtx->streams[ix]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
- ixInputStream = ix;
- break;
- }
- }
- if (ixInputStream == -1) {
- fprintf(stderr, "No video stream in file\n");
- return 1;
- }
- /* Get a pointer to the codec pICodecCtx for the video stream */
- AVCodecContext *pICodecCtx = pIFormatCtx->streams[ixInputStream]->codec;
- /* Find the decoder for the video stream */
- AVCodec *pICodec = avcodec_find_decoder(pICodecCtx->codec_id);
- if (!pICodec) {
- fprintf(stderr, "Codec not found\n");
- return 1;
- }
- /* Open input codec */
- if (avcodec_open2(pICodecCtx, pICodec,NULL) < 0) {
- fprintf(stderr, "Could not open codec\n");
- return 1;
- }
- AVPacket inputPacket;
- /* Get 1 frame from input */
- av_init_packet(&inputPacket);
- bRet = av_read_frame(pIFormatCtx, &inputPacket);
- if (bRet < 0) {
- fprintf(stderr, "Could not read frame\n");
- return 1;
- }
- if (inputPacket.stream_index != ixInputStream) {
- fprintf(stderr, "Packet is not for our stream\n");
- return 1;
- }
- /* Allocate video frame */
- AVFrame *pFrame = avcodec_alloc_frame();
- /* Determine required buffer size and allocate buffer */
- int szBuffer = avpicture_get_size(pICodecCtx->pix_fmt, pICodecCtx->width, pICodecCtx->height);
- uint8_t *pBuffer = av_mallocz(szBuffer);
- /* Decode video frame */
- int got_frame = 0;
- int e = avcodec_decode_video2(pICodecCtx, pFrame, &got_frame,&inputPacket);
- av_free_packet(&inputPacket);
- if (!got_frame) {
- fprintf(stderr, "Error reading frame\n");
- return 1;
- }
- pFrame->pts = 1;
- /* ------------------------------------------------------------------------------------ */
- // description of the filter
- // TODO: write here the filter description
- const char *filter_desc = "drawbox=20:20:20:20:red,format=rgb24";
- /* ---------------------------------------------------------------------------- */
- /* Init the filter */
- AVFilterGraph *filter_graph = avfilter_graph_alloc();
- AVFilterContext *buffersink_ctx = NULL;
- AVFilterContext *buffersrc_ctx = NULL;
- {
- char args[512];
- AVFilterInOut *outputs = avfilter_inout_alloc();
- AVFilterInOut *inputs = avfilter_inout_alloc();
- enum PixelFormat pix_fmts[] = { pICodecCtx->pix_fmt, PIX_FMT_NONE };
- /* buffer video source: the decoded frames from the decoder will be inserted here. */
- snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d:flags=%d",
- pICodecCtx->width, pICodecCtx->height, pICodecCtx->pix_fmt,
- pICodecCtx->time_base.num, pICodecCtx->time_base.den,
- pICodecCtx->sample_aspect_ratio.num, pICodecCtx->sample_aspect_ratio.den,
- SWS_BILINEAR
- );
- int ret = avfilter_graph_create_filter(&buffersrc_ctx, avfilter_get_by_name("buffer"), "in",
- args, NULL, filter_graph);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
- return ret;
- }
- /* buffer video sink: to terminate the filter chain. */
- ret = avfilter_graph_create_filter(&buffersink_ctx, avfilter_get_by_name("buffersink"), "out",
- NULL, pix_fmts, filter_graph);
- if (ret < 0) {
- av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
- return ret;
- }
- /* Endpoints for the filter graph. */
- outputs->name = av_strdup("in");
- outputs->filter_ctx = buffersrc_ctx;
- outputs->pad_idx = 0;
- outputs->next = NULL;
- inputs->name = av_strdup("out");
- inputs->filter_ctx = buffersink_ctx;
- inputs->pad_idx = 0;
- inputs->next = NULL;
- if (avfilter_graph_parse(filter_graph, filter_desc,&inputs, &outputs, NULL) < 0) {
- fprintf(stderr, "Could init filters\n");
- return 1;
- }
- if (avfilter_graph_config(filter_graph, NULL) < 0) {
- fprintf(stderr, "Could init filters\n");
- return 1;
- }
- }
- /* ---------------------------------------------------------------------------- */
- // Apply the filter in one frame
- if (av_vsrc_buffer_add_frame(buffersrc_ctx,pFrame,0) < 0) {
- fprintf(stderr, "Error reading frame II\n");
- return 1;
- }
- AVFilterBufferRef *picref = NULL;
- if (avfilter_poll_frame(buffersink_ctx->inputs[0])<0) {
- fprintf(stderr, "Error applying filter frame\n");
- return 1;
- }
- if (av_buffersink_get_buffer_ref(buffersink_ctx,&picref,0) > 0 || !picref) {
- fprintf(stderr, "Error applying filter frame II\n");
- return 1;
- }
- /* ----------------------------------------------------------------------------------- */
- // prepare the output
- AVCodec *pOCodec = avcodec_find_encoder(CODEC_ID_PNG);
- /* Allocate Output Codec */
- AVCodecContext *pOCodecCtx = avcodec_alloc_context3(pOCodec);
- if (!pOCodecCtx) {
- fprintf(stderr, "Could not allocate codec\n");
- return 1;
- }
- /* Initialize picture size and other format parameters */
- pOCodecCtx->width = pICodecCtx->width;
- pOCodecCtx->height = pICodecCtx->height;
- pOCodecCtx->pix_fmt = PIX_FMT_RGB24;
- pOCodecCtx->time_base.num = 1;
- pOCodecCtx->time_base.den = 1;
- pOCodecCtx->thread_count = 2;
- if (avcodec_open2(pOCodecCtx, pOCodec,NULL) < 0) {
- fprintf(stderr, "Could not open final codec\n");
- return 1;
- }
- /* -------------------------------------------------------------------------------------- */
- // frame in jpeg
- AVFrame *finalFrame = avcodec_alloc_frame();
- // copy the filtered picture to the final frame
- bRet = avfilter_fill_frame_from_video_buffer_ref(finalFrame,picref);
- if (bRet) {
- fprintf(stderr, "Error copyng filter to frame\n");
- return 1;
- }
- finalFrame->pts = 1;
- /* -------------------------------------------------------------------------------------- */
- // where the encoded frame will be stored
- AVPacket packet;
- av_init_packet(&packet);
- packet.size = szBuffer;
- packet.data = pBuffer;
- int gotPacket = 0;
- int szBufferActual = avcodec_encode_video2(pOCodecCtx, &packet,pFrame,&gotPacket);
- if (!szBufferActual && gotPacket && pOCodecCtx->coded_frame) {
- pOCodecCtx->coded_frame->pts = packet.pts;
- pOCodecCtx->coded_frame->key_frame = !!(packet.flags & AV_PKT_FLAG_KEY);
- }
- /* Write frame to file */
- FILE *file = fopen("test.png", "wb");
- bRet = fwrite(pBuffer, sizeof(uint8_t), packet.size, file);
- fclose(file);
- if (bRet != packet.size) {
- fprintf(stderr, "Error writing jpeg file\n");
- return 1;
- }
- avfilter_unref_buffer(picref);
- /* Cleanup */
- if (pBuffer) {
- av_freep(&pBuffer);
- pBuffer = NULL;
- szBuffer = 0;
- }
- if (pFrame) {
- av_freep(&pFrame);
- pFrame = NULL;
- }
- if (pICodecCtx) {
- avcodec_close(pICodecCtx);
- pICodecCtx = NULL;
- }
- if (pOCodecCtx) {
- avcodec_close(pOCodecCtx);
- pOCodecCtx = NULL;
- }
- if (pIFormatCtx) {
- avformat_close_input(&pIFormatCtx);
- pIFormatCtx = NULL;
- }
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement