2017-12-05 2 views
1

Erste, sorry für mein Englisch. Wenn ich h264 720p in ardrone2.0 dekodiere, ist meine Ausgabe schwarz und ich kann nichts sehen.Ausgang schwarz, wenn ich dekodieren h264 720p mit ffmpeg

Ich habe versucht, den Wert von pCodecCtx->pix_fmt = AV_PIX_FMT_BGR24; zu pCodecCtx->pix_fmt = AV_PIX_FMT_YUV420P; und den Wert von pCodecCtxH264->pix_fmt = AV_PIX_FMT_BGR24; zu pCodecCtxH264->pix_fmt = AV_PIX_FMT_YUV420P; aber meinen Programmabsturz zu ändern. Was mache ich falsch?. Danke, siehe Teil meines Codes:

av_register_all(); 
avcodec_register_all(); 
avformat_network_init(); 

// 1.2. Open video file 
if(avformat_open_input(&pFormatCtx, drone_addr, NULL, NULL) != 0) { 
    mexPrintf("No conecct with Drone"); 
    EndVideo(); 
    return; 
} 

pCodec = avcodec_find_decoder(AV_CODEC_ID_H264); 

pCodecCtx = avcodec_alloc_context3(pCodec); 
pCodecCtx->pix_fmt = AV_PIX_FMT_BGR24; 
pCodecCtx->skip_frame = AVDISCARD_DEFAULT; 
pCodecCtx->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; 
pCodecCtx->err_recognition = AV_EF_CAREFUL; 
pCodecCtx->skip_loop_filter = AVDISCARD_DEFAULT; 
pCodecCtx->workaround_bugs = FF_BUG_AUTODETECT; 
pCodecCtx->codec_type = AVMEDIA_TYPE_VIDEO; 
pCodecCtx->codec_id = AV_CODEC_ID_H264; 
pCodecCtx->skip_idct = AVDISCARD_DEFAULT; 
pCodecCtx->width = 1280; 
pCodecCtx->height = 720; 

pCodecH264 = avcodec_find_decoder(AV_CODEC_ID_H264); 
pCodecCtxH264 = avcodec_alloc_context3(pCodecH264); 


pCodecCtxH264->pix_fmt = AV_PIX_FMT_BGR24; 
pCodecCtxH264->skip_frame = AVDISCARD_DEFAULT; 
pCodecCtxH264->error_concealment = FF_EC_GUESS_MVS | FF_EC_DEBLOCK; 
pCodecCtxH264->err_recognition = AV_EF_CAREFUL; 
pCodecCtxH264->skip_loop_filter = AVDISCARD_DEFAULT; 
pCodecCtxH264->workaround_bugs = FF_BUG_AUTODETECT; 
pCodecCtxH264->codec_type = AVMEDIA_TYPE_VIDEO; 
pCodecCtxH264->codec_id = AV_CODEC_ID_H264; 
pCodecCtxH264->skip_idct = AVDISCARD_DEFAULT; 

if(avcodec_open2(pCodecCtxH264, pCodecH264, &optionsDict) < 0) 
{ 
    mexPrintf("Error opening H264 codec"); 
    return ; 
} 

pFrame_BGR24 = av_frame_alloc(); 


if(pFrame_BGR24 == NULL) { 
    mexPrintf("Could not allocate pFrame_BGR24\n"); 
    return ; 
} 

// Determine required buffer size and allocate buffer 

buffer_BGR24 = 
(uint8_t *)av_mallocz(av_image_get_buffer_size(AV_PIX_FMT_BGR24, 
pCodecCtx->width, ((pCodecCtx->height == 720) ? 720 : pCodecCtx->height) * 
sizeof(uint8_t)*3,1)); 

// Assign buffer to image planes 

av_image_fill_arrays(pFrame_BGR24->data, pFrame_BGR24->linesize, 
buffer_BGR24,AV_PIX_FMT_BGR24, pCodecCtx->width, pCodecCtx->height,1); 

// format conversion context 
pConvertCtx_BGR24 = sws_getContext(pCodecCtx->width, pCodecCtx->height, 
pCodecCtx->pix_fmt, pCodecCtx->width, pCodecCtx->height, AV_PIX_FMT_BGR24, 
           SWS_BILINEAR | SWS_ACCURATE_RND, 0, 0, 0); 

// 1.6. get video frames 
pFrame = av_frame_alloc(); 

av_init_packet(&packet); 
packet.data = NULL; 
packet.size = 0; 
} 

