Recherche avancée

Médias (16)

Mot : - Tags -/mp3

Autres articles (46)

  • La sauvegarde automatique de canaux SPIP

    1er avril 2010, par

    Dans le cadre de la mise en place d’une plateforme ouverte, il est important pour les hébergeurs de pouvoir disposer de sauvegardes assez régulières pour parer à tout problème éventuel.
    Pour réaliser cette tâche on se base sur deux plugins SPIP : Saveauto qui permet une sauvegarde régulière de la base de donnée sous la forme d’un dump mysql (utilisable dans phpmyadmin) mes_fichiers_2 qui permet de réaliser une archive au format zip des données importantes du site (les documents, les éléments (...)

  • Publier sur MédiaSpip

    13 juin 2013

    Puis-je poster des contenus à partir d’une tablette Ipad ?
    Oui, si votre Médiaspip installé est à la version 0.2 ou supérieure. Contacter au besoin l’administrateur de votre MédiaSpip pour le savoir

  • HTML5 audio and video support

    13 avril 2011, par

    MediaSPIP uses HTML5 video and audio tags to play multimedia files, taking advantage of the latest W3C innovations supported by modern browsers.
    The MediaSPIP player used has been created specifically for MediaSPIP and can be easily adapted to fit in with a specific theme.
    For older browsers the Flowplayer flash fallback is used.
    MediaSPIP allows for media playback on major mobile platforms with the above (...)

Sur d’autres sites (9721)

  • Use libavcodec on MPEG-TS to transcode video and copy audio

    16 août 2017, par Danny

    I’m trying to use libavcodec to reduce the video bitrate of an MPEG transport stream while passing audio streams unchanged. The equivalent ffmpeg command line would be :

    ffmpeg -i SPTS_HD_2min.prog.ts -b:v 800k -s cif -map 0:0 -map 0:1 -map 0:2 -c:a copy ./transcodeCLI.ts

    The input file contains :

    Input #0, mpegts, from 'SPTS_HD_2min.program8.ts': Duration: 00:02:01.56 bitrate: 10579 kb/s
    Program 1
     Stream #0:0[0x21]: Video: h264 (High) ([27][0][0][0] / 0x001B), yuv420p(tv, bt709, top first), 1920x1080 [SAR 1:1 DAR 16:9], 25 fps, 25 tbr, 90k tbn, 50 tbc
     Stream #0:1[0x61](eng): Audio: ac3 (AC-3 / 0x332D4341), 48000 Hz, 5.1(side), fltp, 384 kb/s
     Stream #0:2[0x63](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, s16p, 192 kb/s

    Using the transcoding.c example, the program does generate a valid transport stream. However, the file does not play. Also, analysis tools show the file duration as almost twice as long. Something is not right.

    The program is simple : read, encode, write in a loop. The codec context for the video stream is set for a lower bit rate and width/height.

    I’ve tinkered with it for a long time without success, but nothing I set gets the expected behavior...

    The very summarized source is directly below. (I’ve removed variable defs, error checking and debug messages for brevity).

    EDIT

    And I’ve included the full, compilable, source code just after that.

    EDIT II

    The MPEG-TS test file can be downloaded from this sharing server

    typedef struct StreamContext
    {
       AVCodecContext *decodeCtx;
       AVCodecContext *encodeCtx;
    } StreamContext;
    static StreamContext *streamCtx;


    static int
    openInputFile(const char *filename)
    {
       inFormatCtx = NULL;
       ret = avformat_open_input(&inFormatCtx, filename, NULL, NULL);
       ret = avformat_find_stream_info(inFormatCtx, NULL)
       streamCtx = av_mallocz_array(inFormatCtx->nb_streams, sizeof(*streamCtx));

       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           AVStream *stream = inFormatCtx->streams[i];
           AVCodec     *dec = avcodec_find_decoder(stream->codecpar->codec_id);
           AVCodecContext *pCodecCtx = avcodec_alloc_context3(dec);

           ret = avcodec_parameters_to_context(pCodecCtx, stream->codecpar);

           if (pCodecCtx->codec_type == AVMEDIA_TYPE_VIDEO || pCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO)
           {
               if (pCodecCtx->codec_type == AVMEDIA_TYPE_VIDEO)
                   pCodecCtx->framerate = av_guess_frame_rate(inFormatCtx, stream, NULL);

               /* Open decoder */
               ret = avcodec_open2(pCodecCtx, dec, NULL);
           }
           streamCtx[i].decodeCtx = pCodecCtx;
       }
       return 0;
    }

    static int
    openOutputFile(const char *filename)
    {
       outFormatCtx = NULL;
       avformat_alloc_output_context2(&outFormatCtx, NULL, NULL, filename);

       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           out_stream = avformat_new_stream(outFormatCtx, NULL);
           in_stream  = inFormatCtx->streams[i];
           decodeCtx  = streamCtx[i].decodeCtx;

           if (decodeCtx->codec_type == AVMEDIA_TYPE_VIDEO || decodeCtx->codec_type == AVMEDIA_TYPE_AUDIO)
           {
               encoder = avcodec_find_encoder(decodeCtx->codec_id);
               pEncodeCtx = avcodec_alloc_context3(encoder);

               if (decodeCtx->codec_type == AVMEDIA_TYPE_VIDEO)
               {
                   // MAKE IT SMALLER!
                   pEncodeCtx->height = decodeCtx->height / 4;
                   pEncodeCtx->width  = decodeCtx->width  / 4;
                   pEncodeCtx->sample_aspect_ratio = decodeCtx->sample_aspect_ratio;

                   // perhaps set these too?
                   pEncodeCtx->bit_rate = 700000;
                   pEncodeCtx->bit_rate_tolerance = 0;
                   pEncodeCtx->framerate = decodeCtx->framerate;
                   pEncodeCtx->time_base = decodeCtx->time_base;

                   /* take first format from list of supported formats */
                   if (encoder->pix_fmts)
                       pEncodeCtx->pix_fmt = encoder->pix_fmts[0];
                   else
                       pEncodeCtx->pix_fmt = decodeCtx->pix_fmt;

                   /* video time_base can be set to whatever is handy and supported by encoder */
                   pEncodeCtx->time_base = av_inv_q(decodeCtx->framerate);
               }
               else
               {
                   pEncodeCtx->sample_rate    = decodeCtx->sample_rate;
                   pEncodeCtx->channel_layout = decodeCtx->channel_layout;
                   pEncodeCtx->channels = av_get_channel_layout_nb_channels(pEncodeCtx->channel_layout);
                   /* take first format from list of supported formats */
                   pEncodeCtx->sample_fmt = encoder->sample_fmts[0];
                   pEncodeCtx->time_base  = (AVRational) { 1, pEncodeCtx->sample_rate };
               }

               ret = avcodec_open2(pEncodeCtx, encoder, NULL);
               ret = avcodec_parameters_from_context(out_stream->codecpar, pEncodeCtx);

               if (outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
                   pEncodeCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

               out_stream->time_base = pEncodeCtx->time_base;
               streamCtx[i].encodeCtx = pEncodeCtx;
           }
           else if (decodeCtx->codec_type == AVMEDIA_TYPE_UNKNOWN)
               return AVERROR_INVALIDDATA;
           else
           {
               /* if this stream must be remuxed */
               ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
               out_stream->time_base = in_stream->time_base;
           }

       }
       av_dump_format(outFormatCtx, 0, filename, 1);

       if (!(outFormatCtx->oformat->flags & AVFMT_NOFILE))
           ret = avio_open(&outFormatCtx->pb, filename, AVIO_FLAG_WRITE);

       /* init muxer, write output file header */
       ret = avformat_write_header(outFormatCtx, NULL);

       return 0;
    }

    static int
    encodeAndWriteFrame(AVFrame *inFrame, unsigned int streamIndex, int *pGotFrame)
    {
       encodedPkt.data = NULL;
       encodedPkt.size = 0;
       av_init_packet(&encodedPkt);

       int codecType = inFormatCtx->streams[streamIndex]->codecpar->codec_type;

       if (codecType == AVMEDIA_TYPE_VIDEO)
           ret = avcodec_encode_video2(streamCtx[streamIndex].encodeCtx, &encodedPkt, inFrame, pGotFrame);
       else
           ret = avcodec_encode_audio2(streamCtx[streamIndex].encodeCtx, &encodedPkt, inFrame, pGotFrame);

       if (*pGotFrame == 0)
           return 0;

       /* prepare packet for muxing */
       encodedPkt.stream_index = streamIndex;
       av_packet_rescale_ts(&encodedPkt, streamCtx[streamIndex].encodeCtx->time_base, outFormatCtx->streams[streamIndex]->time_base);

       /* mux encoded frame */
       ret = av_interleaved_write_frame(outFormatCtx, &encodedPkt);
       return ret;
    }

    int
    main(int argc, char **argv)
    {
       av_register_all();
       avfilter_register_all();

       if ((ret = openInputFile(argv[1])) < 0)
           goto end;
       if ((ret = openOutputFile(argv[2])) < 0)
           goto end;

       /* read all packets */
       while (1)
       {
           if ((ret = av_read_frame(inFormatCtx, &packet)) < 0)
               break;
           readPktNum++;

           streamIndex = packet.stream_index;
           type = inFormatCtx->streams[packet.stream_index]->codecpar->codec_type;
           av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", streamIndex);

           if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)
           {
               pDecFrame = av_frame_alloc();

               av_packet_rescale_ts(&packet, inFormatCtx->streams[streamIndex]->time_base, streamCtx[streamIndex].decodeCtx->time_base);

               if (type == AVMEDIA_TYPE_VIDEO)
                   ret = avcodec_decode_video2(streamCtx[streamIndex].decodeCtx, pDecFrame, &gotDecFrame, &packet);
               else
                   ret = avcodec_decode_audio4(streamCtx[streamIndex].decodeCtx, pDecFrame, &gotDecFrame, &packet);

               if (gotDecFrame)
               {
                   pDecFrame->pts = av_frame_get_best_effort_timestamp(pDecFrame);

                   ret = encodeAndWriteFrame(pDecFrame, streamIndex, 0);
                   av_frame_free(&pDecFrame);
                   if (ret < 0)
                       goto end;
               }
               else
                   av_frame_free(&pDecFrame);
           }
           else
           {
               /* remux this frame without reencoding */
               av_packet_rescale_ts(&packet, inFormatCtx->streams[streamIndex]->time_base, outFormatCtx->streams[streamIndex]->time_base);

               ret = av_interleaved_write_frame(outFormatCtx, &packet);
               if (ret < 0)
                   goto end;
           }
           av_packet_unref(&packet);
       }

       /* flush encoders */
       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           /* flush encoder */
           ret = flushEncoder(i);
       }

       av_write_trailer(outFormatCtx);

    end:
       av_packet_unref(&packet);
       av_frame_free(&pDecFrame);
       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           avcodec_free_context(&streamCtx[i].decodeCtx);
           if (outFormatCtx && outFormatCtx->nb_streams > i && outFormatCtx->streams[i] && streamCtx[i].encodeCtx)
               avcodec_free_context(&streamCtx[i].encodeCtx);
       }

       av_free(streamCtx);
       avformat_close_input(&inFormatCtx);

       if (outFormatCtx && !(outFormatCtx->oformat->flags & AVFMT_NOFILE))
           avio_closep(&outFormatCtx->pb);

       avformat_free_context(outFormatCtx);

       return ret ? 1 : 0;
    }

    **EDIT - Full source **

    /**
    * @file
    * API example for demuxing, decoding, filtering, encoding and muxing
    * @example transcoding.c
    */

    #include "libavcodec/avcodec.h"
    #include "libavformat/avformat.h"
    #include "libavfilter/avfiltergraph.h"
    #include "libavfilter/buffersink.h"
    #include "libavfilter/buffersrc.h"
    #include "libavutil/opt.h"
    #include "libavutil/pixdesc.h"

    #define ANSI_COLOR_RED     "\x1b[31m"
    #define ANSI_COLOR_PINK    "\x1b[31;1m"
    #define ANSI_COLOR_GREEN   "\x1b[32m"
    #define ANSI_COLOR_LIME    "\x1b[32;1m"
    #define ANSI_COLOR_YELLOW  "\x1b[33;1m"
    #define ANSI_COLOR_BLUE    "\x1b[34;1m"
    #define ANSI_COLOR_MAGENTA "\x1b[35m"
    #define ANSI_COLOR_CYAN    "\x1b[36;1m"
    #define ANSI_COLOR_RESET   "\x1b[0m"

    #define true 1
    #define false 0

    static int readPktNum  = 0;
    static int decFrameNum = 0;
    static int encFrameNum = 0;

    static AVFormatContext *inFormatCtx;
    static AVFormatContext *outFormatCtx;

    typedef struct StreamContext
    {
       AVCodecContext *decodeCtx;
       AVCodecContext *encodeCtx;
    } StreamContext;
    static StreamContext *streamCtx;

    void
    writeAVFrameAsYUVFile(const char *filePath, AVFrame *pFrame)
    {
       printf("Writing YUV file: %d x %d\n", pFrame->width, pFrame->height);
       FILE *pFile = fopen(filePath, "wb");
       if (!pFile)
           return;

       int y;

       // Writing Y
       for (y=0; y < pFrame->height; y++)
           fwrite(&pFrame->data[0][pFrame->linesize[0] * y], pFrame->width, 1, pFile);

       // Writing U
       for (y=0; y < pFrame->height/2; y++)
           fwrite(&pFrame->data[1][pFrame->linesize[1] * y], pFrame->width/2, 1, pFile);

       // Writing V
       for (y=0; y < pFrame->height/2; y++)
           fwrite(&pFrame->data[2][pFrame->linesize[2] * y], pFrame->width/2, 1, pFile);

       fclose(pFile);
       printf("Wrote %s: %d x %d\n", filePath, pFrame->width, pFrame->height);
    }

    static void
    dumpCodecContext(const AVCodecContext *pCodecContext)
    {
       printf("Codec Context:\n");
       printf(" bit rate           %d\n",      (int)pCodecContext->bit_rate);
       printf(" bit rate tolerance %d\n",      pCodecContext->bit_rate_tolerance);
       printf(" size               %d x %d\n", pCodecContext->width, pCodecContext->height);
       printf(" GOP Size           %d\n",      pCodecContext->gop_size);
       printf(" Max B Frames       %d\n",      pCodecContext->max_b_frames);

       printf(" Sample Aspect      %d:%d (%.3f)\n",
           pCodecContext->sample_aspect_ratio.num, pCodecContext->sample_aspect_ratio.den,
           1.0 * pCodecContext->sample_aspect_ratio.num / pCodecContext->sample_aspect_ratio.den);

       printf(" framerate          %d / %d (%.3f fps)\n",
           pCodecContext->framerate.num, pCodecContext->framerate.den,
           1.0 * pCodecContext->framerate.den / pCodecContext->framerate.num);

       printf(" time_base          %d / %d (%.3f fps)\n",
           pCodecContext->time_base.num, pCodecContext->time_base.den,
           1.0 * pCodecContext->time_base.den / pCodecContext->time_base.num);
    }

    static int
    openInputFile(const char *filename)
    {
       int ret;
       unsigned int i;

       inFormatCtx = NULL;
       if ((ret = avformat_open_input(&inFormatCtx, filename, NULL, NULL)) < 0)
       {
           av_log(NULL, AV_LOG_ERROR, "Cannot open input file\n");
           return ret;
       }

       if ((ret = avformat_find_stream_info(inFormatCtx, NULL)) < 0)
       {
           av_log(NULL, AV_LOG_ERROR, "Cannot find stream information\n");
           return ret;
       }

       streamCtx = av_mallocz_array(inFormatCtx->nb_streams, sizeof(*streamCtx));
       if (!streamCtx)
           return AVERROR(ENOMEM);

       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           AVStream *stream = inFormatCtx->streams[i];
           AVCodec *dec = avcodec_find_decoder(stream->codecpar->codec_id);
           AVCodecContext *pCodecCtx;
           if (!dec)
           {
               av_log(NULL, AV_LOG_ERROR, "Failed to find decoder for stream #%u\n", i);
               return AVERROR_DECODER_NOT_FOUND;
           }

           pCodecCtx = avcodec_alloc_context3(dec);
           if (!pCodecCtx)
           {
               av_log(NULL, AV_LOG_ERROR, "Failed to allocate the decoder context for stream #%u\n", i);
               return AVERROR(ENOMEM);
           }

           ret = avcodec_parameters_to_context(pCodecCtx, stream->codecpar);
           if (ret < 0)
           {
               av_log(NULL, AV_LOG_ERROR, "Failed to copy decoder parameters to input decoder context for stream #%u\n", i);
               return ret;
           }

           /* Reencode video & audio and remux subtitles etc. */
           if (pCodecCtx->codec_type == AVMEDIA_TYPE_VIDEO || pCodecCtx->codec_type == AVMEDIA_TYPE_AUDIO)
           {
               if (pCodecCtx->codec_type == AVMEDIA_TYPE_VIDEO)
                   pCodecCtx->framerate = av_guess_frame_rate(inFormatCtx, stream, NULL);

               /* Open decoder */
               ret = avcodec_open2(pCodecCtx, dec, NULL);
               if (ret < 0)
               {
                   av_log(NULL, AV_LOG_ERROR, "Failed to open decoder for stream #%u\n", i);
                   return ret;
               }
           }
           streamCtx[i].decodeCtx = pCodecCtx;
       }

       av_dump_format(inFormatCtx, 0, filename, 0);
       return 0;
    }

    static int
    openOutputFile(const char *filename)
    {
       AVStream *out_stream;
       AVStream *in_stream;
       AVCodecContext *decodeCtx, *pEncodeCtx;
       AVCodec *encoder;
       int ret;
       unsigned int i;

       outFormatCtx = NULL;
       avformat_alloc_output_context2(&outFormatCtx, NULL, NULL, filename);
       if (!outFormatCtx)
       {
           av_log(NULL, AV_LOG_ERROR, "Could not create output context\n");
           return AVERROR_UNKNOWN;
       }

       for (i = 0; i < inFormatCtx->nb_streams; i++)
       {
           out_stream = avformat_new_stream(outFormatCtx, NULL);
           if (!out_stream)
           {
               av_log(NULL, AV_LOG_ERROR, "Failed allocating output stream\n");
               return AVERROR_UNKNOWN;
           }

           in_stream = inFormatCtx->streams[i];
           decodeCtx = streamCtx[i].decodeCtx;

           if (decodeCtx->codec_type == AVMEDIA_TYPE_VIDEO || decodeCtx->codec_type == AVMEDIA_TYPE_AUDIO)
           {
               /* in this example, we choose transcoding to same codec */
               encoder = avcodec_find_encoder(decodeCtx->codec_id);
               if (!encoder)
               {
                   av_log(NULL, AV_LOG_FATAL, "Necessary encoder not found\n");
                   return AVERROR_INVALIDDATA;
               }
               pEncodeCtx = avcodec_alloc_context3(encoder);
               if (!pEncodeCtx)
               {
                   av_log(NULL, AV_LOG_FATAL, "Failed to allocate the encoder context\n");
                   return AVERROR(ENOMEM);
               }

               /* In this example, we transcode to same properties (picture size,
                * sample rate etc.). These properties can be changed for output
                * streams easily using filters */
               if (decodeCtx->codec_type == AVMEDIA_TYPE_VIDEO)
               {
                   printf("DECODE CONTEXT "); dumpCodecContext(decodeCtx);

                   // MAKE IT SMALLER!
                   pEncodeCtx->height = decodeCtx->height / 4;
                   pEncodeCtx->width  = decodeCtx->width  / 4;
                   pEncodeCtx->sample_aspect_ratio = decodeCtx->sample_aspect_ratio;

                   // perhaps set these too?
                   pEncodeCtx->bit_rate = 700000;
                   pEncodeCtx->bit_rate_tolerance = 0;
                   pEncodeCtx->framerate = decodeCtx->framerate;
                   pEncodeCtx->time_base = decodeCtx->time_base;

                   printf("ENCODE CONTEXT "); dumpCodecContext(pEncodeCtx);

                   /* take first format from list of supported formats */
                   if (encoder->pix_fmts)
                       pEncodeCtx->pix_fmt = encoder->pix_fmts[0];
                   else
                       pEncodeCtx->pix_fmt = decodeCtx->pix_fmt;

                   /* video time_base can be set to whatever is handy and supported by encoder */
                   pEncodeCtx->time_base = av_inv_q(decodeCtx->framerate);
               }
               else
               {
                   pEncodeCtx->sample_rate    = decodeCtx->sample_rate;
                   pEncodeCtx->channel_layout = decodeCtx->channel_layout;
                   pEncodeCtx->channels = av_get_channel_layout_nb_channels(pEncodeCtx->channel_layout);
                   /* take first format from list of supported formats */
                   pEncodeCtx->sample_fmt = encoder->sample_fmts[0];
                   pEncodeCtx->time_base  = (AVRational) { 1, pEncodeCtx->sample_rate };
               }

               /* Third parameter can be used to pass settings to encoder */
               ret = avcodec_open2(pEncodeCtx, encoder, NULL);
               if (ret < 0)
               {
                   av_log(NULL, AV_LOG_ERROR, "Cannot open video encoder for stream #%u\n", i);
                   return ret;
               }

               ret = avcodec_parameters_from_context(out_stream->codecpar, pEncodeCtx);
               if (ret < 0)
               {
                   av_log(NULL, AV_LOG_ERROR, "Failed to copy encoder parameters to output stream #%u\n", i);
                   return ret;
               }

               if (outFormatCtx->oformat->flags & AVFMT_GLOBALHEADER)
                   pEncodeCtx->flags |= AV_CODEC_FLAG_GLOBAL_HEADER;

               out_stream->time_base = pEncodeCtx->time_base;
               streamCtx[i].encodeCtx = pEncodeCtx;
           }
           else if (decodeCtx->codec_type == AVMEDIA_TYPE_UNKNOWN)
           {
               av_log(NULL, AV_LOG_FATAL, "Elementary stream #%d is of unknown type, cannot proceed\n", i);
               return AVERROR_INVALIDDATA;
           }
           else
           {
               printf("STREAM %d is not video or audio\n", i);

               /* if this stream must be remuxed */
               ret = avcodec_parameters_copy(out_stream->codecpar, in_stream->codecpar);
               if (ret < 0)
               {
                   av_log(NULL, AV_LOG_ERROR, "Copying parameters for stream #%u failed\n", i);
                   return ret;
               }
               out_stream->time_base = in_stream->time_base;
           }

       }
       av_dump_format(outFormatCtx, 0, filename, 1);

       if (!(outFormatCtx->oformat->flags & AVFMT_NOFILE))
       {
           ret = avio_open(&outFormatCtx->pb, filename, AVIO_FLAG_WRITE);
           if (ret < 0)
           {
               av_log(NULL, AV_LOG_ERROR, "Could not open output file '%s'", filename);
               return ret;
           }
       }

       /* init muxer, write output file header */
       ret = avformat_write_header(outFormatCtx, NULL);
       if (ret < 0)
       {
           av_log(NULL, AV_LOG_ERROR, "Error occurred when opening output file\n");
           return ret;
       }

       return 0;
    }

    static int
    encodeAndWriteFrame(AVFrame *inFrame, unsigned int streamIndex, int *pGotFrame)
    {
       int      ret;
       int      got_frame_local;
       AVPacket encodedPkt;

       if (pGotFrame == 0)
           pGotFrame = &got_frame_local;

       encodedPkt.data = NULL;
       encodedPkt.size = 0;
       av_init_packet(&encodedPkt);

       int codecType = inFormatCtx->streams[streamIndex]->codecpar->codec_type;

       if (codecType == AVMEDIA_TYPE_VIDEO)
           ret = avcodec_encode_video2(streamCtx[streamIndex].encodeCtx, &encodedPkt, inFrame, pGotFrame);
       else
           ret = avcodec_encode_audio2(streamCtx[streamIndex].encodeCtx, &encodedPkt, inFrame, pGotFrame);

       if (ret < 0)
           return ret;

       if (*pGotFrame == 0)
           return 0;

       if (encFrameNum++ % 10 == 0)
           printf("Encoded %s frame #%d\n", (codecType == AVMEDIA_TYPE_VIDEO) ? "Video" : "Audio", encFrameNum);

       /* prepare packet for muxing */
       encodedPkt.stream_index = streamIndex;
       av_packet_rescale_ts(&encodedPkt, streamCtx[streamIndex].encodeCtx->time_base, outFormatCtx->streams[streamIndex]->time_base);

       av_log(NULL, AV_LOG_DEBUG, "Muxing frame\n");

       /* mux encoded frame */
       ret = av_interleaved_write_frame(outFormatCtx, &encodedPkt);
       return ret;
    }


    static int
    flushEncoder(unsigned int streamIndex)
    {
       int ret;
       int got_frame;

       if (!(streamCtx[streamIndex].encodeCtx->codec->capabilities & AV_CODEC_CAP_DELAY))
           return 0;

       while (1)
       {
           av_log(NULL, AV_LOG_INFO, "Flushing stream #%u encoder\n", streamIndex);
           ret = encodeAndWriteFrame(NULL, streamIndex, &got_frame);
           if (ret < 0)
               break;
           if (!got_frame)
               return 0;
       }
       return ret;
    }

    int
    main(int argc, char **argv)
    {
       int      ret;
       AVPacket packet = { .data = NULL, .size = 0 };
       AVFrame          *pDecFrame = NULL;
       enum AVMediaType type;
       unsigned int     streamIndex;
       unsigned int     i;
       int              gotDecFrame;

       if (argc != 3)
       {
           av_log(NULL, AV_LOG_ERROR, "Usage: %s <input file="file" /> <output file="file">\n", argv[0]);
           return 1;
       }

       av_register_all();
       avfilter_register_all();

       if ((ret = openInputFile(argv[1])) &lt; 0)
           goto end;
       if ((ret = openOutputFile(argv[2])) &lt; 0)
           goto end;

       /* read all packets */
       while (1)
       {
           if ((ret = av_read_frame(inFormatCtx, &amp;packet)) &lt; 0)
           {
               printf(ANSI_COLOR_YELLOW "READ PACKET RETURNED %d\n" ANSI_COLOR_RESET, ret);
               break;
           }
           readPktNum++;

           streamIndex = packet.stream_index;
           type = inFormatCtx->streams[packet.stream_index]->codecpar->codec_type;
           av_log(NULL, AV_LOG_DEBUG, "Demuxer gave frame of stream_index %u\n", streamIndex);

           if (type == AVMEDIA_TYPE_VIDEO || type == AVMEDIA_TYPE_AUDIO)
           {
               pDecFrame = av_frame_alloc();
               if (!pDecFrame)
               {
                   ret = AVERROR(ENOMEM);
                   break;
               }

               av_packet_rescale_ts(&amp;packet, inFormatCtx->streams[streamIndex]->time_base, streamCtx[streamIndex].decodeCtx->time_base);

               if (type == AVMEDIA_TYPE_VIDEO)
                   ret = avcodec_decode_video2(streamCtx[streamIndex].decodeCtx, pDecFrame, &amp;gotDecFrame, &amp;packet);
               else
                   ret = avcodec_decode_audio4(streamCtx[streamIndex].decodeCtx, pDecFrame, &amp;gotDecFrame, &amp;packet);

               if (ret &lt; 0)
               {
                   av_frame_free(&amp;pDecFrame);
                   av_log(NULL, AV_LOG_ERROR, "Decoding failed\n");
                   break;
               }

               if (gotDecFrame)
               {
                   if (decFrameNum++ % 10 == 0)
                       printf("Decoded %s frame #%d\n", (type == AVMEDIA_TYPE_VIDEO) ? "Video" : "Audio", decFrameNum);

                   if (0 &amp;&amp; type == AVMEDIA_TYPE_VIDEO)
                   {
                       printf("VIDEO width %d height %d\n", pDecFrame->width, pDecFrame->height);
                       writeAVFrameAsYUVFile("/mnt/swdevel/DVStor/decodedYUV.yuv", pDecFrame);
                   }

                   pDecFrame->pts = av_frame_get_best_effort_timestamp(pDecFrame);

                   ret = encodeAndWriteFrame(pDecFrame, streamIndex, 0);
                   av_frame_free(&amp;pDecFrame);
                   if (ret &lt; 0)
                       goto end;
               }
               else
                   av_frame_free(&amp;pDecFrame);
           }
           else
           {
               /* remux this frame without reencoding */
               av_packet_rescale_ts(&amp;packet, inFormatCtx->streams[streamIndex]->time_base, outFormatCtx->streams[streamIndex]->time_base);

               ret = av_interleaved_write_frame(outFormatCtx, &amp;packet);
               if (ret &lt; 0)
                   goto end;
           }
           av_packet_unref(&amp;packet);
       }

       printf(ANSI_COLOR_YELLOW "EXIT MAIN WHILE(1) - FLUSHING\n" ANSI_COLOR_RESET);

       /* flush encoders */
       for (i = 0; i &lt; inFormatCtx->nb_streams; i++)
       {
           /* flush encoder */
           ret = flushEncoder(i);
           if (ret &lt; 0)
           {
               av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
               goto end;
           }
       }

       av_write_trailer(outFormatCtx);

    end:
       av_packet_unref(&amp;packet);
       av_frame_free(&amp;pDecFrame);
       for (i = 0; i &lt; inFormatCtx->nb_streams; i++)
       {
           avcodec_free_context(&amp;streamCtx[i].decodeCtx);
           if (outFormatCtx &amp;&amp; outFormatCtx->nb_streams > i &amp;&amp; outFormatCtx->streams[i] &amp;&amp; streamCtx[i].encodeCtx)
               avcodec_free_context(&amp;streamCtx[i].encodeCtx);
       }

       av_free(streamCtx);
       avformat_close_input(&amp;inFormatCtx);

       if (outFormatCtx &amp;&amp; !(outFormatCtx->oformat->flags &amp; AVFMT_NOFILE))
           avio_closep(&amp;outFormatCtx->pb);

       avformat_free_context(outFormatCtx);

       if (ret &lt; 0)
           av_log(NULL, AV_LOG_ERROR, "Error occurred: %s\n", av_err2str(ret));

       return ret ? 1 : 0;
    }
    </output>
  • Algorithm when recording SegmentTimeline of MPEG-DASH MPD in shaka packager

    25 mars 2021, par jgkim0518

    I packaged a media stream by mpeg-dash transcoded video at twice the speed and audio at normal speed.&#xA;Here is the command :

    &#xA;

    ffmpeg -re -stream_loop -1 -i timing_logic.mp4 -c:v hevc_nvenc -filter:v "setpts=2*PTS" -c:a libfdk_aac -map 0:v -map 0:a -f mpegts udp://xxx.xxx.xxx.xxx:xxxx?pkt_size=1316&#xA;

    &#xA;

    The source information used here is as follows :

    &#xA;

    Input #0, mpegts, from &#x27;/home/test/timing_logic/timing_logic.mp4&#x27;:&#xA;Duration: 00:00:30.22, start: 1.400000, bitrate: 16171 kb/s&#xA;Program 1&#xA;Metadata:&#xA;service_name : Service01&#xA;service_provider: FFmpeg&#xA;Stream #0:0[0x100]: Video: hevc (Main 10) (HEVC / 0x43564548), yuv420p10le(tv, bt709), 3840x2160 [SAR 1:1 DAR 16:9], 50 fps, 50 tbr, 90k tbn, 50 tbc&#xA;Stream #0:1[0x101](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s Stream mapping:&#xA;Stream #0:0 -> #0:0 (hevc (native) -> hevc (hevc_nvenc))&#xA;Stream #0:1 -> #0:1 (mp2 (native) -> aac (libfdk_aac))&#xA;Press [q] to stop, [?] for help&#xA;frame= 0 fps=0.0 q=0.0 size= 0kB time=-577014:32:22.77 bitrate= -0.0kbits/s speed=N/A&#xA;frame= 0 fps=0.0 q=0.0 size= 0kB time=-577014:32:22.77 bitrate= -0.0kbits/s speed=N/A&#xA;Output #0, mpegts, to &#x27;udp://xxx.xxx.xxx.xxx:xxxx?pkt_size=1316&#x27;:&#xA;Metadata:&#xA;encoder : Lavf58.45.100&#xA;Stream #0:0: Video: hevc (hevc_nvenc) (Main 10), p010le, 3840x2160 [SAR 1:1 DAR 16:9], q=-1--1, 2000 kb/s, 50 fps, 90k tbn, 50 tbc&#xA;Metadata:&#xA;encoder : Lavc58.91.100 hevc_nvenc&#xA;Side data:&#xA;cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 4000000 vbv_delay: N/A&#xA;Stream #0:1(eng): Audio: aac (libfdk_aac), 48000 Hz, stereo, s16, 139 kb/s&#xA;Metadata:&#xA;encoder : Lavc58.91.100 libfdk_aac&#xA;

    &#xA;

    My shaka packager command is :

    &#xA;

    packager \ &#x27;in=udp://xxx.xxx.xxx.xxx:xxxx,stream=video,init_segment=/home/test/timing_logic/package/video/0/video.mp4,segment_template=/home/test/timing_logic/package/video/0/$Time$.m4s&#x27; \&#xA;&#x27;in=udp://xxx.xxx.xxx.xxx:xxxx,stream=audio,init_segment=/home/test/timing_logic/package/audio/0/audio.mp4,segment_template=/home/test/timing_logic/package/audio/0/$Time$.m4a&#x27; \&#xA;--segment_duration 5 --fragment_duration 5 --minimum_update_period 5 --min_buffer_time 5 \&#xA;--preserved_segments_outside_live_window 24 --time_shift_buffer_depth 40 \&#xA;--allow_codec_switching --allow_approximate_segment_timeline --log_file_generation_deletion \&#xA;--mpd_output $OUTPUT/$output_mpd.mpd &amp;&#xA;

    &#xA;

    Looking at the mpd generated as a result of packaging, the duration of the audio is twice that of the video, and the number of segments is half.&#xA;The following is the content of mpd :

    &#xA;

    &lt;?xml version="1.0" encoding="UTF-8"?>&#xA;&#xA;<mpd xmlns="urn:mpeg:dash:schema:mpd:2011" profiles="urn:mpeg:dash:profile:isoff-live:2011" minbuffertime="PT5S" type="dynamic" publishtime="2021-03-23T10:01:57Z" availabilitystarttime="2021-03-23T09:59:55Z" minimumupdateperiod="PT5S" timeshiftbufferdepth="PT40S">&#xA;<period start="PT0S">&#xA;<adaptationset contenttype="audio" segmentalignment="true">&#xA;<representation bandwidth="140020" codecs="mp4a.40.2" mimetype="audio/mp4" audiosamplingrate="48000">&#xA;<audiochannelconfiguration schemeiduri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></audiochannelconfiguration>&#xA;<segmenttemplate timescale="90000" initialization="/home/test/timing_logic/package/audio/0/audio.mp4" media="/home/test/timing_logic/package/audio/0/$Time$.m4a" startnumber="16">&#xA;<segmenttimeline>&#xA;<s t="6751436" d="449280"></s>&#xA;<s t="7200716" d="451200"></s>&#xA;<s t="7651916" d="449280"></s>&#xA;<s t="8101196" d="374400"></s>&#xA;<s t="8551196" d="449280"></s>&#xA;<s t="9000476" d="451200"></s>&#xA;<s t="9451674" d="449280"></s>&#xA;<s t="9900956" d="449280"></s>&#xA;<s t="10350236" d="451200"></s>&#xA;<s t="10801434" d="374400"></s>&#xA;</segmenttimeline>&#xA;</segmenttemplate>&#xA;</representation>&#xA;</adaptationset>&#xA;<adaptationset contenttype="video" width="3840" height="2160" framerate="90000/3600" segmentalignment="true" par="16:9">&#xA;<representation bandwidth="1520392" codecs="hvc1.2.4.L153" mimetype="video/mp4" sar="1:1">&#xA;<segmenttemplate timescale="90000" initialization="/home/test/timing_logic/package/video/0/video.mp4" media="/home/test/timing_logic/package/video/0/$Time$.m4s" startnumber="19">&#xA;<segmenttimeline>&#xA;<s t="16954440" d="900000" r="4"></s>&#xA;</segmenttimeline>&#xA;</segmenttemplate>&#xA;</representation>&#xA;</adaptationset>&#xA;</period>&#xA;</mpd>&#xA;

    &#xA;

    When looking at the MPD, it seems that the shaka packager checks the PTS or DTS of the TS when creating a segment and recording the contents of the SegmentTimeline.&#xA;But I couldn't understand even by looking at the MPEG standard documentation and the DASH-IF documentation.

    &#xA;

    My question is whether the packager refers to PTS or DTS when creating a segment.&#xA;How are SegmentTimeline's S@t and S@d recorded ?&#xA;What algorithm is the SegmentTimeline recorded with ? Please help me. Thank you.

    &#xA;

  • JavaCV Create Compatible MP4

    15 juin 2017, par Hamish258

    Trying to modify JavaCV 3.2.0 sample https://github.com/bytedeco/javacv/blob/master/samples/WebcamAndMicrophoneCapture.java, to produce an mp4 that quicktime on macOS 10.12.5 can use. Output mp4 works fine with VLC but for the software I’m producing I’d like to minimise users having to install additional products.

    The sample code produces the following output

    [libx264 @ 0x7f927794e200] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
    [libx264 @ 0x7f927794e200] profile Constrained Baseline, level 3.1
    [libx264 @ 0x7f927794e200] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=0 ref=1 deblock=0:0:0 analyse=0:0 me=dia subme=0 psy=1 psy_rd=1.00:0.00 mixed_ref=0 me_range=16 chroma_me=1 trellis=0 8x8dct=0 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=0 threads=4 lookahead_threads=4 sliced_threads=1 slices=4 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=0 weightp=0 keyint=60 keyint_min=6 scenecut=0 intra_refresh=0 rc=crf mbtree=0 crf=28.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=0
    Output #0, mp4, to 'alatest.mp4':
     Metadata:
       encoder         : Lavf57.56.100
       Stream #0:0: Video: h264 (Constrained Baseline) ([33][0][0][0] / 0x0021), yuv420p, 1280x720, q=2-31, 2000 kb/s, 15360 tbn
       Stream #0:1: Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo fltp, 192 kb/s

    The constrained baseline to 3.1 should produce usable mp4 according to https://trac.ffmpeg.org/wiki/Encode/H.264

    If I use the command line ffmpeg -i alatest.mp4 -pix_fmt yuv420p alantest.mp4 it produces a usable mo4, even though as you can see above yuv420p is the pixel format in use so there’s something else I don’t understand, the code snippet from the sample link is :

       FFmpegFrameRecorder recorder = new FFmpegFrameRecorder("alatest.mp4",1280, 720, 2);
       recorder.setInterleaved(true);
       recorder.setVideoOption("tune", "zerolatency");
       recorder.setVideoOption("preset", "ultrafast");
       recorder.setVideoOption("crf", "28");
       recorder.setVideoBitrate(2000000);
       recorder.setVideoCodec(avcodec.AV_CODEC_ID_H264);
       recorder.setPixelFormat(avutil.AV_PIX_FMT_YUV420P);
       recorder.setFormat("flv");
       recorder.setFrameRate(30);
       recorder.setGopSize(60);

    The command line ffmpeg is displaying

    [libx264 @ 0x7ffca4019400] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX
    [libx264 @ 0x7ffca4019400] profile High, level 3.1
    [libx264 @ 0x7ffca4019400] 264 - core 148 - H.264/MPEG-4 AVC codec - Copyleft 2003-2016 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=6 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
    Output #0, mp4, to 'alantest.mp4':
     Metadata:
       encoder         : Lavf57.71.100
       Stream #0:0: Video: h264 (libx264) ([33][0][0][0] / 0x0021), yuv420p, 1280x720, q=-1--1, 30 fps, 15360 tbn, 30 tbc
       Metadata:
         encoder         : Lavc57.89.100 libx264
       Side data:
         cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: -1
       Stream #0:1: Audio: aac (LC) ([64][0][0][0] / 0x0040), 44100 Hz, stereo, fltp, 128 kb/s
       Metadata:
         encoder         : Lavc57.89.100 aac
    frame=  179 fps= 54 q=-1.0 Lsize=     570kB time=00:00:05.94 bitrate= 786.2kbits/s dup=93 drop=0 speed= 1.8x
    video:470kB audio:93kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 1.341890%

    This is using a High profile and I see q being set differently and tbc. I can’t figure out how to mimic this behaviour in JavaCV, all help greatly appreciated !