FFmpeg codec instance

Source: Internet
Author: User

# Include <stdlib. h>
# Include <stdio. h>
# Include <string. h>

# Ifdef have_av_config_h
# UNDEF have_av_config_h
# Endif

# Include "libavcodec/avcodec. H"
# Include "libavutil/mathematics. H"

# Define inbuf_size 4096
# Define audio_inbuf_size 20480
# Define audio_refill_thresh 4096

/*
* Audio Encoding example
*/
Static void audio_encode_example (const char * filename)
{
Avcodec * codec;
Avcodeccontext * c = NULL;
Int frame_size, I, j, out_size, outbuf_size;
File * F;
Short * samples;
Float T, tincr;
Uint8_t * outbuf;

Printf ("Audio Encoding \ n ");

/* Find the MP2 encoder */
Codec = avcodec_find_encoder (codec_id_mp2 );
If (! Codec ){
Fprintf (stderr, "codec not found \ n ");
Exit (1 );
}

C = avcodec_alloc_context ();

/* Put sample parameters */
C-> bit_rate = 64000;
C-> sample_rate = 44100;
C-> channels = 2;

/* Open It */
If (avcodec_open (C, codec) <0 ){
Fprintf (stderr, "cocould not open codec \ n ");
Exit (1 );
}

/* The codec gives us the frame size, in samples */
Frame_size = C-> frame_size;
Samples = malloc (frame_size * 2 * C-> channels );
Outbuf_size = 10000;
Outbuf = malloc (outbuf_size );

F = fopen (filename, "WB ");
If (! F ){
Fprintf (stderr, "cocould not open % s \ n", filename );
Exit (1 );
}

/* Encode a single tone sound */
T = 0;
Tincr = 2 * m_pi * 440.0/C-> sample_rate;
For (I = 0; I <200; I ++ ){
For (j = 0; j <frame_size; j ++ ){
Samples [2 * j] = (INT) (sin (t) * 10000 );
Samples [2 * j + 1] = samples [2 * j];
T + = tincr;
}
/* Encode the samples */
Out_size = avcodec_encode_audio (C, outbuf, outbuf_size, samples );
Fwrite (outbuf, 1, out_size, F );
}
Fclose (f );
Free (outbuf );
Free (samples );

Avcodec_close (C );
Av_free (C );
}

/*
* Audio decoding.
*/
Static void audio_decode_example (const char * outfilename, const char * filename)
{
Avcodec * codec;
Avcodeccontext * c = NULL;
Int out_size, Len;
File * F, * OUTFILE;
Uint8_t * outbuf;
Uint8_t inbuf [audio_inbuf_size + ff_input_buffer_padding_size];
Avpacket avpkt;

Av_init_packet (& avpkt );

Printf ("audio decoding \ n ");

/* Find the MPEG audio decoder */
Codec = avcodec_find_decoder (codec_id_mp2 );
If (! Codec ){
Fprintf (stderr, "codec not found \ n ");
Exit (1 );
}

C = avcodec_alloc_context ();

/* Open It */
If (avcodec_open (C, codec) <0 ){
Fprintf (stderr, "cocould not open codec \ n ");
Exit (1 );
}

Outbuf = malloc (avcodec_max_audio_frame_size );

F = fopen (filename, "rb ");
If (! F ){
Fprintf (stderr, "cocould not open % s \ n", filename );
Exit (1 );
}
OUTFILE = fopen (outfilename, "WB ");
If (! OUTFILE ){
Av_free (C );
Exit (1 );
}

/* Decode until EOF */
Avpkt. Data = inbuf;
Avpkt. size = fread (inbuf, 1, audio_inbuf_size, F );

While (avpkt. size> 0 ){
Out_size = avcodec_max_audio_frame_size;
Len = avcodec_decode_audio3 (C, (short *) outbuf, & out_size, & avpkt );
If (LEN <0 ){
Fprintf (stderr, "error while decoding \ n ");
Exit (1 );
}
If (out_size> 0 ){
/* If a frame has been decoded, output it */
Fwrite (outbuf, 1, out_size, OUTFILE );
}
Avpkt. Size-= Len;
Avpkt. Data + = Len;
If (avpkt. Size <audio_refill_thresh ){
/* Refill the input buffer, to avoid trying to decode
* Incomplete frames. Instead of this, one cocould also use
* A parser, or use a proper container format through
* Libavformat .*/
Memmove (inbuf, avpkt. Data, avpkt. size );
Avpkt. Data = inbuf;
Len = fread (avpkt. Data + avpkt. Size, 1,
Audio_inbuf_size-avpkt. Size, F );
If (LEN> 0)
Avpkt. Size + = Len;
}
}

Fclose (OUTFILE );
Fclose (f );
Free (outbuf );

Avcodec_close (C );
Av_free (C );
}

