Revision 51d67a10

View differences:

chunker_streamer/Makefile
1 1
include ../common.mak
2 2

  
3 3
OBJECTS += dbg.o
4
OBJECTS += chunker_filtering.o
5
CPPFLAGS += -DUSE_AVFILTER
4 6

  
5 7
ifeq ($(IO), httpevent)
6 8
CPPFLAGS += -DHTTPIO
chunker_streamer/chunker_filtering.c
1
/*
2
 * Copyright (c) 2010 Nicolas George
3
 * Copyright (c) 2011 Stefano Sabatini
4
 * Copyright (c) 2011 Csaba Kiraly
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

  
25
/**
26
 * @file
27
 * decoding and filtering, based on ffmpeg's avfiler example
28
 */
29

  
30
#ifdef USE_AVFILTER
31

  
32
#include <libavcodec/avcodec.h>
33
#include <libavformat/avformat.h>
34
#include <libavfilter/avfiltergraph.h>
35
#include <libavfilter/vsink_buffer.h>
36
#include <libavfilter/vsrc_buffer.h>
37

  
38
#include <libavfilter/avcodec.h>	//might not be needed in newer versions of ffmpeg
39

  
40
#include "chunker_filtering.h"
41

  
42
AVFilterContext *buffersink_ctx;
43
AVFilterContext *buffersrc_ctx;
44
AVFilterGraph *filter_graph;
45

  
46
int init_filters(const char *filters_descr, const AVCodecContext *dec_ctx)
47
{
48
    char args[512];
49
    int ret;
50
    AVFilter *buffersrc  = avfilter_get_by_name("buffer");
51
    AVFilter *buffersink = avfilter_get_by_name("buffersink");
52
    AVFilterInOut *outputs = avfilter_inout_alloc();
53
    AVFilterInOut *inputs  = avfilter_inout_alloc();
54
    enum PixelFormat pix_fmts[] = { PIX_FMT_YUV420P, PIX_FMT_GRAY8, PIX_FMT_NONE };
55
    filter_graph = avfilter_graph_alloc();
56

  
57
    /* buffer video source: the decoded frames from the decoder will be inserted here. */
58
    snprintf(args, sizeof(args), "%d:%d:%d:%d:%d:%d:%d",
59
             dec_ctx->width, dec_ctx->height, dec_ctx->pix_fmt,
60
             dec_ctx->time_base.num, dec_ctx->time_base.den,
61
             dec_ctx->sample_aspect_ratio.num, dec_ctx->sample_aspect_ratio.den);
62
    ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
63
                                       args, NULL, filter_graph);
64
    if (ret < 0) {
65
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer source\n");
66
        return ret;
67
    }
68

  
69
    /* buffer video sink: to terminate the filter chain. */
70
    ret = avfilter_graph_create_filter(&buffersink_ctx, buffersink, "out",
71
                                       NULL, pix_fmts, filter_graph);
72
    if (ret < 0) {
73
        av_log(NULL, AV_LOG_ERROR, "Cannot create buffer sink\n");
74
        return ret;
75
    }
76

  
77
    /* Endpoints for the filter graph. */
78
    outputs->name       = av_strdup("in");
79
    outputs->filter_ctx = buffersrc_ctx;
80
    outputs->pad_idx    = 0;
81
    outputs->next       = NULL;
82

  
83
    inputs->name       = av_strdup("out");
84
    inputs->filter_ctx = buffersink_ctx;
85
    inputs->pad_idx    = 0;
86
    inputs->next       = NULL;
87

  
88
    if ((ret = avfilter_graph_parse(filter_graph, filters_descr,
89
                                    &inputs, &outputs, NULL)) < 0)
90
        return ret;
91

  
92
    if ((ret = avfilter_graph_config(filter_graph, NULL)) < 0)
93
        return ret;
