
Recherche avancée
Médias (16)
-
#7 Ambience
16 octobre 2011, par
Mis à jour : Juin 2015
Langue : English
Type : Audio
-
#6 Teaser Music
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#5 End Title
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#3 The Safest Place
16 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#4 Emo Creates
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
-
#2 Typewriter Dance
15 octobre 2011, par
Mis à jour : Février 2013
Langue : English
Type : Audio
Autres articles (46)
-
La sauvegarde automatique de canaux SPIP
1er avril 2010, parDans 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 2013Puis-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, parMediaSPIP 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 DannyI’m trying to use
libavcodec
to reduce the video bitrate of an MPEG transport stream while passing audio streams unchanged. The equivalentffmpeg
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/sUsing 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])) < 0)
goto end;
if ((ret = openOutputFile(argv[2])) < 0)
goto end;
/* read all packets */
while (1)
{
if ((ret = av_read_frame(inFormatCtx, &packet)) < 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(&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 (ret < 0)
{
av_frame_free(&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 && 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(&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);
}
printf(ANSI_COLOR_YELLOW "EXIT MAIN WHILE(1) - FLUSHING\n" ANSI_COLOR_RESET);
/* flush encoders */
for (i = 0; i < inFormatCtx->nb_streams; i++)
{
/* flush encoder */
ret = flushEncoder(i);
if (ret < 0)
{
av_log(NULL, AV_LOG_ERROR, "Flushing encoder failed\n");
goto end;
}
}
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);
if (ret < 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 jgkim0518I packaged a media stream by mpeg-dash transcoded video at twice the speed and audio at normal speed.
Here is the command :


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



The source information used here is as follows :


Input #0, mpegts, from '/home/test/timing_logic/timing_logic.mp4':
Duration: 00:00:30.22, start: 1.400000, bitrate: 16171 kb/s
Program 1
Metadata:
service_name : Service01
service_provider: FFmpeg
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
Stream #0:1[0x101](eng): Audio: mp2 ([3][0][0][0] / 0x0003), 48000 Hz, stereo, fltp, 128 kb/s Stream mapping:
Stream #0:0 -> #0:0 (hevc (native) -> hevc (hevc_nvenc))
Stream #0:1 -> #0:1 (mp2 (native) -> aac (libfdk_aac))
Press [q] to stop, [?] for help
frame= 0 fps=0.0 q=0.0 size= 0kB time=-577014:32:22.77 bitrate= -0.0kbits/s speed=N/A
frame= 0 fps=0.0 q=0.0 size= 0kB time=-577014:32:22.77 bitrate= -0.0kbits/s speed=N/A
Output #0, mpegts, to 'udp://xxx.xxx.xxx.xxx:xxxx?pkt_size=1316':
Metadata:
encoder : Lavf58.45.100
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
Metadata:
encoder : Lavc58.91.100 hevc_nvenc
Side data:
cpb: bitrate max/min/avg: 0/0/2000000 buffer size: 4000000 vbv_delay: N/A
Stream #0:1(eng): Audio: aac (libfdk_aac), 48000 Hz, stereo, s16, 139 kb/s
Metadata:
encoder : Lavc58.91.100 libfdk_aac



My shaka packager command is :


packager \ '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' \
'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' \
--segment_duration 5 --fragment_duration 5 --minimum_update_period 5 --min_buffer_time 5 \
--preserved_segments_outside_live_window 24 --time_shift_buffer_depth 40 \
--allow_codec_switching --allow_approximate_segment_timeline --log_file_generation_deletion \
--mpd_output $OUTPUT/$output_mpd.mpd &



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.
The following is the content of mpd :


<?xml version="1.0" encoding="UTF-8"?>

<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">
<period start="PT0S">
<adaptationset contenttype="audio" segmentalignment="true">
<representation bandwidth="140020" codecs="mp4a.40.2" mimetype="audio/mp4" audiosamplingrate="48000">
<audiochannelconfiguration schemeiduri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2"></audiochannelconfiguration>
<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">
<segmenttimeline>
<s t="6751436" d="449280"></s>
<s t="7200716" d="451200"></s>
<s t="7651916" d="449280"></s>
<s t="8101196" d="374400"></s>
<s t="8551196" d="449280"></s>
<s t="9000476" d="451200"></s>
<s t="9451674" d="449280"></s>
<s t="9900956" d="449280"></s>
<s t="10350236" d="451200"></s>
<s t="10801434" d="374400"></s>
</segmenttimeline>
</segmenttemplate>
</representation>
</adaptationset>
<adaptationset contenttype="video" width="3840" height="2160" framerate="90000/3600" segmentalignment="true" par="16:9">
<representation bandwidth="1520392" codecs="hvc1.2.4.L153" mimetype="video/mp4" sar="1:1">
<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">
<segmenttimeline>
<s t="16954440" d="900000" r="4"></s>
</segmenttimeline>
</segmenttemplate>
</representation>
</adaptationset>
</period>
</mpd>



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.
But I couldn't understand even by looking at the MPEG standard documentation and the DASH-IF documentation.


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


-
JavaCV Create Compatible MP4
15 juin 2017, par Hamish258Trying 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/sThe 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 !