<div dir="ltr"><div class="gmail-adn gmail-ads"><div class="gmail-gs"><div class="gmail-"><div id="gmail-:1y8" class="gmail-ii gmail-gt gmail-adO"><div id="gmail-:1y7" class="gmail-a3s gmail-aiL"><div dir="ltr"><span class="gmail-VIiyi" lang="en"><span class="gmail-JLqJ4b gmail-ChMk0b"><span>I am looking to develop an application which demux and decodes an mpeg ts stream in real time for a multi-viewer (reception multi services tv).</span></span></span> <br></div><div dir="ltr">i tested this code (below) but I noticed macroblocks and intolerable cuts in reception (unusable)<br>In
 my opinion, the problem is that I have to read the psi / si table well 
to recover the data necessary for the demuxing and decoding, the thing 
that I could not do with the libav functions? Are there any APIs ? how to get the psi / si table?<br>+++++++++++++++++++++++++++++++++<br>#include <stdio.h><br>#include <stdlib.h><br>#include <stdbool.h><br>#include <time.h><br>#include <windows.h><br>#include <libavcodec/avcodec.h><br>#include <libavformat/avformat.h><br>#include <SDL.h><br><br>void display(AVCodecContext* ctx, AVPacket* pkt, AVFrame* frame, SDL_Rect* rect,<br>    SDL_Texture* texture, SDL_Renderer* renderer, double fpsrend);<br><br>int main(int argc, char* argv[]) {<br>   <br>    char* url = "rtp://<a href="http://192.168.3.3:5501" target="_blank">192.168.3.3:5501</a>"; //src rtp stream mpeg ts dvb-s<br>    // ffmpeg part<br>    AVFormatContext* pFormatCtx;<br>    AVFormatContext* ppf;<br>    int vidId = -1;<br>    double fpsrendering = 0.0;<br>    AVCodecContext* vidCtx;<br>    AVCodec* vidCodec=NULL;<br>    AVCodecParameters* vidpar=NULL;<br>    AVFrame* vframe;<br>    AVPacket* packet=NULL;<br>    <br>     //sdl part<br>    int swidth, sheight;<br>    SDL_Window* screen;<br>    SDL_Renderer* renderer;<br>    SDL_Texture* texture;<br>    SDL_Rect rect;<br>    //SDL_AudioDeviceID auddev;<br>    //SDL_AudioSpec want, have;<br><br>    SDL_Init(SDL_INIT_EVERYTHING);<br>    pFormatCtx = avformat_alloc_context();<br>    ppf = avformat_alloc_context();<br>   // char bufmsg[1024];<br><br>    if (avformat_open_input(&pFormatCtx, url , NULL, NULL) < 0) {<br>        printf("Cannot open %s", url);<br>       <br>    }<br>    if (avformat_find_stream_info(pFormatCtx, NULL) < 0) {<br>        perror("Cannot find stream info. Quitting.");<br>        goto clean_format_context;<br>    }<br><br>    int val = avformat_flush(pFormatCtx);<br>    //int p = pFormatCtx->programs->program_num==54;<br>    bool foundVideo = false;<br>    for (int i = 0; i < pFormatCtx->nb_streams; i++)<br>    {<br>        AVCodecParameters* localparam = pFormatCtx->streams[i]->codecpar;<br>        AVCodec* localcodec = avcodec_find_decoder(localparam->codec_id);<br> 
       if (localparam->codec_type == AVMEDIA_TYPE_VIDEO && 
localparam->codec_id == AV_CODEC_ID_MPEG2VIDEO && 
!foundVideo) {<br>            vidCodec = localcodec;<br>            vidpar = localparam;<br>            vidId = i;<br>            AVRational rational = pFormatCtx->streams[i]->avg_frame_rate;<br>            fpsrendering = 1.0 / ((double)rational.num / (double)(rational.den));<br>            foundVideo = true;<br>        }<br>        if (foundVideo) { break; }<br>    }<br>   <br><br><br>    vidCtx = avcodec_alloc_context3(vidCodec);<br><br>    if (avcodec_parameters_to_context(vidCtx, vidpar) < 0) {<br>        perror("vidCtx");<br>        goto clean_codec_context;<br>    }<br><br>    if (avcodec_open2(vidCtx, vidCodec, NULL) < 0) {<br>        perror("vidCtx");<br>        goto clean_codec_context;<br>    }<br><br>    vframe = av_frame_alloc();<br><br>    packet = av_packet_alloc();<br>    swidth = vidpar->width;<br>    sheight = vidpar->height;<br>    screen = SDL_CreateWindow("ouldji_V", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,<br>        swidth, sheight, SDL_WINDOW_RESIZABLE);<br>    if (!screen) {<br>        perror("screen");<br>        goto clean_packet_frame;<br>    }<br>    renderer = SDL_CreateRenderer(screen, -1, SDL_RENDERER_ACCELERATED);<br>    if (!renderer) {<br>        perror("renderer");<br>        goto clean_renderer;<br>    }<br>    texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_IYUV,<br>        SDL_TEXTUREACCESS_STREAMING | SDL_TEXTUREACCESS_TARGET,<br>        swidth, sheight);<br>    if (!texture) {<br>        perror("texture");<br>        goto clean_texture;<br>    }<br>    rect.x = 0;<br>    rect.y = 0;<br>    rect.w = swidth;<br>    rect.h = sheight;<br><br>    SDL_Event evt;<br>    uint32_t windowID = SDL_GetWindowID(screen);<br>    bool running = true;<br>    while (running) {<br>        while (av_read_frame(pFormatCtx, packet) >= 0)<br>        {<br>            while (SDL_PollEvent(&evt))<br>            {<br>                switch (evt.type) {<br>                case SDL_WINDOWEVENT: {<br>                    if (evt.window.windowID == windowID) {<br>                        switch (evt.window.event) {<br>                        case SDL_WINDOWEVENT_CLOSE: {<br>                            evt.type = SDL_QUIT;<br>                            running = false;<br>                            SDL_PushEvent(&evt);<br>                            break;<br>                        }<br>                        };<br>                    }<br>                    break;<br>                }<br>                case SDL_QUIT: {<br>                    running = false;<br>                    break;<br>                }<br>                }<br>            }<br><br>            if (packet->stream_index == vidId) {<br>                display(vidCtx, packet, vframe, &rect,<br>                    texture, renderer, fpsrendering);<br><br>            }<br>            av_packet_unref(packet);<br>        }<br>    }<br><br><br>    //clean_audio_device:<br>   // SDL_CloseAudioDevice(auddev);<br>clean_texture:<br>    SDL_DestroyTexture(texture);<br>clean_renderer:<br>    SDL_DestroyRenderer(renderer);<br>    SDL_DestroyWindow(screen);<br>clean_packet_frame:<br>    av_packet_free(&packet);<br>    av_frame_free(&vframe);<br>    //av_frame_free(&aframe);<br>clean_codec_context:<br>    avcodec_free_context(&vidCtx);<br>    // avcodec_free_context(&audCtx);<br>clean_format_context:<br>    avformat_close_input(&pFormatCtx);<br>    avformat_free_context(pFormatCtx);<br><br>    SDL_Quit();<br>  //  free(mtsc);<br>    return 0;<br>}<br><br><br>void display(AVCodecContext* ctx, AVPacket* pkt, AVFrame* frame, SDL_Rect* rect,<br>    SDL_Texture* texture, SDL_Renderer* renderer, double fpsrend)<br>{<br>    time_t start = time(NULL);<br>    if (avcodec_send_packet(ctx, pkt) < 0) {<br>        perror("send packet");<br>        return;<br>    }<br>    if (avcodec_receive_frame(ctx, frame) < 0) {<br>        perror("receive frame");<br>        return;<br>    }<br>    int framenum = ctx->frame_number;<br>    if ((framenum % 1000) == 0) {<br>        printf("Frame %d (size=%d pts %lld dts %lld key_frame %d"<br>            " [ codec_picture_number %d, display_picture_number %d\n",<br>            framenum, frame->pkt_size, frame->pts, frame->pkt_dts, frame->key_frame,<br>            frame->coded_picture_number, frame->display_picture_number);<br>    }<br>    SDL_UpdateYUVTexture(texture, rect,<br>        frame->data[0], frame->linesize[0],<br>        frame->data[1], frame->linesize[1],<br>        frame->data[2], frame->linesize[2]);<br>    SDL_RenderClear(renderer);<br>    SDL_RenderCopy(renderer, texture, NULL, rect);<br>    SDL_RenderPresent(renderer);<br>    time_t end = time(NULL);<br>    double diffms = difftime(end, start) / 1000.0;<br>    if (diffms < fpsrend) {<br>        uint32_t diff = (uint32_t)((fpsrend - diffms) * 1000);<br>        printf("diffms: %f, delay time %d ms.\n", diffms, diff);<br>        SDL_Delay(diff);<br>    }<br>}<div class="gmail-yj6qo gmail-ajU"><div id="gmail-:1ym" class="gmail-ajR" tabindex="0"><img class="gmail-ajT" src="https://ssl.gstatic.com/ui/v1/icons/mail/images/cleardot.gif"></div></div></div></div></div></div></div></div><div class="gmail-gA gmail-gt gmail-acV"><div class="gmail-gB gmail-xu"><div class="gmail-ip gmail-iq"><div id="gmail-:1y9"><table class="gmail-cf gmail-wS"><tbody><tr><td class="gmail-amq"><img id="gmail-:x2_30" name=":x2" src="https://lh3.googleusercontent.com/a-/AOh14GjhJXJQSSLA_wzqks8nkqCQ_jeiLZ2O_pYwcUnB=s40" class="gmail-ajn gmail-bofPge"></td><td class="gmail-amr"><br></td></tr></tbody></table></div></div></div></div></div>