Hello,

we are trying to change ffserver.c to open several mpegts raw files and
start streaming them to a Set Top Box than only reads TS packets. We don't
need to demux the files into streams just send them. For this we have
changed the rtp_new_av_stream function as in the solution you give:


static int rtp_new_av_stream(HTTPContext *c,
                             int stream_index, struct sockaddr_in
*dest_addr,
                             HTTPContext *rtsp_c)
{

        int res=0;
char *ipaddr;
        

        AVFormatContext *tscontext = av_alloc_format_context();
        if (!tscontext) return -1;
        http_log("Reservamos memoria para tscontext\r\n");
        tscontext->oformat = av_guess_format("mpegts",NULL,NULL);
        http_log("Despues de guess_format\r\n");

        AVStream *fakevideo = 0;
        fakevideo = av_new_stream(tscontext,0);        //Videostream as 
fakeinput
MPEG-TS
        http_log("Creamos el fakevideo\r\n");
        if (!fakevideo) return -1;
        avcodec_get_context_defaults(fakevideo->codec);
        fakevideo->codec->codec_id = CODEC_ID_MPEG2TS;

        tscontext->audio_codec_id = CODEC_ID_NONE;
        tscontext->video_codec_id = CODEC_ID_MPEG2TS;
        
        res = av_set_parameters(tscontext,0);
        
        
        
        
            ipaddr = inet_ntoa(dest_addr->sin_addr);
        if (c->stream->is_multicast) {
            int ttl;
            ttl = c->stream->multicast_ttl;
            if (!ttl)
                ttl = 16;
            snprintf(tscontext->filename, sizeof(tscontext->filename),
                     "rtp://%s:%d?multicast=1&ttl=%d&pkt_size=1316",
                     ipaddr, ntohs(dest_addr->sin_port), ttl);
        } else {
            snprintf(tscontext->filename, sizeof(tscontext->filename),
                     "rtp://%s:%d?pkt_size=1316", ipaddr,
ntohs(dest_addr->sin_port));
                
        }

         
         if (url_open(&tscontext->pb, tscontext->filename, URL_WRONLY) < 0)
         goto fail;

        
        
        
        
         
        c->rtp_handles[stream_index] = tscontext->pb;
        

        

        //3. OK to initialize outputs call av_write_header() for both contexts
        
        
        if (av_write_header(tscontext) < 0) {

fail:
        
        if (tscontext->pb)
            url_close(tscontext->pb);
        av_free(tscontext);
        return -1;
    
    }
  
        
    c->rtp_ctx[stream_index] = tscontext;

        return 0;
        }


And we have changed the code where the ffserver is sending packets
(http_preparedata function) like this:

case HTTPSTATE_SEND_DATA:
        /* find a new packet */
        /* read a packet from the input stream */
        if (c->stream->feed)
            ffm_set_write_index(c->fmt_in,
                                c->stream->feed->feed_write_index,
                                c->stream->feed->feed_size);

        if (c->stream->max_time &&
            c->stream->max_time + c->start_time - cur_time < 0)
            /* We have timed out */
            c->state = HTTPSTATE_SEND_DATA_TRAILER;
        else {

                
                        
                        AVPacket avpkt;
                        AVPacket tspkt;
                        AVCodecContext *codec;
                        uint8_t *videobuf;
                        uint8_t *destbuff;
                        int res=0;
                        int len;
                         int videobuf_size;
                        AVStream *ist;
                        int enc_size =0;
                        AVFrame *outframe;
                         ByteIOContext *ioctx;
                        if (res = url_open_dyn_buf(&ioctx))
                        {
                                return -1;
                        }
                        c->pb = ioctx; 
                        
                        av_init_packet(&avpkt); // ts-packet
                        av_init_packet(&tspkt); // rtp-packet
                        //int source_index = avpkt.stream_index;
                        ist = c->fmt_in->streams[0];
                        ctx = c->rtp_ctx[c->packet_stream_index];
                        if(!ctx) {
                            
                            av_free_packet(&avpkt);
                            break;
                        }
                        codec = ctx->streams[0]->codec;
                        
                       avpkt.stream_index = 0;
                        outframe = alloc_picture(codec->pix_fmt, codec->width, 
codec->height);
                        if (!outframe)
                        {
                                
                                exit(1);

                        }
                   
                        outframe->interlaced_frame = 1; //if wanted and in 
video parameters
defined
                        outframe->top_field_first = 1;

                        enc_size = avcodec_encode_video(codec, videobuf 
,videobuf_size,outframe);
// encode videoframe

                        if (enc_size > 0)
                        {
                                if (codec->coded_frame->key_frame)
                                {
                                        avpkt.flags |= PKT_FLAG_KEY;
                                }

                                avpkt.size= enc_size;
                                avpkt.pts = 
av_rescale_q(codec->coded_frame->pts,
                                codec->time_base, ist->time_base);
                                avpkt.stream_index= ist->index;
                                avpkt.data= videobuf;

                                // write into the dyn_buf (ts-context)
                                ret = av_interleaved_write_frame(c, &avpkt);

                                //close the buffer to read the bytes
                                len = url_close_dyn_buf(ioctx, &destbuff);

                                //prepare the packet for rtp
                                tspkt.size = len;
                                tspkt.data = destbuff;

                                //write to output , not sure if _interleaved_ 
is the right call
                                av_interleaved_write_frame(ctx, &tspkt);
                                av_free(destbuff);

                                //open new buffer for the next frame
                                if (res = url_open_dyn_buf(&ioctx))
                                {
                                        return -1;
                                }

                        }
                        av_free_packet(&avpkt);
                        av_free_packet(&tspkt);

        

Can anyone help us to make this work? We have spent a lot of time trying to
send ts packets to the STB and don't know what are we doing wrong.

Thank you very much

Kind regards

-- 
View this message in context: 
http://libav-users.943685.n4.nabble.com/Output-mpeg-ts-to-rtp-tp2234066p3263370.html
Sent from the libav-users mailing list archive at Nabble.com.
_______________________________________________
libav-user mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/libav-user

Reply via email to