summaryrefslogtreecommitdiff
path: root/rotord/test_ffms2.c
blob: 759bde38d433850e648c2c6680a8a8c89967b703 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
#include <ffms.h>
#include <stdio.h>
#ifdef _WIN32
#include <objbase.h>
#endif



int main (int argc, char *argv[]) {

	if(argc<2){
            printf("Error: USAGE - test filename\n");
        return 0;
  	}
	/* If you are on Windows you should first initialize COM, or all MPEG-TS/PS and OGM
	files may return an error when you try to open them (if the library was built
	with HAALISOURCE defined). All other formats will work normally. */
#ifdef _WIN32
	bool com_inited = false;
	HRESULT res = CoInitializeEx(NULL, COINIT_MULTITHREADED);
	if (SUCCEEDED(res)) 
		com_inited = true;
	else if (res != RPC_E_CHANGED_MODE) {
		/* com initialization failed, handle error */
	}
#endif

	/* Initialize the library itself.
	The cpu caps are autodetected almost all places nowadays. Passing 0 should have close to no performance
	impact with a recent FFmpeg. If you want you can pass something like
	FFMS_CPU_CAPS_MMX | FFMS_CPU_CAPS_MMX2. */
	FFMS_Init(0, 0);

	/* Index the source file. Note that this example does not index any audio tracks. */
	char errmsg[1024];
	FFMS_ErrorInfo errinfo;
	errinfo.Buffer      = errmsg;
	errinfo.BufferSize  = sizeof(errmsg);
	errinfo.ErrorType   = FFMS_ERROR_SUCCESS;
	errinfo.SubType     = FFMS_ERROR_SUCCESS;
	const char *sourcefile = argv[1];
	FFMS_Index *index = FFMS_MakeIndex(sourcefile, 0, 0, NULL, NULL, FFMS_IEH_STOP_TRACK, NULL, NULL, &errinfo);
	if (index == NULL) {
		/* handle error (print errinfo.Buffer somewhere) */
		printf("Error: cannot index %s: %s\n",sourcefile,errmsg);
		return 0;
	}

	/* Retrieve the track number of the first video track */
	int trackno = FFMS_GetFirstTrackOfType(index, FFMS_TYPE_VIDEO, &errinfo);
	if (trackno < 0) {
		/* no video tracks found in the file, this is bad and you should handle it */
		/* (print the errmsg somewhere) */
	}

	/* We now have enough information to create the video source object */
	FFMS_VideoSource *videosource = FFMS_CreateVideoSource(sourcefile, trackno, index, 1, FFMS_SEEK_NORMAL, &errinfo);
	if (videosource == NULL) {
		/* handle error (you should know what to do by now) */
	}

	/* Since the index is copied into the video source object upon its creation,
	we can and should now destroy the index object. */
	FFMS_DestroyIndex(index);

	/* Retrieve video properties so we know what we're getting.
	As the lack of the errmsg parameter indicates, this function cannot fail. */
	const FFMS_VideoProperties *videoprops = FFMS_GetVideoProperties(videosource);

	/* Now you may want to do something with the info, like check how many frames the video has */
	int num_frames = videoprops->NumFrames;
	
	/* Get the first frame for examination so we know what we're getting. This is required
	because resolution and colorspace is a per frame property and NOT global for the video. */
	const FFMS_Frame *propframe = FFMS_GetFrame(videosource, 0, &errinfo);

	/* Now you may want to do something with the info; particularly interesting values are:
	propframe->EncodedWidth; (frame width in pixels)
	propframe->EncodedHeight; (frame height in pixels)
	propframe->EncodedPixelFormat; (actual frame colorspace)
	*/

	/* If you want to change the output colorspace or resize the output frame size,
	now is the time to do it. IMPORTANT: This step is also required to prevent
	resolution and colorspace changes midstream. You can you can always tell a frame's 
	original properties by examining the Encoded* properties in FFMS_Frame. */
	/* See libavutil/pixfmt.h for the list of pixel formats/colorspaces.
	To get the name of a given pixel format, strip the leading PIX_FMT_
	and convert to lowercase. For example, PIX_FMT_YUV420P becomes "yuv420p". */
	
	/* A -1 terminated list of the acceptable output formats. */
	int pixfmts[2];
	pixfmts[0] = FFMS_GetPixFmt("bgra");
	pixfmts[1] = -1;
	
	if (FFMS_SetOutputFormatV2(videosource, pixfmts, propframe->EncodedWidth, propframe->EncodedHeight, FFMS_RESIZER_BICUBIC, &errinfo)) {
		/* handle error */
	}

	/* now we're ready to actually retrieve the video frames */
	int framenumber = 0; /* valid until next call to FFMS_GetFrame* on the same video object */
	const FFMS_Frame *curframe = FFMS_GetFrame(videosource, framenumber, &errinfo);
	if (curframe == NULL) {
		/* handle error */
	}
	/* do something with curframe */
	/* continue doing this until you're bored, or something */

	/* now it's time to clean up */
	FFMS_DestroyVideoSource(videosource);
#ifdef _WIN32
	if (com_inited)
		CoUninitialize();
#endif
	
	return 0;
}