<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>