source: trunk/lang/tcl/src/RpVideoTclInterface.cc @ 1916

Last change on this file since 1916 was 1916, checked in by dkearney, 14 years ago

switching from RpMediaPlayer? to RpVideo? code for the video viewer widget. changed flowdial widget so the dial moved as needed for the video widget.

File size: 8.7 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture::MediaPlayer
4 *
5 *  This is an interface to the rappture movieplayer module.
6 *  It allows you to grab image frames from mpeg movies using ffmpeg.
7 * ======================================================================
8 *  AUTHOR:  Derrick Kearney, Purdue University
9 *  Copyright (c) 2005-2010  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15#include <tcl.h>
16#include <string.h>
17#include "RpVideo.h"
18
19extern "C" Tcl_AppInitProc RpVideo_Init;
20
21#include "RpOp.h"
22
23static Tcl_ObjCmdProc VideoCmd;
24static Tcl_ObjCmdProc VideoCallCmd;
25static Tcl_ObjCmdProc GetOp;
26static Tcl_ObjCmdProc NextOp;
27static Tcl_ObjCmdProc SeekOp;
28static Tcl_ObjCmdProc ReleaseOp;
29
30static Rp_OpSpec rpVideoOps[] = {
31    {"get",  1, (void *)GetOp, 3, 5, "[image width height]|[position cur|end]|[framerate]",},
32    {"next",  1, (void *)NextOp, 2, 2, "",},
33    {"seek",  1, (void *)SeekOp, 3, 3, "+n|-n|n",},
34    {"release", 1, (void *)ReleaseOp, 2, 2, "",},
35};
36
37static int nRpVideoOps = sizeof(rpVideoOps) / sizeof(Rp_OpSpec);
38
39/*
40 * ------------------------------------------------------------------------
41 *  RpVideo_Init()
42 *
43 *  Called in Rappture_Init() to initialize the commands defined
44 *  in this file.
45 * ------------------------------------------------------------------------
46 */
47int
48RpVideo_Init(Tcl_Interp *interp)
49{
50
51    Tcl_CreateObjCommand(interp, "::Rappture::Video",
52        VideoCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
53
54    return TCL_OK;
55}
56
57/*
58 * USAGE: Video <file>
59 */
60static int
61VideoCmd(ClientData clientData, Tcl_Interp *interp, int objc,
62       Tcl_Obj* const *objv)
63{
64    char cmdName[64];
65    static int movieCount = 0;
66    const char *filename = Tcl_GetString(objv[1]);
67
68    // create a new command
69    VideoObj *movie = NULL;
70    movie = VideoInitCmd();
71    if (movie == NULL) {
72        Tcl_AppendResult(interp, "error while creating movie object", "\n",
73                         "VideoInitCmd(movie);", (char*)NULL);
74        return TCL_ERROR;
75    }
76    VideoOpenFile(movie,filename,"r");
77
78    sprintf(cmdName,"::movieObj%d",movieCount);
79
80    Tcl_CreateObjCommand(interp, cmdName, VideoCallCmd,
81        (ClientData)movie, (Tcl_CmdDeleteProc*)NULL);
82
83    Tcl_AppendResult(interp, cmdName, (char*)NULL);
84    return TCL_OK;
85}
86
87
88static int
89VideoCallCmd(ClientData clientData, Tcl_Interp *interp, int objc,
90           Tcl_Obj *const *objv)
91{
92    Tcl_ObjCmdProc *proc;
93
94    proc = (Tcl_ObjCmdProc *)Rp_GetOpFromObj(interp, nRpVideoOps, rpVideoOps,
95        RP_OP_ARG1, objc, objv, 0);
96
97    if (proc == NULL) {
98        return TCL_ERROR;
99    }
100    return (*proc)(clientData, interp, objc, objv);
101}
102
103/**********************************************************************/
104// FUNCTION: GetOp()
105/// Get info about the video
106/**
107 * Full function call:
108 *
109 * get position cur
110 * get position end
111 * get image width height
112 * get framerate
113 *
114 */
115static int
116GetOp (ClientData clientData, Tcl_Interp *interp, int objc,
117         Tcl_Obj *const *objv)
118{
119    const char *cmd = Tcl_GetString(objv[1]);
120
121    /*
122     * Decode the first arg and figure out how we're supposed to advance.
123     */
124    if (objc > 5) {
125        Tcl_AppendResult(interp, "wrong # args: should be \"", cmd,
126            " [image width height]|[position cur|end]\"", (char*)NULL);
127        return TCL_ERROR;
128    }
129
130    const char *info = Tcl_GetString(objv[2]);
131    if ((*info == 'p') && (strcmp(info,"position") == 0)) {
132        if (objc != 4) {
133            Tcl_AppendResult(interp, "wrong # args: should be \"", cmd,
134                " position cur|end\"", (char*)NULL);
135            return TCL_ERROR;
136        }
137        const char *which = Tcl_GetString(objv[3]);
138        if ((*which == 'c') && (strcmp(which,"cur") == 0)) {
139            int pos = 0;
140            VideoGetPositionCur((VideoObj *)clientData,&pos);
141            Tcl_SetObjResult(interp, Tcl_NewIntObj(pos));
142        }
143        else if ((*which == 'e') && (strcmp(which,"end") == 0)) {
144            int pos = 0;
145            VideoGetPositionEnd((VideoObj *)clientData,&pos);
146            Tcl_SetObjResult(interp, Tcl_NewIntObj(pos));
147        }
148        else {
149            Tcl_AppendResult(interp, "unrecognized command: \"", which,
150                "\" should be one of cur,end ", (char*)NULL);
151            return TCL_ERROR;
152        }
153    }
154    else if ((*info == 'i') && (strcmp(info,"image") == 0)) {
155        if (objc != 5) {
156            Tcl_AppendResult(interp, "wrong # args: should be \"", cmd,
157                " image width height\"", (char*)NULL);
158            return TCL_ERROR;
159        }
160
161        void *img = NULL;
162        int width = 0;
163        int height = 0;
164        int bufSize = 0;
165
166        Tcl_GetIntFromObj(interp, objv[3], &width);
167        Tcl_GetIntFromObj(interp, objv[4], &height);
168
169//        VideoGoNext((VideoObj *)clientData);
170        VideoGetImage((VideoObj *)clientData, width, height, &img, &bufSize);
171
172        Tcl_SetByteArrayObj(Tcl_GetObjResult(interp),
173                            (const unsigned char*)img, bufSize);
174    }
175    else if ((*info == 'f') && (strcmp(info,"framerate") == 0)) {
176        if (objc != 3) {
177            Tcl_AppendResult(interp, "wrong # args: should be \"", cmd,
178                " framerate\"", (char*)NULL);
179            return TCL_ERROR;
180        }
181
182        double fr = 0;
183
184        VideoGetFrameRate((VideoObj *)clientData, &fr);
185        Tcl_SetObjResult(interp, Tcl_NewDoubleObj(fr));
186    }
187    else {
188        Tcl_AppendResult(interp, "unrecognized command \"", info, "\": should be \"", cmd,
189            " [image width height]|[position cur|end]|[framerate]\"", (char*)NULL);
190        return TCL_ERROR;
191    }
192
193
194    return TCL_OK;
195}
196
197
198/**********************************************************************/
199// FUNCTION: NextOp()
200/// Get the next frame from a video
201/**
202 * Return the next frame from a video as an image
203 * Full function call:
204 *
205 * next
206 *
207 */
208static int
209NextOp (ClientData clientData, Tcl_Interp *interp, int objc,
210         Tcl_Obj *const *objv)
211{
212
213    void *img = NULL;
214    int width = 960;
215    int height = 540;
216    int bufSize = 0;
217
218    VideoGoNext((VideoObj *)clientData);
219    VideoGetImage((VideoObj *)clientData, width, height, &img, &bufSize);
220
221    Tcl_SetByteArrayObj(Tcl_GetObjResult(interp),
222                        (const unsigned char*)img, bufSize);
223
224    return TCL_OK;
225}
226
227/**********************************************************************/
228// FUNCTION: SeekOp()
229/// Get the next frame from a video
230/**
231 * Return the frame specified, or at the specified offset, as an image
232 * Full function call:
233 *
234 * seek +5
235 * seek -5
236 * seek 22
237 *
238 */
239static int
240SeekOp (ClientData clientData, Tcl_Interp *interp, int objc,
241         Tcl_Obj *const *objv)
242{
243
244    void *img = NULL;
245    int width = 960;
246    int height = 540;
247    int bufSize = 0;
248    const char *val_s = NULL;
249    int val = 0;
250
251    val_s = Tcl_GetString(objv[2]);
252    if (*val_s == '+') {
253        if (Tcl_GetInt(interp, val_s+1, &val) != TCL_OK) {
254            Tcl_AppendResult(interp, "bad value \"", val_s,
255                "\": should be next, +n, -n, or n", (char*)NULL);
256            return TCL_ERROR;
257        }
258        VideoGoPlusMinusN((VideoObj *)clientData, val);
259    }
260    else if (*val_s == '-') {
261        if (Tcl_GetInt(interp, val_s, &val) != TCL_OK) {
262            Tcl_AppendResult(interp, "bad value \"", val_s,
263                "\": should be next, +n, -n, or n", (char*)NULL);
264            return TCL_ERROR;
265        }
266        VideoGoPlusMinusN((VideoObj *)clientData, val);
267    }
268    else if (Tcl_GetInt(interp, val_s, &val) != TCL_OK) {
269        Tcl_AppendResult(interp, "bad value \"", val_s,
270            "\": should be next, +n, -n, or n", (char*)NULL);
271        return TCL_ERROR;
272    }
273    else {
274        int c = 0;
275        c = VideoGoToN((VideoObj *)clientData, val);
276        // printf("c = %d\tval = %d\n",c,val);
277    }
278
279    VideoGetImage((VideoObj *)clientData, width, height, &img, &bufSize);
280
281    if (img == NULL) {
282        printf("img is null\n");
283    }
284
285    Tcl_SetByteArrayObj(Tcl_GetObjResult(interp),
286                        (const unsigned char*)img, bufSize);
287
288    return TCL_OK;
289}
290
291/**********************************************************************/
292// FUNCTION: ReleaseOp()
293/// Clean up memory from an open video in a movie player object
294/**
295 * Close all file handles and free allocated memory associated with an
296 * open video in a movie player object.
297 * Full function call:
298 *
299 * close
300 *
301 */
302static int
303ReleaseOp (ClientData clientData, Tcl_Interp *interp, int objc,
304         Tcl_Obj *const *objv)
305{
306    VideoClose((VideoObj *)clientData);
307
308    Tcl_ResetResult(interp);
309    return TCL_OK;
310}
Note: See TracBrowser for help on using the repository browser.