I am trying to mux an MPEG4-TS stream produced by a TI DM355 and raw 32KHz, 16-bit stereo audio into an AVI file. I've pretty much just followed the muxing-example.c in the docs directory of the ffmpeg source tree.<br>
<br>I've gotten the raw audio working, and I can mux in the video data. After running for a few minutes I have an AVI file. Here is what mplayer tells me:<br>nlbutts@nlbutts-desktop:/media/temp/analyze$ mplayer VIS-FF1M-2923-0007.avi <br>
MPlayer SVN-r1.0~rc3+svn20090426-4.4.3 (C) 2000-2009 MPlayer Team<br>mplayer: could not connect to socket<br>mplayer: No such file or directory<br>Failed to open LIRC support. You will not be able to use your remote control.<br>
<br>Playing VIS-FF1M-2923-0007.avi.<br>AVI file format detected.<br>[aviheader] Video stream found, -vid 0<br>[aviheader] Audio stream found, -aid 1<br>** empty list?!<br>Could not determine number of frames (for absolute seek).<br>
VIDEO: [FMP4] 1280x720 24bpp 20.000 fps -17179870.0 kbps (-2097152.0 kbyte/s)<br>Clip info:<br> Software: Lavf53.3.0<br>open: No such file or directory<br>[MGA] Couldn't open: /dev/mga_vid<br>open: No such file or directory<br>
[MGA] Couldn't open: /dev/mga_vid<br>[VO_TDFXFB] Can't open /dev/fb0: Permission denied.<br>[VO_3DFX] Unable to open /dev/3dfx.<br>[VO_XV] It seems there is no Xvideo support for your video card available.<br>[VO_XV] Run 'xvinfo' to verify its Xv support and read<br>
[VO_XV] DOCS/HTML/en/video.html#xv!<br>[VO_XV] See 'mplayer -vo help' for other (non-xv) video out drivers.<br>[VO_XV] Try -vo x11.<br>[vdpau] Could not open dynamic library libvdpau.so.1<br>==========================================================================<br>
Opening video decoder: [ffmpeg] FFmpeg's libavcodec codec family<br>Selected video codec: [ffodivx] vfm: ffmpeg (FFmpeg MPEG-4)<br>==========================================================================<br>==========================================================================<br>
Opening audio decoder: [pcm] Uncompressed PCM audio decoder<br>AUDIO: 32000 Hz, 2 ch, s16le, 1024.0 kbit/100.00% (ratio: 128000->128000)<br>Selected audio codec: [pcm] afm: pcm (Uncompressed PCM)<br>==========================================================================<br>
AO: [pulse] 32000Hz 2ch s16le (2 bytes per sample)<br>Starting playback...<br>VDec: vo config request - 1280 x 720 (preferred colorspace: Planar YV12)<br>VDec: using Planar YV12 as output csp (no 0)<br>Movie-Aspect is 1.78:1 - prescaling to correct movie aspect.<br>
VO: [x11] 1280x720 => 1280x720 Planar YV12 <br>[swscaler @ 0xab79c0]using unscaled yuv420p -> rgb32 special converter<br>Incomplete stream? Trying resync. 0.005 22/ 22 20% 8% 6.2% 0 0 <br>A: 1.4 V: 1.5 A-V: -0.079 ct: 0.018 30/ 30 17% 7% 4.5% 0 0 <br>
<br>Exiting... (End of file)<br><br><br>This is what ffprobe tells me:<br>ffprobe version N-31774-g6c4e9ca, Copyright (c) 2007-2011 the FFmpeg developers<br> built on Aug 6 2011 22:22:11 with gcc 4.6.1<br> configuration: --enable-gpl --enable-version3 --enable-memalign-hack --enable-<br>
runtime-cpudetect --enable-avisynth --enable-bzlib --enable-frei0r --enable-libo<br>pencore-amrnb --enable-libopencore-amrwb --enable-libfreetype --enable-libgsm --<br>enable-libmp3lame --enable-libopenjpeg --enable-librtmp --enable-libschroedinger<br>
--enable-libspeex --enable-libtheora --enable-libvorbis --enable-libvpx --enabl<br>e-libx264 --enable-libxavs --enable-libxvid --enable-zlib<br> libavutil 51. 11. 1 / 51. 11. 1<br> libavcodec 53. 9. 1 / 53. 9. 1<br>
libavformat 53. 6. 0 / 53. 6. 0<br> libavdevice 53. 2. 0 / 53. 2. 0<br> libavfilter 2. 28. 0 / 2. 28. 0<br> libswscale 2. 0. 0 / 2. 0. 0<br> libpostproc 51. 2. 0 / 51. 2. 0<br>Input #0, avi, from 'VIS-FF1M-2923-0007.avi':<br>
Metadata:<br> encoder : Lavf53.3.0<br> Duration: 00:00:00.00, start: 0.000000, bitrate: -2147483 kb/s<br> Stream #0.0: Video: mpeg4, yuv420p, 1280x720 [SAR 1:1 DAR 16:9], 20 fps, 20<br>tbr, 20 tbn, 20k tbc<br>
Stream #0.1: Audio: pcm_s16le, 32000 Hz, 2 channels, s16, 1024 kb/s<br>[STREAM]<br>index=0<br>codec_name=mpeg4<br>codec_long_name=MPEG-4 part 2<br>codec_type=video<br>codec_time_base=1/20000<br>codec_tag_string=FMP4<br>
codec_tag=0x34504d46<br>width=1280<br>height=720<br>has_b_frames=1<br>sample_aspect_ratio=1:1<br>display_aspect_ratio=16:9<br>pix_fmt=yuv420p<br>level=-99<br>r_frame_rate=20/1<br>avg_frame_rate=20/1<br>time_base=1/20<br>start_time=0.000000<br>
duration=0.000000<br>[/STREAM]<br>[STREAM]<br>index=1<br>codec_name=pcm_s16le<br>codec_long_name=PCM signed 16-bit little-endian<br>codec_type=audio<br>codec_time_base=0/1<br>codec_tag_string=[1][0][0][0]<br>codec_tag=0x0001<br>
sample_rate=32000.000000<br>channels=2<br>bits_per_sample=16<br>r_frame_rate=0/0<br>avg_frame_rate=40/1<br>time_base=1/32000<br>start_time=0.000000<br>duration=N/A<br>[/STREAM]<br><br>Here is my init code:<br>/* initialize libavcodec, and register all codecs and formats */<br>
av_register_all();<br> /* allocate the output media context */<br> avformat_alloc_output_context2(&_avFormatContext, NULL, NULL, "output.avi");<br> if (!_avFormatContext)<br> {<br> avformat_alloc_output_context2(&_avFormatContext, NULL, "avi", "output.avi");<br>
}<br> if (!_avFormatContext)<br> return -1;<br> _avFormat = _avFormatContext->oformat;<br> _audioStream = NULL;<br> _videoStream = NULL;<br> if (_avFormat->video_codec != CODEC_ID_NONE)<br>
_videoStream = add_video_stream(_avFormat->video_codec);<br> _avFormat->audio_codec = CODEC_ID_PCM_S16LE;<br> _audioStream = add_audio_stream(_avFormat->audio_codec);<br><br> if (_videoStream)<br>
open_video();<br> else<br> return -1;<br> if (_audioStream)<br> open_audio();<br> else<br> return -1;<br><br> // Allocate a dynamic buffer system<br> if (avio_open_dyn_buf(&_avFormatContext->pb) != 0)<br>
return -1;<br><br> /* write the stream header, if any */<br> if (av_write_header(_avFormatContext) != 0) <br> return -1;<br><br>Here is the add stream code:<br>AVStream *AVIMuxerFilter::add_video_stream(enum CodecID codec_id) const<br>
{<br> AVCodecContext *c;<br> AVStream *st;<br><br> st = av_new_stream(_avFormatContext, 0);<br> if (!st)<br> {<br> Log::logDebugForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::add_video_stream] Could not allocate video stream");<br>
return NULL;<br> }<br><br> c = st->codec;<br> c->codec_id = codec_id;<br> c->codec_type = AVMEDIA_TYPE_VIDEO;<br><br> /* put sample parameters */<br> c->bit_rate = _bitRate;<br> /* resolution must be a multiple of two */<br>
c->width = 1280;<br> c->height = 720;<br> /* time base: this is the fundamental unit of time (in seconds) in terms<br> of which frame timestamps are represented. for fixed-fps content,<br> timebase should be 1/framerate and timestamp increments should be<br>
identically 1. */<br> c->time_base.den = _frameRate;<br> c->time_base.num = 1;<br> c->gop_size = _frameRate; /* emit one intra frame every twelve frames at most */<br> c->pix_fmt = PIX_FMT_YUV420P;<br>
// some formats want stream headers to be separate<br> if(_avFormatContext->oformat->flags & AVFMT_GLOBALHEADER)<br> c->flags |= CODEC_FLAG_GLOBAL_HEADER;<br><br> return st;<br>}<br><br>Here is the open video codec code:<br>
bool AVIMuxerFilter::open_video() const<br>{<br> AVCodec *codec;<br> AVCodecContext *c;<br><br> c = _videoStream->codec;<br><br> /* find the video encoder */<br> codec = avcodec_find_encoder(c->codec_id);<br>
Log::logErrorForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::open_video] codec_id=%d", c->codec_id);<br> if (!codec)<br> {<br> Log::logErrorForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::open_video] Codec not found");<br>
return false;<br> }<br><br> /* open the codec */<br> if (avcodec_open(c, codec) < 0)<br> {<br> Log::logErrorForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::open_video] cound not open codec");<br>
return false;<br> }<br><br> //video_outbuf = NULL;<br> if (!(_avFormatContext->oformat->flags & AVFMT_RAWPICTURE)) {<br> Log::logErrorForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::open_video] need to allocate something");<br>
}<br><br> return true;<br>}<br><br>Finally, here is the code that writes the video frames:<br>void AVIMuxerFilter::write_video_frame(void * frame, uint32_t length, bool iFrame) const<br>{<br> int ret;<br> AVCodecContext *c;<br>
<br> c = _videoStream->codec;<br><br> AVPacket pkt;<br> av_init_packet(&pkt);<br><br> if(iFrame)<br> {<br> pkt.flags |= AV_PKT_FLAG_KEY;<br> }<br> pkt.stream_index= _videoStream->index;<br>
pkt.data= (uint8_t*)frame;<br> pkt.size= length;<br> if (c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)<br> pkt.pts= av_rescale_q(c->coded_frame->pts, c->time_base, _videoStream->time_base);<br>
<br> /* write the compressed frame in the media file */<br> ret = av_interleaved_write_frame(_avFormatContext, &pkt);<br><br> if (ret != 0)<br> {<br> Log::logErrorForCategory(IM_FILTERS_CATEGORY, "[AVIMuxerFilter::write_video_frame] Error writing video frame");<br>
}<br> _frame_count++;<br>}<br><br clear="all"><br>One odd thing is the MPEG4-TS has a weird timebase. It uses a 1/20000 timebase, whereas the container is trying to use a different timebase. I'm not sure if that is the problem. This is the version of FFMPEG that I downloaded:<br>
git-N-30694-g16c9e67<br><br><br>Thanks for any help.<br><br>