Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Video 用于视频解码到视频编码组件的OpenMax隧道_Video_Decode_H.264_Raspberry Pi_Openmax - Fatal编程技术网

Video 用于视频解码到视频编码组件的OpenMax隧道

Video 用于视频解码到视频编码组件的OpenMax隧道,video,decode,h.264,raspberry-pi,openmax,Video,Decode,H.264,Raspberry Pi,Openmax,有人知道如何在Raspberry Pi上设置带有视频解码和视频编码OpenMax组件的隧道吗?如何正确设置输入和输出端口的属性? (130131200201) 我的代码成功解码并在屏幕上渲染帧,但在我添加视频编码器并设置隧道视频解码:131->视频编码:200后,我收到错误: -5: the data format was not acceptable to the sink 我的代码: #include <stdio.h> #include <stdlib.h> #i

有人知道如何在Raspberry Pi上设置带有视频解码和视频编码OpenMax组件的隧道吗?如何正确设置输入和输出端口的属性? (130131200201)

我的代码成功解码并在屏幕上渲染帧,但在我添加视频编码器并设置隧道视频解码:131->视频编码:200后,我收到错误:

-5: the data format was not acceptable to the sink
我的代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include "bcm_host.h"
#include "ilclient.h"

#include "libavformat/avformat.h"
#include "libavutil/avutil.h"
#include "libavcodec/avcodec.h"
#include "libavutil/mathematics.h"
#include <error.h>

#define WIDTH     1920//736//640//320//1280//
#define HEIGHT    1080//1088//400//368//((WIDTH*9)/16)//720//
#define PITCH     ((WIDTH+31)&~31)
#define HEIGHT16  ((HEIGHT+15)&~15)
#define SIZE      ((WIDTH * HEIGHT16 * 3)/2)//(WIDTH*HEIGHT*12/8)//

//http://fossies.org/dox/xbmc-12.0/DVDClock_8h_source.html
#define DVD_NOPTS_VALUE (-1LL<<52) // should be possible to represent in both double and int64_t

static inline OMX_TICKS ToOMXTime(int64_t pts)
{
  OMX_TICKS ticks;
  ticks.nLowPart = pts;
  ticks.nHighPart = pts >> 32;
  return ticks;
}

static AVBitStreamFilterContext *dofiltertest(AVPacket *rp)
{
    AVBitStreamFilterContext *bsfc;
    bsfc = NULL;

    if (!(rp->data[0] == 0x00 && rp->data[1] == 0x00 &&
        rp->data[2] == 0x00 && rp->data[3] == 0x01)) {
        bsfc = av_bitstream_filter_init("h264_mp4toannexb");
        if (!bsfc) {
            printf("Failed to open filter.  This is bad.\n");
        } else {
            printf("Have a filter at %p\n", bsfc);
        }
    } else
        printf("No need for a filter.\n");

    return bsfc;
}

static AVPacket filter(AVBitStreamFilterContext *bsfc,AVFormatContext *ctx, AVPacket *rp,int *video_stream_index)
{
if(ctx==NULL){printf("!!! ctx is NULL, filed set filter!\n");exit(-1);}
    //AVBitStreamFilterContext *bsfc=dofiltertest(rp);
    AVPacket *p;
    AVPacket *fp;
    int rc;
if(bsfc){
    fp = calloc(sizeof(AVPacket), 1);

    if (bsfc) {
        rc = av_bitstream_filter_filter(bsfc,
                ctx->streams[*video_stream_index]->codec,
                NULL, &(fp->data), &(fp->size),
                rp->data, rp->size,
                rp->flags & AV_PKT_FLAG_KEY);
        if (rc > 0) {
            av_free_packet(rp);
            fp->destruct = av_destruct_packet;
            p = fp;
        } else {
            printf("Failed to filter frame: "
                "%d (%x)\n", rc, rc);
            p = rp;
        }
    } else
        p = rp;

    return *p;
}//if
else{return *rp;}
}