94
}
95

  
96
int filter(AVFrame* src, AVFrame *dst)
97
{
98
    int ret;
99
    AVFilterBufferRef *picref;
100

  
101
    /* push the decoded frame into the filtergraph. 3rd parameter might not be needed with new ffmpeg */
102
    av_vsrc_buffer_add_frame(buffersrc_ctx, src, 0);
103

  
104
    /* pull filtered pictures from the filtergraph */
105
    ret = avfilter_poll_frame(buffersink_ctx->inputs[0]);
106
    if (ret) {
107
        av_vsink_buffer_get_video_buffer_ref(buffersink_ctx, &picref, 0);
108
        if (picref) {
109
            avfilter_fill_frame_from_video_buffer_ref(dst, picref);
110
            dst->pts = picref->pts;
111
            avfilter_unref_buffer(picref);
112
        }
113
    }
114

  
115
    return ret;
116
}
117

  
118
void close_filters(void)
119
{
120
    avfilter_graph_free(&filter_graph);
121
}
122

  
123
#endif
chunker_streamer/chunker_filtering.h
1
/*
2
 * Copyright (c) 2010 Nicolas George
3
 * Copyright (c) 2011 Stefano Sabatini
4
 * Copyright (c) 2011 Csaba Kiraly
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24

  
25
/**
26
 * @file
27
 * decoding and filtering, based on ffmpeg's avfiler example
28
 */
29

  
30
#ifndef CHUNKER_FILTERING_H
31
#define CHUNKER_FILTERING_H
32

  
33
//do not forget to call avfilter_register_all() before
34
int init_filters(const char *filters_descr, const AVCodecContext *dec_ctx);
35

  
36
int filter(AVFrame* src, AVFrame *dst);
37

  
38
void close_filters(void);
39

  
40
#endif
chunker_streamer/chunker_streamer.c
11 11
#include <getopt.h>
12 12
#include <libswscale/swscale.h>
13 13

  
14
#ifdef USE_AVFILTER
15
#include "chunker_filtering.h"
16
#endif
17

  
14 18
#define DEBUG
15 19
#define DEBUG_AUDIO_FRAMES  false
16 20
#define DEBUG_VIDEO_FRAMES  false
......
55 59

  
56 60
long delay_audio = 0; //delay audio by x millisec
57 61

  
62
char *avfilter="yadif";
63

  
58 64
// Constant number of frames per chunk
59 65
int chunkFilledFramesStrategy(ExternalChunk *echunk, int chunkType)
60 66
{
......
126 132
    "\t[-p]: pts anomaly threshold (default: -1=off).\n"
127 133
    "\t[-q]: sync anomaly threshold ((default: -1=off).\n"
128 134
    "\t[-t]: QoE test mode\n\n"
135

  
136
    "\t[--avfilter]:set input filter (default: yadif\n"
137
    "\n"
129 138
    "Codec options:\n"
130 139
    "\t[-g GOP]: gop size\n"
131 140
    "\t[-b frames]: max number of consecutive b frames\n"
......
181 190
	//a raw buffer for decoded uncompressed audio samples
182 191
	int16_t *samples = NULL;
183 192
	//a raw uncompressed video picture
184
	AVFrame *pFrame = NULL;
193
	AVFrame *pFrame1 = NULL;
194
	AVFrame *pFrame2 = NULL;
185 195
	AVFrame *scaledFrame = NULL;
186 196

  
187 197
	AVFormatContext *pFormatCtx;
......
213 223
		/* These options set a flag. */
214 224
		{"audio_stream", required_argument, 0, 0},
215 225
		{"video_stream", required_argument, 0, 0},
226
		{"avfilter", required_argument, 0, 0},
216 227
		{0, 0, 0, 0}
217 228
	};
218 229
	/* `getopt_long' stores the option index here. */
......
224 235
			case 0: //for long options
225 236
				if( strcmp( "audio_stream", long_options[option_index].name ) == 0 ) { audioStream = atoi(optarg); }
226 237
				if( strcmp( "video_stream", long_options[option_index].name ) == 0 ) { videoStream = atoi(optarg); }
238
				if( strcmp( "avfilter", long_options[option_index].name ) == 0 ) { avfilter = strdup(optarg); }
227 239
				break;
228 240
			case 'i':
229 241
				sprintf(av_input, "%s", optarg);
......
571 583
	}
572 584

  
573 585
	// Allocate video in frame and out buffer
574
	pFrame=avcodec_alloc_frame();
586
	pFrame1=avcodec_alloc_frame();
587
	pFrame2=avcodec_alloc_frame();
575 588
	scaledFrame=avcodec_alloc_frame();
