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