//Captura un frame 
void video::capture(mxArray *plhs[]) { 

    if(av_read_frame(pFormatCtx, &packet) < 0){ 
     mexPrintf("Error al leer frame"); 
     return; 
    } 
    do { 
     do { 
      rest = avcodec_send_packet(pCodecCtxH264, &packet); 
     } while(rest == AVERROR(EAGAIN)); 

     if(rest == AVERROR_EOF || rest == AVERROR(EINVAL)) { 
       printf("AVERROR(EAGAIN): %d, AVERROR_EOF: %d, 
       AVERROR(EINVAL): %d\n", AVERROR(EAGAIN), AVERROR_EOF, 
       AVERROR(EINVAL)); 
      printf("fe_read_frame: Frame getting error (%d)!\n", rest); 
      return; 
     } 

     rest = avcodec_receive_frame(pCodecCtxH264, pFrame); 
    } while(rest == AVERROR(EAGAIN)); 

    if(rest == AVERROR_EOF || rest == AVERROR(EINVAL)) { 

    // An error or EOF occured,index break out and return what 
    // we have so far. 
     printf("AVERROR(EAGAIN): %d, AVERROR_EOF: %d, AVERROR(EINVAL): %d\n", 
     AVERROR(EAGAIN), AVERROR_EOF, AVERROR(EINVAL)); 
     printf("fe_read_frame: EOF or some othere decoding error (%d)!\n", 
     rest); 
     return; 
    } 


    // 2.1.1. convert frame to GRAYSCALE [or BGR] for OpenCV 
    sws_scale(pConvertCtx_BGR24, (const uint8_t* const*)pFrame->data, 
     pFrame->linesize, 0,pCodecCtx->height, pFrame_BGR24->data, 
      pFrame_BGR24->linesize); 
//} 
    av_packet_unref(&packet); 
    av_init_packet(&packet); 
    mwSize dims[] = {(pCodecCtx->width)*((pCodecCtx->height == 720) ? 720 : 
    pCodecCtx->height)*sizeof(uint8_t)*3}; 
    plhs[0] = mxCreateNumericArray(1,dims,mxUINT8_CLASS, mxREAL); 
    //plhs[0]=mxCreateDoubleMatrix(pCodecCtx->height,pCodecCtx- 
    >width,mxREAL); 
    point=mxGetPr(plhs[0]); 
    memcpy(point, pFrame_BGR24->data[0],(pCodecCtx->width)*(pCodecCtx- 
    >height)*sizeof(uint8_t)*3); 
} 
+0

Sie dekodieren den Rahmen nicht. – szatmary

+0

Ich muss sagen, dass, wenn ich die Auflösung auf 640x360 ändern kann ich den Rahmen mit 'AV_PIX_FMT_YUV420P' erhalten, aber Ardrone können qualitativ hochwertige Videos senden und ich verstehe nicht, weil der Code mit 640x360 funktioniert und nicht mit 1280x720 –

Antwort

0

Gehen Sie zum Debugger und sehen Sie Ihren memcpy. Ich bin mir nicht sicher, ob es für alle Dimensionen funktioniert, die Sie wollen. Außerdem kann es mehr Speicherprobleme geben. Versucht zum Beispiel zu sehen, was der Wert von buffer_BGR24 und pFrame ist. Ich wette, dass sie manchmal keine richtigen Werte zurückgeben. Überprüfen Sie sie im Code.

+0

funktioniert Das Problem ist in sws_scale Funktion ('sws_scale (pConvertCtx_BGR24, (const uint8_t * const *) pFrame-> Daten, pFrame-> Liniengröße, 0, pCodecCtx-> Höhe, pFrame_BGR24-> Daten, pFrame_BGR24-> Linesize);'). Der Code stürzt in diesem Punkt ab. Dies funktioniert mit niedriger Auflösung (640x360) aber Absturz mit hoher Auflösung (1280x720). –

+0

Es scheint, dass Sie 6 Argumente beim Aufruf von sws_scale haben, und ich kann sehen, dass die Funktion 7 Argumente benötigt: int sws_scale (SwsContext * c, uint8_t * src, int srcStride [], int srcSliceY, int srcSliceH, uint8_t dst [], int dstStride [], gemäß http://dranger.com/ffmpeg/functions.html#sws_scale.Bitte gehen Sie zum Debugger und überprüfen Sie die Eingabe für diese Funktion.Manchmal wird der Kontext automatisch auf Werte geändert, die Sie nicht erwarten Das macht die Bibliothek. – VladP

Verwandte Themen