static int getInputHendle(char *filename,AVFormatContext *pFmtCtx,AVCodecContext pCodCtx,int *video_stream_index){
printf("Start getInputHandle %s\n", filename);
     AVFormatContext *pFormatCtx;
    // Open video file
    if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0){printf("Couldn't open file\n");return -1;}
    // Retrieve stream information
    if(av_find_stream_info(pFormatCtx)<0){printf("Couldn't find stream information\n");return -1;}
    // print file file info
    dump_format(pFormatCtx, 0, filename,false);
//memcpy(pFmtCtx,pFormatCtx,sizeof(pFormatCtx));
    //find video stream
    int i;
     *video_stream_index=-1;
    AVCodecContext *pCodecCtx;
    // Find the first video stream
    for(i=0; i<pFormatCtx->nb_streams; i++){if(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO){*video_stream_index=i;break;}}
    if(*video_stream_index==-1){printf("Didn't find a video stream\n");return -1;}
    // Get a pointer to the codec context for the video stream
    pCodecCtx=pFormatCtx->streams[*video_stream_index]->codec;

printf("\n=>My info about video: \n Bitrate: %d\n Frame width: %d\n Frame height: %d\n Frame rate: %d:%d\n Aspect ratio: %d:%d\n ",pCodecCtx->bit_rate,pCodecCtx->width,pCodecCtx->height,pCodecCtx->time_base.num,pCodecCtx->time_base.den,pCodecCtx->sample_aspect_ratio.num,pCodecCtx->sample_aspect_ratio.den);

FILE *outFile=fopen("encoded.h264","w");

   OMX_ERRORTYPE r;
   OMX_VIDEO_PARAM_PORTFORMATTYPE in_dec_format,out_enc_format,out_dec_Format;
   OMX_PARAM_PORTDEFINITIONTYPE in_enc_format;
   COMPONENT_T *video_decode = NULL,*video_encode=NULL,*video_resize=NULL, *video_render = NULL;
   COMPONENT_T *list[5];
   TUNNEL_T tunnel[4];
   ILCLIENT_T *client;
   int status = 0;

   memset(list, 0, sizeof(list));
   memset(tunnel, 0, sizeof(tunnel));

   if((client = ilclient_init()) == NULL){printf("=>Can't init ilclient_init()!\n");exit(-1);}
   if(OMX_Init() != OMX_ErrorNone){ilclient_destroy(client);printf("=>Can't init omx!\n");exit(-1);}

   // create video_decode
   if(ilclient_create_component(client, &video_decode, "video_decode", ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_INPUT_BUFFERS) != 0)
      status = -14;
   list[0] = video_decode;

   // create resize
   if(ilclient_create_component(client, &video_resize, "resize",ILCLIENT_DISABLE_ALL_PORTS) != 0){status = -14; printf("=> ilclient_create_component() for video_resize failed!!\n");exit(1);}
   list[1] = video_resize;

   // create video_encode
   if(ilclient_create_component(client, &video_encode, "video_encode",ILCLIENT_DISABLE_ALL_PORTS | ILCLIENT_ENABLE_OUTPUT_BUFFERS) != 0){status = -14; printf("=> ilclient_create_component() for video_encode failed!!\n");exit(1);}
   list[2] = video_encode;

   // create video_render
   if(status == 0 && ilclient_create_component(client, &video_render, "video_render", ILCLIENT_DISABLE_ALL_PORTS) != 0)
      status = -14;
   list[3] = video_render;


