ivan16luis / javacv

Automatically exported from code.google.com/p/javacv
GNU General Public License v2.0
0 stars 0 forks source link

FFmpegFrameGrabber pst\framerate logic #151

Closed GoogleCodeExporter closed 9 years ago

GoogleCodeExporter commented 9 years ago
here:
http://code.google.com/p/javacv/source/browse/trunk/javacv/src/com/googlecode/ja
vacv/FFmpegFrameGrabber.java#328

the code:
=======================
                LongPointer opaque = new LongPointer(pFrame.opaque());
                if (packet.dts() != AV_NOPTS_VALUE) {
                    pts = packet.dts();
                } else if (!opaque.isNull() && opaque.get() != AV_NOPTS_VALUE) {
                    pts = opaque.get();
                } else {
                    pts = 0;
                }
                AVRational time_base = pStream.time_base();
                pts = 1000*pts*time_base.num()/time_base.den();
=======================
seems have no sense. in c/c++ example here 
http://dranger.com/ffmpeg/tutorial05.html pFrame.opaque() used tricky. it's 
stores starting packet pts with custom callback functions get_buffer(...), see 
"Coding it: getting the frame PTS" chapter of those tutorial.

also, here 
http://code.google.com/p/javacv/source/browse/trunk/javacv/src/com/googlecode/ja
vacv/FFmpegFrameGrabber.java#146
function name is "getFrameRate()" but actually it's return flipped timebase.

Original issue reported on code.google.com by aleksey....@gmail.com on 8 Feb 2012 at 3:59

GoogleCodeExporter commented 9 years ago
I don't remember exactly where I read about this opaque thing, and I don't know 
for sure if it's working.. If you have a patch to make it better, please attach 
it to this issue, thank you

As for the frame rate, it is the inverse of the time base. Just inverse it back 
if you wish to have the time base: "We can convert this value to seconds by 
dividing by the framerate. The time_base value of the stream is going to be 
1/framerate (for fixed-fps content), so to get the PTS in seconds, we multiply 
by the time_base. " - http://dranger.com/ffmpeg/tutorial05.html

Original comment by samuel.a...@gmail.com on 8 Feb 2012 at 10:05

GoogleCodeExporter commented 9 years ago
as i wrote before, this code is from http://dranger.com/ffmpeg/tutorial05.html
there, it's used to get pts from callback thougth pFrame.opaque());
since we can't assing java function like 
pcodecCtx.get_buffer(pointer_to_our_get_buffer_java_function) like it's done 
there: codecCtx->get_buffer = our_get_buffer; it's useless. pFrame.opaque() 
itself have no connection to timing.
so, we only can have pts = packet.dts(); with hope pakets have dts. it's 
common, they haven't.

FRAMERATE!

look, for standart mpeg2 ntsc file:
Input #0, mpeg, from 'd:\incoming\dva-yaitsa.mpg':
  Duration: 00:17:08.85, start: 0.250000, bitrate: 7051 kb/s
    Stream #0.0[0x1e0]: Video: mpeg2video (Main), yuv420p, 720x480 [PAR 8:9 DAR
4:3], 9500 kb/s, 29.97 fps, 29.97 tbr, 90k tbn, 59.94 tbc
    Stream #0.1[0x1c0]: Audio: mp2, 48000 Hz, stereo, s16, 224 kb/s

we can see:
codec  timebase:1001/60000
stream timebase:1/90000
stream framerat:30000/1001

with code:
        System.out.format("codec  timebase:%d/%d%n",pCodecCtx.time_base().num(), pCodecCtx.time_base().den());
        System.out.format("stream timebase:%d/%d%n",pStream.time_base().num(), pStream.time_base().den());

        System.out.format("stream framerat:%d/%d%n",pStream.r_frame_rate().num(), pStream.r_frame_rate().den());

Original comment by aleksey....@gmail.com on 8 Feb 2012 at 11:13

GoogleCodeExporter commented 9 years ago
Yes, we can do callbacks from C to Java, but they are expensive, so I don't 
think it would be appropriate to impose this overhead on users who may or may 
not be interested in PTS values. Do you have an alternative in mind?

As for the frame rate, I get that, to return the expected value, getFrameRate() 
should be returning pStream.r_frame_rate().num()/pStream.r_frame_rate().den() ? 
I'll be fixing that then, thanks!

Original comment by samuel.a...@gmail.com on 8 Feb 2012 at 11:31

GoogleCodeExporter commented 9 years ago
paket.dts() is valid for all common video i already test for now. so i think 
it's ok to use. the one needs callback trick, can reimpliment grabber.
how to do such callback, by the way?
also, if your natives based on 0.7(0.6) branch, maybe it's better to use 
lastest 0.7.11 "Peace"(2012-01-12) instead old 0.7.1 ?

Original comment by aleksey....@gmail.com on 8 Feb 2012 at 1:53

GoogleCodeExporter commented 9 years ago
It seems what I was trying to do with the opaque field changed to the 
reordered_opaque field at some point, e.g.:
http://libav-users.943685.n4.nabble.com/Purpose-of-reordered-opaque-td943839.htm
l
Does the callback-less voodoo in ffplay.c look good to you? If so, I guess I'll 
be changing/fixing that too..

Here's one example of a callback:
http://code.google.com/p/javacv/source/browse/trunk/procamcalib/src/com/googleco
de/javacv/procamcalib/MainFrame.java#182

If you have some compiled binaries of FFmpeg 0.7.11 for Windows x86 and x86_64, 
let me know. I'll be happy to link against those!

Original comment by samuel.a...@gmail.com on 9 Feb 2012 at 6:14

GoogleCodeExporter commented 9 years ago
can't guarantie it's the best way but i think ffplay is good enought to follow.
oh, right, still no win binaries.

Original comment by aleksey....@gmail.com on 9 Feb 2012 at 5:37

GoogleCodeExporter commented 9 years ago
I have adjusted all this in the latest release, thanks for the report!

Original comment by samuel.a...@gmail.com on 18 Feb 2012 at 2:17