<div dir="ltr">My goal is to develop an application which demux and decodes a real-time multiservice mpeg-ts stream (mcpc dvb-s) to create a multi-viewer and an alarm manager.<br>I tested this code (below) but I noticed macroblocks and intolerable cuts (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 or functions that make it easier for me? how to recover 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">192.168.3.3:5501</a>";<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>}<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">Le mar. 18 mai 2021 à 11:02, Nicolas George <<a href="mailto:george@nsup.org">george@nsup.org</a>> a écrit :<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">David Get (12021-05-17):<br>
> I am looking to develop an application in c / c ++ which demux and decodes<br>
> a mpeg ts stream in real time and which contains several tv and radio<br>
> services (mcpc dvb-s), for that I opted to operate the ffmpeg library. I<br>
> work under the unix environment, I installed the library well and I<br>
> succeeded in demuxing and decoding video and audio using the libavformat.<br>
<br>
Good.<br>
<br>
> however, when I see the include / libavformat folder I can't find all the<br>
> headers I need such as mpegts.h mpeg.h .... (I find avformat.h, avio.h and<br>
> internal.h)!<br>
> Is adding headers manually in the libavformation folder correct or not? if<br>
> so why can't I load the MpegTsContext structure with the MpegTSContext *<br>
> function avpriv_mpegts_parse_open (AVFormatContext * s)?<br>
<br>
These headers and functions are not public, they are there to implement<br>
the workings of the FFmpeg libraries, but they are not available to<br>
applications programmers. Only functions and structures whose name<br>
starts in AV are available to you. And not functions whose name starts<br>
with avpriv, that should be pretty obvious.<br>
<br>
Since FFmpeg is Libre Software, you are obviously free to take the<br>
source code and make anything you need available to you. But if you do<br>
that:<br>
<br>
1. It is unlikely you will get help for that.<br>
<br>
2. We will not take your needs into consideration. If we need to change<br>
these structures, and it breaks your project, that would be your<br>
problem.<br>
<br>
> How to track the PIDs of each TV and radio service in real time?<br>
<br>
A much better solution would be for you to describe exactly what you<br>
want to do (I am personally not versed in MPEG-TS enough), what you<br>
tried with the public API and how you think it is not sufficient.<br>
<br>
Regards,<br>
<br>
-- <br>
  Nicolas George<br>
_______________________________________________<br>
Libav-user mailing list<br>
<a href="mailto:Libav-user@ffmpeg.org" target="_blank">Libav-user@ffmpeg.org</a><br>
<a href="https://ffmpeg.org/mailman/listinfo/libav-user" rel="noreferrer" target="_blank">https://ffmpeg.org/mailman/listinfo/libav-user</a><br>
<br>
To unsubscribe, visit link above, or email<br>
<a href="mailto:libav-user-request@ffmpeg.org" target="_blank">libav-user-request@ffmpeg.org</a> with subject "unsubscribe".<br>
</blockquote></div>