Newest 'libx264' Questions - Stack Overflow

http://stackoverflow.com/questions/tagged/libx264

Les articles publiés sur le site

  • streaming H.264 over RTP with libavformat

    16 avril 2012, par Jacob Peddicord

    I've been trying over the past week to implement H.264 streaming over RTP, using x264 as an encoder and libavformat to pack and send the stream. Problem is, as far as I can tell it's not working correctly.

    Right now I'm just encoding random data (x264_picture_alloc) and extracting NAL frames from libx264. This is fairly simple:

    x264_picture_t pic_out;
    x264_nal_t* nals;
    int num_nals;
    int frame_size = x264_encoder_encode(this->encoder, &nals, &num_nals, this->pic_in, &pic_out);
    
    if (frame_size <= 0)
    {
        return frame_size;
    }
    
    // push NALs into the queue
    for (int i = 0; i < num_nals; i++)
    {
        // create a NAL storage unit
        NAL nal;
        nal.size = nals[i].i_payload;
        nal.payload = new uint8_t[nal.size];
        memcpy(nal.payload, nals[i].p_payload, nal.size);
    
        // push the storage into the NAL queue
        {
            // lock and push the NAL to the queue
            boost::mutex::scoped_lock lock(this->nal_lock);
            this->nal_queue.push(nal);
        }
    }
    

    nal_queue is used for safely passing frames over to a Streamer class which will then send the frames out. Right now it's not threaded, as I'm just testing to try to get this to work. Before encoding individual frames, I've made sure to initialize the encoder.

    But I don't believe x264 is the issue, as I can see frame data in the NALs it returns back. Streaming the data is accomplished with libavformat, which is first initialized in a Streamer class:

    Streamer::Streamer(Encoder* encoder, string rtp_address, int rtp_port, int width, int height, int fps, int bitrate)
    {
        this->encoder = encoder;
    
        // initalize the AV context
        this->ctx = avformat_alloc_context();
        if (!this->ctx)
        {
            throw runtime_error("Couldn't initalize AVFormat output context");
        }
    
        // get the output format
        this->fmt = av_guess_format("rtp", NULL, NULL);
        if (!this->fmt)
        {
            throw runtime_error("Unsuitable output format");
        }
        this->ctx->oformat = this->fmt;
    
        // try to open the RTP stream
        snprintf(this->ctx->filename, sizeof(this->ctx->filename), "rtp://%s:%d", rtp_address.c_str(), rtp_port);
        if (url_fopen(&(this->ctx->pb), this->ctx->filename, URL_WRONLY) < 0)
        {
            throw runtime_error("Couldn't open RTP output stream");
        }
    
        // add an H.264 stream
        this->stream = av_new_stream(this->ctx, 1);
        if (!this->stream)
        {
            throw runtime_error("Couldn't allocate H.264 stream");
        }
    
        // initalize codec
        AVCodecContext* c = this->stream->codec;
        c->codec_id = CODEC_ID_H264;
        c->codec_type = AVMEDIA_TYPE_VIDEO;
        c->bit_rate = bitrate;
        c->width = width;
        c->height = height;
        c->time_base.den = fps;
        c->time_base.num = 1;
    
        // write the header
        av_write_header(this->ctx);
    }
    

    This is where things seem to go wrong. av_write_header above seems to do absolutely nothing; I've used wireshark to verify this. For reference, I use Streamer streamer(&enc, "10.89.6.3", 49990, 800, 600, 30, 40000); to initialize the Streamer instance, with enc being a reference to an Encoder object used to handle x264 previously.

    Now when I want to stream out a NAL, I use this:

    // grab a NAL
    NAL nal = this->encoder->nal_pop();
    cout << "NAL popped with size " << nal.size << endl;
    
    // initalize a packet
    AVPacket p;
    av_init_packet(&p);
    p.data = nal.payload;
    p.size = nal.size;
    p.stream_index = this->stream->index;
    
    // send it out
    av_write_frame(this->ctx, &p);
    

    At this point, I can see RTP data appearing over the network, and it looks like the frames I've been sending, even including a little copyright blob from x264. But, no player I've used has been able to make any sense of the data. VLC quits wanting an SDP description, which apparently isn't required.

    I then tried to play it through gst-launch:

    gst-launch udpsrc port=49990 ! rtph264depay ! decodebin ! xvimagesink

    This will sit waiting for UDP data, but when it is received, I get:

    ERROR: element /GstPipeline:pipeline0/GstRtpH264Depay:rtph264depay0: No RTP format was negotiated. Additional debug info: gstbasertpdepayload.c(372): gst_base_rtp_depayload_chain (): /GstPipeline:pipeline0/GstRtpH264Depay:rtph264depay0: Input buffers need to have RTP caps set on them. This is usually achieved by setting the 'caps' property of the upstream source element (often udpsrc or appsrc), or by putting a capsfilter element before the depayloader and setting the 'caps' property on that. Also see http://cgit.freedesktop.org/gstreamer/gst-plugins-good/tree/gst/rtp/README

    As I'm not using GStreamer to stream itself, I'm not quite sure what it means with RTP caps. But, it makes me wonder if I'm not sending enough information over RTP to describe the stream. I'm pretty new to video and I feel like there's some key thing I'm missing here. Any hints?

  • Given an x264 stream and an ogg vorbis stream, how do I make a muxed stream that mplayer/VLC can read ?

    14 avril 2012, par dascandy

    I'm confused and a bit stuck with this question. All I can find on Google is basic usage of transcoding software, which is not related to the question.

    I'm making a game and I'd like to include native capture ability to stream video. I would much like to stream this to a standard-ish client, such as VLC. It needs to be both in a format it recognizes and it needs to be multiplexed in order for this to work.

    My question therefore is, I know how to encode stuff from raw video frames to x264 (see also How to encode series of images into H264 using x264 API? (C/C++) ). I know how to encode raw audio samples into ogg/vorbis. Now, how do I put one and one together for VLC?

  • Tune FFMPEG h264 decoder

    9 avril 2012, par user1002473

    I use FFMPEG avcodec for decode live video. avcodec_decode_video2 function if be more exactly (libx264). How can i make a less decoding time for each frame? Now I have 20 ms by each frame (frame size about 1,5 kbyte)

    Thanks

  • x264 Faster decode speed

    26 mars 2012, par ddlshack

    I'm using x264 to encode videos for a flash video streaming site. I use -tune fastdecode, which turns off cabac and deblock, which I've heard are the features which take most cpu to decode. However, I've still had reports of jerky video playback and high cpu usage.

    Heres a typical encode command:

    ffmpeg -y -i $infile -c:v libx264 -crf 28 -preset slow -vprofile main -tune fastdecode -f h264 -r:v 29.970 -vf "..." $outfile
    

    My users view the videos using flash, on all desktop OSes and a wide variety of hardware.

    Which encoding options are the most cpu-intense, and what are the recommended options for 'reasonable' playback on most machines?

  • Encoding video only FLV

    25 mars 2012, par NadavRub

    I am trying to generate a video only FLV file, I am using:

    1. libx264 + ffmpeg
    2. 30 fps ( fixed )
    3. playback is done using VLC 2.0.1 and flowplayer

    When playing the FLV the frame-rate seems ~1 frame per sec, following is the way I cfg ffmpeg:

    AVOutputFormat* fmtOutput = av_oformat_next(0);
    while((0 != fmtOutput) && (0 != strcmp(fmtOutput->name, "flv")))
        fmtOutput = av_oformat_next(fmtOutput);
    m_pFmtCtxOutput          = avformat_alloc_context();
    m_pFmtCtxOutput->oformat = fmtOutput;
    
    AVStream* pOutVideoStream= av_new_stream(m_pFmtCtxOutput, pInVideoStream->id);
    AVCodec*  videoEncoder   = avcodec_find_encoder(CODEC_ID_H264);
    
    pOutVideoStream->codec->width    = 640;
    pOutVideoStream->codec->height   = 480;
    pOutVideoStream->codec->level    = 30;
    pOutVideoStream->codec->pix_fmt  = PIX_FMT_YUV420P;
    pOutVideoStream->codec->bit_rate = 3000000;
    
    pOutVideoStream->cur_dts         = 0;
    pOutVideoStream->first_dts       = 0;
    pOutVideoStream->index           = 0;
    pOutVideoStream->avg_frame_rate  = (AVRational){ 30, 1 };
    pOutVideoStream->time_base       =
    pOutVideoStream->codec->time_base= (AVRational){ 1, 30000 };
    pOutVideoStream->codec->gop_size = 30;
    %% Some specific libx264 settings %%
    m_dVideoStep                     = 1000;// packet dts/pts is incremented by this amount each frame
    
    pOutVideoStream->codec->flags   |= CODEC_FLAG_GLOBAL_HEADER;
    avcodec_open(pOutVideoStream->codec, videoEncoder);
    

    The resulting file seems OK, with the exception of the playback frame-rate.
    having in mind that:

    1. pOutVideoStream->avg_frame_rate = (AVRational){ 30, 1 };
    2. pOutVideoStream->time_base = (AVRational){ 1, 30000 };
    3. pOutVideoStream->codec->time_base= (AVRational){ 1, 30000 };
    4. For each frame I increment the dts/pts by 1000

    What am I doing wrong here? why the file is playing choppy ( ~1 fps )?

    Any help will be appreciated.

    Nadav at Sophin