2016-08-06 41 views
2

Ich habe versucht, einen AVFrame zu kopieren, genau wie in ffmpeg: make a copy from a decoded frame (AVFrame) beantwortet wurde. Aber ich kann es nicht bekommen, um einen positiven Returncode von av_frame_copy() zu bekommen.Kopieren eines decodierten ffmpeg AVFrame

Hier ist im Grunde, was ich tue:

AVFrame *copyFrame = NULL; 
copyFrame = av_frame_alloc(); 

int return_code = av_frame_copy(copyFrame, originalFrame); 
if(return_code < 0){ 
    fprintf(stderr, "av_frame_copy failed with return code %d\n", return_code); 
    return(1); 
} 

Wenn es hilft, der Return-Code I von av_frame_copy bekommen ist -22.

+0

Fehler -22 scheint zu bedeuten, dass eines Ihrer Argumente in ungültig, nach [diese Antwort] (https://stackoverflow.com/questions/26205017/ffmpeg-avcodec-open2-returns-22-ifi- change-my-loader-configuration/26205126 # 26205126) – user3386109

Antwort

6

Wenn Sie die Dokumentation für av_frame_copy lesen, heißt es "Diese Funktion weist nichts zu, dst muss bereits initialisiert und mit denselben Parametern wie src zugewiesen sein."

av_frame_alloc tut nichts anderes als die AVFrame Struktur zuweisen und initialisieren es einige Standardwerte. Am wichtigsten ist, dass es keine Puffer für die Rahmendaten zuweist oder den Rahmen für die Verwendung vorbereitet. av_frame_copy schlägt fehl, da der Zielframe nicht das richtige Pixelformat festgelegt oder Puffer zugewiesen hat.

Wenn Sie einen Frame klonen möchten (indem Sie seinen Referenzzähler inkrementieren und keine tiefe Kopie erstellen), können Sie av_frame_clone oder av_frame_ref verwenden.

Wenn Sie den Rahmen verschieben möchten, können Sie av_frame_move_ref verwenden.

Aber Sie möchten wahrscheinlich eine ordnungsgemäße tiefe Kopie machen. In diesem Fall können Sie den Quellcode der av_frame_make_writable betrachten. Diese Funktion macht eine tiefe Kopie des Rahmens, wenn es nicht beschreibbar ist, so können wir die gleiche Logik verwenden, um eine tiefe Kopie des Rahmens zu machen hier:

AVFrame *copyFrame = av_frame_alloc(); 
copyFrame->format = frame->format; 
copyFrame->width = frame->width; 
copyFrame->height = frame->height; 
copyFrame->channels = frame->channels; 
copyFrame->channel_layout = frame->channel_layout; 
copyFrame->nb_samples = frame->nb_samples; 
av_frame_get_buffer(copyFrame, 32); 
av_frame_copy(copyFrame, frame); 
av_frame_copy_props(copyFrame, frame); 

Hinweis, dass ich nicht auf Fehler überprüft in die Funktionen, die ich angerufen habe. Sie sollten das in Ihrem echten Code tun. Ich habe es hier der Kürze halber weggelassen.

+0

Danke dafür. Ich habe die Dokumentation gelesen, bin aber nicht weitergekommen, um av_frame_get_buffer() zu verwenden. Ich habe hauptsächlich mit Skriptsprachen gearbeitet, aber ich arbeite gerade hart, um C zu lernen. Danke für Ihre Geduld. Es war der Parameter "int align", der mich abwarf, weil ich keine Ahnung hatte, welche Ausrichtung sein sollte. – loneraver

+1

Ich bin froh, dass es hilfreich war! Die Ausrichtung hängt davon ab, was Sie tun, obwohl eine Ausrichtung von 32 ziemlich sicher ist und für so ziemlich alles, was Sie tun, funktionieren sollte. Einige CPU-Anweisungen, insbesondere erweiterte SIMD-Anweisungen, die in optimierten Routinen verwendet werden, erfordern eine spezifische Ausrichtung. Sie könnten mit einer Ausrichtung von 1 durchkommen, aber wenn Sie nicht wissen, was Sie mit der Ausrichtung tun, würde ich 32 empfehlen. Die ['AVFrame.linesize'] (https://www.ffmpeg.org /doxygen/trunk/structAVFrame.html#aa52bfc6605f6a3059a0c3226cc0f6567) Dokumentation hat ein paar mehr Details. – Cornstalks