
Recherche avancée
Médias (91)
-
Géodiversité
9 septembre 2011, par ,
Mis à jour : Août 2018
Langue : français
Type : Texte
-
USGS Real-time Earthquakes
8 septembre 2011, par
Mis à jour : Septembre 2011
Langue : français
Type : Texte
-
SWFUpload Process
6 septembre 2011, par
Mis à jour : Septembre 2011
Langue : français
Type : Texte
-
La conservation du net art au musée. Les stratégies à l’œuvre
26 mai 2011
Mis à jour : Juillet 2013
Langue : français
Type : Texte
-
Podcasting Legal guide
16 mai 2011, par
Mis à jour : Mai 2011
Langue : English
Type : Texte
-
Creativecommons informational flyer
16 mai 2011, par
Mis à jour : Juillet 2013
Langue : English
Type : Texte
Autres articles (15)
-
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 -
Organiser par catégorie
17 mai 2013, parDans MédiaSPIP, une rubrique a 2 noms : catégorie et rubrique.
Les différents documents stockés dans MédiaSPIP peuvent être rangés dans différentes catégories. On peut créer une catégorie en cliquant sur "publier une catégorie" dans le menu publier en haut à droite ( après authentification ). Une catégorie peut être rangée dans une autre catégorie aussi ce qui fait qu’on peut construire une arborescence de catégories.
Lors de la publication prochaine d’un document, la nouvelle catégorie créée sera proposée (...) -
Les thèmes de MediaSpip
4 juin 20133 thèmes sont proposés à l’origine par MédiaSPIP. L’utilisateur MédiaSPIP peut rajouter des thèmes selon ses besoins.
Thèmes MediaSPIP
3 thèmes ont été développés au départ pour MediaSPIP : * SPIPeo : thème par défaut de MédiaSPIP. Il met en avant la présentation du site et les documents média les plus récents ( le type de tri peut être modifié - titre, popularité, date) . * Arscenic : il s’agit du thème utilisé sur le site officiel du projet, constitué notamment d’un bandeau rouge en début de page. La structure (...)
Sur d’autres sites (5171)
-
What am I doing wrong with my audio writing in ffmpeg ? [on hold]
12 septembre 2014, par Michael NguyenI’m trying to splice multiple video sources into one. I’m having trouble understanding the audio portion of it. Rather I should say, the audio part of my code doesn’t seem to work. I don’t understand it. Could somebody help me understand what I am doing wrong ? The method doing all the work is called renderMovieRequest
Thanks in advance.
My entire code can be found here : http://pastebin.com/rAZkU3XZ
Any help would be appreciated.
below is a snippet of the code (it’s too long otherwise)int64_t timeBase;
bool seek(AVFormatContext *pFormatCtx, int frameIndex){
if(!pFormatCtx)
return false;
int64_t seekTarget = int64_t(frameIndex) * timeBase;
if(av_seek_frame(pFormatCtx, -1, seekTarget, AVSEEK_FLAG_ANY) < 0) {
ELOG("av_seek_frame failed.");
return false;
}
return true;
}
typedef struct OutputStream {
AVStream *st;
/* pts of the next frame that will be generated */
int64_t next_pts;
int samples_count;
AVFrame *frame;
AVFrame *tmp_frame;
float t, tincr, tincr2;
struct SwsContext *sws_ctx;
struct SwrContext *swr_ctx;
} OutputStream;
static int write_frame(AVFormatContext *fmt_ctx, const AVRational *time_base, AVStream *st, AVPacket *pkt)
{
/* rescale output packet timestamp values from codec to stream timebase */
av_packet_rescale_ts(pkt, *time_base, st->time_base);
pkt->stream_index = st->index;
/* Write the compressed frame to the media file. */
log_packet(fmt_ctx, pkt);
return av_interleaved_write_frame(fmt_ctx, pkt);
}
/* Add an output stream. */
static void add_stream(OutputStream *ost, AVFormatContext *oc,
AVCodec **codec,
enum AVCodecID codec_id) {
AVCodecContext *c;
int i;
/* find the encoder */
*codec = avcodec_find_encoder(codec_id);
if (!(*codec)) {
ELOG("Could not find encoder for '%s'\n", avcodec_get_name(codec_id));
return;
}
ost->st = avformat_new_stream(oc, *codec);
if (!ost->st) {
ELOG("Could not allocate stream\n");
return;
}
ost->st->id = oc->nb_streams-1;
c = ost->st->codec;
switch ((*codec)->type) {
case AVMEDIA_TYPE_AUDIO:
c->sample_fmt = (*codec)->sample_fmts ?
(*codec)->sample_fmts[0] : AV_SAMPLE_FMT_FLTP;
c->bit_rate = 64000;
c->sample_rate = 44100;
if ((*codec)->supported_samplerates) {
c->sample_rate = (*codec)->supported_samplerates[0];
for (i = 0; (*codec)->supported_samplerates[i]; i++) {
if ((*codec)->supported_samplerates[i] == 44100)
c->sample_rate = 44100;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
c->channel_layout = AV_CH_LAYOUT_STEREO;
if ((*codec)->channel_layouts) {
c->channel_layout = (*codec)->channel_layouts[0];
for (i = 0; (*codec)->channel_layouts[i]; i++) {
if ((*codec)->channel_layouts[i] == AV_CH_LAYOUT_STEREO)
c->channel_layout = AV_CH_LAYOUT_STEREO;
}
}
c->channels = av_get_channel_layout_nb_channels(c->channel_layout);
ost->st->time_base = (AVRational){ 1, c->sample_rate };
break;
case AVMEDIA_TYPE_VIDEO:
c->codec_id = codec_id;
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
// c->width = 352;
// c->height = 288;
c->width = 1280;
c->height = 720;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
ost->st->time_base = (AVRational){ 1, STREAM_FRAME_RATE };
c->time_base = ost->st->time_base;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->pix_fmt = STREAM_PIX_FMT;
if (c->codec_id == AV_CODEC_ID_MPEG2VIDEO) {
/* just for testing, we also add B frames */
c->max_b_frames = 2;
}
if (c->codec_id == AV_CODEC_ID_MPEG1VIDEO) {
/* Needed to avoid using macroblocks in which some coeffs overflow.
* This does not happen with normal video, it just happens here as
* the motion of the chroma plane does not match the luma plane. */
c->mb_decision = 2;
}
break;
default:
break;
}
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
}
/**************************************************************/
/* audio output */
static AVFrame *alloc_audio_frame(enum AVSampleFormat sample_fmt,
uint64_t channel_layout,
int sample_rate, int nb_samples)
{
AVFrame *frame = av_frame_alloc();
int ret;
if (!frame) {
fprintf(stderr, "Error allocating an audio frame\n");
exit(1);
}
frame->format = sample_fmt;
frame->channel_layout = channel_layout;
frame->sample_rate = sample_rate;
frame->nb_samples = nb_samples;
if (nb_samples) {
ret = av_frame_get_buffer(frame, 0);
if (ret < 0) {
fprintf(stderr, "Error allocating an audio buffer\n");
exit(1);
}
}
return frame;
}
static int open_audio(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
{
AVCodecContext *c;
int nb_samples;
int ret;
AVDictionary *opt = NULL;
c = ost->st->codec;
/* open it */
av_dict_copy(&opt, opt_arg, 0);
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
ELOG("Could not open audio codec: %s\n", av_err2str(ret));
return ret;
}
/* init signal generator */
ost->t = 0;
ost->tincr = 2 * M_PI * 110.0 / c->sample_rate;
/* increment frequency by 110 Hz per second */
ost->tincr2 = 2 * M_PI * 110.0 / c->sample_rate / c->sample_rate;
if (c->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE)
nb_samples = 10000;
else
nb_samples = c->frame_size;
ost->frame = alloc_audio_frame(c->sample_fmt, c->channel_layout,
c->sample_rate, nb_samples);
ost->tmp_frame = alloc_audio_frame(AV_SAMPLE_FMT_S16, c->channel_layout,
c->sample_rate, nb_samples);
/* create resampler context */
ost->swr_ctx = swr_alloc();
if (!ost->swr_ctx) {
ELOG("Could not allocate resampler context\n");
return -300;
}
/* set options */
av_opt_set_int (ost->swr_ctx, "in_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "in_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "in_sample_fmt", AV_SAMPLE_FMT_S16, 0);
av_opt_set_int (ost->swr_ctx, "out_channel_count", c->channels, 0);
av_opt_set_int (ost->swr_ctx, "out_sample_rate", c->sample_rate, 0);
av_opt_set_sample_fmt(ost->swr_ctx, "out_sample_fmt", c->sample_fmt, 0);
/* initialize the resampling context */
if ((ret = swr_init(ost->swr_ctx)) < 0) {
ELOG("Failed to initialize the resampling context: %i\n", ret);
return ret;
}
return 0;
}
/*
* encode one audio frame and send it to the muxer
* return 1 when encoding is finished, 0 otherwise
*/
static int write_audio_frame(AVFormatContext *oc, OutputStream *ost, AVFrame *frame)
{
AVCodecContext *c;
AVPacket pkt = { 0 }; // data and size must be 0;
// AVFrame *frame;
int ret;
int got_packet;
int dst_nb_samples;
av_init_packet(&pkt);
c = ost->st->codec;
// frame = get_audio_frame(ost);
if (frame) {
/* convert samples from native format to destination codec format, using the resampler */
/* compute destination number of samples */
dst_nb_samples = av_rescale_rnd(swr_get_delay(ost->swr_ctx, c->sample_rate) + frame->nb_samples,
c->sample_rate, c->sample_rate, AV_ROUND_UP);
av_assert0(dst_nb_samples == frame->nb_samples);
/* when we pass a frame to the encoder, it may keep a reference to it
* internally;
* make sure we do not overwrite it here
*/
ret = av_frame_make_writable(ost->frame);
if (ret < 0) {
ELOG("Unable to prepare frame for writing: Error code: %s", av_err2str(ret));
return ret;
}
/* convert to destination format */
ret = swr_convert(ost->swr_ctx,
ost->frame->data, dst_nb_samples,
(const uint8_t **)frame->data, frame->nb_samples);
if (ret < 0) {
ELOG("Error while converting: %s\n", av_err2str(ret));
return -1;
}
frame = ost->frame;
frame->pts = av_rescale_q(ost->samples_count, (AVRational){1, c->sample_rate}, c->time_base);
ost->samples_count += dst_nb_samples;
}
ret = avcodec_encode_audio2(c, &pkt, frame, &got_packet);
if (ret < 0) {
ELOG("Error encoding audio frame: %s\n", av_err2str(ret));
return -1;
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
if (ret < 0) {
ELOG( "Error while writing audio frame: %s\n", av_err2str(ret));
return -1;
}
}
return (frame || got_packet) ? 0 : 1;
}
/**************************************************************/
/* video output */
static AVFrame *alloc_picture(enum AVPixelFormat pix_fmt, int width, int height)
{
AVFrame *picture;
int ret;
picture = av_frame_alloc();
if (!picture)
return NULL;
picture->format = pix_fmt;
picture->width = width;
picture->height = height;
/* allocate the buffers for the frame data */
ret = av_frame_get_buffer(picture, 32);
if (ret < 0) {
fprintf(stderr, "Could not allocate frame data.\n");
exit(1);
}
return picture;
}
static int open_video(AVFormatContext *oc, AVCodec *codec, OutputStream *ost, AVDictionary *opt_arg)
{
int ret;
AVCodecContext *c = ost->st->codec;
AVDictionary *opt = NULL;
av_dict_copy(&opt, opt_arg, 0);
/* open the codec */
ret = avcodec_open2(c, codec, &opt);
av_dict_free(&opt);
if (ret < 0) {
ELOG("Could not open video codec: %s\n", av_err2str(ret));
return ret;
}
/* allocate and init a re-usable frame */
DLOG("Allocate and init a are-usable frame: %i x %i Format: %i", c->width, c->height, c->pix_fmt);
ost->frame = alloc_picture(c->pix_fmt, c->width, c->height);
if (!ost->frame) {
ELOG("Could not allocate video frame\n");
return -100;
}
/* If the output format is not YUV420P, then a temporary YUV420P
* picture is needed too. It is then converted to the required
* output format. */
ost->tmp_frame = NULL;
if (c->pix_fmt != AV_PIX_FMT_YUV420P) {
DLOG("input format is not YUV420P converting to size %i x %i", c->width, c->height);
ost->tmp_frame = alloc_picture(AV_PIX_FMT_YUV420P, c->width, c->height);
if (!ost->tmp_frame) {
ELOG("Could not allocate temporary picture\n");
return -200;
}
}
return 0;
}
/*
* encode one video frame and send it to the muxer
* return 1 when encoding is finished, 0 otherwise
*/
static int write_video_frame(AVFormatContext *oc, OutputStream *ost, AVFrame *frame)
{
int ret;
AVCodecContext *c;
int got_packet = 0;
c = ost->st->codec;
if (oc->oformat->flags & AVFMT_RAWPICTURE) {
/* a hack to avoid data copy with some raw video muxers */
AVPacket pkt;
av_init_packet(&pkt);
if (!frame)
return 1;
pkt.flags |= AV_PKT_FLAG_KEY;
pkt.stream_index = ost->st->index;
pkt.data = (uint8_t *)frame;
pkt.size = sizeof(AVPicture);
pkt.pts = pkt.dts = frame->pts;
av_packet_rescale_ts(&pkt, c->time_base, ost->st->time_base);
ret = av_interleaved_write_frame(oc, &pkt);
} else {
AVPacket pkt = { 0 };
av_init_packet(&pkt);
/* encode the image */
ret = avcodec_encode_video2(c, &pkt, frame, &got_packet);
if (ret < 0) {
fprintf(stderr, "Error encoding video frame: %s\n", av_err2str(ret));
exit(1);
}
if (got_packet) {
ret = write_frame(oc, &c->time_base, ost->st, &pkt);
} else {
ret = 0;
}
}
if (ret < 0) {
fprintf(stderr, "Error while writing video frame: %s\n", av_err2str(ret));
exit(1);
}
return (frame || got_packet) ? 0 : 1;
}
static void close_stream(AVFormatContext *oc, OutputStream *ost)
{
avcodec_close(ost->st->codec);
av_frame_free(&ost->frame);
av_frame_free(&ost->tmp_frame);
sws_freeContext(ost->sws_ctx);
swr_free(&ost->swr_ctx);
}
int renderMovieRequest(movieRequest *movieRequestObj, string outputPath) {
AVOutputFormat *ofmt = NULL;
AVFormatContext *ifmt_ctx = NULL, *ofmt_ctx = NULL;
AVFormatContext *pFormatCtx = NULL;
AVCodec *audio_codec, *video_codec;
OutputStream video_st = { 0 }, audio_st = { 0 };
size_t i;
int videoStream, audioStream;
AVCodecContext *pCodecCtx = NULL;
AVCodec *pCodec = NULL;
AVFrame *pFrame = NULL;
AVFrame *pFrameRGB = NULL;
AVPacket packet = { 0 };
int frameFinished;
int audioFrameFinished;
int numBytes;
uint8_t *buffer = NULL;
AVDictionary *optionsDict = NULL;
AVDictionary *opt = NULL;
struct SwsContext *sws_ctx = NULL;
const char *in_filename, *out_filename;
int ret;
int have_audio = 0, have_video = 0;
int encode_audio = 0, encode_video = 0;
processProtobuf(movieRequestObj);
out_filename = outputPath.c_str();
av_register_all();
DLOG("attempting to create context for output file %s", out_filename);
avformat_alloc_output_context2(&ofmt_ctx, NULL, NULL, out_filename);
if (!ofmt_ctx) {
ELOG("Could not create output context\n");
ret = AVERROR_UNKNOWN;
return ret; //goto end;
}
ofmt = ofmt_ctx->oformat;
/* Add the audio and video streams using the default format codecs
* and initialize the codecs. */
if (ofmt->video_codec != AV_CODEC_ID_NONE) {
add_stream(&video_st, ofmt_ctx, &video_codec, ofmt->video_codec);
have_video = 1;
encode_video = 1;
}
if (ofmt->audio_codec != AV_CODEC_ID_NONE) {
add_stream(&audio_st, ofmt_ctx, &audio_codec, ofmt->audio_codec);
have_audio = 1;
encode_audio = 1;
}
DLOG("allocate encode buffers");
/* Now that all the parameters are set, we can open the audio and
* video codecs and allocate the necessary encode buffers. */
if (have_video)
open_video(ofmt_ctx, video_codec, &video_st, opt);
if (have_audio) {
DLOG("Opening audio codec");
open_audio(ofmt_ctx, audio_codec, &audio_st, opt);
}
DLOG("open output file for writing");
/* open the output file, if needed */
if (!(ofmt->flags & AVFMT_NOFILE)) {
ret = avio_open(&ofmt_ctx->pb, out_filename, AVIO_FLAG_WRITE);
if (ret < 0) {
ELOG( "Could not open '%s': %s\n", out_filename, av_err2str(ret));
return 1;
}
}
/* Write the stream header, if any. */
ret = avformat_write_header(ofmt_ctx, &opt);
if (ret < 0) {
ELOG("Error occurred when opening output file: %s\n", av_err2str(ret));
return 1;
}
vector<clipshptr> * clips = &(movieRequestObj->clips);
DLOG("ready to process clips: %i", clips->size());
for (size_t clipIdx = 0; clipIdx < clips->size(); ++clipIdx) {
shared_ptr<clip> currentClip = clips->at(clipIdx);
switch (currentClip->getClipType()) {
case VIDEO_CLIP: {
DLOG("clip is a video clip...");
shared_ptr<videoclip> vidClip = dynamic_pointer_cast<videoclip>(clips->at(clipIdx));
if (vidClip->shouldHaveSegments) {
// open the file for reading and create a temporary file for output
in_filename = vidClip->vidFileName.c_str();
DLOG("Opening %s for reading", in_filename);
if ((ret = avformat_open_input(&ifmt_ctx, in_filename, 0, 0)) < 0) {
ELOG("Could not open input file '%s'", in_filename);
return ret; //goto end;
}
if ((ret = avformat_find_stream_info(ifmt_ctx, 0)) < 0) {
ELOG("Failed to retrieve input stream information");
return ret; //goto end;
}
av_dump_format(ifmt_ctx, 0, in_filename, 0);
videoStream = -1;
audioStream = -1;
// setup input format context and output format context;
// AVStream *video_in_stream = NULL;
for (i = 0; i < ifmt_ctx->nb_streams; i++) {
if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO) {
videoStream=i;
// video_in_stream = ifmt_ctx->streams[i];
}
else if(ifmt_ctx->streams[i]->codec->codec_type==AVMEDIA_TYPE_AUDIO) {
audioStream=i;
// video_in_stream = ifmt_ctx->streams[i];
}
}
if (videoStream == -1) {
DLOG("not a video stream.");
continue;
}
// Get a pointer to the codec context for the video stream
pCodecCtx = ifmt_ctx->streams[videoStream]->codec;
if (pCodecCtx == NULL) {
ELOG("Error in getting pointer to codec for vidstream");
}
DLOG("Input pixel format: %i ", pCodecCtx->pix_fmt);
// Find the decoder for the video stream
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
ELOG("Unsupported codec!\n");
return -1; // Codec not found
}
// Open codec
if(avcodec_open2(pCodecCtx, pCodec, &optionsDict)<0) {
ELOG("Unable to open codec");
return -1; // Could not open codec
}
// get the timebase
timeBase = (int64_t(pCodecCtx->time_base.num) * AV_TIME_BASE) / int64_t(pCodecCtx->time_base.den);
// Allocate video frame
pFrame=av_frame_alloc();
// Allocate an AVFrame structure
pFrameRGB=av_frame_alloc();
if(pFrameRGB==NULL)
return -1;
// Determine required buffer size and allocate buffer
// numBytes=avpicture_get_size(PIX_FMT_RGB24, pCodecCtx->width, pCodecCtx->height);
numBytes = avpicture_get_size(PIX_FMT_RGB24, movieRequestObj->width, movieRequestObj->height);
DLOG("Buffer size allocated: %i x %i: %i ", movieRequestObj->width, movieRequestObj->height, numBytes);
buffer=(uint8_t *)av_malloc(numBytes*sizeof(uint8_t));
sws_ctx = sws_getContext
(
pCodecCtx->width,
pCodecCtx->height,
pCodecCtx->pix_fmt,
movieRequestObj->width,
movieRequestObj->height,
PIX_FMT_RGB24,
SWS_BILINEAR,
NULL,
NULL,
NULL
);
// Assign appropriate parts of buffer to image planes in pFrameRGB
// Note that pFrameRGB is an AVFrame, but AVFrame is a superset
// of AVPicture
avpicture_fill((AVPicture *)pFrameRGB, buffer, PIX_FMT_RGB24, movieRequestObj->width, movieRequestObj->height);
size_t numSegments = vidClip->segments.size();
DLOG("Found %i segments to process", numSegments);
for (size_t segmentIdx = 0; segmentIdx < numSegments; ++segmentIdx) {
// seek to the right position
int frameOffset = vidClip->segments.at(segmentIdx).first;
int clipDuration = vidClip->segments.at(segmentIdx).second;
DLOG("Starting Frame Number: %i Duration: %i", frameOffset, clipDuration);
seek(ifmt_ctx, frameOffset);
// loop for X frames where X is < frameOffset + clipDuration; clipDuration is the length of the clip in terms of frames
for (int frameIdx = frameOffset; frameIdx < (frameOffset + clipDuration); ++frameIdx) {
av_init_packet(&packet);
int avReadResult = 0;
int continueRecording = 1;
while ((continueRecording == 1) && (frameIdx < (frameOffset + clipDuration) )) {
avReadResult = av_read_frame(ifmt_ctx, &packet);
if(avReadResult != 0){
if (avReadResult != AVERROR_EOF) {
ELOG("av_read_frame error: %i", avReadResult );
} else {
ILOG("End of input file");
}
continueRecording = 0;
}
// Is this a packet from the video stream?
if(packet.stream_index==videoStream) {
// Decode video frame
avcodec_decode_video2(pCodecCtx, pFrameRGB, &frameFinished, &packet);
// Did we get a video frame?
if(frameFinished) {
// Convert the image from its native format to RGB
sws_scale
(
sws_ctx,
(uint8_t const * const *)pFrame->data,
pFrame->linesize,
0,
pCodecCtx->height,
pFrameRGB->data,
pFrameRGB->linesize
);
write_video_frame(ofmt_ctx, &video_st, pFrameRGB);
frameIdx++;
}
}
else if (packet.stream_index == audioStream) {
// Decode audio frame
DLOG("Audio frame found");
avcodec_decode_audio4(pCodecCtx, pFrameRGB, &audioFrameFinished, &packet);
if (audioFrameFinished) {
// write the audio frame to file
write_audio_frame(ofmt_ctx, &audio_st, pFrameRGB);
}
}
// Free the packet that was allocated by av_read_frame
av_free_packet(&packet);
}
// Free the RGB image
}
}
DLOG("Cleaning up frame allocations");
av_free(buffer);
av_free(pFrameRGB);
// Free the YUV frame
av_free(pFrame);
} // end video clip processing
}
break;
case TITLE_CLIP: {
}
break;
default:
ELOG("Failed to identify clip");
break;
} // end switch statement
DLOG("Finished processing clip #%i", clipIdx);
avformat_close_input(&ifmt_ctx);
} // end main for loop -> clip iteration
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header; otherwise
* av_write_trailer() may try to use memory that was freed on
* av_codec_close(). */
av_write_trailer(ofmt_ctx);
/* Close each codec. */
if (have_video)
close_stream(ofmt_ctx, &video_st);
if (have_audio)
close_stream(ofmt_ctx, &audio_st);
if (ofmt_ctx && !(ofmt->flags & AVFMT_NOFILE)) {
/* Close the output file. */
avio_close(ofmt_ctx->pb);
}
DLOG("Closing input format context");
avformat_close_input(&ifmt_ctx);
DLOG("Free ouptut format context");
avformat_free_context(ofmt_ctx);
if (ret < 0 && ret != AVERROR_EOF) {
ELOG( "Error occurred: %s\n", av_err2str(ret));
return 1;
}
return 0;
}
#ifdef __cplusplus
}
#endif
</videoclip></videoclip></clip></clipshptr> -
Not able to decode audio from video using ffmpeg API
26 août 2014, par AshishI’m developing some Video converter application for MAC OS using FFMPEG API(Not Command Line).
the objective of the app is "converting Videos".
and...
I’m just completed converted video file but.. I can’t attach audio into the video.
I am using this :
const char* inFileName = "C:\\Ek.avi";
const char* outFileName = "c:\\avi234567.mp4";
const char* outFileType = "mp4";
av_register_all();
AVFormatContext* inContainer = NULL;
if(avformat_open_input(&inContainer, inFileName, NULL, NULL) < 0)
exit(1);
if(avformat_find_stream_info(inContainer, NULL) < 0)
exit(1);
// Find video stream
int videoStreamIndex = -1;
int AudioStreamIndex = -1;
for (unsigned int i = 0; i < inContainer->nb_streams; ++i)
{
if (inContainer->streams[i] && inContainer->streams[i]->codec &&
inContainer->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO)
{
videoStreamIndex = i;
break;
}
}
for (unsigned int i = 0; i < inContainer->nb_streams; ++i)
{
if (inContainer->streams[i] && inContainer->streams[i]->codec &&
inContainer->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
{
AudioStreamIndex = i;
break;
}
}
if (videoStreamIndex == -1)
exit(1);
AVFormatContext* outContainer = NULL;
if(avformat_alloc_output_context2(&outContainer, NULL, outFileType, outFileName) < 0)
exit(1);
// ----------------------------
// Decoder
// ----------------------------
AVStream const *const inStream = inContainer->streams[videoStreamIndex];
AVStream const *const inStreamAudio = inContainer->streams[AudioStreamIndex];
AVCodec *const decoder = avcodec_find_decoder(inStream->codec->codec_id);
AVCodec *const Audiodecoder = avcodec_find_decoder(inStreamAudio->codec->codec_id);
if(!decoder)
exit(1);
if(!Audiodecoder)
exit(1);
if(avcodec_open2(inStream->codec, decoder, NULL) < 0)
exit(1);
if(avcodec_open2(inStreamAudio->codec, Audiodecoder, NULL) < 0)
exit(1);
// ----------------------------
// Encoder
// ----------------------------
AVCodec *encoder = avcodec_find_encoder(AV_CODEC_ID_MPEG4);
AVCodec *Audioencoder = avcodec_find_encoder(AV_CODEC_ID_MP3);
if(!encoder)
exit(1);
AVStream *outStream = avformat_new_stream(outContainer, encoder);
AVStream *AudiooutStream = avformat_new_stream(outContainer, Audioencoder);
if(!outStream)
exit(1);
avcodec_get_context_defaults3(outStream->codec, encoder);
avcodec_get_context_defaults3(AudiooutStream->codec, Audioencoder);
// Construct encoder
if(outContainer->oformat->flags & AVFMT_GLOBALHEADER)
outStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
if(outContainer->oformat->flags & AVFMT_GLOBALHEADER)
AudiooutStream->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
outStream->codec->coder_type = AVMEDIA_TYPE_VIDEO;
outStream->codec->pix_fmt = AV_PIX_FMT_YUV420P;
outStream->codec->width = inStream->codec->width;
outStream->codec->height = inStream->codec->height;
outStream->codec->codec_id = encoder->id;
outStream->codec->bit_rate = inStream->codec->bit_rate;
outStream->codec->time_base.den = inStream->time_base.den/inStream->time_base.num;
outStream->codec->time_base.num = inStream->codec->time_base.num;
outStream->codec->gop_size = inStream->codec->gop_size;; // Keyframe interval(=GOP length). Determines maximum distance distance between I-frames
outStream->codec->keyint_min = inStream->codec->keyint_min; // minimum GOP size
outStream->codec->max_b_frames = inStream->codec->max_b_frames; // maximum number of B-frames between non-B-frames
outStream->codec->b_frame_strategy =inStream->codec->b_frame_strategy; // decides the best number of B-frames to use. Default mode in x264.
outStream->codec->scenechange_threshold = inStream->codec->scenechange_threshold;
outStream->codec->refs = inStream->codec->refs; // abillity to reference frames other than the one immediately prior to the current frame. specify how many references can be used.
outStream->codec->qmin = inStream->codec->qmin;
outStream->codec->qmax = inStream->codec->qmax;
outStream->codec->i_quant_factor = inStream->codec->i_quant_factor;
//for audio
AudiooutStream->codec->codec_type = inStreamAudio->codec->codec_type;
AudiooutStream->codec->codec_id = inStreamAudio->codec->codec_id;
AudiooutStream->codec->bit_rate = inStreamAudio->codec->bit_rate;
AudiooutStream->codec->sample_rate=inStreamAudio->codec->sample_rate;
AudiooutStream->codec->channels =inStreamAudio->codec->channels;
AudiooutStream->codec->time_base.den =(int64_t)inStreamAudio->time_base.num * inStreamAudio->codec->sample_rate;//inStreamAudio->codec->time_base.den;
AudiooutStream->codec->time_base.num =inStreamAudio->codec->time_base.num;
AudiooutStream->codec->gop_size = inStreamAudio->codec->gop_size;
AudiooutStream->codec->frame_size = inStreamAudio->codec->frame_size;
AudiooutStream->codec->coder_type =inStreamAudio->codec->coder_type;
AudiooutStream->codec->sample_fmt= AV_SAMPLE_FMT_S16;
if(outStream->codec->codec_id == AV_CODEC_ID_H264)
av_opt_set(outStream->codec->priv_data, "preset", "slow", 0);
// Open encoder
if(avcodec_open2(outStream->codec, encoder, NULL) < 0)
exit(1);
// Open output container
if(avio_open(&outContainer->pb, outFileName, AVIO_FLAG_WRITE) < 0)
exit(1);
av_dump_format(inContainer, 0, inFileName,0);
//Write header to ouput container
int ret=avformat_write_header(outContainer, NULL);
AVPacket decodePacket, encodedPacket;
int got_frame, len;
while(av_read_frame(inContainer, &decodePacket)>=0)
{
if (decodePacket.stream_index == videoStreamIndex)
{
AVFrame *decodedFrame = avcodec_alloc_frame();
if(!decodedFrame)
exit(1);
AVFrame *encodeFrame = avcodec_alloc_frame();
if(!encodeFrame)
exit(1);
encodeFrame->format = outStream->codec->pix_fmt;
encodeFrame->width = outStream->codec->width;
encodeFrame->height = outStream->codec->height;
if(av_image_alloc(encodeFrame->data, encodeFrame->linesize,outStream->codec->width, outStream->codec->height,outStream->codec->pix_fmt, 1) < 0)
exit(1);
len = avcodec_decode_video2(inStream->codec, decodedFrame, &got_frame, &decodePacket);
if(len < 0)
exit(1);
if(got_frame)
{
av_init_packet(&encodedPacket);
encodedPacket.data = NULL;
encodedPacket.size = 0;
if(avcodec_encode_video2(outStream->codec, &encodedPacket, decodedFrame, &got_frame) < 0)
exit(1);
if(got_frame)
{
if (outStream->codec->coded_frame->key_frame)
encodedPacket.flags |= AV_PKT_FLAG_KEY;
encodedPacket.stream_index = outStream->index;
if (encodedPacket.pts != AV_NOPTS_VALUE)
encodedPacket.pts = av_rescale_q(encodedPacket.pts, outStream->codec->time_base, outStream->time_base);
if (encodedPacket.dts != AV_NOPTS_VALUE)
encodedPacket.dts = av_rescale_q(encodedPacket.dts, outStream->codec->time_base, outStream->time_base);
if(av_write_frame(outContainer, &encodedPacket) < 0)
exit(1);
av_free_packet(&encodedPacket);
}
}
avcodec_free_frame(&encodeFrame);
avcodec_free_frame(&decodedFrame);
}
else if(decodePacket.stream_index == AudioStreamIndex)
{
AVDictionary *opts = NULL;
av_dict_set(&opts, "strict", "experimental", 0);
if(avcodec_open2(AudiooutStream->codec, Audioencoder,&opts) < 0)
exit(1);
av_dict_free(&opts);
AVFrame *decodedFrame = avcodec_alloc_frame();
if(!decodedFrame)
exit(1);
AVFrame *encodeFrame = avcodec_alloc_frame();
if(!encodeFrame)
exit(1);
//encodeFrame->format = AudiooutStream->codec->pix_fmt;
//encodeFrame->width = AudiooutStream->codec->coded_width;
//->height = AudiooutStream->codec->coded_height;
/*if(av_image_alloc(encodeFrame->data, encodeFrame->linesize,AudiooutStream->codec->width, AudiooutStream->codec->height,AudiooutStream->codec->pix_fmt, 1) < 0)
exit(1);*/
len = avcodec_decode_audio4(inStreamAudio->codec, decodedFrame, &got_frame, &decodePacket);
if(len < 0)
exit(1);
if(got_frame)
{
av_init_packet(&encodedPacket);
encodedPacket.data = NULL;
encodedPacket.size = 0;
if(avcodec_encode_audio2(AudiooutStream->codec, &encodedPacket, decodedFrame, &got_frame) < 0)
exit(1);
if(got_frame)
{
if (outStream->codec->coded_frame->key_frame)
encodedPacket.flags |= AV_PKT_FLAG_KEY;
encodedPacket.stream_index = AudiooutStream->index;
if(av_write_frame(outContainer, &encodedPacket) < 0)
exit(1);
av_free_packet(&encodedPacket);
}
}
int audio=0;//for audio
avcodec_free_frame(&encodeFrame);
avcodec_free_frame(&decodedFrame);
}
else
{
int audio=0;//for audio
}
av_free_packet(&decodePacket);
}
av_write_trailer(outContainer);
avio_close(outContainer->pb);
avformat_free_context(outContainer);
av_close_input_file(inContainer);
}Problem is here :
Video of finally created video file was normally played. but the Audio wasn’t. When I tried the same code on windows, then it works fine and converts video file with proper audio and video. Guys its really freaking me out. Please help me how to add audio in that video with proper synchronizing.
I’ve googled with many keywords but they only say about "FFmpeg command line usage".
I wanna make with FFMpeg API. not a Command line tool.
Please help.
-
c++, FFMPEG, H264, creating zero-delay stream
5 février 2015, par MatI’m trying to encode video (using h264 codec at the moment, but other codecs would be fine too if better suited for my needs) such that the data needed for decoding is available directly after a frame (including the first frame) was encoded (so, i want only I and P frames, no B frames).
How do I need to setup the AVCodecContext to get such a stream ? So far my testing arround with the values still always resulted in avcodec_encode_video() returning 0 on the first frame.
//edit : this is currently my setup code of the AVCodecContext :
static AVStream* add_video_stream(AVFormatContext *oc, enum CodecID codec_id, int w, int h, int fps)
{
AVCodecContext *c;
AVStream *st;
AVCodec *codec;
/* find the video encoder */
codec = avcodec_find_encoder(codec_id);
if (!codec) {
fprintf(stderr, "codec not found\n");
exit(1);
}
st = avformat_new_stream(oc, codec);
if (!st) {
fprintf(stderr, "Could not alloc stream\n");
exit(1);
}
c = st->codec;
/* Put sample parameters. */
c->bit_rate = 400000;
/* Resolution must be a multiple of two. */
c->width = w;
c->height = h;
/* timebase: This is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented. For fixed-fps content,
* timebase should be 1/framerate and timestamp increments should be
* identical to 1. */
c->time_base.den = fps;
c->time_base.num = 1;
c->gop_size = 12; /* emit one intra frame every twelve frames at most */
c->codec = codec;
c->codec_type = AVMEDIA_TYPE_VIDEO;
c->coder_type = FF_CODER_TYPE_VLC;
c->me_method = 7; //motion estimation algorithm
c->me_subpel_quality = 4;
c->delay = 0;
c->max_b_frames = 0;
c->thread_count = 1; // more than one threads seem to increase delay
c->refs = 3;
c->pix_fmt = PIX_FMT_YUV420P;
/* Some formats want stream headers to be separate. */
if (oc->oformat->flags & AVFMT_GLOBALHEADER)
c->flags |= CODEC_FLAG_GLOBAL_HEADER;
return st;
}but with this avcodec_encode_video() will buffer 13 frames before returning any bytes (after that, it will return bytes on every frame). if I set gop_size to 0, then avcodec_encode_video() will return bytes only after the second frame was passed to it. I need a zero delay though.
This guy apparently was successful (even with larger gop) : http://mailman.videolan.org/pipermail/x264-devel/2009-May/005880.html but I don’t see what he is doing differently