H264 encode and decode

http://www.chinavideo.org/archiver/?tid-14008.html

 

 

关于实时编码解码问题  请教  分享一个编码代码 H264

首先分享一个编码代码使用的是X264  core 122版本 [code]
H264EncWrapper::~H264EncWrapper()
{
        Destroy();
}

int H264EncWrapper::Initialize(int iWidth, int iHeight, int iRateBit, int iFps)
{
    m_param.i_fps_num = iFps;
    m_param.i_fps_den = 1;
    m_param.rc.i_bitrate = iRateBit;
        m_param.rc.i_vbv_max_bitrate=128;
        m_param.i_threads = X264_THREADS_AUTO;
        m_param.i_width = iWidth;
        m_param.i_height = iHeight;
        m_param.i_bframe=0;
        m_param.i_frame_reference=3;
        m_param.rc.i_rc_method=X264_RC_ABR;//X264_RC_CQP ;
        m_param.i_csp = X264_CSP_I420;
        m_param.b_visualize=1;

        m_param.b_cabac =0;    
        m_param.b_interlaced=0;
        m_param.i_level_idc=21;
        m_param.i_keyint_max=m_param.i_fps_num*1.5;
        m_param.i_keyint_min=1;

        m_param.pf_log = NULL; //x264log;
        m_param.p_log_private = NULL;
        m_param.i_log_level=X264_LOG_NONE;



    //m_param.i_keyint_max = 8;
    //m_param.i_keyint_min = 4;

    /* 根据输入参数param初始化总结构 x264_t *h     */
    if( ( m_h = x264_encoder_open( &m_param) ) == NULL )
    {
        fprintf( stderr, "x264 [error]: x264_encoder_open failed\n" );
        return -1;
    }

       
        int i_nal;
        if(x264_encoder_headers( m_h, &m_headers, &i_nal )<0)
        {
                fprintf( stderr, "x264 [error]: x264_encoder_headers failed\n" );
                return -1;
        }

    x264_picture_alloc( &m_pic, X264_CSP_I420, m_param.i_width, m_param.i_height );
    m_pic.i_type = X264_TYPE_AUTO;
    m_pic.i_qpplus1 = 0;
   
    return 0;
}

int H264EncWrapper::Destroy()
{
        x264_picture_clean( &m_pic );
        x264_encoder_close(m_h);

   return 0;
}

//编码
int H264EncWrapper::Encode(unsigned char* szYUVFrame, unsigned char * pOutputBuffer)
{
        m_pic.img.i_plane = 3;
        m_pic.img.plane[0] = szYUVFrame;
        m_pic.img.plane[1] = szYUVFrame + m_param.i_width * m_param.i_height;
        m_pic.img.plane[2] = (unsigned char *)m_pic.img.plane[1] +  m_param.i_width * m_param.i_height / 4;
        m_pic.img.plane[3] = 0;
   
    m_pic.i_pts = (int64_t)m_iFrameNum * m_param.i_fps_den;

    x264_picture_t pic_out;
    x264_nal_t *nal;
    int i_nal, i; // nal的个数

    if( x264_encoder_encode( m_h, &nal, &i_nal, &m_pic, &pic_out ) < 0 )
    {
        fprintf( stderr, "x264 [error]: x264_encoder_encode failed\n" );
        return -1;
    }

        if(i_nal==0)
        {
                //m_iFrameNum++;
                return 0;
        }

        int result=0;
  

        for( i = 0; i < i_nal; i++ )
        {
                memcpy(pOutputBuffer, nal[i].p_payload, nal[i].i_payload);
                pOutputBuffer += nal[i].i_payload;
                result += nal[i].i_payload;
        }

    m_iFrameNum++;
    return result;
}
[/code]



编码出来可以用播放器播放 也可以用ffplay 播放 和 ffmpeg解码




请教一个问题  在我解码的时候 解码几针后出现 avcodec_decode_video2 函数崩溃了
[attach]1780[/attach]

而且出现了这个提示
[attach]1781[/attach]

但我通过软件查看数据流发现有PPS 和 SPS帧   
[attach]1782[/attach]

我用的是最新的ffmpeg库 

