參與:3
分享評論舉報
邱繼慶

邱繼慶

初學乍練

9 則回答

2得分


最佳解


1、就是调用 avcodec_find_decoder() 获取指定类型的解码器

2、安装完 VSDK 后可以找到 s32v234_sdk 目录,里面有相应的 ffmpeg 的库文件,如有库文件相关问题,一般直接使用配套的 VSDK 中的 ffmpeg 库文件即可,文件系统本身含有这类的库文件。您这边自己编译 ffmpeg 的话,那这个库肯定也是要替换成你自己的了,就是把这个自己编译的库的名称修改成你要替换的就行了

3、推荐使用 S32DS,支持 S32V234 平台,调试起来相对方便 

4、可能是 CodecId 设置有问题,MP4 是封装格式,编解码器的设定可以直接设定如果你确定解封转后是 H264 格式的话,可直接设定,例如:

enum  AVCodecID emViDecId  = AV_CODEC_ID_H264;

AVCodec* ptCodec = NULL;

ptCodec = avcodec_find_decoder( emViDecId  )

5、硬编码部分是无法通过 ffmpeg 的参数设置进行开启的,两者在使用上没有太多的关联,需要另外学习其使用

 

1F
百万伏特

百万伏特

略有小成
評論 1:嘗試您的方法後 還是一樣的結果 我用vsdk 上的s32v234_sdk/3rdparty/ffmpeg/linux-arm64/lib 裡面的庫文件覆蓋掉板子上的庫文件(名稱都一樣)仍然是一樣的結果
邱繼慶2020年8月10日
評論 2:但能肯定 s32v234 是有支援ffmpeg 自帶的函式庫解碼對吧? 請問您的vsdk版本 跟ffmpeg的版本是?
邱繼慶2020年8月10日
評論 3:是的 ,vsdk 版本和 BSP 版本是有对应关系的,您这边使用的 BSP 版本是 ?
百万伏特2020年8月11日
評論 4:例如: BSP18 对应 VSDK1.2
百万伏特2020年8月11日
評論 5:我這邊轉換回vsdk1.3 之後 可以正常運行了 十分感謝您
邱繼慶2020年8月12日
評論 6:好的,其实我这边测试也是 OK 的
百万伏特2020年8月12日
1得分


最佳解


想問 你們是自己實現ffmpeg 的 h264 解碼嗎 還是說存粹調用 av_find_decoder/av_find_decoder_by_name ?

另外 想請教 我在pc 端上build 完 ffmpeg, cross-compile nxp 的代碼後 

是不是還需要在板子上更新新的.so檔? 猜測是我板子上的.so 太舊 (/usr/lib/libavcodex.so.56 ) 具體怎麼更換 再請教您?

或是透過 vsdk 裡面的 SDI_H264DecDescriptor 去做 解碼的?

沒有安裝S32DS 我是用vscode 寫完再cross-compile 成.elf

看到你說使用硬解碼 所以說 我該怎麼在s32v234開啟 因為 我用了 ffmpeg -hwaccels 並沒有任何可支援的選項

很多問題 麻煩您了

 

2F
邱繼慶

邱繼慶

初學乍練
評論 1:调用 avcodec_find_decoder() 获取指定类型的解码器
百万伏特2020年8月10日
評論 2:调用 avcodec_find_decoder() 获取指定类型的解码器
百万伏特2020年8月10日
評論 3:调用 avcodec_find_decoder() 获取指定类型的解码器
百万伏特2020年8月10日
評論 4:调用 avcodec_find_decoder() 获取指定类型的解码器
百万伏特2020年8月10日
1得分


最佳解


#ifndef APEX2_EMULATE

#include "apex.h"

#else

#include "acf_lib.hpp"

#endif


 

#include <apexcv_base.h>

#include <common_helpers.h>

#include <string>


 

#include "frame_output_v234fb.h"

typedef io::FrameOutputV234Fb io_FrameOutput_t;


 

#ifdef __cplusplus

extern "C"

{

#endif

#include <libavcodec/avcodec.h>

#include <libavformat/avformat.h>

#include <libswscale/swscale.h>

#include <libavutil/avutil.h>

#include <libavutil/attributes.h>

#include <libavutil/opt.h>

#include <libavutil/mathematics.h>

#include <libavutil/imgutils.h>

#include <libavutil/samplefmt.h>

#include <libavutil/timestamp.h>

#include <libavutil/mathematics.h>

#include <libavutil/channel_layout.h>

#include <libavutil/common.h>

#include <libavformat/avio.h>

#include <libavutil/file.h>

#include <libswresample/swresample.h>

#ifdef __cplusplus

};

#endif


 

#include <iostream>

#include <opencv/cv.h>

#include <opencv2/core/core.hpp>

#include <opencv2/highgui/highgui.hpp>

#include <opencv2/imgproc/imgproc.hpp>

int thread_exit=0;



 

cv::Mat avFrame2Mat(AVFrame* pAvFrame, AVCodecContext*pCodecCtx) {

AVFrame* pFrameBGR = av_frame_alloc();

int size = avpicture_get_size(AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);

uint8_t *out_buffer = (uint8_t *)av_malloc(size);

avpicture_fill((AVPicture *)pFrameBGR, out_buffer, AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height);

 

struct SwsContext *img_convert_ctx;

img_convert_ctx = sws_getContext(pCodecCtx->width,

pCodecCtx->height,

pCodecCtx->pix_fmt,

pCodecCtx->width,

pCodecCtx->height,

AV_PIX_FMT_BGR24,

SWS_BICUBIC,

NULL, NULL, NULL);

 

sws_scale(img_convert_ctx,

(const uint8_t* const*)pAvFrame->data,

pAvFrame->linesize,

0,

pCodecCtx->height,

pFrameBGR->data,

pFrameBGR->linesize);

 

cv::Mat mRGB(cv::Size(pCodecCtx->width, pCodecCtx->height), CV_8UC3);

mRGB.data = (uchar*)pFrameBGR->data[0];

 

av_free(pFrameBGR);

sws_freeContext(img_convert_ctx);

return mRGB;

}

