[Libav-user] Muxing MPEG-4 motion imagery into a MPEG-2 Transport Stream

Mark Fonnemann markf78 at yahoo.com
Fri Jul 29 22:37:14 CEST 2011


OK, if i change this line:

 avformat_alloc_output_context2(&muxer, NULL, "mpegts", NULL);

to this line:

 avformat_alloc_output_context2(&muxer, NULL, "mp4", NULL);

then, i am able to open the video with VLC and play it the MP4 stream in an MPEG4 container. thus, my code must be very close to being correct and i must have a parameter wrong here or there when using a MPEG-2 TS container. any suggestions?

mark.

--- On Thu, 7/28/11, Mark Fonnemann <markf78 at yahoo.com> wrote:

> From: Mark Fonnemann <markf78 at yahoo.com>
> Subject: Re: [Libav-user] Muxing MPEG-4 motion imagery into a MPEG-2 Transport Stream
> To: " libavformat libavutil libavdevice and libavfilter.This list is about using libavcodec" <libav-user at ffmpeg.org>
> Date: Thursday, July 28, 2011, 8:13 PM
> I recently posted a question about
> Muxing MPEG-4 video into a MPEG-2 TS. I was using quite an
> outdated version of libav so i am assuming that is the
> reason I received no responses. I have rewritten the code to
> use release 0.8.
> 
> I am now able to write data to the MPEG-2 TS but when
> opening it with VLC nothing appears despite the fact it
> knows there is a MPEG-4 video stream in there. I then tried
> to inspect with ffmpeg as follows:
> 
> > ffmpeg.exe -i c:\bat.ts
> 
> ffmpeg version 0.8, Copyright (c) 2000-2011 the FFmpeg
> developers
>   built on Jul 23 2011 23:24:23 with gcc 3.4.4
> (cygming special, gdc 0.12, using
>  dmd 0.125)
>   configuration: --enable-memalign-hack
> --enable-swscale --enable-w32threads --e
> nable-shared --target-os=mingw32 --extra-cflags=-mno-cygwin
> --extra-libs=-mno-cy
> gwin
>   libavutil    51.  9. 1 / 51.  9.
> 1
>   libavcodec   53.  7. 0 /
> 53.  7. 0
>   libavformat  53.  4. 0 / 53.  4. 0
>   libavdevice  53.  1. 1 / 53.  1. 1
>   libavfilter   2. 23. 0 /  2. 23.
> 0
>   libswscale    2.  0. 0 / 
> 2.  0. 0
> [mpeg4 @ 00ba80b0] hmm, seems the headers are not complete,
> trying to guess time_increment_bits
> [mpeg4 @ 00ba80b0] my guess is 5 bits ;)
> Compiler did not align stack variables. Libavcodec has been
> miscompiled
> and may be very slow or crash. This is not a bug in
> libavcodec,
> but in the compiler. You may try recompiling using gcc
> >= 4.2.
> Do not report crashes to FFmpeg developers.
> [mpeg4 @ 00ba80b0] hmm, seems the headers are not complete,
> trying to guess time
> _increment_bits
> [mpeg4 @ 00ba80b0] my guess is 5 bits ;)
> [mpeg4 @ 00ba80b0] looks like this file was encoded with
> (divx4/(old)xvid/opendivx) -> forcing low_delay flag
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpeg4 @ 00ba80b0] [IMGUTILS @ 0022e290] Picture size 0x0
> is invalid
> [mpeg4 @ 00ba80b0] get_buffer() failed (-1 0 0 00000000)
> [mpegts @ 003ea370] Could not find codec parameters (Video:
> mpeg4, yuv420p)
> [NULL @ 00ba80b0] start time is not set in
> av_estimate_timings_from_pts
> c:\bat.ts: could not find codec parameters
> 
> any help would be greatly appreciated.
> 
> mark.
> 
> p.s. here's some code that i am using:
> 
> void initialize()
> {
>     int framewidth = 704;
>     int frameheight = 480;
>     
>     //av_register_all etc.
>         init();
> 
>     // alloc the libavformat context and set
> the type to "MPEG-2 TS"
>    
> avformat_alloc_output_context2(&muxer, NULL, "mpegts",
> NULL);
>     if(!muxer) {
>         // error
> handling    
>         }
> 
>     // add the video stream to the muxer
>     addVideoStream(codec_name, framewidth,
> frameheight);
> 
>     // not sure what this does? not
> documented in doxygen
>     av_dump_format(muxer, 0, "c:\\bat.ts",
> 1);
> 
>     // open the video stream and allocate
> default buffers
>     openVideoStream();
> 
>     // allocate the buffer to write the
> destination packets to
>     avio_open(&muxer->pb,
> "c:\\bat.ts", URL_WRONLY);
> 
>     // set the parameters for the muxer
>     av_write_header(muxer);
> }
> 
> void addVideoStream(std::string codec_name, int width, int
> height)
> {
>     // add a new stream to the container
>     vstream = av_new_stream(muxer, 0);
>     if (!vstream) {
>         // error handling
>     }
> 
>     // set a handle to the stream's codec
> ("the codec context")
>     codecContext = vstream->codec;
> 
>     // set the stream type to video and
> specify the codec
>     codecContext->codec_type =
> AVMEDIA_TYPE_VIDEO;
> 
>     if ( "H.264" == codec_name) 
>     {
>        
> codecContext->codec_id = CODEC_ID_H264;
>     }
>     else if ( "MPEG-4" == codec_name) 
>     {
>        
> codecContext->codec_id = CODEC_ID_MPEG4;
>     } 
>     else // "MPEG2"
>     {
>        
> codecContext->codec_id = CODEC_ID_MPEG2VIDEO;
>     }
> 
>     // fill in sample parameters
>     codecContext->global_quality =
> FF_QP2LAMBDA;
>     codecContext->bit_rate = 200000;
> 
>     // resolution must be a multiple of two
>     codecContext->width = width;  
>     codecContext->height = height;
>     
>     // set additional properties of the
> video stream
>     codecContext->time_base.den =
> 25;  
>     codecContext->time_base.num = 1;
>     codecContext->gop_size = 12; /* emit
> one intra frame every twelve frames at most */
>     codecContext->pix_fmt =
> PIX_FMT_YUV420P;
>     codecContext->flags |=
> CODEC_FLAG_GLOBAL_HEADER;
>     codecContext->flags |=
> CODEC_FLAG_QSCALE;
>     codecContext->max_b_frames = 0;
> 
>     // some formats want stream headers to
> be separate
>     if (muxer->oformat->flags &
> AVFMT_GLOBALHEADER)
>        
> codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;
> }
> 
> void openVideoStream()
> {
>     // get the encoder for the codec
>     vcodec =
> avcodec_find_encoder(codecContext->codec_id);
> 
>     // attempt to open the encoder
>     if (avcodec_open(codecContext, vcodec)
> < 0)
>     {
>         // error handling
>     }
> 
>     video_outbuf_size = 200000; // not sure
> how this number was chosen? it seems to be the accepted
> value though
>     fTo = (uint8_t *)
> malloc(video_outbuf_size);
>     video_outbuf = (uint8_t *)
> malloc(video_outbuf_size);
> 
> }
> 
> 
> void doGetNextFrame(AVFrame* rgbimage)
> {
> 
>     AVFrame *tmp_picture =
> avcodec_alloc_frame();
>     unsigned int size =
> avpicture_get_size(codecContext->pix_fmt,
> codecContext->width, codecContext->height);
>     uint8_t *picture_buf = (uint8_t *)
> malloc(size);
> 
>     int fillres = avpicture_fill((AVPicture
> *)tmp_picture, picture_buf, codecContext->pix_fmt,
> codecContext->width, codecContext->height);
> 
>     int out_size = 0;
> 
>         // color convert the
> image... swsConvert is a company wrapper for sws_scale
>         bool success =
> swsConvert(tmp_picture, rgbimage,
> codecContext->pix_fmt);
>        
> tmp_picture->quality = FF_QP2LAMBDA;
> 
>         // encode the stream
> into video_outbuf
>         // returns a negative
> value on error
>         out_size =
> avcodec_encode_video(codecContext, video_outbuf,
> video_outbuf_size, tmp_picture);
>         
>        
> mFrameQueue->pop_front();
>         if (out_size > 0)
>         {
>             //
> create an AVPacket using the encoded imagery
>            
> AVPacket pkt;
>            
> av_init_packet(&pkt);
> 
>            
> pkt.data = video_outbuf;
>             pkt.size =
> out_size;
>            
> pkt.stream_index = vstream->index;
>             pkt.pts=
> av_rescale_q(codecContext->coded_frame->pts,
> codecContext->time_base, vstream->time_base);
>             pkt.flags |=
> AV_PKT_FLAG_KEY;
> 
>             //
> write the frame
>             if
> (av__write_frame(muxer, &pkt) < 0)
>             {
>                
>    // error handling
>             }
> 
>            
> av_free_packet(&pkt);
> 
>     av_free(tmp_picture);
>     delete[] picture_buf;
> }
> 
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
> 


More information about the Libav-user mailing list