附上解码部分代码
主函数中:
[code]        avcodec_register_all(); 
        av_register_all();
       
        m_pCodec=avcodec_find_decoder(CODEC_ID_H264); 
        if(m_pCodec==NULL)
        {
                printf("Error avcodec_find_decoder");
                return -1;
        }
       
        m_pCodecContext=avcodec_alloc_context();
        if(m_pCodecContext==NULL)
        {
                printf("Error avcodec_alloc_context");
                return -1;
        }

        m_pCodecContext->width = 320;
        m_pCodecContext->height = 240;
        //m_pCodecContext->pix_fmt = PIX_FMT_YUV420P;
        //m_pCodecContext->codec_id  = CODEC_ID_H264;
        m_pCodecContext->pix_fmt = PIX_FMT_YUV420P;
        int iRet = avcodec_open(m_pCodecContext,m_pCodec);

        if(iRet<0)
        {
                printf("Error avcodec_open");
                return -1;
        }

        m_pFrame=avcodec_alloc_frame();
        if(m_pFrame==NULL)
        {
                printf("Error avcodec_alloc_frame");
                return -1;
        }

        m_pFormatCtx=avformat_alloc_context();

        if (!m_pFormatCtx)//分配内存失败
        {
                printf("avformat_alloc_context error\n");      
                return -1;    
        }
        m_parser = av_parser_init(CODEC_ID_H264);
        if(!m_parser)
                return -1; [/code]

解码函数:
[code]VCodecContext* m_pCodecContext; 
AVFrame * m_pFrame;
AVFormatContext *m_pFormatCtx;
AVCodecParserContext * m_parser;

static int DecodeFrame(uint8_t *data , int size)
{
        int got_picture=0;
        AVPacket avp;
        av_init_packet(&avp);

        int right=0;
        avp.data=data;
        avp.size=size;

        int iRet = avcodec_decode_video2(m_pCodecContext,m_pFrame,&got_picture,&avp);

        if(iRet>=0)
        {
                if(got_picture)
                {

                        right++;
                }
        }
       
        return got_picture;
}

static void DecodeVideo(uint8_t * pInBuffer, int size)
{
        int pos=0;
        int64_t pts=AV_NOPTS_VALUE;
        int64_t dts=AV_NOPTS_VALUE;
        do
        {
                uint8_t *pout;
                int pout_len;
                int len= av_parser_parse2(m_parser,m_pCodecContext,&pout,&pout_len,
                        pInBuffer+pos,size-pos,pts,dts,AV_NOPTS_VALUE);

                pos +=len;

                if(pout_len >0 )
                {
                        DecodeFrame(pout,pout_len);
                }
        } while (pos<size);


        if(size<=0)
        {
                while(DecodeFrame(NULL,0));

        }

}
[/code]



希望大家能帮帮忙  ,  任何回复都十分感谢  !

louyily 发表于 2012-3-22 02:24 PM

你的数据来源 能不能保证 传入 解码器的 是一个个完整的 nal 单元,我之前做实时编码的时候 发现传入数据如果不是完整帧就有可能出错的,判断一下 nal的头吧

lovesxw 发表于 2012-3-22 02:36 PM

av_parser_parse2 函数不是校验完整吗? 如果完整的话 就会有返回 不完整就会等待输入 ?

louyily 发表于 2012-3-22 03:13 PM

我之前一直没有用 这个parser,是自己对nal 头做下了判断 因为解的数据是udp发过来的,会出现一些错误的包数据

lovesxw 发表于 2012-3-22 04:00 PM

[i=s] 本帖最后由 lovesxw 于 2012-3-22 04:26 PM 编辑 [/i]

我加了一个判断这回 不过还是不对

[code]
/*the return value is the head offset*/
static int findheader(unsigned char* databuf, int len)
{
       
        char aa[320*240*3]={0};
        CopyMemory(aa,databuf,len);
        int offset = 0;
        bool bFind=false;
        for(; offset< len -4; offset++,databuf++)
        {
                if(databuf[0] == 0x00 && databuf[1] == 0x00 && databuf[2] == 0x00 && databuf[3] == 0x01 && databuf[4] == 0x67)
                {       
                        bFind=true;
                        return offset;
                }
                if(databuf[0] == 0x00 && databuf[1] == 0x00 && databuf[2] == 0x00 && databuf[3] == 0x01 && databuf[4] == 0x65)
                {       
                        bFind=true;
                        return offset;
                }
                if(databuf[0] == 0x00 && databuf[1] == 0x00 && databuf[2] == 0x00 && databuf[3] == 0x01 && databuf[4] == 0x68)
                {       
                        bFind=true;
                        return offset;
                }
        }

        if(!bFind)
        {
                return -1;
        }
        return offset;
}

