[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