/*
* Video Encoding example
*/
Static void video_encode_example (const char * filename)
{
Avcodec * codec;
Avcodeccontext * c = NULL;
Int I, out_size, size, X, Y, outbuf_size;
File * F;
Avframe * picture;
Uint8_t * outbuf, * picture_buf;

Printf ("video encoding \ n ");

/* Find the mpeg1 Video Encoder */
Codec = avcodec_find_encoder (codec_id_mpeg1video );
If (! Codec ){
Fprintf (stderr, "codec not found \ n ");
Exit (1 );
}

C = avcodec_alloc_context ();
Picture = avcodec_alloc_frame ();

/* Put sample parameters */
C-> bit_rate = 400000;
/* Resolution must be a multiple of two */
C-> width = 352;
C-> Height = 288;
/* Frames per second */
C-> time_base = (avrational) {25 };
C-> gop_size = 10;/* emit one intra frame every ten frames */
C-> max_ B _frames = 1;
C-> pix_fmt = pix_fmt_yuv420p;

/* Open It */
If (avcodec_open (C, codec) <0 ){
Fprintf (stderr, "cocould not open codec \ n ");
Exit (1 );
}

F = fopen (filename, "WB ");
If (! F ){
Fprintf (stderr, "cocould not open % s \ n", filename );
Exit (1 );
}

/* Alloc image and output buffer */
Outbuf_size = 100000;
Outbuf = malloc (outbuf_size );
Size = C-> width * C-> height;
Picture_buf = malloc (size * 3)/2);/* size for YUV 420 */

Picture-> data [0] = picture_buf;
Picture-> data [1] = picture-> data [0] + size;
Picture-> data [2] = picture-> data [1] + size/4;
Picture-> linesize [0] = C-> width;
Picture-> linesize [1] = C-> width/2;
Picture-> linesize [2] = C-> width/2;

/* Encode 1 second of video */
For (I = 0; I <25; I ++ ){
Fflush (stdout );
/* Prepare a dummy image */
/* Y */
For (y = 0; y <c-> height; y ++ ){
For (x = 0; x <c-> width; X ++ ){
Picture-> data [0] [y * picture-> linesize [0] + x] = x + y + I * 3;
}
}

/* CB and Cr */
For (y = 0; y <c-> height/2; y ++ ){
For (x = 0; x <c-> width/2; X ++ ){
Picture-> data [1] [y * picture-> linesize [1] + x] = 128 + Y + I * 2;
Picture-> data [2] [y * picture-> linesize [2] + x] = 64 + x + I * 5;
}
}

/* Encode the image */
Out_size = avcodec_encode_video (C, outbuf, outbuf_size, picture );
Printf ("Encoding Frame % 3d (size = % 5d) \ n", I, out_size );
Fwrite (outbuf, 1, out_size, F );
}

/* Get the delayed frames */
For (; out_size; I ++ ){
Fflush (stdout );

Out_size = avcodec_encode_video (C, outbuf, outbuf_size, null );
Printf ("Write frame % 3d (size = % 5d) \ n", I, out_size );
Fwrite (outbuf, 1, out_size, F );
}

/* Add sequence end code to have a real mpeg file */
Outbuf [0] = 0x00;
Outbuf [1] = 0x00;
Outbuf [2] = 0x01;
Outbuf [3] = 0xb7;
Fwrite (outbuf, 1, 4, F );
Fclose (f );
Free (picture_buf );
Free (outbuf );

Avcodec_close (C );
Av_free (C );
Av_free (picture );
Printf ("\ n ");
}

/*
* Video decoding example
*/

Static void pgm_save (unsigned char * Buf, int wrap, int xsize, int ysize,
Char * filename)
{
File * F;
Int I;

F = fopen (filename, "W ");
Fprintf (F, "P5 \ n % d \ n", xsize, ysize, 255 );
For (I = 0; I <ysize; I ++)
Fwrite (BUF + I * Wrap, 1, xsize, F );
Fclose (f );
}