static int DecodeFrame(uint8_t *data , int size)
{
        //防止数据错误
        int offset = findheader(data,size);
        if(offset<0)
        {
                printf("Error data \n");
                return 0;
        }
        int got_picture=0;
        AVPacket avp;
        av_init_packet(&avp);

        int right=0;
        avp.data=data+offset;
        avp.size=size-offset;

        int iRet = avcodec_decode_video2(m_pCodecContext,m_pFrame,&got_picture,&avp);

        if(iRet>=0)
        {
                if(got_picture)
                {
                        right++;
                }
        }
       
        return got_picture;
}

static void DecodeVideo(uint8_t * pInBuffer, int size)
{
        int pos=0;
        int64_t pts=AV_NOPTS_VALUE;
        int64_t dts=AV_NOPTS_VALUE;
        do
        {
                uint8_t *pout;
                int pout_len;
                int len= av_parser_parse2(m_parser,m_pCodecContext,&pout,&pout_len,
                        pInBuffer+pos,size-pos,pts,dts,AV_NOPTS_VALUE);

                pos +=len;

                if(pout_len >0 )
                {
                        DecodeFrame(pout,pout_len);
                }
        } while (pos<size);


        if(size<=0)
        {
                while(DecodeFrame(NULL,0));

        }

}[/code]

这种判断可以吧?

louyily 发表于 2012-3-22 05:21 PM