/****************************************************************************

* Main function

****************************************************************************/

int main(int argc, char* argv[])

{

io_FrameOutput_t aFrameOutput;

AVFormatContext *pFormatCtx;

int i, videoindex;

AVCodecContext *pCodecCtx;

AVCodec *pCodec;

AVFrame *pFrame,*pFrameYUV;

AVPacket *packet;

struct SwsContext *img_convert_ctx;

 

int ret, got_picture;

int screen_w=0,screen_h=0;


 

char* filepath=argv[1];

av_register_all();

avformat_network_init();

pFormatCtx = avformat_alloc_context();


 

if(avformat_open_input(&pFormatCtx,filepath,NULL,NULL)!=0){

printf("Couldn't open input stream.\n");

return -1;

}


 

if(avformat_find_stream_info(pFormatCtx,NULL)<0){

printf("Couldn't find stream information.\n");

return -1;

}

videoindex=-1;

/*for(i=0; i<pFormatCtx->nb_streams; i++)

if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){

videoindex=i;

break;

}*/


 

videoindex = av_find_best_stream(pFormatCtx, AVMEDIA_TYPE_VIDEO, videoindex, -1, NULL, 0);

if(videoindex==-1){

printf("Didn't find a video stream.\n");

return -1;

}


 

pCodecCtx=pFormatCtx->streams[videoindex]->codec;

 

//pCodec = avcodec_find_decoder_by_name("h264_mediacodec");

pCodec = avcodec_find_decoder(pCodecCtx->codec_id);

avcodec_alloc_context3(pCodec);

if(!av_codec_is_decoder(pCodec))

{

printf("Codec not found.\n");

return -1;

}

if(pCodec == NULL)

{

printf("Codec is NULL.\n");

return -1;

}


 

if(avcodec_open2(pCodecCtx, pCodec,NULL)<0)

{

printf("Could not open codec.\n");

return -1;

}


 

pFrame=av_frame_alloc();

pFrameYUV=av_frame_alloc();

//uint8_t *out_buffer=(uint8_t *)av_malloc(avpicture_get_size(PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height));

//avpicture_fill((AVPicture *)pFrameYUV, out_buffer, PIX_FMT_YUV420P, pCodecCtx->width, pCodecCtx->height);


 

packet=(AVPacket *)av_malloc(sizeof(AVPacket));


 

printf("---------------File Information------------------\n");

av_dump_format(pFormatCtx,0,filepath,0);

printf("-------------------------------------------------\n");



 

img_convert_ctx = sws_getContext(pCodecCtx->width, pCodecCtx->height, pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, PIX_FMT_YUV420P, SWS_BICUBIC, NULL, NULL, NULL);


 

//Event Loop


 

for (;;) {

//------------------------------

if(av_read_frame(pFormatCtx, packet)>=0){

if(packet->stream_index==videoindex){

ret = avcodec_decode_video2(pCodecCtx, pFrame, &got_picture, packet);

if(ret < 0){

printf("Decode Error.\n");

return -1;

}

if(got_picture){

cv::Mat mRGB = avFrame2Mat(pFrame, pCodecCtx);

aFrameOutput.PutFrame(mRGB.data, false);

 

}

}

av_free_packet(packet);

}else{

//Exit Thread

thread_exit=1;

break;

}


 

}


 

sws_freeContext(img_convert_ctx);

//--------------

//av_free(out_buffer);

av_free(pFrameYUV);

avcodec_close(pCodecCtx);

avformat_close_input(&pFormatCtx);


 

return 0;

}


 

3F
邱繼慶

邱繼慶

初學乍練
評論 1:測試用的代碼貼給您了 麻煩您幫忙確認是 代碼的問題 還是板子的問題 感謝
邱繼慶2020年8月10日
1得分


最佳解


芯片上有专门解码模块,需调用专用的 API 进行硬解码实现 

4F
百万伏特

百万伏特

略有小成
1得分


最佳解


我们这边在 S32DS 平台上使用 FFMPEG 实现过 H264 的解码播放,所以建议您将测试代码发过来,我这边好进行分析

5F
百万伏特

百万伏特

略有小成
0得分


最佳解


如允许,可将测试代码提供下,我这边可帮您测试下

6F
百万伏特

百万伏特

略有小成
1得分


最佳解


您这边有安装 S32DS 吗?

7F
百万伏特

百万伏特

略有小成
2得分


最佳解


软解码:S32V234 平台支持 FFMPEG,可使用 FFMPEG 中的 API 设定软解码器进行解码

硬解码:S32V234 平台支持 硬解码,可参考官方 SDK 包中的例程 

8F
百万伏特

百万伏特

略有小成
2得分


最佳解


S32V234 影像软解码:支持使用 FFMPEG 库设定解码器进行软解码 

S32V234 影像硬解码:可根据官方 SDK 提供单图片解码 demo:isp_h264dec_single_stream,自行开发 

9F
小路-慢走

小路-慢走

初學乍練
評論 1:好的 感謝您
邱繼慶2020年8月12日

我要回答