Read memory reads and writes based on the simplest ffmpeg sampling: storage

Source: Internet
Author: User

=====================================================

Based on the simplest FFmpeg sample series read-Write memory list:

Simplest example of ffmpeg-based memory read and write: Memory player

Simplest sample of memory read-write based on ffmpeg: memory transcoding device

=====================================================

The previous article recorded a ffmpeg-based memory player that was able to read and play the data in memory using FFmpeg.

This article records a ffmpeg-based memory transcoding device.

The transcoding device can use FFmpeg to read in-memory data, transcoding to H. I and then outputting the data to memory.

For information on how to read data from memory and how to output it to memory, you can refer to the article:

FFmpeg reading data from memory (or outputting data to memory)

There are 2 key points for ffmpeg reading and writing memory:
1. Initialize your own defined Aviocontext, specifying your own defined callback function.
2. Write the callback function yourself.

Note the parameters of the function and the return value (especially the return value).


Transcoding is actually a combination of decoding and encoding.

This knowledge can be involved in the article:

Decoding: 100 lines of code for the simplest FFMPEG+SDL-based video player (sdl1.x)

Coding: The simplest video encoder based on FFmpeg (YUV encoded as H.

Transcoding: The simplest ffmpeg-based transcoding program

Flow chart Flowchart For example, as seen in. It can be seen that the input and output avformatcontext are initially initialized separately. The input avpacket is then decoded first, and the avframe of the stored pixel data (yuv420p format) is obtained. Then encode avframe to H. Avpacket, and finally encode the avpacket output.


watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbgvpeglhb2h1ytewmja=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma== /dissolve/70/gravity/southeast "/>
The code is directly labeled as follows:

/** * Simplest memory-read-write sample based on FFmpeg (memory transcoding) * Simplest FFmpeg mem transcoder * * Lei Hua, Zhang Hui * [email protected] * Communication University/Digital TV Technology * Co Mmunication University of China/digital TV technology * http://blog.csdn.net/leixiaohua1020 * * This program realizes the random format video data (such as MPEG2) turn The code is a stream data of H. * This program does not process the files, but instead handles the in-memory video data. * It reads data from memory and outputs the transcoded data into memory. * Is the simplest example of using ffmpeg to read and write memory. * * This software convert video bitstream (Such as MPEG2) to H. Bitstream. It read video bitstream from memory (not from a file), * convert it to H. bitstream, and finally output to another memo Ry. * It ' s The simplest example to use FFmpeg to read (or write) from * memory. * */#include <stdio.h>extern "C" {#include "libavcodec/avcodec.h" #include "libavformat/avformat.h" #include " Libavutil/avutil.h "#include" libavutil/opt.h "#include" libavutil/pixdesc.h "}; FILE *fp_open; FILE *fp_write;//read fileint read_buffer (void *opaque, uint8_t *buf, int buf_size) {if (!feof (Fp_open)) {int true_size= Fread (Buf,1,buf_size,fp_open); return true_size;} Else{return-1;}} Write fileint write_buffer (void *opaque, uint8_t *buf, int buf_size) {if (!feof (fp_write)) {int True_size=fwrite (buf,1, Buf_size,fp_write); return true_size;} else{return-1;}}    int Flush_encoder (avformatcontext *fmt_ctx,unsigned int stream_index) {int ret; int got_frame;    Avpacket enc_pkt; if (! ( Fmt_ctx->streams[stream_index]->codec->codec->capabilities & Codec_cap_delay) retur    n 0;        while (1) {Av_log (NULL, Av_log_info, "Flushing stream #%u encoder\n", Stream_index);        ret = Encode_write_frame (NULL, Stream_index, &got_frame); Enc_pkt.data = Null;enc_pkt.size = 0;av_init_packet (&AMP;ENC_PKT); ret = Avcodec_encode_video2 (fmt_ctx->streams[ Stream_index]->codec, &enc_pkt,null, &got_frame); Av_frame_free (NULL); if (Ret < 0) break;if (!got_frame) {ret=0;break;} /* Prepare packet for muxing */enc_pkt.stream_index = Stream_index;enc_pkt.dts = Av_rescale_q_rnd (enc_pkt.dts,fmt_ctx-& gt;streams[stream_index]-&Gt;codec->time_base,fmt_ctx->streams[stream_index]->time_base, (avrounding) (AV_ROUND_NEAR_INF| Av_round_pass_minmax)); enc_pkt.pts = Av_rescale_q_rnd (enc_pkt.pts,fmt_ctx->streams[stream_index]->codec- >time_base,fmt_ctx->streams[stream_index]->time_base, (avrounding) (av_round_near_inf| Av_round_pass_minmax)); enc_pkt.duration = Av_rescale_q (enc_pkt.duration,fmt_ctx->streams[stream_index]-> Codec->time_base,fmt_ctx->streams[stream_index]->time_base); Av_log (NULL, Av_log_debug, "Muxing frame\n")    ;/* MUX encoded frame */ret = Av_write_frame (Fmt_ctx, &AMP;ENC_PKT); if (Ret < 0) break; } return ret;} int main (int argc, char* argv[]) {int ret; avformatcontext* Ifmt_ctx=null; avformatcontext* Ofmt_ctx=null; Avpacket packet,enc_pkt; Avframe *frame = null;enum avmediatype type;unsigned int stream_index;unsigned int i=0;int got_frame,enc_got_frame; Avstream *out_stream; Avstream *in_stream; Avcodeccontext *dec_ctx, *enc_ctx; Avcodec *encoder;fp_open = fopen ("Cuc60anniversary_start.ts", "RB");//Video source file Fp_write=fopen ("cuc60anniversary_start.h264", "wb+"); Output file Av_register_all (); Ifmt_ctx=avformat_alloc_context (); Avformat_alloc_output_context2 (&ofmt_ctx, NULL, " H264 ", NULL); unsigned char* inbuffer=null;unsigned char* outbuffer=null;inbuffer= (unsigned char*) av_malloc (32768); o utbuffer= (unsigned char*) av_malloc (32768);/*open input File*/aviocontext *avio_in =avio_alloc_context (Inbuffer,  32768,0,null,read_buffer,null,null); if (avio_in==null) goto end;ifmt_ctx->pb=avio_in; Ifmt_ctx->flags=avfmt_flag_custom_io;if (ret = Avformat_open_input (&ifmt_ctx, "Whatever", NULL, NULL)) < 0) {Av_log (NULL, Av_log_error, "Cannot open input file\n"); return ret;} if (ret = Avformat_find_stream_info (ifmt_ctx, NULL)) < 0) {Av_log (null, Av_log_error, "Cannot find stream information\ n "); return ret;} for (i = 0; i < ifmt_ctx->nb_streams; i++) {Avstream *stream; Avcodeccontext *codec_ctx;stream = Ifmt_ctx->streams[i];codec_ctx = Stream->codec;/* Reencode Video & Audio and Remux subtitles etc. */if (Codec_ctx->codec_type = = Avmedia_type_video) {/* Open de Coder */ret = Avcodec_open2 (Codec_ctx,avcodec_find_decoder (codec_ctx->codec_id), NULL); if (Ret < 0) {Av_log (null , Av_log_error, "Failed to open decoder for stream #%u\n", I); return ret;}}} Av_dump_format (ifmt_ctx, 0, "whatever", 0);/*open output File*/aviocontext *avio_out =avio_alloc_context (Outbuffer,  32768,0,null,null,write_buffer,null); if (avio_out==null) goto end;//avio_out->write_packet=write_packet;ofmt_ctx->pb=avio_out; Ofmt_ctx->flags=avfmt_flag_custom_io;for (i = 0; i < 1; i++) {Out_stream = Avformat_new_stream (Ofmt_ctx, NULL); Out_stream) {Av_log (NULL, Av_log_error, "Failed allocating output stream\n"); return averror_unknown;} In_stream = ifmt_ctx->streams[i];d ec_ctx = In_stream->codec;enc_ctx = Out_stream->codec;if (dec_ctx-> Codec_type = = Avmedia_type_video) {encoder = Avcodec_find_encoder (av_codec_id_h264); enc_ctx->height = Dec_ctx->height;enc_ctx->width = Dec_ctx->width;enc_ctx->sample_aspect_ratio = Dec_ctx->sample _aspect_ratio;enc_ctx->pix_fmt = Encoder->pix_fmts[0];enc_ctx->time_base = dec_ctx->time_base;//enc_ Ctx->time_base.num = 1;//enc_ctx->time_base.den = 25;//h264 of the necessary options, no will be wrong enc_ctx->me_range=16;enc_ctx-> Max_qdiff = 4;enc_ctx->qmin = 10;enc_ctx->qmax = 51;enc_ctx->qcompress = 0.6; Enc_ctx->refs=3;enc_ctx->bit_rate = 500000;ret = Avcodec_open2 (Enc_ctx, encoder, NULL); if (Ret < 0) {Av_log ( NULL, Av_log_error, "Cannot open video encoder for stream #%u\n", I); return ret;}} else if (Dec_ctx->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 {/* If this stream must be remuxed */ret = Avcodec_copy_context (ofmt_ctx->streams[i]->codec,ifmt_ctx-> STREAMS[I]-&GT;CODEC); if (Ret < 0) {Av_log (NULL, Av_log_error, "Copying streAM Context failed\n "); return ret;}} if (Ofmt_ctx->oformat->flags & Avfmt_globalheader) enc_ctx->flags |= Codec_flag_global_header;} Av_dump_format (ofmt_ctx, 0, "whatever", 1);/* init muxer, write output file header */ret = Avformat_write_header (ofmt_ct X, NULL), if (Ret < 0) {Av_log (NULL, Av_log_error, "ERROR occurred when opening output file\n"); return ret;} i=0;/* Read all packets */while (1) {i++;if (ret = Av_read_frame (Ifmt_ctx, &packet)) < 0) Break;stream_index = Pack Et.stream_index;if (stream_index!=0) Continue;type = Ifmt_ctx->streams[packet.stream_index]->codec->codec _type;av_log (NULL, Av_log_debug, "Demuxer gave frame of Stream_index%u\n", Stream_index); Av_log (null, Av_log_debug, " Going to reencode the frame\n "), frame = Av_frame_alloc (), if (!frame) {ret = Averror (ENOMEM); break;} Packet.dts = Av_rescale_q_rnd (packet.dts,ifmt_ctx->streams[stream_index]->time_base,ifmt_ctx->streams[ Stream_index]->codec->time_base, (avrounding) (av_round_near_Inf| Av_round_pass_minmax));p acket.pts = Av_rescale_q_rnd (packet.pts,ifmt_ctx->streams[stream_index]->time_base , Ifmt_ctx->streams[stream_index]->codec->time_base, (avrounding) (av_round_near_inf| Av_round_pass_minmax)); ret = Avcodec_decode_video2 (Ifmt_ctx->streams[stream_index]->codec, Frame,&got_ Frame, &packet);p rintf ("Decode 1 packet\tsize:%d\tpts:%d\n", packet.size,packet.pts); if (Ret < 0) {Av_frame_ Free (&frame); Av_log (NULL, Av_log_error, "decoding failed\n"); if (got_frame) {frame->pts = Av_frame_get_best_effort_timestamp (frame); Frame->pict_type=av_picture_type_none ; enc_pkt.data = Null;enc_pkt.size = 0;av_init_packet (&AMP;ENC_PKT); ret = Avcodec_encode_video2 (ofmt_ctx->streams[ Stream_index]->codec, &enc_pkt,frame, &enc_got_frame);p rintf ("Encode 1 packet\tsize:%d\tpts:%d\n", enc_ pkt.size,enc_pkt.pts); Av_frame_free (&frame); if (Ret < 0) goto end;if (!enc_got_frame) continue;/* prepare packet For muxing */enc_pkt.stream_index = Stream_index;enc_pkt.dts = Av_rescale_q_rnd (enc_pkt.dts,ofmt_ctx->streams[stream_index]->codec->time_ Base,ofmt_ctx->streams[stream_index]->time_base, (avrounding) (av_round_near_inf| Av_round_pass_minmax)); enc_pkt.pts = Av_rescale_q_rnd (enc_pkt.pts,ofmt_ctx->streams[stream_index]->codec- >time_base,ofmt_ctx->streams[stream_index]->time_base, (avrounding) (av_round_near_inf| Av_round_pass_minmax)); enc_pkt.duration = Av_rescale_q (enc_pkt.duration,ofmt_ctx->streams[stream_index]-> Codec->time_base,ofmt_ctx->streams[stream_index]->time_base); Av_log (NULL, Av_log_info, "Muxing frame%d\n ", i);/* MUX encoded frame */av_write_frame (OFMT_CTX,&AMP;ENC_PKT); if (Ret < 0) goto end;} else {av_frame_free (&frame);} Av_free_packet (&packet);} /* Flush encoders */for (i = 0; i < 1; i++) {/* Flush encoder */ret = Flush_encoder (ofmt_ctx,i); if (Ret < 0) {Av_log (NULL, Av_log_error, "Flushing encoder failed\n"); goto end;}} Av_write_trailer (OFMT_CTX); end:av_fReep (avio_in); Av_freep (avio_out); Av_free (Inbuffer); Av_free (Outbuffer); Av_free_packet (&packet); av_frame_ Free (&frame); Avformat_close_input (&AMP;IFMT_CTX); Avformat_free_context (OFMT_CTX); Fcloseall (); if (Ret < 0) Av_log (NULL, Av_log_error, "ERROR occurred\n"); return (ret. 1:0);}

Results

The results of the program execution, for example, are seen.


Before transcoding the video information use MediaInfo to view for example as seen.

watermark/2/text/ahr0cdovl2jsb2cuy3nkbi5uzxqvbgvpeglhb2h1ytewmja=/font/5a6l5l2t/fontsize/400/fill/i0jbqkfcma== /dissolve/70/gravity/southeast "/>

After transcoding the video information use MediaInfo to view for example as seen.


Download


Simplest FFmpeg mem Handler


Project Home

sourceforge:https://sourceforge.net/projects/simplestffmpegmemhandler/

Github:https://github.com/leixiaohua1020/simplest_ffmpeg_mem_handler

Open source China: Http://git.oschina.net/leixiaohua1020/simplest_ffmpeg_mem_handler


CSDN:
http://download.csdn.net/detail/leixiaohua1020/8003731

This project includes two examples of FFmpeg read and write memory:
Simplest_ffmpeg_mem_player: FFmpeg-based memory player.
Simplest_ffmpeg_mem_transcoder: FFmpeg-based memory transcoding device.



Updated-1.1 (2015.2.13) =========================================

This time considering the cross-platform requirements, adjusted the source code. After this adjustment, the source code can be compiled on the following platform:

VC + +: Open the SLn file to compile without configuration.

Cl.exe: Open Compile_cl.bat can be compiled using cl.exe on the command line. Note that you may need to adjust the number of references in the script according to the VC's installation path. Compile commands such as the following.

:: VS2010 environmentcall "D:\Program Files\Microsoft Visual Studio 10.0\vc\vcvarsall.bat":: Include@set include= Include;%i Nclude%::lib@set Lib=lib;%lib%::compile and Linkcl simplest_ffmpeg_mem_transcoder.cpp/link avcodec.lib avformat.lib Avutil.lib ^avdevice.lib avfilter.lib postproc.lib swresample.lib swscale.lib/opt:noref

The MINGW:MINGW command-line execution compile_mingw.sh can be compiled using MinGW's g++. Compile commands such as the following.

g++ simplest_ffmpeg_mem_transcoder.cpp-g-o simplest_ffmpeg_mem_transcoder.exe-i/usr/local/include-l/usr/local/ Lib-lavcodec-lavformat-lavutil-lavdevice-lavfilter-lpostproc-lswresample-lswscale

Gcc:linux or MacOS command line execution compile_gcc.sh can be compiled using GCC.

Compile commands such as the following.

GCC simplest_ffmpeg_mem_transcoder.cpp-g-o simplest_ffmpeg_mem_transcoder.out-i/usr/local/include-l/usr/local/ Lib-lavcodec-lavformat-lavutil-lavdevice-lavfilter-lpostproc-lswresample-lswscale

PS: The related compilation commands have been saved in the project directory

CSDN Download: http://download.csdn.net/detail/leixiaohua1020/8445795

SourceForge has been updated.

Read memory reads and writes based on the simplest ffmpeg sampling: storage

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.