//   set_tunnel(tunnel, video_decode, 131, video_render, 90);
   set_tunnel(tunnel, video_decode, 131, video_encode, 200);


   if(status == 0){
      ilclient_change_component_state(video_decode, OMX_StateIdle);
     ilclient_change_component_state(video_encode, OMX_StateIdle);
                   }//if status

   //input dec format
   memset(&in_dec_format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
   in_dec_format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   in_dec_format.nVersion.nVersion = OMX_VERSION;
   in_dec_format.nPortIndex = 130;
   in_dec_format.eCompressionFormat = OMX_VIDEO_CodingAVC;
   r = OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &in_dec_format);
   if ( r!= OMX_ErrorNone){printf("%s:%d: OMX_SetParameter() for video_decode port 130 failed with 0x%08x!\n",__FUNCTION__, __LINE__, r);exit(-1);}


   //output dec format
   memset(&out_dec_Format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
   out_dec_Format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   out_dec_Format.nVersion.nVersion = OMX_VERSION;
   out_dec_Format.nPortIndex = 131;
  // out_dec_Format.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
  //if (OMX_GetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamPortDefinition, &out_dec_Format) != OMX_ErrorNone) {printf("%s:%d: OMX_GetParameter() for video_encode port 131 failed!\n", __FUNCTION__, __LINE__);status=-1;exit(-1);}

   if(OMX_SetParameter(ILC_GET_HANDLE(video_decode), OMX_IndexParamVideoPortFormat, &out_dec_Format)!=OMX_ErrorNone){printf("=> Failed set  output port formats of buffers for port (video_decode) : 131 \n");status=-1;exit(-1);}

//   //input video_encode
   memset(&in_enc_format, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
   in_enc_format.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   in_enc_format.nVersion.nVersion = OMX_VERSION;
   in_enc_format.nPortIndex = 200;
   if (OMX_GetParameter(ILC_GET_HANDLE(video_encode), OMX_IndexParamPortDefinition,&in_enc_format) != OMX_ErrorNone) {printf("%s:%d: OMX_GetParameter() for video_encode port 200 failed!\n", __FUNCTION__, __LINE__);exit(1);}
   // Port 200: in 1/1 115200 16 enabled,not pop.,not cont. 320x240 320x240 @1966080 20
   in_enc_format.format.video.nFrameWidth = WIDTH;
   in_enc_format.format.video.nFrameHeight = HEIGHT;
   in_enc_format.format.video.xFramerate = 30 << 16;
   in_enc_format.format.video.nSliceHeight = in_enc_format.format.video.nFrameHeight;
   in_enc_format.format.video.nStride = in_enc_format.format.video.nFrameWidth;
   in_enc_format.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;
   if (( r = OMX_SetParameter(ILC_GET_HANDLE(video_encode),OMX_IndexParamPortDefinition, &in_enc_format)) != OMX_ErrorNone){printf("%s:%d: OMX_SetParameter() for video_encode port 200 failed with %x!\n", __FUNCTION__, __LINE__, r);exit(1);}

   //output video_encode
   memset(&out_enc_format, 0, sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
   out_enc_format.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   out_enc_format.nVersion.nVersion = OMX_VERSION;
   out_enc_format.nPortIndex = 201;
   out_enc_format.eCompressionFormat = OMX_VIDEO_CodingAVC;
   if ((r = OMX_SetParameter(ILC_GET_HANDLE(video_encode),OMX_IndexParamVideoPortFormat, &out_enc_format)) != OMX_ErrorNone){printf("%s:%d: OMX_SetParameter() for video_encode port 201 failed with %x!\n",__FUNCTION__, __LINE__, r);exit(1);}


   if(status != 0 &&
      ilclient_enable_port_buffers(video_decode, 130, NULL, NULL, NULL) != 0 &&
      ilclient_enable_port_buffers(video_encode, 201, NULL, NULL, NULL) != 0){printf("Failed ilclient_enable_port_buffers\n");exit(-1);}

      OMX_BUFFERHEADERTYPE *buf,*out;


    AVPacket *p_packet;
    AVBitStreamFilterContext *p_btsf;
    p_packet = malloc(sizeof(AVPacket));
    //int video_index=0;
    int index=0;
    int pstatus=0;
    int first_frame=true;

    //int t_error=ilclient_setup_tunnel(tunnel, 0, 0);
    //if( t_error!= 0){status = -7;printf("=>Can't setup tunnel, error: %d!!!\n",t_error);exit(status);}




           ilclient_change_component_state(video_decode, OMX_StateExecuting);
           //ilclient_change_component_state(video_render, OMX_StateExecuting);
           ilclient_change_component_state(video_encode, OMX_StateExecuting);



//int result = m_pSubtitleCodec->Decode(pkt->data, pkt->size, pkt->pts, pkt->duration);




      do{  
    printf("###before DO!\n");

pstatus=av_read_frame(pFormatCtx,p_packet);

     if(first_frame==true){
p_btsf= dofiltertest(p_packet);
first_frame=false;
}//if

AVPacket packet=filter(p_btsf,pFormatCtx,p_packet,video_stream_index);

//only for video
if(packet.stream_index==*video_stream_index){
printf("=>Read frame, status: %d, index: %d, stream index: %d, packet duration: %d, size: %d\n",pstatus,index++,packet.stream_index,packet.duration,packet.size);

int psize=packet.size;
int preaded=0;
//double pts=packet.duration;

while(psize!=0){
    printf("while\n");
     buf = ilclient_get_input_buffer(video_decode, 130, 1);
     buf->nFilledLen = (psize > buf->nAllocLen) ? buf->nAllocLen : psize;
    memcpy(buf->pBuffer, packet.data+preaded,buf->nFilledLen);
    psize-=buf->nFilledLen;
    preaded+=buf->nFilledLen;

     if(psize == 0){buf->nFlags|=OMX_BUFFERFLAG_ENDOFFRAME;printf("#######################################OMX_BUFFERFLAG_ENDOFFRAME\n");}

printf("=>BUFF size: %d\n",(int)buf->nFilledLen);
r=OMX_EmptyThisBuffer(ILC_GET_HANDLE(video_decode), buf);
if(pstatus==0){if(r!= OMX_ErrorNone){status = -6;printf("Failed, OMX_EmptyThisBuffer, error: 0x%08x , buf allocate: %d, buf lenght: %d \n", r,(int)buf->nAllocLen,(int)buf->nFilledLen);break;}}



}//while psize
av_free_packet(&packet);



//################################################################### encode
//if(psize == 0){
    printf("###Start encoder..\n");

out = ilclient_get_output_buffer(video_encode, 201, 1);

r = OMX_FillThisBuffer(ILC_GET_HANDLE(video_encode), out);
if (r != OMX_ErrorNone) {printf("### Error filling buffer: %x\n", r);}

printf("############## Encoded buf, size: %d\n",(int)out->nFilledLen);

if (out != NULL) {
   if (out->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
      int i;
      for (i = 0; i < out->nFilledLen; i++)
     printf("%x ", out->pBuffer[i]);
      printf("\n");
   }

  size_t len = fwrite(out->pBuffer, 1, out->nFilledLen, outFile);
   if (len != out->nFilledLen) {printf("### fwrite: Error emptying encoder buffer: %d!\n", r);}
   else {printf("### Writing encoded frame, size: %d\n",(int)len);}
   out->nFilledLen = 0;
                }//out!=NULL
else {
   printf("### Not getting encode buf !\n");
}
//}//if psize



   }//if index
}//do
while(pstatus==0);

printf("=>After while! \n");












      // wait for EOS from render
/*      ilclient_wait_for_event(video_render, OMX_EventBufferFlag, 90, 0, OMX_BUFFERFLAG_EOS, 0,*/
/*                              ILCLIENT_BUFFER_FLAG_EOS, 10);*/

      // need to flush the renderer to allow video_decode to disable its input port
      ilclient_flush_tunnels(tunnel, 0);

      ilclient_disable_port_buffers(video_decode, 130, NULL, NULL, NULL);




   ilclient_disable_tunnel(tunnel);
   ilclient_teardown_tunnels(tunnel);

   ilclient_state_transition(list, OMX_StateIdle);
   ilclient_state_transition(list, OMX_StateLoaded);

   ilclient_cleanup_components(list);

   OMX_Deinit();

   ilclient_destroy(client);
   return status;
}



int main (int argc, char **argv)
{
   if (argc < 2) {
      printf("Usage: %s <filename>\n", argv[0]);
      exit(1);
   }
av_register_all();//  initialize libavformat/libavcodec: 
   bcm_host_init();
    AVFormatContext *in_formatCtx;
    AVCodecContext in_codecCtx;
        //AVPacket *packet;
    int video_stream_index;
    //get input codec params object
    if(getInputHendle(argv[1],in_formatCtx,in_codecCtx,&video_stream_index)==-1){exit(-1);}
    if(&in_formatCtx==NULL){printf("before formatCtx is NULL! \n");}

//printf("DATAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA: H= %d",in_formatCtx.streams[video_stream_index]->codec->height);

//video_decode_test(&in_formatCtx,video_stream_index);


 return 0;
}
#包括
#包括
#包括
#包括
#包括“bcm_host.h”
#包括“ilclient.h”
#包括“libavformat/avformat.h”
#包括“libavutil/avutil.h”
#包括“libavcodec/avcodec.h”
#包括“libavutil/mathematics.h”
#包括
#定义宽度1920//736//640//320//1280//
#定义高度1080//1088//400//368//((宽度*9)/16)//720//
#定义节距((宽度+31)和~31)
#定义高度16((高度+15)和~15)
#定义尺寸((宽*高16*3)/2)/(宽*高*12/8)//
//http://fossies.org/dox/xbmc-12.0/DVDClock_8h_source.html
#定义DVD的NOPTS值(-1LL 32;
返回滴答声;
}
静态AVBitStreamFilterContext*dofiltertest(AVPacket*rp)
{
AVBitStreamFilterContext*bsfc;
bsfc=NULL;
如果(!(rp->data[0]==0x00&&rp->data[1]==0x00&&
rp->data[2]==0x00&&rp->data[3]==0x01)){
bsfc=av_比特流_过滤器_初始化(“h264_mp4toannexb”);
如果(!bsfc){
printf(“未能打开筛选器。这是错误的。\n”);
}否则{
printf(“在%p\n处有一个过滤器”,bsfc);
}
}否则
printf(“不需要过滤器。\n”);
返回bsfc;
}
静态AVPacket筛选器(AVBitStreamFilterContext*bsfc、AVFormatContext*ctx、AVPacket*rp、int*视频流索引)
{
如果(ctx==NULL){printf(!!!ctx为NULL,文件集过滤器!\n”);退出(-1);}
//AVBitStreamFilterContext*bsfc=dofiltertest(rp);
avp;
AVPacket*fp;
int rc;
国际单项体育联合会(bsfc){
fp=calloc(sizeof(AVPacket),1);
国际单项体育联合会(bsfc){
rc=av_比特流_过滤器_过滤器(bsfc,
ctx->streams[*视频流索引]->编解码器,
空,&(fp->数据),&(fp->大小),
rp->数据,rp->大小,
rp->flags&AV_PKT_FLAG_KEY);
如果(rc>0){
av_免费_包(rp);
fp->destruct=av_destruct_数据包;
p=fp;
}否则{
printf(“未能筛选帧:”
“%d(%x)\n”,rc,rc);
p=rp;
}
}否则
p=rp;
返回*p;
}//如果
else{return*rp;}
}
静态int-getInputHendle(char*文件名,AVFormatContext*pFmtCtx,AVCodecContext-pCodCtx,int*视频流索引){
printf(“启动getInputHandle%s\n”,文件名);
AVFormatContext*pFormatCtx;
//打开视频文件
if(av_open_input_file(&pFormatCtx,filename,NULL,0,NULL)!=0){printf(“无法打开文件”);返回-1;}
//检索流信息
如果(av_find_stream_info(pFormatCtx)streams[i]->codec->codec_type==AVMEDIA_type_VIDEO){*VIDEO_stream_index=i;break;}
if(*video_stream_index==-1){printf(“未找到视频流”);返回-1;}
//获取指向视频流的编解码器上下文的指针
pCodecCtx=pFormatCtx->streams[*视频流索引]->编解码器;
printf(“\n=>我的视频信息:\n比特率:%d\n帧宽:%d\n帧高:%d\n帧速率:%d:%d\n纵横比:%d:%d\n”,pCodecCtx->比特率,pCodecCtx->宽度,pCodecCtx->高度,pCodecCtx->时间基数.num,pCodecCtx->时间基数.den,pCodecCtx->样本纵横比.num,pCodecCtx->样本纵横比.den);
文件*outFile=fopen(“encoded.h264”,“w”);
OMX_错误类型r;
OMX_视频_参数_端口格式输入_dec_格式、输出_enc_格式、输出_dec_格式;
OMX_参数_端口定义类型为_enc_格式;
组件*video\u decode=NULL、*video\u encode=NULL、*video\u resize=NULL、*video\u render=NULL;
组件清单[5];
隧道[4];
ILCLIENT_T*客户;
int status=0;
memset(list,0,sizeof(list));
memset(tunnel,0,sizeof(tunnel));
如果((client=ilclient_init())==NULL){printf(“=>无法初始化ilclient_init()!\n”);退出(-1);}
如果(OMX_Init()!=OMX_ErrorNone){ilclient_destroy(client);printf(“=>无法初始化OMX!\n”);退出(-1);}
//创建视频解码
if(ilclient_创建_组件(客户端和视频解码,“视频解码”,ilclient_禁用所有端口,ilclient_启用输入缓冲区)!=0)
状态=-14;
列表[0]=视频解码;
//创建调整大小
如果(ilclient\u create\u component(client,&video\u resize,“resize”,ilclient\u DISABLE\u ALL\u port)!=0){status=-14;printf(=>ilclient\u create\u component(),用于video\u resize失败!!\n”);退出(1);}
列表[1]=视频大小;
//创建视频编码
如果(ilclient_create_component(client,&video_encode,“video_encode”,ilclient_DISABLE_ALL_port | ilclient_ENABLE_OUTPUT_BUFFERS)!=0{status=-14;printf(=>ilclient_create_component(),视频_encode failed!!\n”);退出(1)}
列表[2]=视频编码;
//创建视频渲染
如果(状态==0&&ilclient\u创建\u组件(客户端和视频渲染,“视频渲染”,ilclient\u禁用所有端口)!=0)
状态=-14;
列表[3]=视频渲染;
//设置隧道(隧道,视频解码,131,视频渲染,90);
设置隧道(隧道,视频解码,131,视频编码,200);
如果(状态==0){
ilclient\u change\u component\u state(视频解码、OMX\u StateIdle);
ilclient\u change\u component\u state(视频编码、OMX\u StateIdle);
}//如果状态
//输入dec格式
memset(&in_dec_格式,0,sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
in_dec_format.nSize=sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
在_dec_format.nVersion.nVersion=OMX_版本中;
在_dec_format.nPortIndex=130;
in_dec_format.eCompressionFormat=OMX_VIDEO_CodingAVC;
r=OMX_SetParameter(ILC_GET_HANDLE(视频解码)、OMX_IndexParamVideoPortFormat和in_dec_格式);
如果(r!=OMX_ErrorNone){printf(“%s:%d:OMX_SetParameter(),用于视频解码端口130,失败,错误为0x%08x!\n“,_函数,_行,r);退出(-1);}
//输出dec格式
memset(&out_dec_格式,0,sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE));
12月1日