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

Mark Fonnemann markf78 at yahoo.com
Sun Jul 31 03:42:22 CEST 2011


So, after figuratively pulling my hair out the past couple of dats, i found the solution. It seems that this line:

codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER

was the offending line. Changing that line to this:

// some formats want stream headers to be separate
if (muxer->oformat->flags & AVFMT_GLOBALHEADER)
	codecContext->flags |= CODEC_FLAG_GLOBAL_HEADER;

remedies the problem. Not exactly sure why and if anyone can explain this further that would be great.

mark.

--- On Fri, 7/29/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: Friday, July 29, 2011, 4:37 PM
> 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
> > 
> _______________________________________________
> Libav-user mailing list
> Libav-user at ffmpeg.org
> http://ffmpeg.org/mailman/listinfo/libav-user
> 


More information about the Libav-user mailing list