576
	if(pFrame==NULL || scaledFrame == NULL) {
589
	if(pFrame1==NULL || pFrame2==NULL || scaledFrame == NULL) {
577 590
		fprintf(stderr, "INIT: Memory error alloc video frame!!!\n");
578 591
		return -1;
579 592
	}
......
657 670
	FILE* videotrace = fopen(videotrace_filename, "w");
658 671
	FILE* psnrtrace = fopen(psnr_filename, "w");
659 672

  
673
#ifdef USE_AVFILTER
674
	//init AVFilter
675
	avfilter_register_all();
676
	init_filters(avfilter, pCodecCtx);
677
#endif
678

  
660 679
	//main loop to read from the input file
661 680
	while((av_read_frame(pFormatCtx, &packet)>=0) && !quit)
662 681
	{
......
709 728
			gettimeofday(&tmp_tv, NULL);
710 729
			
711 730
			//decode the video packet into a raw pFrame
712
			if(avcodec_decode_video2(pCodecCtx, pFrame, &frameFinished, &packet)>0)
731
			if(avcodec_decode_video2(pCodecCtx, pFrame1, &frameFinished, &packet)>0)
713 732
			{
733
				AVFrame *pFrame;
734
				pFrame = pFrame1;
735

  
714 736
				// usleep(5000);
715 737
				dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOin pkt: dts %lld pts %lld pts-dts %lld\n", packet.dts, packet.pts, packet.pts-packet.dts );
716 738
				dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode: pkt_dts %lld pkt_pts %lld frame.pts %lld\n", pFrame->pkt_dts, pFrame->pkt_pts, pFrame->pts);
......
731 753
				}
732 754
#endif
733 755

  
756

  
734 757
					dcprintf(DEBUG_VIDEO_FRAMES, "VIDEO: finished frame %d dts %lld pts %lld\n", frame->number, packet.dts, packet.pts);
735 758
					if(frame->number==0) {
736 759
						if(packet.dts==AV_NOPTS_VALUE)
......
783 806
						}
784 807
					    }
785 808

  
809
#ifdef USE_AVFILTER
810
					//apply avfilters
811
					filter(pFrame,pFrame2);
812
					pFrame = pFrame2;
813
					dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode: pkt_dts %lld pkt_pts %lld frame.pts %lld\n", pFrame2->pkt_dts, pFrame2->pkt_pts, pFrame2->pts);
814
					dcprintf(DEBUG_VIDEO_FRAMES, "VIDEOdecode intype %d%s\n", pFrame2->pict_type, pFrame2->key_frame ? " (key)" : "");
815
#endif
816

  
786 817
					    if(pCodecCtx->height != pCodecCtxEnc->height || pCodecCtx->width != pCodecCtxEnc->width) {
787 818
//						static AVPicture pict;
788 819
						static struct SwsContext *img_convert_ctx = NULL;
......
1183 1214
	free(cmeta);
1184 1215

  
1185 1216
	// Free the YUV frame
1186
	av_free(pFrame);
1217
	av_free(pFrame1);
1218
	av_free(pFrame2);
1187 1219
	av_free(scaledFrame);
1188 1220
	av_free(samples);
1189 1221
  
......
1245 1277
	finalizeTCPChunkPusher();
1246 1278
#endif
1247 1279

  
1280
#ifdef USE_AVFILTER
1281
	close_filters();
1282
#endif
1283

  
1248 1284
	return 0;
1249 1285
}
1250 1286

  
common.mak
27 27
ifdef WINDOWS
28 28
LOCAL_FFMPEG_LDLIBS = $(LOCAL_FFMPEG)/lib/libavdevice.a $(LOCAL_FFMPEG)/lib/libavformat.a $(LOCAL_FFMPEG)/lib/libavcodec.a $(LOCAL_FFMPEG)/lib/libavutil.a $(LOCAL_FFMPEG)/lib/libswscale.a -lws2_32
29 29
else
30
LOCAL_FFMPEG_LDLIBS = $(LOCAL_FFMPEG)/lib/libavdevice.a $(LOCAL_FFMPEG)/lib/libavformat.a $(LOCAL_FFMPEG)/lib/libavcodec.a $(LOCAL_FFMPEG)/lib/libavutil.a $(LOCAL_FFMPEG)/lib/libswscale.a
30
LOCAL_FFMPEG_LDLIBS = $(LOCAL_FFMPEG)/lib/libavdevice.a $(LOCAL_FFMPEG)/lib/libavformat.a $(LOCAL_FFMPEG)/lib/libavcodec.a $(LOCAL_FFMPEG)/lib/libavutil.a $(LOCAL_FFMPEG)/lib/libswscale.a $(LOCAL_FFMPEG)/lib/libavfilter.a
31 31
endif
32 32

  
33 33
LOCAL_COMMON_CPPFLAGS = -I$(LOCAL_X264)/include -I$(LOCAL_BZ2)/include -I$(LOCAL_Z)/include -I$(LOCAL_MP3LAME)/include

Also available in: Unified diff