I am wondering what it would take to get imlist to respect file timestamps.
This may be another way of asking if variable fps is possible.
Here is why:
I was at an hour long presentation with my VGA2USBLR gizmo hooked up to the
projector. I gave up trying to use the v4l interface and used a simple "save
image to file" in a loop:
D=$(date +%H_%M_%S)
./vga2usb s /media/disk/test$D.png
That command normally took about 2 seconds, so 1 second resolution is fine. I
ended up with 1.8gig of images, so much higher res wouldn't be worth it.
I now have 1630 pngs, like this:
-rw-r--r-- 1 root root 1156819 2008-02-14 19:30 test19_30_09.png
-rw-r--r-- 1 root root 1202172 2008-02-14 19:31 test19_31_27.png
...
-rw-r--r-- 1 root root 1592156 2008-02-14 20:37 test20_37_17.png
-rw-r--r-- 1 root root 1698687 2008-02-14 20:37 test20_37_21.png
-rw-r--r-- 1 root root 1572864 2008-02-14 20:37 test20_37_24.png
I put some examples here:
http://dev.personnelware.com/carl/temp/Feb15/a/test20_24_01.png
btw, the presentation was:
Paul Smith - mapping solution from scratch with Mapnik, Django, and OpenLayers.
so almost topical :)
I have an audio track. I want to make a video track. Not sure what format to
use. Size is secondary to quality. Huge is fine, as long as it is needed. I
am expecting a few gig per hour.
I have used transcode -i image_list.txt -x imlist - but here is the problem:
the images were not evenly across time. looking at the times, there are groups
of "quick" (1 second per frame) and groups of "slow" (3 seconds per frame.) (I
am guessing image complexity had something to do with it.) So applying a
constant fps means it will easily drift by 5 or 10 seconds. thus my quest to
get imlist to respect file timestamps.
An easy solution to my current problem would be to write a script that copies
frames to fill in the gaps so that there is one frame per second. but I would
rather hack the code and make it somehow use the file's timestamp.
I have some questions about the code below.
Does MARK_TIME_RANGE set anything? (MARK made me think it did.)
Why the while(0) loop?
Why is there both ptr->video_len and video_size ?
How does anything's timing work? I thought there was something that would keep
the audio and video streams synced, but I don't see how.
Carl K
#define MARK_TIME_RANGE(PTR, VOB) do { \
/* Set skip attribute based on -c */ \
if (fc_time_contains((VOB)->ttime, (PTR)->id)) \
(PTR)->attributes &= ~TC_FRAME_IS_OUT_OF_RANGE; \
else \
(PTR)->attributes |= TC_FRAME_IS_OUT_OF_RANGE; \
} while (0)
/* stage 2: fill the frame with data */
ptr->attributes = 0;
MARK_TIME_RANGE(ptr, vob);
if (verbose >= TC_THREADS)
tc_log_msg(__FILE__, "new video frame registered and marked, now
filling...");
if (video_decdata.fd != NULL) {
if (vbytes && (ret = mfread(ptr->video_buf, vbytes, 1,
video_decdata.fd)) != 1)
ret = -1;
ptr->video_len = vbytes;
ptr->video_size = vbytes;
} else {
import_para.fd = NULL;
import_para.buffer = ptr->video_buf;
import_para.buffer2 = ptr->video_buf2;
import_para.size = vbytes;
import_para.flag = TC_VIDEO;
import_para.attributes = ptr->attributes;
ret = tcv_import(TC_IMPORT_DECODE, &import_para, vob);
ptr->video_len = import_para.size;
ptr->video_size = import_para.size;
ptr->attributes |= import_para.attributes;
}
if (verbose >= TC_THREADS)
tc_log_msg(__FILE__, "new video frame filled (%s)", (ret == -1)
?"FAILED" :"OK");
if (ret < 0) {
if (verbose >= TC_DEBUG)
tc_log_msg(__FILE__, "video data read failed - end of stream");
ptr->video_len = 0;
ptr->video_size = 0;
ptr->attributes = TC_FRAME_IS_END_OF_STREAM;
}
ptr->v_height = vob->im_v_height;
ptr->v_width = vob->im_v_width;
ptr->v_bpp = BPP;
* import_imlist.c
MOD_decode
{
char filename[PATH_MAX+1];
MagickBooleanType status;
if (param->flag == TC_AUDIO) {
return TC_IMPORT_OK;
}
if (param->flag == TC_VIDEO) {
// read a filename from the list
if (fgets(filename, PATH_MAX, fd) == NULL) {
return TC_IMPORT_ERROR;
}
filename[PATH_MAX] = '\0'; /* enforce */
tc_strstrip(filename);
ClearMagickWand(wand);
/*
* This avoids IM to buffer all read images.
* I'm quite sure that this can be done in a smarter way,
* but I haven't yet figured out how. -- FRomani
*/
status = MagickReadImage(wand, filename);
if (status == MagickFalse) {
return TCHandleMagickError(wand);
}
MagickSetLastIterator(wand);
status = MagickGetImagePixels(wand,
0, 0, width, height,
"RGB", CharPixel,
param->buffer);
if (status == MagickFalse) {
return TCHandleMagickError(wand);
}
param->attributes |= TC_FRAME_IS_KEYFRAME;
return TC_IMPORT_OK;