Opened 5 years ago
Last modified 6 months ago
#8338 new enhancement
GoPro metadata not properly handled
Reported by: | importon | Owned by: | |
---|---|---|---|
Priority: | wish | Component: | avformat |
Version: | git-master | Keywords: | mov GPMF TMCD |
Cc: | bertmcintosh@gmail.com, MasterQuestionable | Blocked By: | |
Blocking: | Reproduced by developer: | no | |
Analyzed by developer: | no |
Description
Summary of the bug: I'm trying to swap out the video track of a GoPro mp4 file (0.mp4) with another (1.mp4) while keeping all the GPMF metadata in the 1st GoPro file. It results in error message "[mp4 @ 000002a357fdef40] Could not find tag for codec none in stream #2, codec not currently supported in container Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument Stream mapping: Stream #0:0 -> #0:0 (copy) Stream #0:1 -> #0:1 (copy) Stream #0:2 -> #0:2 (copy) Stream #0:3 -> #0:3 (copy) Stream #0:4 -> #0:4 (copy)"
How to reproduce:
ffmpeg -i 0.MP4 -i 1.mp4 -map_metadata 0 -map 0 -movflags use_metadata_tags -c copy -copy_unknown GHO10772mux.MP4
Patches should be submitted to the ffmpeg-devel mailing list and not this bug tracker.
Change History (25)
comment:1 by , 5 years ago
Priority: | normal → important |
---|
comment:2 by , 5 years ago
Cc: | added |
---|
comment:3 by , 5 years ago
Keywords: | metadata gopro removed |
---|---|
Priority: | important → normal |
comment:4 by , 5 years ago
Thanks for the follow up.
I can't make my sample files small enough(2.5mb)to attach them so please grab them from here.
https://drive.google.com/drive/folders/1Sow7A_Wz_K4Ug-2RwX3YAqCAlAEDia2J?usp=sharing
I upgraded to ffmpeg version 20191028-68f623d and ran the following with the results below.
ffmpeg -i 0.MP4 -i 1.mp4 -map_metadata 0 -map 0 -movflags use_metadata_tags -c copy -copy_unknown 01mux.mp4
ffmpeg version N-92498-g77bf85515e Copyright (c) 2000-2018 the FFmpeg developers
built with gcc 8.2.1 (GCC) 20181017
configuration: --enable-gpl --enable-version3 --enable-sdl2 --enable-fontconfig --enable-gnutls --enable-iconv --enable-libass --enable-libbluray --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libopus --enable-libshine --enable-libsnappy --enable-libsoxr --enable-libtheora --enable-libtwolame --enable-libvpx --enable-libwavpack --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libzimg --enable-lzma --enable-zlib --enable-gmp --enable-libvidstab --enable-libvorbis --enable-libvo-amrwbenc --enable-libmysofa --enable-libspeex --enable-libxvid --enable-libaom --enable-libmfx --enable-amf --enable-ffnvcodec --enable-cuvid --enable-d3d11va --enable-nvenc --enable-nvdec --enable-dxva2 --enable-avisynth
libavutil 56. 23.101 / 56. 23.101
libavcodec 58. 39.100 / 58. 39.100
libavformat 58. 22.100 / 58. 22.100
libavdevice 58. 6.100 / 58. 6.100
libavfilter 7. 46.100 / 7. 46.100
libswscale 5. 4.100 / 5. 4.100
libswresample 3. 4.100 / 3. 4.100
libpostproc 55. 4.100 / 55. 4.100
[mov,mp4,m4a,3gp,3g2,mj2 @ 000001c2556aa6c0] Using non-standard frame rate 59/1
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '0.MP4':
Metadata:
major_brand : mp41
minor_version : 538120216
compatible_brands: mp41
creation_time : 2019-05-03T16:55:07.000000Z
firmware : HD6.01.01.60.00
Duration: 00:00:06.42, start: 0.000000, bitrate: 47516 kb/s
Stream #0:0(eng): Video: h264 (High) (avc1 / 0x31637661), yuvj420p(pc, bt709), 1920x1080 [SAR 1:1 DAR 16:9], 47337 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
Metadata:
creation_time : 2019-05-03T16:55:07.000000Z
handler_name : GoPro AVC
encoder : GoPro AVC encoder
timecode : 17:11:17:56
Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 188 kb/s (default)
Metadata:
creation_time : 2019-05-03T16:55:07.000000Z
handler_name : GoPro AAC
timecode : 17:11:17:56
Stream #0:2(eng): Data: none (tmcd / 0x64636D74), 0 kb/s (default)
Metadata:
creation_time : 2019-05-03T16:55:07.000000Z
handler_name : GoPro TCD
timecode : 17:11:17:56
Stream #0:3(eng): Data: bin_data (gpmd / 0x646D7067), 37 kb/s (default)
Metadata:
creation_time : 2019-05-03T16:55:07.000000Z
handler_name : GoPro MET
Stream #0:4(eng): Data: none (fdsc / 0x63736466), 14 kb/s (default)
Metadata:
creation_time : 2019-05-03T16:55:07.000000Z
handler_name : GoPro SOS
Input #1, mov,mp4,m4a,3gp,3g2,mj2, from '1.mp4':
Metadata:
major_brand : isom
minor_version : 512
compatible_brands: isomiso2avc1mp41
encoder : Lavf58.22.100
Duration: 00:00:06.42, start: 0.000000, bitrate: 101923 kb/s
Stream #1:0(eng): Video: h264 (High 4:4:4 Predictive) (avc1 / 0x31637661), yuv444p, 1920x1080 [SAR 1:1 DAR 16:9], 101967 kb/s, 59.94 fps, 59.94 tbr, 60k tbn, 119.88 tbc (default)
Metadata:
handler_name : GoPro AVC
timecode : 17:11:17:56
Stream #1:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 188 kb/s (default)
Metadata:
handler_name : GoPro AAC
Stream #1:2(eng): Data: none (tmcd / 0x64636D74), 0 kb/s
Metadata:
handler_name : GoPro AVC
timecode : 17:11:17:56
[mp4 @ 000001c2556aef00] You requested a copy of the original timecode track so timecode metadata are now ignored
[mp4 @ 000001c2556aef00] Could not find tag for codec none in stream #2, codec not currently supported in container
Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument
Stream mapping:
Stream #0:0 -> #0:0 (copy)
Stream #0:1 -> #0:1 (copy)
Stream #0:2 -> #0:2 (copy)
Stream #0:3 -> #0:3 (copy)
Stream #0:4 -> #0:4 (copy)
Last message repeated 1 times
comment:5 by , 5 years ago
Component: | undetermined → avformat |
---|---|
Keywords: | mov added |
Priority: | normal → wish |
Type: | defect → enhancement |
Version: | unspecified → git-master |
I believe the following works as expected:
ffmpeg -i 0.MP4 -c copy -map 0:v -map 0:a -map 0:3 out.mp4
The fdsc
tag is unsupported afaict.
comment:6 by , 5 years ago
Thanks again for looking into this.
Unfortunately that does not copy all the GPMF metadata over. Is there anything in the works to handle GoPro GPMF data? More info here https://github.com/gopro/gpmf-parser.
comment:7 by , 5 years ago
Cc: | added |
---|
comment:8 by , 5 years ago
Cc: | removed |
---|
follow-up: 10 comment:9 by , 4 years ago
Hi. I just wanted to follow up on this. I got a similar error when trying to cut an .mp4 GoPro video with an app that relies on FFmpeg. According to the developer, "it seems that FFmpeg tries to process the data streams and fails to write that 'none' tag".
Here's the original issue so you can see the context: https://gitlab.gnome.org/YaLTeR/video-trimmer/-/issues/22
comment:10 by , 4 years ago
Replying to eldelacajita:
Hi. I just wanted to follow up on this. I got a similar error when trying to cut an .mp4 GoPro video with an app that relies on FFmpeg. According to the developer, "it seems that FFmpeg tries to process the data streams and fails to write that 'none' tag".
Here's the original issue so you can see the context: https://gitlab.gnome.org/YaLTeR/video-trimmer/-/issues/22
If this is the case, would this be considered a bug that might be escalated to possibly being fixed? How does that process work?
comment:11 by , 4 years ago
Any solution to this? - I tried:
ffmpeg -i 0.MP4 -c copy -map 0:v -map 0:a -map 0:3 out.mp4
But I get 4 steams in my output file instead of 5 in the original.
if I change to -map 0:4 it says:
$ ffmpeg -i GX010804\ NEW.MP4 -c copy -map 0:v -map 0:a -map 0:4 -y out.mp4 ffmpeg version 4.4 Copyright (c) 2000-2021 the FFmpeg developers built with Apple clang version 12.0.5 (clang-1205.0.22.9) configuration: --prefix=/opt/homebrew/Cellar/ffmpeg/4.4_2 --enable-shared --enable-pthreads --enable-version3 --cc=clang --host-cflags= --host-ldflags= --enable-ffplay --enable-gnutls --enable-gpl --enable-libaom --enable-libbluray --enable-libdav1d --enable-libmp3lame --enable-libopus --enable-librav1e --enable-librubberband --enable-libsnappy --enable-libsrt --enable-libtesseract --enable-libtheora --enable-libvidstab --enable-libvorbis --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libxvid --enable-lzma --enable-libfontconfig --enable-libfreetype --enable-frei0r --enable-libass --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-libspeex --enable-libsoxr --enable-libzmq --enable-libzimg --disable-libjack --disable-indev=jack --enable-avresample --enable-videotoolbox libavutil 56. 70.100 / 56. 70.100 libavcodec 58.134.100 / 58.134.100 libavformat 58. 76.100 / 58. 76.100 libavdevice 58. 13.100 / 58. 13.100 libavfilter 7.110.100 / 7.110.100 libavresample 4. 0. 0 / 4. 0. 0 libswscale 5. 9.100 / 5. 9.100 libswresample 3. 9.100 / 3. 9.100 libpostproc 55. 9.100 / 55. 9.100 Input #0, mov,mp4,m4a,3gp,3g2,mj2, from 'GX010804 NEW.MP4': Metadata: major_brand : mp41 minor_version : 538120216 compatible_brands: mp41 creation_time : 2021-04-24T16:42:06.000000Z firmware : HD8.01.02.50.00 Duration: 00:05:09.96, start: 0.000000, bitrate: 60283 kb/s Stream #0:0(eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 60022 kb/s, 50 fps, 50 tbr, 90k tbn, 50 tbc (default) Metadata: creation_time : 2021-04-24T16:42:06.000000Z handler_name : GoPro H.265 vendor_id : [0][0][0][0] encoder : GoPro H.265 encoder timecode : 16:42:06:19 Stream #0:1(eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default) Metadata: creation_time : 2021-04-24T16:42:06.000000Z handler_name : GoPro AAC vendor_id : [0][0][0][0] timecode : 16:42:06:19 Stream #0:2(eng): Data: none (tmcd / 0x64636D74) (default) Metadata: creation_time : 2021-04-24T16:42:06.000000Z handler_name : GoPro TCD timecode : 16:42:06:19 Stream #0:3(eng): Data: bin_data (gpmd / 0x646D7067), 45 kb/s (default) Metadata: creation_time : 2021-04-24T16:42:06.000000Z handler_name : GoPro MET Stream #0:4(eng): Data: none (fdsc / 0x63736466), 12 kb/s (default) Metadata: creation_time : 2021-04-24T16:42:06.000000Z handler_name : GoPro SOS [mp4 @ 0x12d81d000] Could not find tag for codec none in stream #2, codec not currently supported in container Could not write header for output file #0 (incorrect codec parameters ?): Invalid argument Error initializing output stream 0:2 -- Stream mapping: Stream #0:0 -> #0:0 (copy) Stream #0:1 -> #0:1 (copy) Stream #0:4 -> #0:2 (copy) Last message repeated 1 times ``` Any solution to this?
comment:13 by , 2 years ago
I tested the latest version of FFmpeg and this issue still occurs, ffmpeg refuses to copy the GPMD metadata stream with the same error message "Could not find tag for codec none in stream #2, codec not currently supported in container" when working with MP4 files.
I can copy such a GoPro stream to other file formats (TS or MOV, for example) just fine, but that doesn't help me if I need to edit the original MP4 files coming from a GoPro camera.
I have also not found any other MP4 editing tool that can work with these files - but I can't imagine just having write support for that raw binary type could be that hard. FFmpeg already properly detects it and can extract it from a video, it just can't add it back to a video.
Is there any chance of FFmpeg getting support for writing GoPro metadata to an MP4 file?
Also, I'd agree with the statement in comment 10 that this should be a bug, not a feature request.
comment:14 by , 9 months ago
Have you been able to find a workaround? I'm having the same issue with ffmpeg 6.1.1 and I'd like to keep gopro data in the MP4 file.
Thanks
comment:15 by , 6 months ago
I have not found any workarounds for this problem.
copy_unknown
, forcing a tag with tag:d:0
, disabling write_tmcd
(because this is the stream with which we are having issues with), none helps.
There is a mention of this issue (https://superuser.com/a/1488253) not existing in an old version of ffmpeg tagged 4.0.2
. But with my goal being re-encoding of the video stream into high quality HEVC, I see no reason in messing around with compilation of incompatible software.
I see a solution in adding a handler for this timecode stream into ffmpeg, or making it possible to copy data without known type (?codec?) tag, with copy_unknown
.
I am looking into the code to find interesting diffs that caused the missing type tag fail the copy, but as someone not well acquainted with coding software like ffmpeg, I wouldn't hold my hopes up.
comment:16 by , 6 months ago
I have seeked information on difference in code, between reported difference in handling the tmcd stream, by versions 4.0.2
& 4.2.1
with 4.2.1
, being a version reporting the error Could not find tag for codec %s in stream #%d, codec not currently supported in container
.
This error string is generated by code in libavformat/movenc.c
. Diffing 4.2.1
with 4.0.2
reveals to me:
- In commit
981178f3b0b547a228804ff36641b2237eb75a16
streams withgpmd
tag have been permitted into the MP4 container, as "GoPro Binary Data". (This is the stream which is detected by ffprobe and doesn't report any issues when copy is attempted) tmcd
stream appears often associated with the .mov container and attempting to repackage the streams into .mov passes without issues.
Compared original .mp4 file
Duration: 00:01:31.69, start: 0.000000, bitrate: 44716 kb/s Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 44456 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro H.265 vendor_id : [0][0][0][0] encoder : GoPro H.265 encoder timecode : 11:07:03:02 Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro AAC vendor_id : [0][0][0][0] timecode : 11:07:03:02 Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro TCD timecode : 11:07:03:02 Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 52 kb/s (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro MET
With .mov file in which only video stream should have been altered.
Duration: 00:01:31.69, start: 0.000000, bitrate: 10166 kb/s Stream #0:0[0x1](eng): Video: hevc (Main) (hvc1 / 0x31637668), yuvj420p(pc, bt709, progressive), 3840x2160 [SAR 1:1 DAR 16:9], 9915 kb/s, 29.97 fps, 29.97 tbr, 30k tbn (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro H.265 vendor_id : FFMP encoder : Lavc61.3.100 hevc_nvenc timecode : 11:07:03:02 Stream #0:1[0x2](eng): Audio: aac (LC) (mp4a / 0x6134706D), 48000 Hz, stereo, fltp, 189 kb/s (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro AAC vendor_id : [0][0][0][0] Stream #0:2[0x3](eng): Data: none (tmcd / 0x64636D74) (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro TCD timecode : 11:07:03:02 Stream #0:3[0x4](eng): Data: bin_data (gpmd / 0x646D7067), 52 kb/s (default) Metadata: creation_time : 2024-03-09T11:07:43.000000Z handler_name : GoPro MET
comment:17 by , 6 months ago
On v4.0.2, the error is thrown when no track->par->codec_tag
is found. For both .mov & .mp4 format.
The codec_tag is read in mov_find_codec_tag(s, track)
function, with .mov going down to sub-function mov_get_codec_tag(s, track)
, where the same codec_tag
parameter is read in case of unidentifiable codec.
In the branch where v4.2.1 has been released, a validate_codec_tag
function has been introduced. It is not ran when MODE is set to MOV, but is executed for MODE of MP4 files.
The validate_codec_tag
only does a simple check if the codec_tag or id exists in the white tables.
As I see the timecode track being a feature exclusive to Apple QuickTime & MOV container. I don't see any reason for it to receive preferential treatment.
But, I also don't see a reason for it to not be allowed a copy, if it already exists in the container and user explicitly accepts the risks with the copy_unknown
flag.
So, I propose adoption of copy_unknown
flag into the validate_codec_tag
, where validation this validation is skipped and the stream is copied, just like in the case of MOV container. I'll attempt to make a valid commit for this change.
comment:18 by , 6 months ago
Cc: | added |
---|
͏ Such practice is alike the embedded subtitle streams... thus the serious failure.
͏ https://github.com/gopro/gpmf-parser#gpmf-introduction
͏ Essentially an issue regarding the whole container structure current.
comment:19 by , 6 months ago
I am not sure if I understand you correctly @MasterQuestionable, but GPMF
is handled correctly.
It is the TMCD
stream which is not part of the MP4 container, but of QuickTime & MOV container. GoPro includes this stream anyway. For ?some?, hopefully, valid reason.
comment:20 by , 6 months ago
Keywords: | GPMF TMCD added |
---|---|
Summary: | can't copy GoPro metadata → GoPro metadata not properly handled |
͏ See also: https://github.com/MasterInQuestion/talk/discussions/3#discussioncomment-9376594
͏ The problem is that metadata self tends to be non-interoperable:
͏ At best mostly useless. (generally data ignorable: i.e. ideally removed as optimization)
͏ At times causes problems... (bug, side-channel of unintended information)
comment:21 by , 6 months ago
I am not sure how we got from copying data streams between identical containers, to considering "ideal media container format", but I can not say it is not interesting.
From related information, I have figured out how to build statically linked FFMPEG binary on one of my servers (4G of RAM and limited storage being the biggest issues). It does take a while + my 500kb/s internet does not help in syphoning out a 140MB file.
Thus, hopefully, the tiny change I have introduced, is going to fulfil the task of permitting copy of the damn TMCD stream in GoPro files, so I can start re-encoding the ever growing GoPro footage library.
comment:22 by , 6 months ago
I have tested the workaround and am experiencing no issues. Right now, sucessfuly re-encoding, N-th video.
Here is a release for anyone interested in playing with their GoPro footage (in my case re-encoding into more condensed H265)
https://github.com/HighPriest/FFmpeg/releases/tag/Temp_GoPro_Workaround
The workaround IS NOT SAFE FOR PRODUCTION, as it is essentially skipping codec_validation
function present in remuxer code.
The skip happens only for streams with unknown codec_tag, which shouldn't be mapped by ffmpeg anyway, if copy_unknown flag is not set. But I am only speculating based on my findings from one day.
comment:23 by , 6 months ago
͏ How serious is the issue concerning contemporary GoPro?
͏ Recognized typical streams should be still properly handled..?
͏ Is keeping only the video, audio (via ͏"-map") adequately working for you?
͏ [ Quote Master ? @ CE 2024-03-18 13:18:03 UTC:
https://bugzilla.mozilla.org/show_bug.cgi?id=1860417#c29
͏ "outside the scope"...
͏ 不识 庐山 真面目: 只缘身在此山中.
+͏ Unable to tell Lú Mountain's true look: For self already in the mountain.
͏ .
͏ At many times the real problem is indeed "outside the scope". ]
follow-up: 25 comment:24 by , 6 months ago
͏ Does comment:16 mean "-copy_unknown" doesn't just copy unknown and failed saying "unsupported" in current FFmpeg?
comment:25 by , 6 months ago
Replying to MasterQuestionable:
͏ Does comment:16 mean "-copy_unknown" doesn't just copy unknown and failed saying "unsupported" in current FFmpeg?
Precisely. The FFmpeg_opts code handles the copy just fine (although, looking at the code, I don't see the copy_unknown
option doing much). The streams we just want to copy, appear in the preview of output file structure.
But the re-muxing code present in movenc.c doesn't have any information about the copy_unknown
option being set, so the codec validation code throws an error that the codec tag of the stream we want to copy is... unknown. This validation is not executed for .mov files, so you can do the copy and repackaging into MOV format just fine.
In general, swapping is not possible because
ffmpeg
is a transcoding tool, not a file editor.Please test current FFmpeg git head and provide the command line you tested together with the complete, uncut console output and a short input sample to make this a valid ticket.