Static void video_decode_example (const char * outfilename, const char * filename)
{
Avcodec * codec;
Avcodeccontext * c = NULL;
Int frame, got_picture, Len;
File * F;
Avframe * picture;
Uint8_t inbuf [inbuf_size + ff_input_buffer_padding_size];
Char Buf [1024];
Avpacket avpkt;

Av_init_packet (& avpkt );

/* Set end of buffer to 0 (this ensures that no overreading happens for damaged MPEG streams )*/
Memset (inbuf + inbuf_size, 0, ff_input_buffer_padding_size );

Printf ("video decoding \ n ");

/* Find the mpeg1 Video Decoder */
Codec = avcodec_find_decoder (codec_id_mpeg1video );
If (! Codec ){
Fprintf (stderr, "codec not found \ n ");
Exit (1 );
}

C = avcodec_alloc_context ();
Picture = avcodec_alloc_frame ();

If (codec-> capabilities & codec_cap_truncated)
C-> flags | = codec_flag_truncated;/* we do not send complete frames */

/* For some codecs, such as msmpeg4 and MPEG4, width and height
Must be initialized there because this information is not
Available in the bitstream .*/

/* Open It */
If (avcodec_open (C, codec) <0 ){
Fprintf (stderr, "cocould not open codec \ n ");
Exit (1 );
}

/* The codec gives us the frame size, in samples */

F = fopen (filename, "rb ");
If (! F ){
Fprintf (stderr, "cocould not open % s \ n", filename );
Exit (1 );
}

Frame = 0;
For (;;){
Avpkt. size = fread (inbuf, 1, inbuf_size, F );
If (avpkt. size = 0)
Break;

/* Note1: Some codecs are stream based (mpegvideo, mpegaudio)
And this is the only method to use them because you cannot
Know the compressed data size before analyzing it.

But some other codecs (msmpeg4, MPEG4) are inherently Frame
Based, so you must call them with all the data for one
Frame exactly. You must also initialize 'width' and
'Height' before initializing them .*/

/* Note2: Some codecs allow the raw parameters (frame size,
Sample Rate) to be changed at any frame. we handle this, so
You shoshould also take care of it */

/* Here, we use a stream based Decoder (mpeg1video), so we
Feed decoder and see if it coshould decode a frame */
Avpkt. Data = inbuf;
While (avpkt. size> 0 ){
Len = avcodec_decode_video2 (C, picture, & got_picture, & avpkt );
If (LEN <0 ){
Fprintf (stderr, "error while Decoding Frame % d \ n", frame );
Exit (1 );
}
If (got_picture ){
Printf ("Saving frame % 3d \ n", frame );
Fflush (stdout );

/* The picture is allocated by the decoder. No need
Free It */
Snprintf (BUF, sizeof (BUF), outfilename, frame );
Pgm_save (picture-> data [0], picture-> linesize [0],
C-> width, C-> height, Buf );
Frame ++;
}
Avpkt. Size-= Len;
Avpkt. Data + = Len;
}
}

/* Some codecs, such as MPEG, transmit the I and P frame with
Latency of one frame. You must do the following to have
Chance to get the last frame of the video */
Avpkt. Data = NULL;
Avpkt. size = 0;
Len = avcodec_decode_video2 (C, picture, & got_picture, & avpkt );
If (got_picture ){
Printf ("Saving last frame % 3d \ n", frame );
Fflush (stdout );

/* The picture is allocated by the decoder. No need
Free It */
Snprintf (BUF, sizeof (BUF), outfilename, frame );
Pgm_save (picture-> data [0], picture-> linesize [0],
C-> width, C-> height, Buf );
Frame ++;
}

Fclose (f );

Avcodec_close (C );
Av_free (C );
Av_free (picture );
Printf ("\ n ");
}

Int main (INT argc, char ** argv)
{
Const char * filename;

/* Must be called before using avcodec lib */
Avcodec_init ();

/* Register all the codecs */
Avcodec_register_all ();

If (argc <= 1 ){
Audio_encode_example ("/tmp/test. MP2 ");
Audio_decode_example ("/tmp/test. SW", "/tmp/test. MP2 ");

Video_encode_example ("/tmp/test. mpg ");
Filename = "/tmp/test. mpg ";
} Else {
Filename = argv [1];
}

// Audio_decode_example ("/tmp/test. SW", filename );
Video_decode_example ("/tmp/test % d. PGM", filename );

Return 0;
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.