会不会是av_parser_parse2的用法问题
看了下 我的解码流程 就是比你多了个av_free_packet(&packet);
:(等晚上 让版主来看看吧

lovesxw 发表于 2012-3-22 05:29 PM

o(︶︿︶)o 唉  不知道版主能不能帮忙。。。     这个函数是释放  好像和功能无关  愁啊

lovesxw 发表于 2012-3-22 09:00 PM

自己解决了   希望大家不要走弯路    原因是我自己编译的ffmpeg有问题 可以直接下载官方提供的 。
最终代码
[code]static int DecodeFrame(uint8_t *data , int size)
{
        int got_picture=0;
        AVPacket avp;
        av_init_packet(&avp);

        avp.data=data;
        avp.size=size;

        int iRet = avcodec_decode_video2(m_pCodecContext,m_pFrame,&got_picture,&avp);

        if(iRet>=0)
        {
                if(got_picture)
                {

                        FILE * fp;
                        if((fp=fopen("d:/testout.yuv","ab"))==NULL)
                        {
                                printf("cant open the file");
                                exit(0);
                        }
                        for(int i=0; i<m_pCodecContext->height; i++)
                                fwrite(m_pFrame->data[0] + i * m_pFrame->linesize[0], 1, m_pCodecContext->width, fp);
                        for(int i=0; i<m_pCodecContext->height/2; i++)
                                fwrite(m_pFrame->data[1] + i * m_pFrame->linesize[1], 1, m_pCodecContext->width/2, fp);
                        for(int i=0; i<m_pCodecContext->height/2; i++)
                                fwrite(m_pFrame->data[2] + i * m_pFrame->linesize[2], 1, m_pCodecContext->width/2, fp);

                        fclose(fp);
                }
        }
       
        return got_picture;
}

static void DecodeVideo(uint8_t * pInBuffer, int size)
{
        int pos=0;
        int64_t pts=AV_NOPTS_VALUE;
        int64_t dts=AV_NOPTS_VALUE;
        do
        {
                uint8_t *pout;
                int pout_len;
                int len= av_parser_parse2(m_parser,m_pCodecContext,&pout,&pout_len,
                        pInBuffer+pos,size-pos,pts,dts,AV_NOPTS_VALUE);

                pos +=len;

                if(pout_len >0 )
                {
                        DecodeFrame(pout,pout_len);
                }
        } while (pos<size);


        if(size<=0)
        {
                while(DecodeFrame(NULL,0));

        }

}
[/code]

保存为yuv图像  不需要检测header  以为我那个已经保证是完整的包了

lovesxw 发表于 2012-3-22 09:01 PM

对了 忘了free 我就不补充了

niulei20012001 发表于 2012-3-24 03:03 PM

[i=s] 本帖最后由 niulei20012001 于 2012-3-24 03:07 PM 编辑 [/i]

兄弟,我来给你补充完整[code]AVFrame * m_pFrame;

//AVFormatContext *m_pFormatCtx;

AVCodecParserContext * m_parser;

AVCodec *m_pCodec;
AVCodecContext *m_pCodecContext;

//初始化
bool Decode_init(unsigned int width,unsigned int height)
{
  m_pCodec=avcodec_find_decoder(CODEC_ID_H264); 
        if(m_pCodec==NULL)
        {
                printf("Error avcodec_find_decoder");
                return 0;
        }
        m_pCodecContext=avcodec_alloc_context();
        if(m_pCodecContext==NULL)
        {
                printf("Error avcodec_alloc_context");
                return 0;
        }
        m_pCodecContext->width = width;
        m_pCodecContext->height = height;
        //m_pCodecContext->codec_id  = CODEC_ID_H264;
        m_pCodecContext->pix_fmt = PIX_FMT_YUV420P;
        int iRet = avcodec_open(m_pCodecContext,m_pCodec);
        if(iRet<0)
        {
                printf("Error avcodec_open");
                return 0;
        }
        m_pFrame=avcodec_alloc_frame();
        if(m_pFrame==NULL)
        {
               printf("Error avcodec_alloc_frame");
                return 0;
        }
  //下面的内容,示例中没有
        //m_pFormatCtx=avformat_alloc_context();
        //if (!m_pFormatCtx)//分配内存失败
        //{
        //        printf("avformat_alloc_context error\n");      
        //        return 0;    
        //}
        m_parser = av_parser_init(CODEC_ID_H264);
        if(!m_parser)
                return 0;
return 1;
}
//释放
bool Decode_uninit()
{
av_free(m_pFrame);
avcodec_close(m_pCodecContext);
    av_free(m_pCodecContext);
return 1;
}

static int DecodeFrame(uint8_t *data , int size,unsigned char *yuvOutBuffer)
{
        int got_picture=0;
        AVPacket avp;
        av_init_packet(&avp);

        avp.data=data;
        avp.size=size;

        int iRet = avcodec_decode_video2(m_pCodecContext,m_pFrame,&got_picture,&avp);

        if(iRet>=0)
        {
                if(got_picture)
                {

                    for(int i=0,nDataLen=0;i<3;i++)
                                        {
                                                int nShift=(i==0)?0:1;
                                                PBYTE pYUVData=(PBYTE)m_pFrame->data[i];
                                                for(int j=0;j<(m_pCodecContext->height>>nShift);j++)
                                                {
                                                        memcpy(&yuvOutBuffer[nDataLen],pYUVData,(m_pCodecContext->width>>nShift));
                                                        pYUVData+=m_pFrame->linesize[i];
                                                        nDataLen+=(m_pCodecContext->width>>nShift);
                                                }
                                        }   
                                        /*FILE * fp;
                        if((fp=fopen("d:/testout.yuv","ab"))==NULL)
                        {
                                printf("cant open the file");
                                exit(0);
                        }
                        for(int i=0; i<m_pCodecContext->height; i++)
                                fwrite(m_pFrame->data[0] + i * m_pFrame->linesize[0], 1, m_pCodecContext->width, fp);
                        for(int i=0; i<m_pCodecContext->height/2; i++)
                                fwrite(m_pFrame->data[1] + i * m_pFrame->linesize[1], 1, m_pCodecContext->width/2, fp);
                        for(int i=0; i<m_pCodecContext->height/2; i++)
                                fwrite(m_pFrame->data[2] + i * m_pFrame->linesize[2], 1, m_pCodecContext->width/2, fp);

                        fclose(fp);*/
                }
        }
       
        return got_picture;
}
//调用入口函数
void DecodeVideo(uint8_t * pInBuffer, int size,unsigned char *yuvOutBuffer)
{
        int pos=0;
        int64_t pts=AV_NOPTS_VALUE;
        int64_t dts=AV_NOPTS_VALUE;
        do
        {
                uint8_t *pout;
                int pout_len;
int len= av_parser_parse2(m_parser,m_pCodecContext,&pout,&pout_len, pInBuffer+pos,size-pos,pts,dts,AV_NOPTS_VALUE);

                pos +=len;

                if(pout_len >0 )
                {
                        DecodeFrame(pout,pout_len,yuvOutBuffer);
                }
        } while (pos<size);


        if(size<=0)
        {
                while(DecodeFrame(NULL,0,yuvOutBuffer));

        }

}[/code]

qibo15193 发表于 2012-4-21 04:07 PM

这个代码没问题么?

cbzhaojay 发表于 2012-5-26 03:26 PM

[b]回复 [url=http://bbs.chinavideo.org/redirect.php?goto=findpost&pid=55342&ptid=14008]10#[/url] [i]niulei20012001[/i] [/b]
你好呀,兄弟, DecodeVideo你这个函数入口 传入的 pInBuffer是一个frame数据还是?
我传入了数据格式如下:
h264head sps h264head pps h264head +后面为一帧的数据
解码不成功也 兄弟能帮忙解释下么?
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
下面是一个使用FFmpeg库实现将H.265编码的mp4视频转换为H.264编码的mp4视频的C++示例代码: ```cpp #include <iostream> #include <string> #include <cstdlib> #include <cstdio> #include <cstring> #include "ffmpeg.h" using namespace std; #define INBUF_SIZE 4096 #define OUTBUF_SIZE 4096 int main(int argc, char **argv) { if (argc != 3) { cerr << "Usage: " << argv[0] << " <input_file> <output_file>" << endl; return 1; } // Register all codecs and formats av_register_all(); AVFormatContext *input_ctx = NULL, *output_ctx = NULL; AVCodecContext *input_codec_ctx = NULL, *output_codec_ctx = NULL; AVCodec *input_codec = NULL, *output_codec = NULL; AVPacket packet; AVFrame *frame = NULL; uint8_t inbuf[INBUF_SIZE + AV_INPUT_BUFFER_PADDING_SIZE]; uint8_t outbuf[OUTBUF_SIZE]; int ret, got_output; // Open input file if ((ret = avformat_open_input(&input_ctx, argv[1], NULL, NULL)) < 0) { cerr << "Could not open input file: " << argv[1] << endl; goto end; } // Retrieve input stream information if ((ret = avformat_find_stream_info(input_ctx, NULL)) < 0) { cerr << "Could not find stream information" << endl; goto end; } // Open output file if ((ret = avformat_alloc_output_context2(&output_ctx, NULL, NULL, argv[2])) < 0) { cerr << "Could not create output context" << endl; goto end; } // Find the input video stream int video_stream_index = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &input_codec, 0); if (video_stream_index < 0) { cerr << "Could not find input video stream" << endl; goto end; } // Create a new video stream in the output file output_codec = avcodec_find_encoder(AV_CODEC_ID_H264); if (!output_codec) { cerr << "Could not find H.264 encoder" << endl; goto end; } AVStream *output_stream = avformat_new_stream(output_ctx, NULL); if (!output_stream) { cerr << "Failed to allocate output stream" << endl; goto end; } output_codec_ctx = avcodec_alloc_context3(output_codec); if (!output_codec_ctx) { cerr << "Failed to allocate codec context" << endl; goto end; } output_codec_ctx->codec_id = AV_CODEC_ID_H264; output_codec_ctx->width = input_codec_ctx->width; output_codec_ctx->height = input_codec_ctx->height; output_codec_ctx->bit_rate = input_codec_ctx->bit_rate; output_codec_ctx->time_base = input_codec_ctx->time_base; output_codec_ctx->gop_size = input_codec_ctx->gop_size; output_codec_ctx->max_b_frames = input_codec_ctx->max_b_frames; output_codec_ctx->pix_fmt = AV_PIX_FMT_YUV420P; if ((ret = avcodec_open2(output_codec_ctx, output_codec, NULL)) < 0) { cerr << "Failed to open output codec" << endl; goto end; } if ((ret = avcodec_parameters_from_context(output_stream->codecpar, output_codec_ctx)) < 0) { cerr << "Failed to copy parameters from codec context to stream" << endl; goto end; } output_stream->time_base = output_codec_ctx->time_base; // Open output file if (!(output_ctx->oformat->flags & AVFMT_NOFILE)) { if ((ret = avio_open(&output_ctx->pb, argv[2], AVIO_FLAG_WRITE)) < 0) { cerr << "Could not open output file: " << argv[2] << endl; goto end; } } // Write file header if ((ret = avformat_write_header(output_ctx, NULL)) < 0) { cerr << "Error writing output file header" << endl; goto end; } // Allocate input and output frame buffers frame = av_frame_alloc(); if (!frame) { cerr << "Could not allocate frame" << endl; goto end; } // Loop through input packets while (1) { // Read packet from input file if ((ret = av_read_frame(input_ctx, &packet)) < 0) break; // If the packet is from the video stream if (packet.stream_index == video_stream_index) { // Decode video frame ret = avcodec_decode_video2(input_codec_ctx, frame, &got_output, &packet); if (ret < 0) { cerr << "Error decoding video frame" << endl; goto end; } // If a frame was decoded if (got_output) { // Convert frame format to YUV420P AVFrame *yuv_frame = av_frame_alloc(); if (!yuv_frame) { cerr << "Could not allocate frame" << endl; goto end; } yuv_frame->width = input_codec_ctx->width; yuv_frame->height = input_codec_ctx->height; yuv_frame->format = AV_PIX_FMT_YUV420P; if ((ret = av_frame_get_buffer(yuv_frame, 32)) < 0) { cerr << "Failed to allocate buffer for YUV420P frame" << endl; goto end; } if ((ret = av_image_alloc(yuv_frame->data, yuv_frame->linesize, input_codec_ctx->width, input_codec_ctx->height, AV_PIX_FMT_YUV420P, 32)) < 0) { cerr << "Failed to allocate image buffer for YUV420P frame" << endl; goto end; } if ((ret = sws_scale(input_codec_ctx->sws_ctx, frame->data, frame->linesize, 0, input_codec_ctx->height, yuv_frame->data, yuv_frame->linesize)) < 0) { cerr << "Error converting frame format to YUV420P" << endl; goto end; } // Encode YUV420P frame as H.264 AVPacket output_packet; av_init_packet(&output_packet); output_packet.data = NULL; output_packet.size = 0; output_packet.stream_index = output_stream->index; ret = avcodec_encode_video2(output_codec_ctx, &output_packet, yuv_frame, &got_output); if (ret < 0) { cerr << "Error encoding video frame" << endl; goto end; } // If the frame was encoded if (got_output) { // Write output packet to file if ((ret = av_write_frame(output_ctx, &output_packet)) < 0) { cerr << "Error writing output packet" << endl; goto end; } } av_frame_free(&yuv_frame); } } // Free input packet av_packet_unref(&packet); } // Flush encoder ret = avcodec_send_frame(output_codec_ctx, NULL); if (ret < 0) { cerr << "Error flushing encoder" << endl; goto end; } while (1) { AVPacket output_packet; av_init_packet(&output_packet); output_packet.data = NULL; output_packet.size = 0; output_packet.stream_index = output_stream->index; ret = avcodec_receive_packet(output_codec_ctx, &output_packet); if (ret == AVERROR_EOF) break; if (ret < 0) { cerr << "Error encoding video frame" << endl; goto end; } if ((ret = av_write_frame(output_ctx, &output_packet)) < 0) { cerr << "Error writing output packet" << endl; goto end; } av_packet_unref(&output_packet); } // Write file trailer if ((ret = av_write_trailer(output_ctx)) < 0) { cerr << "Error writing output file trailer" << endl; goto end; } end: avformat_close_input(&input_ctx); if (output_ctx) { if (!(output_ctx->oformat->flags & AVFMT_NOFILE)) avio_closep(&output_ctx->pb); avformat_free_context(output_ctx); } if (input_codec_ctx) avcodec_close(input_codec_ctx); if (output_codec_ctx) avcodec_close(output_codec_ctx); if (frame) av_frame_free(&frame); return ret; } ``` 在上面的示例代码中,使用了FFmpeg库进行视频编解码相关操作。其中,`AVFormatContext`结构体表示输入输出文件的格式上下文,`AVCodecContext`结构体表示编解码器的上下文,`AVCodec`结构体表示编解码器本身,`AVPacket`结构体表示音视频数据包,`AVFrame`结构体表示音视频帧。 该示例代码的主要思路是: 1. 打开输入文件并获取输入流信息。 2. 创建输出文件并添加视频流。 3. 循环读取输入文件的音视频数据包。 4. 如果数据包是视频数据包,则解码视频帧,将帧格式转换为YUV420P格式,编码为H.264格式,然后写入输出文件。 5. 写入文件尾部。 需要注意的是,该示例代码可能需要根据实际情况进行修改,例如需要根据输入视频的分辨率和帧率设置输出视频的参数,以及选择合适的H.264编码器等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值