@ -43,7 +43,7 @@
# define STREAM_DURATION 200.0
# define STREAM_FRAME_RATE 25 /* 25 images/s */
# define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
# define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
# define STREAM_PIX_FMT PIX_FMT_YUV420P /* default pix_fmt */
static int sws_flags = SWS_BICUBIC ;
@ -80,10 +80,10 @@ static AVStream *add_audio_stream(AVFormatContext *oc, enum CodecID codec_id)
c = st - > codec ;
/* put sample parameters */
c - > sample_fmt = AV_SAMPLE_FMT_S16 ;
c - > bit_rate = 64000 ;
c - > sample_fmt = AV_SAMPLE_FMT_S16 ;
c - > bit_rate = 64000 ;
c - > sample_rate = 44100 ;
c - > channels = 2 ;
c - > channels = 2 ;
// some formats want stream headers to be separate
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER )
@ -105,7 +105,7 @@ static void open_audio(AVFormatContext *oc, AVStream *st)
}
/* init signal generator */
t = 0 ;
t = 0 ;
tincr = 2 * M_PI * 110.0 / c - > sample_rate ;
/* increment frequency by 110 Hz per second */
tincr2 = 2 * M_PI * 110.0 / c - > sample_rate / c - > sample_rate ;
@ -114,12 +114,13 @@ static void open_audio(AVFormatContext *oc, AVStream *st)
audio_input_frame_size = 10000 ;
else
audio_input_frame_size = c - > frame_size ;
samples = av_malloc ( audio_input_frame_size * av_get_bytes_per_sample ( c - > sample_fmt )
* c - > channels ) ;
samples = av_malloc ( audio_input_frame_size *
av_get_bytes_per_sample ( c - > sample_fmt ) *
c - > channels ) ;
}
/* p repare a 16 bit dummy audio frame of 'frame_size' samples and
' nb_channels ' channels */
/* P repare a 16 bit dummy audio frame of 'frame_size' samples and
* ' nb_channels ' channels . */
static void get_audio_frame ( int16_t * samples , int frame_size , int nb_channels )
{
int j , i , v ;
@ -128,9 +129,9 @@ static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
q = samples ;
for ( j = 0 ; j < frame_size ; j + + ) {
v = ( int ) ( sin ( t ) * 10000 ) ;
for ( i = 0 ; i < nb_channels ; i + + )
for ( i = 0 ; i < nb_channels ; i + + )
* q + + = v ;
t + = tincr ;
t + = tincr ;
tincr + = tincr2 ;
}
}
@ -138,7 +139,7 @@ static void get_audio_frame(int16_t *samples, int frame_size, int nb_channels)
static void write_audio_frame ( AVFormatContext * oc , AVStream * st )
{
AVCodecContext * c ;
AVPacket pkt ;
AVPacket pkt = { 0 } ; // data and size must be 0;
AVFrame * frame = avcodec_alloc_frame ( ) ;
int got_packet ;
@ -147,17 +148,19 @@ static void write_audio_frame(AVFormatContext *oc, AVStream *st)
get_audio_frame ( samples , audio_input_frame_size , c - > channels ) ;
frame - > nb_samples = audio_input_frame_size ;
avcodec_fill_audio_frame ( frame , c - > channels , c - > sample_fmt , ( uint8_t * ) samples ,
audio_input_frame_size * av_get_bytes_per_sample ( c - > sample_fmt )
* c - > channels , 1 ) ;
avcodec_fill_audio_frame ( frame , c - > channels , c - > sample_fmt ,
( uint8_t * ) samples ,
audio_input_frame_size *
av_get_bytes_per_sample ( c - > sample_fmt ) *
c - > channels , 1 ) ;
avcodec_encode_audio2 ( c , & pkt , frame , & got_packet ) ;
if ( ! got_packet )
return ;
pkt . stream_index = st - > index ;
pkt . stream_index = st - > index ;
/* write the compressed frame in the media file */
/* Write the compressed frame to the media file. */
if ( av_interleaved_write_frame ( oc , & pkt ) ! = 0 ) {
fprintf ( stderr , " Error while writing audio frame \n " ) ;
exit ( 1 ) ;
@ -178,7 +181,7 @@ static AVFrame *picture, *tmp_picture;
static uint8_t * video_outbuf ;
static int frame_count , video_outbuf_size ;
/* add a video output stream */
/* Add a video output stream. */
static AVStream * add_video_stream ( AVFormatContext * oc , enum CodecID codec_id )
{
AVCodecContext * c ;
@ -210,30 +213,30 @@ static AVStream *add_video_stream(AVFormatContext *oc, enum CodecID codec_id)
c - > codec_id = codec_id ;
/* put sample parameters */
/* Put sample parameters. */
c - > bit_rate = 400000 ;
/* resolution must be a multiple of two */
c - > width = 352 ;
c - > height = 288 ;
/* time base: t his is the fundamental unit of time (in seconds) in terms
of which frame timestamps are represented . f or fixed - fps content ,
timebase should be 1 / framerate and timestamp increments should be
identically 1. */
/* Resolution must be a multiple of two. */
c - > width = 352 ;
c - > height = 288 ;
/* timebase: T his is the fundamental unit of time (in seconds) in terms
* of which frame timestamps are represented . F or fixed - fps content ,
* timebase should be 1 / framerate and timestamp increments should be
* identical to 1. */
c - > time_base . den = STREAM_FRAME_RATE ;
c - > time_base . num = 1 ;
c - > gop_size = 12 ; /* emit one intra frame every twelve frames at most */
c - > pix_fmt = STREAM_PIX_FMT ;
c - > gop_size = 12 ; /* emit one intra frame every twelve frames at most */
c - > pix_fmt = STREAM_PIX_FMT ;
if ( c - > codec_id = = CODEC_ID_MPEG2VIDEO ) {
/* just for testing, we also add B frames */
c - > max_b_frames = 2 ;
}
if ( c - > codec_id = = CODEC_ID_MPEG1VIDEO ) {
if ( c - > codec_id = = 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 ;
* 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 ;
}
// some formats want stream headers to be separate
/* Some formats want stream headers to be separate. */
if ( oc - > oformat - > flags & AVFMT_GLOBALHEADER )
c - > flags | = CODEC_FLAG_GLOBAL_HEADER ;
@ -249,7 +252,7 @@ static AVFrame *alloc_picture(enum PixelFormat pix_fmt, int width, int height)
picture = avcodec_alloc_frame ( ) ;
if ( ! picture )
return NULL ;
size = avpicture_get_size ( pix_fmt , width , height ) ;
size = avpicture_get_size ( pix_fmt , width , height ) ;
picture_buf = av_malloc ( size ) ;
if ( ! picture_buf ) {
av_free ( picture ) ;
@ -274,26 +277,26 @@ static void open_video(AVFormatContext *oc, AVStream *st)
video_outbuf = NULL ;
if ( ! ( oc - > oformat - > flags & AVFMT_RAWPICTURE ) ) {
/* allocate output buffer */
/* XXX: API change will be done */
/* b uffers passed into lav* can be allocated any way you prefer,
as long as they ' re aligned enough for the architecture , and
they ' re freed appropriately ( such as using av_free for buffers
allocated with av_malloc ) */
/* Allocate output buffer. */
/* XXX: API change will be done. */
/* B uffers passed into lav* can be allocated any way you prefer,
* as long as they ' re aligned enough for the architecture , and
* they ' re freed appropriately ( such as using av_free for buffers
* allocated with av_malloc ) . */
video_outbuf_size = 200000 ;
video_outbuf = av_malloc ( video_outbuf_size ) ;
video_outbuf = av_malloc ( video_outbuf_size ) ;
}
/* allocate the encoded raw picture */
/* Allocate the encoded raw picture. */
picture = alloc_picture ( c - > pix_fmt , c - > width , c - > height ) ;
if ( ! picture ) {
fprintf ( stderr , " Could not allocate picture \n " ) ;
exit ( 1 ) ;
}
/* i f the output format is not YUV420P, then a temporary YUV420P
picture is needed too . It is then converted to the required
output format */
/* I f the output format is not YUV420P, then a temporary YUV420P
* picture is needed too . It is then converted to the required
* output format . */
tmp_picture = NULL ;
if ( c - > pix_fmt ! = PIX_FMT_YUV420P ) {
tmp_picture = alloc_picture ( PIX_FMT_YUV420P , c - > width , c - > height ) ;
@ -304,23 +307,22 @@ static void open_video(AVFormatContext *oc, AVStream *st)
}
}
/* prepare a dummy image */
static void fill_yuv_image ( AVFrame * pict , int frame_index , int width , int height )
/* Prepare a dummy image. */
static void fill_yuv_image ( AVFrame * pict , int frame_index ,
int width , int height )
{
int x , y , i ;
i = frame_index ;
/* Y */
for ( y = 0 ; y < height ; y + + ) {
for ( x = 0 ; x < width ; x + + ) {
for ( y = 0 ; y < height ; y + + )
for ( x = 0 ; x < width ; x + + )
pict - > data [ 0 ] [ y * pict - > linesize [ 0 ] + x ] = x + y + i * 3 ;
}
}
/* Cb and Cr */
for ( y = 0 ; y < height / 2 ; y + + ) {
for ( x = 0 ; x < width / 2 ; x + + ) {
for ( y = 0 ; y < height / 2 ; y + + ) {
for ( x = 0 ; x < width / 2 ; x + + ) {
pict - > data [ 1 ] [ y * pict - > linesize [ 1 ] + x ] = 128 + y + i * 2 ;
pict - > data [ 2 ] [ y * pict - > linesize [ 2 ] + x ] = 64 + x + i * 5 ;
}
@ -336,13 +338,13 @@ static void write_video_frame(AVFormatContext *oc, AVStream *st)
c = st - > codec ;
if ( frame_count > = STREAM_NB_FRAMES ) {
/* no more frame to compress. The codec has a latency of a few
frames if using B frames , so we get the last frames by
passing the same picture again */
/* No more frames to compress. The codec has a latency of a few
* frames if using B - frames , so we get the last frames by
* passing the same picture again . */
} else {
if ( c - > pix_fmt ! = PIX_FMT_YUV420P ) {
/* as we only generate a YUV420P picture, we must convert it
to the codec pixel format if needed */
* to the codec pixel format if needed */
if ( img_convert_ctx = = NULL ) {
img_convert_ctx = sws_getContext ( c - > width , c - > height ,
PIX_FMT_YUV420P ,
@ -350,7 +352,8 @@ static void write_video_frame(AVFormatContext *oc, AVStream *st)
c - > pix_fmt ,
sws_flags , NULL , NULL , NULL ) ;
if ( img_convert_ctx = = NULL ) {
fprintf ( stderr , " Cannot initialize the conversion context \n " ) ;
fprintf ( stderr ,
" Cannot initialize the conversion context \n " ) ;
exit ( 1 ) ;
}
}
@ -362,36 +365,38 @@ static void write_video_frame(AVFormatContext *oc, AVStream *st)
}
}
if ( oc - > oformat - > flags & AVFMT_RAWPICTURE ) {
/* raw video case. T he API will change slightly in the near
future for that . */
/* Raw video case - t he API will change slightly in the near
* future for that . */
AVPacket pkt ;
av_init_packet ( & pkt ) ;
pkt . flags | = AV_PKT_FLAG_KEY ;
pkt . stream_index = st - > index ;
pkt . data = ( uint8_t * ) picture ;
pkt . size = sizeof ( AVPicture ) ;
pkt . flags | = AV_PKT_FLAG_KEY ;
pkt . stream_index = st - > index ;
pkt . data = ( uint8_t * ) picture ;
pkt . size = sizeof ( AVPicture ) ;
ret = av_interleaved_write_frame ( oc , & pkt ) ;
} else {
/* encode the image */
out_size = avcodec_encode_video ( c , video_outbuf , video_outbuf_size , picture ) ;
/* if zero size, it means the image was buffered */
out_size = avcodec_encode_video ( c , video_outbuf ,
video_outbuf_size , picture ) ;
/* If size is zero, it means the image was buffered. */
if ( out_size > 0 ) {
AVPacket pkt ;
av_init_packet ( & pkt ) ;
if ( c - > coded_frame - > pts ! = AV_NOPTS_VALUE )
pkt . pts = av_rescale_q ( c - > coded_frame - > pts , c - > time_base , st - > time_base ) ;
if ( c - > coded_frame - > key_frame )
pkt . pts = av_rescale_q ( c - > coded_frame - > pts ,
c - > time_base , st - > time_base ) ;
if ( c - > coded_frame - > key_frame )
pkt . flags | = AV_PKT_FLAG_KEY ;
pkt . stream_index = st - > index ;
pkt . data = video_outbuf ;
pkt . size = out_size ;
pkt . data = video_outbuf ;
pkt . size = out_size ;
/* write the compressed frame in the media file */
/* Write the compressed frame to the media file. */
ret = av_interleaved_write_frame ( oc , & pkt ) ;
} else {
ret = 0 ;
@ -428,7 +433,7 @@ int main(int argc, char **argv)
double audio_pts , video_pts ;
int i ;
/* i nitialize libavcodec, and register all codecs and formats */
/* I nitialize libavcodec, and register all codecs and formats. */
av_register_all ( ) ;
if ( argc ! = 2 ) {
@ -453,8 +458,8 @@ int main(int argc, char **argv)
}
fmt = oc - > oformat ;
/* a dd the audio and video streams using the default format codecs
and initialize the codecs */
/* A dd the audio and video streams using the default format codecs
* and initialize the codecs . */
video_st = NULL ;
audio_st = NULL ;
if ( fmt - > video_codec ! = CODEC_ID_NONE ) {
@ -464,15 +469,15 @@ int main(int argc, char **argv)
audio_st = add_audio_stream ( oc , fmt - > audio_codec ) ;
}
av_dump_format ( oc , 0 , filename , 1 ) ;
/* now that all the parameters are set, we can open the audio and
video codecs and allocate the necessary encode buffers */
/* Now that all the parameters are set, we can open the audio and
* video codecs and allocate the necessary encode buffers . */
if ( video_st )
open_video ( oc , video_st ) ;
if ( audio_st )
open_audio ( oc , audio_st ) ;
av_dump_format ( oc , 0 , filename , 1 ) ;
/* open the output file, if needed */
if ( ! ( fmt - > flags & AVFMT_NOFILE ) ) {
if ( avio_open ( & oc - > pb , filename , AVIO_FLAG_WRITE ) < 0 ) {
@ -481,18 +486,20 @@ int main(int argc, char **argv)
}
}
/* write the stream header, if any */
/* Write the stream header, if any. */
avformat_write_header ( oc , NULL ) ;
picture - > pts = 0 ;
for ( ; ; ) {
/* compute current audio and video time */
for ( ; ; ) {
/* Compute current audio and video time. */
if ( audio_st )
audio_pts = ( double ) audio_st - > pts . val * audio_st - > time_base . num / audio_st - > time_base . den ;
else
audio_pts = 0.0 ;
if ( video_st )
video_pts = ( double ) video_st - > pts . val * video_st - > time_base . num / video_st - > time_base . den ;
video_pts = ( double ) video_st - > pts . val * video_st - > time_base . num /
video_st - > time_base . den ;
else
video_pts = 0.0 ;
@ -509,28 +516,27 @@ int main(int argc, char **argv)
}
}
/* write the trailer, if any. the trailer must be written
* before you close the CodecContexts open when you wrote the
* header ; otherwise write_trailer may try to use memory that
* was freed on av_codec_close ( ) */
/* Write the trailer, if any. The trailer must be written before you
* close the CodecContexts open when you wrote the header ; otherwis e
* av_write_trailer ( ) may try to use memory that was freed on
* av_codec_close ( ) . */
av_write_trailer ( oc ) ;
/* close each codec */
/* Close each codec. */
if ( video_st )
close_video ( oc , video_st ) ;
if ( audio_st )
close_audio ( oc , audio_st ) ;
/* free the streams */
for ( i = 0 ; i < oc - > nb_streams ; i + + ) {
/* Free the streams. */
for ( i = 0 ; i < oc - > nb_streams ; i + + ) {
av_freep ( & oc - > streams [ i ] - > codec ) ;
av_freep ( & oc - > streams [ i ] ) ;
}
if ( ! ( fmt - > flags & AVFMT_NOFILE ) ) {
/* close the output file */
if ( ! ( fmt - > flags & AVFMT_NOFILE ) )
/* Close the output file. */
avio_close ( oc - > pb ) ;
}
/* free the stream */
av_free ( oc ) ;