[mythtv-users] Converting MythTV Frame/time to ffmpeg time?
Mark Perkins
perkins1724 at hotmail.com
Mon Jan 25 13:52:48 UTC 2016
> On 25 Jan 2016, at 6:26 pm, Philipp Hahn <pmhahn+mythtv at pmhahn.de> wrote:
>
> Hello,
>
> I have several recordings from DVB-C (Europe/Germany, so PAL with 720p,
> 50Hz) already with H.264, which MythTranscode refuses to cut losslessly.
> I normally start my recordings 2 minutes early and let it record 5
> minutes after the scheduled end to not miss anything.
> I now try to remove those extra seconds to save space. I've then set
> two cut points to cut the beginning and ending.
>
> As MythTranscode refuses to cut H.264 itself (`mythtranscode --mpeg2
> --honorcutlist` errors out with 'no more queue slots' or other error
> messages), it seems I have to do it myself using ffmpeg directly. Bug I
> can't convert the MythTV frame number or time stamp to something ffmpeg
> understand or is exact. There also seems to be different values for the
> end:
>
> # chanid="13120"
> # starttime="20150715225300"
> # mythutil -q --chanid "$chanid" --starttime "$starttime" --getcutlist
> Cutlist: 0-12129,175474-185836
>
> If I open the cut-list editor in the frontend and go to the very end, I
> get a different frame number:
>
> Frame Time
> 1 00:00:021
> 12129 04:02.600
> 175474 58:29.500
> 185776 1:01:55.540
> ^^^^^^ At least the last one is different from the output of
> --getcutlist above?
Based on your sql statements below I think you are seeking by keyframe or time increment (which jumps to nearest keyframe) in the cutlist editor. Press down arrow (up arrow?) until frame increment (not keyframe or time increment) is selected and then right arrow to get to last frame.
>
> If I directly look at the SQL tables, I get yet another set of values:
>
> mysql> SELECT * FROM recordedmarkup WHERE starttime="20150715225300" AND chanid="13120";
> +--------+---------------------+--------+------+---------+
> | chanid | starttime | mark | type | data |
> +--------+---------------------+--------+------+---------+
> | 13120 | 2015-07-15 22:53:00 | 12129 | 0 | NULL |
> 0=MARK_CUT_END
> | 13120 | 2015-07-15 22:53:00 | 1 | 12 | NULL |
> 12=MARK_ASPECT_16_9
> | 13120 | 2015-07-15 22:53:00 | 1 | 30 | 1280 |
> 30=MARK_VIDEO_WIDTH
> | 13120 | 2015-07-15 22:53:00 | 1 | 31 | 720 |
> 31=MARK_VIDEO_HEIGHT
> | 13120 | 2015-07-15 22:53:00 | 1 | 32 | 50000 |
> 32=MARK_VIDEO_RATE: 50 Hz
> | 13120 | 2015-07-15 22:53:00 | 0 | 33 | 3720000 |
> 33=MARK_DURATION_MS: 3729.000s = 1:02:00.000
> | 13120 | 2015-07-15 22:53:00 | 0 | 34 | 185785 |
> 34=MARK_TOTAL_FRAMES: yet another value?
> | 13120 | 2015-07-15 22:53:00 | 0 | -3 | NULL |
> -3=MARK_UPDATED_CUT
> | 13120 | 2015-07-15 22:53:00 | 7014 | 4 | NULL |
> | 13120 | 2015-07-15 22:53:00 | 12126 | 5 | NULL |
> | 13120 | 2015-07-15 22:53:00 | 175468 | 4 | NULL |
> | 13120 | 2015-07-15 22:53:00 | 186260 | 5 | NULL |
> 4=MARK_COMM_START
> 5=MARK_COMM_END
> | 13120 | 2015-07-15 22:53:00 | 175474 | 1 | NULL |
> 1=MARK_CUT_START
> +--------+---------------------+--------+------+---------+
> 13 rows in set (0.00 sec)
>
IMO the numbers are consistent. If the first cut mark is an end mark it cuts every frame to that point. If the last cut mark is a start mark it cuts every frame after. Mark type 0 is 12129 and mark type 1 is 175474 as expected from your cutlist editor.
>
> mysql> SELECT * FROM recordedseek WHERE starttime="20150715225300" AND chanid="13120" LIMIT 0,10;
Recordedseek table holds list of key frames, not list of frames. This sql query doesn't get to the keyframes around the first cut mark but your first cut point is not on a keyframe anyway (I'm guessing because from your sql your initial keyframes are 32 frames apart and your first cut is an odd numbered frame. But just a guess can't tell for certain).
> +--------+---------------------+------+---------+------+
> | chanid | starttime | mark | offset | type |
> +--------+---------------------+------+---------+------+
> | 13120 | 2015-07-15 22:53:00 | 0 | 0 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 32 | 378444 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 64 | 622092 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 100 | 940752 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 136 | 1305096 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 168 | 1673952 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 200 | 2103156 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 232 | 2615456 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 264 | 3061580 | 9 |
> | 13120 | 2015-07-15 22:53:00 | 296 | 3604336 | 9 |
> +--------+---------------------+------+---------+------+
> 10 rows in set (0.01 sec)
> mysql> SELECT * FROM recordedseek WHERE starttime="20150715225300" AND chanid="13120" LIMIT 11480,10;
> +--------+---------------------+--------+---------+------+
> | chanid | starttime | mark | offset | type |
> +--------+---------------------+--------+---------+------+
> | 13120 | 2015-07-15 22:53:00 | 185744 | 3714900 | 33 |
> | 13120 | 2015-07-15 22:53:00 | 185776 | 3715540 | 33 |
> +--------+---------------------+--------+---------+------+
> 2 rows in set (0.02 sec)
>
This shows the last keyframe, frame 185776. But not the key frames around your last cut mark (frame 175474 which may not be a keyframe either, at a guess).
>
> So how does one convert the MythTV values to something I can pass to
> ffmpeg to get the exact cut points?
> My tries with frame * 1s/50 have failed so far, which leads to the
> output file to still start with some frames before or after the exact
> frame, etc.
>
At a guess ffmpeg may only cut on keyframes (unless you also transcode but I'm guessing you are just copying the audio / video codecs not transcoding) and your first cut mark is potentially not a keyframe.
You might be able to try mythtranscode in fifo mode, see the wiki for a script that may serve as a starting point. Not sure if it is frame accurate or keyframe accurate but should work.
> Thanks in advance.
> Philipp
> --
> / / (_)__ __ ____ __ Philipp Hahn
> / /__/ / _ \/ // /\ \/ /
> /____/_/_//_/\_,_/ /_/\_\ pmhahn at pmhahn.de
> _______________________________________________
More information about the mythtv-users
mailing list