
Recherche avancée
Autres articles (49)
-
La file d’attente de SPIPmotion
28 novembre 2010, parUne file d’attente stockée dans la base de donnée
Lors de son installation, SPIPmotion crée une nouvelle table dans la base de donnée intitulée spip_spipmotion_attentes.
Cette nouvelle table est constituée des champs suivants : id_spipmotion_attente, l’identifiant numérique unique de la tâche à traiter ; id_document, l’identifiant numérique du document original à encoder ; id_objet l’identifiant unique de l’objet auquel le document encodé devra être attaché automatiquement ; objet, le type d’objet auquel (...) -
Les vidéos
21 avril 2011, parComme les documents de type "audio", Mediaspip affiche dans la mesure du possible les vidéos grâce à la balise html5 .
Un des inconvénients de cette balise est qu’elle n’est pas reconnue correctement par certains navigateurs (Internet Explorer pour ne pas le nommer) et que chaque navigateur ne gère en natif que certains formats de vidéos.
Son avantage principal quant à lui est de bénéficier de la prise en charge native de vidéos dans les navigateur et donc de se passer de l’utilisation de Flash et (...) -
Personnaliser en ajoutant son logo, sa bannière ou son image de fond
5 septembre 2013, parCertains thèmes prennent en compte trois éléments de personnalisation : l’ajout d’un logo ; l’ajout d’une bannière l’ajout d’une image de fond ;
Sur d’autres sites (6183)
-
FFMPEG : i need audio channels 7 & 8 to be the main audio track for a video
10 avril 2013, par lo_fyeI have a video with 8 channels of audio.
I need tracks 7 (Left Stereo) and 8 (Right Stereo) to be the audio for the video (which I'm converting to flv).
I've tried playing with
-filter_complex
and thejoin
,amix
, andamerge
filters, as well as the-map
parameter, but I can't seem to find the right combination of values :-/Output :
/usr/local/bin/ffmpeg-1.0/bin/ffmpeg -i '/folder/video_name.mov' -f 'flv' \
-s '320x240' -b '250k' -aspect '4:3' -ac 1 -ab '64k' -ar '22050' -y \
/folder/video_name.flv
ffmpeg version N-46241-g09ea482 Copyright (c) 2000-2012 the FFmpeg developers
built on Nov 5 2012 07:33:09 with gcc 4.1.2 (GCC) 20080704 (Red Hat 4.1.2-46)
configuration: --prefix=/usr/local/bin/ffmpeg-1.0
libavutil 52. 1.100 / 52. 1.100
libavcodec 54. 70.100 / 54. 70.100
libavformat 54. 35.100 / 54. 35.100
libavdevice 54. 3.100 / 54. 3.100
libavfilter 3. 21.105 / 3. 21.105
libswscale 2. 1.101 / 2. 1.101
libswresample 0. 16.100 / 0. 16.100
Guessed Channel Layout for Input Stream #0.1 : mono
Guessed Channel Layout for Input Stream #0.2 : mono
Guessed Channel Layout for Input Stream #0.3 : mono
Guessed Channel Layout for Input Stream #0.4 : mono
Guessed Channel Layout for Input Stream #0.5 : mono
Guessed Channel Layout for Input Stream #0.6 : mono
Guessed Channel Layout for Input Stream #0.7 : mono
Guessed Channel Layout for Input Stream #0.8 : mono
Guessed Channel Layout for Input Stream #0.9 : mono
Guessed Channel Layout for Input Stream #0.10 : mono
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/folder/video_name.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2013-04-03 19:45:26
Duration: 00:00:39.03, start: 0.000000, bitrate: 122149 kb/s
Stream #0:0(eng): Video: prores (apch / 0x68637061), yuv422p10le, 1920x1080, 110585 kb/s, SAR 1:1 DAR 16:9, 23.98 fps, 23.98 tbr, 23976 tbn, 23976 tbc
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
timecode : 00:59:53:00
Stream #0:1(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:2(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:3(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:4(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:5(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:6(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:7(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:8(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:9(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:10(eng): Audio: pcm_s24le (in24 / 0x34326E69), 48000 Hz, mono, s32, 1152 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream #0:11(eng): Data: none (tmcd / 0x64636D74)
Metadata:
creation_time : 2013-04-03 19:45:30
handler_name : Apple Alias Data Handler
timecode : 00:59:53:00
Please use -b:a or -b:v, -b is ambiguous
Output #0, flv, to '/folder/video_name.flv':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
encoder : Lavf54.35.100
Stream #0:0(eng): Video: flv1 ([2][0][0][0] / 0x0002), yuv420p, 320x240 [SAR 1:1 DAR 4:3], q=2-31, 250 kb/s, 1k tbn, 23.98 tbc
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
timecode : 00:59:53:00
Stream #0:1(eng): Audio: adpcm_swf ([1][0][0][0] / 0x0001), 22050 Hz, mono, s16, 88 kb/s
Metadata:
creation_time : 2013-04-03 19:45:26
handler_name : Apple Alias Data Handler
Stream mapping:
Stream #0:0 -> #0:0 (prores -> flv)
Stream #0:1 -> #0:1 (pcm_s24le -> adpcm_swf)
Press [q] to stop, [?] for help
frame= 33 fps=0.0 q=2.0 size= 108kB time=00:00:01.99 bitrate= 442.4kbits/s
frame= 66 fps= 65 q=2.0 size= 225kB time=00:00:02.97 bitrate= 619.0kbits/s
frame= 99 fps= 65 q=2.0 size= 341kB time=00:00:04.96 bitrate= 561.8kbits/s
frame= 136 fps= 67 q=2.0 size= 400kB time=00:00:05.99 bitrate= 547.5kbits/s
frame= 177 fps= 70 q=3.0 size= 482kB time=00:00:07.98 bitrate= 494.3kbits/s
frame= 210 fps= 69 q=3.7 size= 590kB time=00:00:08.96 bitrate= 539.7kbits/s
frame= 240 fps= 68 q=6.3 size= 660kB time=00:00:10.01 bitrate= 539.7kbits/s
frame= 264 fps= 65 q=6.7 size= 719kB time=00:00:11.01 bitrate= 535.2kbits/s
frame= 288 fps= 63 q=8.4 size= 772kB time=00:00:12.02 bitrate= 526.1kbits/s
frame= 312 fps= 62 q=15.4 size= 829kB time=00:00:13.65 bitrate= 497.4kbits/s
frame= 336 fps= 60 q=10.4 size= 875kB time=00:00:14.02 bitrate= 511.1kbits/s
frame= 360 fps= 59 q=10.6 size= 916kB time=00:00:15.01 bitrate= 499.9kbits/s
frame= 383 fps= 58 q=17.8 size= 957kB time=00:00:15.97 bitrate= 490.6kbits/s
frame= 411 fps= 58 q=6.5 size= 1008kB time=00:00:17.97 bitrate= 459.3kbits/s
frame= 437 fps= 57 q=9.7 size= 1046kB time=00:00:18.99 bitrate= 451.3kbits/s
frame= 460 fps= 57 q=7.7 size= 1086kB time=00:00:20.01 bitrate= 444.6kbits/s
frame= 489 fps= 57 q=11.3 size= 1144kB time=00:00:20.99 bitrate= 446.3kbits/s
frame= 512 fps= 56 q=10.3 size= 1182kB time=00:00:22.01 bitrate= 439.8kbits/s
frame= 535 fps= 55 q=21.5 size= 1225kB time=00:00:22.98 bitrate= 436.7kbits/s
frame= 564 fps= 55 q=18.3 size= 1280kB time=00:00:24.00 bitrate= 436.8kbits/s
frame= 587 fps= 55 q=8.5 size= 1311kB time=00:00:24.98 bitrate= 429.7kbits/s
frame= 610 fps= 54 q=11.9 size= 1349kB time=00:00:26.00 bitrate= 424.9kbits/s
frame= 636 fps= 54 q=7.5 size= 1383kB time=00:00:26.98 bitrate= 419.8kbits/s
frame= 659 fps= 54 q=9.6 size= 1421kB time=00:00:28.00 bitrate= 415.6kbits/s
frame= 683 fps= 54 q=20.0 size= 1471kB time=00:00:29.02 bitrate= 415.1kbits/s
frame= 711 fps= 54 q=6.4 size= 1518kB time=00:00:30.00 bitrate= 414.5kbits/s
frame= 742 fps= 54 q=6.2 size= 1558kB time=00:00:31.02 bitrate= 411.5kbits/s
frame= 774 fps= 54 q=2.5 size= 1601kB time=00:00:33.01 bitrate= 397.1kbits/s
frame= 816 fps= 55 q=2.0 size= 1632kB time=00:00:34.50 bitrate= 387.6kbits/s
frame= 861 fps= 56 q=2.0 size= 1670kB time=00:00:35.99 bitrate= 380.1kbits/s
frame= 905 fps= 57 q=2.0 size= 1706kB time=00:00:38.03 bitrate= 367.4kbits/s
frame= 936 fps= 58 q=2.0 Lsize= 1730kB time=00:00:39.05 bitrate= 362.8kbits/s
video:1278kB audio:423kB subtitle:0 global headers:0kB muxing overhead 1.654557% -
No audio encoded with ffmpeg using webm/libvorbis
15 mars 2013, par Craig LillardHaving issues getting audio to encode to webm. Tried many different methods and it just ain't happenin. The commands are printed below before each pass.
I have tried moving the audio commands around, trying different bitrates, different audio commands and have tried it on a couple of different files as well that both have audio.
Encoding these files to MP4 using x264 causes no problems and works just fine and the audio plays, so it appears to be an issue just with webm. As you can see below, it is a 2-pass encode.
Thanks for any help you can provide !
Craig
Webm LG PASS 1...........................
webm_pass1: /usr/bin/ffmpeg -i /home/thedirectory/video613268.mov -codec:v libvpx -quality good -vf 'scale=640:360 [scaled];movie=/home/thedirectory/watermarks/w640X360.png [logo];[scaled][logo] overlay' -cpu-used 0 -b:v 500k -aspect 16:9 -qmin 10 -qmax 42 -maxrate:v 500k -bufsize:v 1000k -r:v 25/1 -force_fps -threads 0 -an -acodec libvorbis -ac 2 -ab 96k -ar 44100 -pass 1 -f webm -y /dev/null
ffmpeg version 0.10.2 Copyright (c) 2000-2012 the FFmpeg developers
built on Mar 11 2013 14:48:26 with gcc 4.6.2 20111027 (Red Hat 4.6.2-2)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --mandir=/usr/share/man --incdir=/usr/include --disable-avisynth --extra-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --enable-avfilter --enable-libfaac --enable-libgsm --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads --enable-shared --enable-swscale --enable-vdpau --enable-version3 --enable-x11grab --enable-libvorbis --enable-libvpx
libavutil 51. 35.100 / 51. 35.100
libavcodec 53. 61.100 / 53. 61.100
libavformat 53. 32.100 / 53. 32.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 61.100 / 2. 61.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/thedirectory/video613268.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2013-02-23 20:04:32
Duration: 00:00:21.02, start: 0.000000, bitrate: 114326 kb/s
Stream #0:0(eng): Video: mjpeg (jpeg / 0x6765706A), yuvj422p, 1920x1080 [SAR 72:72 DAR 16:9], 112786 kb/s, 29.97 fps, 29.97 tbr, 2997 tbn, 2997 tbc
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Stream #0:1(eng): Audio: pcm_s16be (twos / 0x736F7774), 48000 Hz, 2 channels, s16, 1536 kb/s
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Incompatible pixel format 'yuvj422p' for codec 'libvpx', auto-selecting format 'yuv420p'
[buffer @ 0x1f675a0] w:1920 h:1080 pixfmt:yuvj422p tb:1/1000000 sar:1/1 sws_param:
[movie @ 0x1f799c0] seek_point:0 format_name:(null) file_name:/home/thedirectory/watermarks/w640X360.png stream_index:0
[overlay @ 0x1f7c2c0] auto-inserting filter 'auto-inserted scale 0' between the filter 'Parsed_movie_1' and the filter 'Parsed_overlay_2'
[scale @ 0x1f78d40] w:1920 h:1080 fmt:yuvj422p -> w:640 h:360 fmt:yuv420p flags:0x4
[scale @ 0x1f7cde0] w:640 h:360 fmt:rgba -> w:640 h:360 fmt:yuva420p flags:0x4
[overlay @ 0x1f7c2c0] main w:640 h:360 fmt:yuv420p overlay x:0 y:0 w:640 h:360 fmt:yuva420p
[overlay @ 0x1f7c2c0] main_tb:1/1000000 overlay_tb:1/25 -> tb:1/1000000 exact:1
[libvpx @ 0x1f77ce0] v1.0.0
Output #0, webm, to '/dev/null':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2013-02-23 20:04:32
encoder : Lavf53.32.100
Stream #0:0(eng): Video: vp8, yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=10-42, pass 1, 500 kb/s, 1k tbn, 25 tbc
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg -> libvpx)
Press [q] to stop, [?] for help
frame= 527 fps= 21 q=0.0 Lsize= 0kB time=00:00:00.00 bitrate= 0.0kbits/s dup=0 drop=103
video:0kB audio:0kB global headers:0kB muxing overhead -nan%
Output file is empty, nothing was encoded (check -ss / -t / -frames parameters if used)
Webm LG PASS 2.......................
webm_pass2: /usr/bin/ffmpeg -i /home/thedirectory/video613268.mov -codec:v libvpx -quality good -vf 'scale=640:360 [scaled];movie=/home/thedirectory/watermarks/w640X360.png [logo];[scaled][logo] overlay' -cpu-used 0 -b:v 500k -aspect 16:9 -qmin 10 -qmax 42 -maxrate:v 500k -bufsize:v 1000k -r:v 24/1 -force_fps -threads 0 -an -acodec libvorbis -ac 2 -ab 96k -ar 44100 -pass 2 -f webm -y /media/amazons3/webmlg/video613268.mov.webm
ffmpeg version 0.10.2 Copyright (c) 2000-2012 the FFmpeg developers
built on Mar 11 2013 14:48:26 with gcc 4.6.2 20111027 (Red Hat 4.6.2-2)
configuration: --prefix=/usr --libdir=/usr/lib64 --shlibdir=/usr/lib64 --mandir=/usr/share/man --incdir=/usr/include --disable-avisynth --extra-cflags='-O2 -g -pipe -Wall -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector --param=ssp-buffer-size=4 -m64 -mtune=generic -fPIC' --enable-avfilter --enable-libfaac --enable-libgsm --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libx264 --enable-gpl --enable-nonfree --enable-postproc --enable-pthreads --enable-shared --enable-swscale --enable-vdpau --enable-version3 --enable-x11grab --enable-libvorbis --enable-libvpx
libavutil 51. 35.100 / 51. 35.100
libavcodec 53. 61.100 / 53. 61.100
libavformat 53. 32.100 / 53. 32.100
libavdevice 53. 4.100 / 53. 4.100
libavfilter 2. 61.100 / 2. 61.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 6.100 / 0. 6.100
libpostproc 52. 0.100 / 52. 0.100
Input #0, mov,mp4,m4a,3gp,3g2,mj2, from '/home/thedirectory/video613268.mov':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2013-02-23 20:04:32
Duration: 00:00:21.02, start: 0.000000, bitrate: 114326 kb/s
Stream #0:0(eng): Video: mjpeg (jpeg / 0x6765706A), yuvj422p, 1920x1080 [SAR 72:72 DAR 16:9], 112786 kb/s, 29.97 fps, 29.97 tbr, 2997 tbn, 2997 tbc
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Stream #0:1(eng): Audio: pcm_s16be (twos / 0x736F7774), 48000 Hz, 2 channels, s16, 1536 kb/s
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Incompatible pixel format 'yuvj422p' for codec 'libvpx', auto-selecting format 'yuv420p'
[buffer @ 0x1f2a5a0] w:1920 h:1080 pixfmt:yuvj422p tb:1/1000000 sar:1/1 sws_param:
[movie @ 0x1f3bec0] seek_point:0 format_name:(null) file_name:/home/thedirectory/watermarks/w640X360.png stream_index:0
[overlay @ 0x1f3f2c0] auto-inserting filter 'auto-inserted scale 0' between the filter 'Parsed_movie_1' and the filter 'Parsed_overlay_2'
[scale @ 0x1f3c8a0] w:1920 h:1080 fmt:yuvj422p -> w:640 h:360 fmt:yuv420p flags:0x4
[scale @ 0x1f3fde0] w:640 h:360 fmt:rgba -> w:640 h:360 fmt:yuva420p flags:0x4
[overlay @ 0x1f3f2c0] main w:640 h:360 fmt:yuv420p overlay x:0 y:0 w:640 h:360 fmt:yuva420p
[overlay @ 0x1f3f2c0] main_tb:1/1000000 overlay_tb:1/25 -> tb:1/1000000 exact:1
[libvpx @ 0x1f3ace0] v1.0.0
Output #0, webm, to '/media/amazons3/webmlg/video613268.mov.webm':
Metadata:
major_brand : qt
minor_version : 537199360
compatible_brands: qt
creation_time : 2013-02-23 20:04:32
encoder : Lavf53.32.100
Stream #0:0(eng): Video: vp8, yuv420p, 640x360 [SAR 1:1 DAR 16:9], q=10-42, pass 2, 500 kb/s, 1k tbn, 24 tbc
Metadata:
creation_time : 2013-02-23 20:04:32
handler_name : ?Gestionnaire d?alias Apple
Stream mapping:
Stream #0:0 -> #0:0 (mjpeg -> libvpx)
Press [q] to stop, [?] for help
frame= 506 fps= 7 q=0.0 Lsize= 1610kB time=00:00:21.08 bitrate= 625.8kbits/s dup=0 drop=124
video:1389kB audio:0kB global headers:0kB muxing overhead 15.952140% -
H.264 muxed to MP4 using libavformat not playing back
14 mai 2015, par Brad MitchellI am trying to mux H.264 data into a MP4 file. There appear to be no errors in saving this H.264 Annex B data out to an MP4 file, but the file fails to playback.
I’ve done a binary comparison on the files and the issue seems to be somewhere in what is being written to the footer (trailer) of the MP4 file.
I suspect it has to be something with the way the stream is being created or something.
Init :
AVOutputFormat* fmt = av_guess_format( 0, "out.mp4", 0 );
oc = avformat_alloc_context();
oc->oformat = fmt;
strcpy(oc->filename, filename);Part of this prototype app I have is creating a png file for each IFrame. So when the first IFrame is encountered, I create the video stream and write the av header etc :
void addVideoStream(AVCodecContext* decoder)
{
videoStream = av_new_stream(oc, 0);
if (!videoStream)
{
cout << "ERROR creating video stream" << endl;
return;
}
vi = videoStream->index;
videoContext = videoStream->codec;
videoContext->codec_type = AVMEDIA_TYPE_VIDEO;
videoContext->codec_id = decoder->codec_id;
videoContext->bit_rate = 512000;
videoContext->width = decoder->width;
videoContext->height = decoder->height;
videoContext->time_base.den = 25;
videoContext->time_base.num = 1;
videoContext->gop_size = decoder->gop_size;
videoContext->pix_fmt = decoder->pix_fmt;
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
videoContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
av_dump_format(oc, 0, filename, 1);
if (!(oc->oformat->flags & AVFMT_NOFILE))
{
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
cout << "Error opening file" << endl;
}
avformat_write_header(oc, NULL);
}I write packets out :
unsigned char* data = block->getData();
unsigned char videoFrameType = data[4];
int dataLen = block->getDataLen();
// store pps
if (videoFrameType == 0x68)
{
if (ppsFrame != NULL)
{
delete ppsFrame; ppsFrameLength = 0; ppsFrame = NULL;
}
ppsFrameLength = block->getDataLen();
ppsFrame = new unsigned char[ppsFrameLength];
memcpy(ppsFrame, block->getData(), ppsFrameLength);
}
else if (videoFrameType == 0x67)
{
// sps
if (spsFrame != NULL)
{
delete spsFrame; spsFrameLength = 0; spsFrame = NULL;
}
spsFrameLength = block->getDataLen();
spsFrame = new unsigned char[spsFrameLength];
memcpy(spsFrame, block->getData(), spsFrameLength);
}
if (videoFrameType == 0x65 || videoFrameType == 0x41)
{
videoFrameNumber++;
}
if (videoFrameType == 0x65)
{
decodeIFrame(videoFrameNumber, spsFrame, spsFrameLength, ppsFrame, ppsFrameLength, data, dataLen);
}
if (videoStream != NULL)
{
AVPacket pkt = { 0 };
av_init_packet(&pkt);
pkt.stream_index = vi;
pkt.flags = 0;
pkt.pts = pkt.dts = 0;
if (videoFrameType == 0x65)
{
// combine the SPS PPS & I frames together
pkt.flags |= AV_PKT_FLAG_KEY;
unsigned char* videoFrame = new unsigned char[spsFrameLength+ppsFrameLength+dataLen];
memcpy(videoFrame, spsFrame, spsFrameLength);
memcpy(&videoFrame[spsFrameLength], ppsFrame, ppsFrameLength);
memcpy(&videoFrame[spsFrameLength+ppsFrameLength], data, dataLen);
// overwrite the start code (00 00 00 01 with a 32-bit length)
setLength(videoFrame, spsFrameLength-4);
setLength(&videoFrame[spsFrameLength], ppsFrameLength-4);
setLength(&videoFrame[spsFrameLength+ppsFrameLength], dataLen-4);
pkt.size = dataLen + spsFrameLength + ppsFrameLength;
pkt.data = videoFrame;
av_interleaved_write_frame(oc, &pkt);
delete videoFrame; videoFrame = NULL;
}
else if (videoFrameType != 0x67 && videoFrameType != 0x68)
{
// Send other frames except pps & sps which are caught and stored
pkt.size = dataLen;
pkt.data = data;
setLength(data, dataLen-4);
av_interleaved_write_frame(oc, &pkt);
}Finally to close the file off :
av_write_trailer(oc);
int i = 0;
for (i = 0; i < oc->nb_streams; i++)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
if (!(oc->oformat->flags & AVFMT_NOFILE))
{
avio_close(oc->pb);
}
av_free(oc);If I take the H.264 data alone and convert it :
ffmpeg -i recording.h264 -vcodec copy recording.mp4
All but the "footer" of the files are the same.
Output from my program :
readrec recording.tcp out.mp4
** START * 01-03-2013 14:26:01 180000
Output #0, mp4, to ’out.mp4’ :
Stream #0:0 : Video : h264, yuv420p, 352x288, q=2-31, 512 kb/s, 90k tbn, 25 tbc
* END ** 01-03-2013 14:27:01 102000
Wrote 1499 video frames.If I try to convert using ffmpeg the MP4 file created using CODE :
ffmpeg -i out.mp4 -vcodec copy out2.mp4
ffmpeg version 0.11.1 Copyright (c) 2000-2012 the FFmpeg developers
built on Mar 7 2013 12:49:22 with suncc 0x5110
configuration: --extra-cflags=-KPIC -g --disable-mmx
--disable-protocol=udp --disable-encoder=nellymoser --cc=cc --cxx=CC
libavutil 51. 54.100 / 51. 54.100
libavcodec 54. 23.100 / 54. 23.100
libavformat 54. 6.100 / 54. 6.100
libavdevice 54. 0.100 / 54. 0.100
libavfilter 2. 77.100 / 2. 77.100
libswscale 2. 1.100 / 2. 1.100
libswresample 0. 15.100 / 0. 15.100
h264 @ 12eaac0] no frame!
Last message repeated 1 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 23 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 74 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 64 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 34 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 49 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 24 times
[h264 @ 12eaac0] Partitioned H.264 support is incomplete
[h264 @ 12eaac0] no frame!
Last message repeated 23 times
[h264 @ 12eaac0] sps_id out of range
[h264 @ 12eaac0] no frame!
Last message repeated 148 times
[h264 @ 12eaac0] sps_id (32) out of range
Last message repeated 1 times
[h264 @ 12eaac0] no frame!
Last message repeated 33 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 128 times
[h264 @ 12eaac0] sps_id (32) out of range
Last message repeated 1 times
[h264 @ 12eaac0] no frame!
Last message repeated 3 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 3 times
[h264 @ 12eaac0] slice type too large (0) at 0 0
[h264 @ 12eaac0] decode_slice_header error
[h264 @ 12eaac0] no frame!
Last message repeated 309 times
[h264 @ 12eaac0] sps_id (32) out of range
Last message repeated 1 times
[h264 @ 12eaac0] no frame!
Last message repeated 192 times
[h264 @ 12eaac0] Partitioned H.264 support is incomplete
[h264 @ 12eaac0] no frame!
Last message repeated 73 times
[h264 @ 12eaac0] sps_id (32) out of range
Last message repeated 1 times
[h264 @ 12eaac0] no frame!
Last message repeated 99 times
[h264 @ 12eaac0] sps_id (32) out of range
Last message repeated 1 times
[h264 @ 12eaac0] no frame!
Last message repeated 197 times
[mov,mp4,m4a,3gp,3g2,mj2 @ 12e3100] decoding for stream 0 failed
[mov,mp4,m4a,3gp,3g2,mj2 @ 12e3100] Could not find codec parameters
(Video: h264 (avc1 / 0x31637661), 393539 kb/s)
out.mp4: could not find codec parametersI really do not know where the issue is, except it has to be something to do with the way the streams are being set up. I’ve looked at bits of code from where other people are doing a similar thing, and tried to use this advice in setting up the streams, but to no avail !
The final code which gave me a H.264/AAC muxed (synced) file is as follows. First a bit of background information. The data is coming from an IP camera. The data is presented via a 3rd party API as video/audio packets. The video packets are presented as the RTP payload data (no header) and consist of NALU’s that are reconstructed and converted to H.264 video in Annex B format. AAC audio is presented as raw AAC and is converted to adts format to enable playback. These packets have been put into a bitstream format that allows the transmission of the timestamp (64 bit milliseconds since Jan 1 1970) along with a few other things.
This is more or less a prototype and is not clean in any respects. It probably leaks bad. I do however, hope this helps anyone else out trying to achieve something similar to what I am.
Globals :
AVFormatContext* oc = NULL;
AVCodecContext* videoContext = NULL;
AVStream* videoStream = NULL;
AVCodecContext* audioContext = NULL;
AVStream* audioStream = NULL;
AVCodec* videoCodec = NULL;
AVCodec* audioCodec = NULL;
int vi = 0; // Video stream
int ai = 1; // Audio stream
uint64_t firstVideoTimeStamp = 0;
uint64_t firstAudioTimeStamp = 0;
int audioStartOffset = 0;
char* filename = NULL;
Boolean first = TRUE;
int videoFrameNumber = 0;
int audioFrameNumber = 0;Main :
int main(int argc, char* argv[])
{
if (argc != 3)
{
cout << argv[0] << " <stream playback="playback" file="file"> <output mp4="mp4" file="file">" << endl;
return 0;
}
char* input_stream_file = argv[1];
filename = argv[2];
av_register_all();
fstream inFile;
inFile.open(input_stream_file, ios::in);
// Used to store the latest pps & sps frames
unsigned char* ppsFrame = NULL;
int ppsFrameLength = 0;
unsigned char* spsFrame = NULL;
int spsFrameLength = 0;
// Setup MP4 output file
AVOutputFormat* fmt = av_guess_format( 0, filename, 0 );
oc = avformat_alloc_context();
oc->oformat = fmt;
strcpy(oc->filename, filename);
// Setup the bitstream filter for AAC in adts format. Could probably also achieve
// this by stripping the first 7 bytes!
AVBitStreamFilterContext* bsfc = av_bitstream_filter_init("aac_adtstoasc");
if (!bsfc)
{
cout << "Error creating adtstoasc filter" << endl;
return -1;
}
while (inFile.good())
{
TcpAVDataBlock* block = new TcpAVDataBlock();
block->readStruct(inFile);
DateTime dt = block->getTimestampAsDateTime();
switch (block->getPacketType())
{
case TCP_PACKET_H264:
{
if (firstVideoTimeStamp == 0)
firstVideoTimeStamp = block->getTimeStamp();
unsigned char* data = block->getData();
unsigned char videoFrameType = data[4];
int dataLen = block->getDataLen();
// pps
if (videoFrameType == 0x68)
{
if (ppsFrame != NULL)
{
delete ppsFrame; ppsFrameLength = 0;
ppsFrame = NULL;
}
ppsFrameLength = block->getDataLen();
ppsFrame = new unsigned char[ppsFrameLength];
memcpy(ppsFrame, block->getData(), ppsFrameLength);
}
else if (videoFrameType == 0x67)
{
// sps
if (spsFrame != NULL)
{
delete spsFrame; spsFrameLength = 0;
spsFrame = NULL;
}
spsFrameLength = block->getDataLen();
spsFrame = new unsigned char[spsFrameLength];
memcpy(spsFrame, block->getData(), spsFrameLength);
}
if (videoFrameType == 0x65 || videoFrameType == 0x41)
{
videoFrameNumber++;
}
// Extract a thumbnail for each I-Frame
if (videoFrameType == 0x65)
{
decodeIFrame(h264, spsFrame, spsFrameLength, ppsFrame, ppsFrameLength, data, dataLen);
}
if (videoStream != NULL)
{
AVPacket pkt = { 0 };
av_init_packet(&pkt);
pkt.stream_index = vi;
pkt.flags = 0;
pkt.pts = videoFrameNumber;
pkt.dts = videoFrameNumber;
if (videoFrameType == 0x65)
{
pkt.flags = 1;
unsigned char* videoFrame = new unsigned char[spsFrameLength+ppsFrameLength+dataLen];
memcpy(videoFrame, spsFrame, spsFrameLength);
memcpy(&videoFrame[spsFrameLength], ppsFrame, ppsFrameLength);
memcpy(&videoFrame[spsFrameLength+ppsFrameLength], data, dataLen);
pkt.data = videoFrame;
av_interleaved_write_frame(oc, &pkt);
delete videoFrame; videoFrame = NULL;
}
else if (videoFrameType != 0x67 && videoFrameType != 0x68)
{
pkt.size = dataLen;
pkt.data = data;
av_interleaved_write_frame(oc, &pkt);
}
}
break;
}
case TCP_PACKET_AAC:
if (firstAudioTimeStamp == 0)
{
firstAudioTimeStamp = block->getTimeStamp();
uint64_t millseconds_difference = firstAudioTimeStamp - firstVideoTimeStamp;
audioStartOffset = millseconds_difference * 16000 / 1000;
cout << "audio offset: " << audioStartOffset << endl;
}
if (audioStream != NULL)
{
AVPacket pkt = { 0 };
av_init_packet(&pkt);
pkt.stream_index = ai;
pkt.flags = 1;
pkt.pts = audioFrameNumber*1024;
pkt.dts = audioFrameNumber*1024;
pkt.data = block->getData();
pkt.size = block->getDataLen();
pkt.duration = 1024;
AVPacket newpacket = pkt;
int rc = av_bitstream_filter_filter(bsfc, audioContext,
NULL,
&newpacket.data, &newpacket.size,
pkt.data, pkt.size,
pkt.flags & AV_PKT_FLAG_KEY);
if (rc >= 0)
{
//cout << "Write audio frame" << endl;
newpacket.pts = audioFrameNumber*1024;
newpacket.dts = audioFrameNumber*1024;
audioFrameNumber++;
newpacket.duration = 1024;
av_interleaved_write_frame(oc, &newpacket);
av_free_packet(&newpacket);
}
else
{
cout << "Error filtering aac packet" << endl;
}
}
break;
case TCP_PACKET_START:
break;
case TCP_PACKET_END:
break;
}
delete block;
}
inFile.close();
av_write_trailer(oc);
int i = 0;
for (i = 0; i < oc->nb_streams; i++)
{
av_freep(&oc->streams[i]->codec);
av_freep(&oc->streams[i]);
}
if (!(oc->oformat->flags & AVFMT_NOFILE))
{
avio_close(oc->pb);
}
av_free(oc);
delete spsFrame; spsFrame = NULL;
delete ppsFrame; ppsFrame = NULL;
cout << "Wrote " << videoFrameNumber << " video frames." << endl;
return 0;
}
</output></stream>The stream stream/codecs are added and the header is created in a function called addVideoAndAudioStream(). This function is called from decodeIFrame() so there are a few assumptions (which aren’t necessarily good)
1. A video packet comes first
2. AAC is presentThe decodeIFrame was kind of a separate prototype by where I was creating a thumbnail for each I Frame. The code to generate thumbnails was from : https://gnunet.org/svn/Extractor/src/plugins/thumbnailffmpeg_extractor.c
The decodeIFrame function passes an AVCodecContext into addVideoAudioStream :
void addVideoAndAudioStream(AVCodecContext* decoder = NULL)
{
videoStream = av_new_stream(oc, 0);
if (!videoStream)
{
cout << "ERROR creating video stream" << endl;
return;
}
vi = videoStream->index;
videoContext = videoStream->codec;
videoContext->codec_type = AVMEDIA_TYPE_VIDEO;
videoContext->codec_id = decoder->codec_id;
videoContext->bit_rate = 512000;
videoContext->width = decoder->width;
videoContext->height = decoder->height;
videoContext->time_base.den = 25;
videoContext->time_base.num = 1;
videoContext->gop_size = decoder->gop_size;
videoContext->pix_fmt = decoder->pix_fmt;
audioStream = av_new_stream(oc, 1);
if (!audioStream)
{
cout << "ERROR creating audio stream" << endl;
return;
}
ai = audioStream->index;
audioContext = audioStream->codec;
audioContext->codec_type = AVMEDIA_TYPE_AUDIO;
audioContext->codec_id = CODEC_ID_AAC;
audioContext->bit_rate = 64000;
audioContext->sample_rate = 16000;
audioContext->channels = 1;
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
{
videoContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
audioContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
av_dump_format(oc, 0, filename, 1);
if (!(oc->oformat->flags & AVFMT_NOFILE))
{
if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
cout << "Error opening file" << endl;
}
}
avformat_write_header(oc, NULL);
}As far as I can tell, a number of assumptions didn’t seem to matter, for example :
1. Bit Rate. The actual video bit rate was 262k whereas I specified 512kbit
2. AAC channels. I specified mono, although the actual output was Stereo from memoryYou would still need to know what the frame rate (time base) is for the video & audio.
Contrary to a lot of other examples, when setting pts & dts on the video packets, it was not playable. I needed to know the time base (25fps) and then set the pts & dts according to that time base, i.e. first frame = 0 (PPS, SPS, I), second frame = 1 (intermediate frame, whatever its called ;)).
AAC I also had to make the assumption that it was 16000 hz. 1024 samples per AAC packet (You can also have AAC @ 960 samples I think) to determine the audio "offset". I added this to the pts & dts. So the pts/dts are the sample number that it is to played back at. You also need to make sure that the duration of 1024 is set in the packet before writing also.
—
I have found additionally today that Annex B isn’t really compatible with any other player so AVCC format should really be used.
These URLS helped :
Problem to Decode H264 video over RTP with ffmpeg (libavcodec)
http://aviadr1.blogspot.com.au/2010/05/h264-extradata-partially-explained-for.htmlWhen constructing the video stream, I filled out the extradata & extradata_size :
// Extradata contains PPS & SPS for AVCC format
int extradata_len = 8 + spsFrameLen-4 + 1 + 2 + ppsFrameLen-4;
videoContext->extradata = (uint8_t*)av_mallocz(extradata_len);
videoContext->extradata_size = extradata_len;
videoContext->extradata[0] = 0x01;
videoContext->extradata[1] = spsFrame[4+1];
videoContext->extradata[2] = spsFrame[4+2];
videoContext->extradata[3] = spsFrame[4+3];
videoContext->extradata[4] = 0xFC | 3;
videoContext->extradata[5] = 0xE0 | 1;
int tmp = spsFrameLen - 4;
videoContext->extradata[6] = (tmp >> 8) & 0x00ff;
videoContext->extradata[7] = tmp & 0x00ff;
int i = 0;
for (i=0;iextradata[8+i] = spsFrame[4+i];
videoContext->extradata[8+tmp] = 0x01;
int tmp2 = ppsFrameLen-4;
videoContext->extradata[8+tmp+1] = (tmp2 >> 8) & 0x00ff;
videoContext->extradata[8+tmp+2] = tmp2 & 0x00ff;
for (i=0;iextradata[8+tmp+3+i] = ppsFrame[4+i];When writing out the frames, don’t prepend the SPS & PPS frames, just write out the I Frame & P frames. In addition, replace the Annex B start code contained in the first 4 bytes (0x00 0x00 0x00 0x01) with the size of the I/P frame.