
Recherche avancée
Autres articles (54)
-
MediaSPIP 0.1 Beta version
25 avril 2011, parMediaSPIP 0.1 beta is the first version of MediaSPIP proclaimed as "usable".
The zip file provided here only contains the sources of MediaSPIP in its standalone version.
To get a working installation, you must manually install all-software dependencies on the server.
If you want to use this archive for an installation in "farm mode", you will also need to proceed to other manual (...) -
MediaSPIP version 0.1 Beta
16 avril 2011, parMediaSPIP 0.1 beta est la première version de MediaSPIP décrétée comme "utilisable".
Le fichier zip ici présent contient uniquement les sources de MediaSPIP en version standalone.
Pour avoir une installation fonctionnelle, il est nécessaire d’installer manuellement l’ensemble des dépendances logicielles sur le serveur.
Si vous souhaitez utiliser cette archive pour une installation en mode ferme, il vous faudra également procéder à d’autres modifications (...) -
Amélioration de la version de base
13 septembre 2013Jolie sélection multiple
Le plugin Chosen permet d’améliorer l’ergonomie des champs de sélection multiple. Voir les deux images suivantes pour comparer.
Il suffit pour cela d’activer le plugin Chosen (Configuration générale du site > Gestion des plugins), puis de configurer le plugin (Les squelettes > Chosen) en activant l’utilisation de Chosen dans le site public et en spécifiant les éléments de formulaires à améliorer, par exemple select[multiple] pour les listes à sélection multiple (...)
Sur d’autres sites (5930)
-
FFMPEG in an AWS Lambda will only output 5 seconds of converted video [duplicate]
5 juin 2021, par beerandsmilesI've been looking for a solution for this issue, but I can't seem to find what's going wrong.


In short, I'm using an AWS Lambda to convert video captured from an raspberry pi in a raw .h264 format to .mp4. The problem is that the output file is always, only 5 seconds long.


So I input a video of say 500mb, that is 10 minutes long, and the output is an mp4 that is exactly the first 5 seconds of the source video.


The lambda has been setup following the tutorial from Amazon that is shown here :
https://aws.amazon.com/blogs/media/processing-user-generated-content-using-aws-lambda-and-ffmpeg/


It is triggered by an upload from one s3 buckets, transcodes, and puts it in a different bucket. The purpose is to store a high quality copy of the video that is smaller to save costs. (this is a personal project, so I'm paying personally)


I've put the full code of the lambda down below.
I had trouble using their recommended stdout method as that resulted in a file being created with a size of 0 bytes.


You'll see a few commented lines where I tried different things to solve it. I thought it best to leave that in while asking the questions so you can see what I've done. Firstly the method of using stdout piped directly into the output S3 did not work, so I stored the output file in lambda's /tmp directory.


However, when I first did this using the signed link as the input it gave me 5 seconds of the input video.


Thinking this had to do with an issue in the stream that FFMPEG was getting, I tried instead to download the file from the first S3 bucket into the temp folder, then convert it, and then upload it.


The actual FFMPEG command is quite simple


f"/opt/bin/ffmpeg -framerate 25 -i {s3_source_key} output.mp4"


But this outputs a 5 second video.


I have also tried using different versions of FFMPEG for the layer with lambda and no help. Also, I have set and execution timeout of 2 minutes with 2gb or ram for this lambda.


The last thing, is that running this command on a linux machine, such as a raspberry pi directly, results in an mp4 of the correct length, only in the lambda am I having this problem.


I'm completely lost, and I can't seem to find any documentation on this happening to anyone else.


import os
import subprocess
import shlex
import boto3
from time import sleep

S3_DESTINATION_BUCKET = "dashcam-duncan"
SIGNED_URL_TIMEOUT = 600

def lambda_handler(event, context):
 print(event)
 os.chdir('/tmp')
 s3_source_bucket = event['Records'][0]['s3']['bucket']['name']
 s3_source_key = event['Records'][0]['s3']['object']['key']

 s3_source_basename = os.path.splitext(os.path.basename(s3_source_key))[0]
 s3_destination_filename = s3_source_basename + ".mp4"

 s3_client = boto3.client('s3')
 s3_source_signed_url = s3_client.generate_presigned_url('get_object',
 Params={'Bucket': s3_source_bucket, 'Key': s3_source_key},
 ExpiresIn=SIGNED_URL_TIMEOUT)
 print(s3_source_signed_url)
 s3_client.download_file(s3_source_bucket,s3_source_key,s3_source_key)
 # ffmpeg_cmd = "/opt/bin/ffmpeg -framerate 25 -i \"" + s3_source_signed_url + "\" output.mp4 "
 ffmpeg_cmd = f"/opt/bin/ffmpeg -framerate 25 -i {s3_source_key} output.mp4 "
 # command1 = shlex.split(ffmpeg_cmd)
 # print(command1)
 os.system(ffmpeg_cmd)
 # os.system('ls')
 # p1 = subprocess.run(command1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
 file = 'output.mp4'
 resp = s3_client.put_object(Body=open(file,"rb"), Bucket=S3_DESTINATION_BUCKET, Key=s3_destination_filename)
 # resp = s3_client.put_object(Body=p1.stdout, Bucket=S3_DESTINATION_BUCKET, Key=s3_destination_filename)
 s3 = boto3.resource('s3')
 s3.Object(s3_source_bucket,s3_source_key).delete()
 return {
 'statusCode': 200,
 'body': json.dumps('Processing complete successfully')
 }



The cloudwatch logs on the last execution of this :


built with gcc 8 (Debian 8.3.0-6)
configuration: --enable-gpl --enable-version3 --enable-static --disable-debug --disable-ffplay --disable-indev=sndio --disable-outdev=sndio --cc=gcc --enable-fontconfig --enable-frei0r --enable-gnutls --enable-gmp --enable-libgme --enable-gray --enable-libaom --enable-libfribidi --enable-libass --enable-libvmaf --enable-libfreetype --enable-libmp3lame --enable-libopencore-amrnb --enable-libopencore-amrwb --enable-libopenjpeg --enable-librubberband --enable-libsoxr --enable-libspeex --enable-libsrt --enable-libvorbis --enable-libopus --enable-libtheora --enable-libvidstab --enable-libvo-amrwbenc --enable-libvpx --enable-libwebp --enable-libx264 --enable-libx265 --enable-libxml2 --enable-libdav1d --enable-libxvid --enable-libzvbi --enable-libzimg
libavutil 56. 70.100 / 56. 70.100
libavcodec 58.134.100 / 58.134.100
libavformat 58. 76.100 / 58. 76.100
libavdevice 58. 13.100 / 58. 13.100
libavfilter 7.110.100 / 7.110.100
libswscale 5. 9.100 / 5. 9.100
libswresample 3. 9.100 / 3. 9.100
libpostproc 55. 9.100 / 55. 9.100
Input #0, h264, from 'video00087.h264':
Duration: N/A, bitrate: N/A
Stream #0:0: Video: h264 (High), yuv420p(progressive), 1280x720, 25 fps, 25 tbr, 1200k tbn, 50 tbc
Stream mapping:
Stream #0:0 -> #0:0 (h264 (native) -> h264 (libx264))
Press [q] to stop, [?] for help
[libx264 @ 0x6aaf500] using cpu capabilities: MMX2 SSE2Fast SSSE3 SSE4.2 AVX FMA3 BMI2 AVX2
[libx264 @ 0x6aaf500] profile High, level 3.1, 4:2:0, 8-bit
[libx264 @ 0x6aaf500] 264 - core 161 r3048 b86ae3c - H.264/MPEG-4 AVC codec - Copyleft 2003-2021 - http://www.videolan.org/x264.html - options: cabac=1 ref=3 deblock=1:0:0 analyse=0x3:0x113 me=hex subme=7 psy=1 psy_rd=1.00:0.00 mixed_ref=1 me_range=16 chroma_me=1 trellis=1 8x8dct=1 cqm=0 deadzone=21,11 fast_pskip=1 chroma_qp_offset=-2 threads=3 lookahead_threads=1 sliced_threads=0 nr=0 decimate=1 interlaced=0 bluray_compat=0 constrained_intra=0 bframes=3 b_pyramid=2 b_adapt=1 b_bias=0 direct=1 weightb=1 open_gop=0 weightp=2 keyint=250 keyint_min=25 scenecut=40 intra_refresh=0 rc_lookahead=40 rc=crf mbtree=1 crf=23.0 qcomp=0.60 qpmin=0 qpmax=69 qpstep=4 ip_ratio=1.40 aq=1:1.00
Output #0, mp4, to 'output.mp4':
Metadata:
encoder : Lavf58.76.100
Stream #0:0: Video: h264 (avc1 / 0x31637661), yuv420p(progressive), 1280x720, q=2-31, 25 fps, 12800 tbn
Metadata:
encoder : Lavc58.134.100 libx264
Side data:
cpb: bitrate max/min/avg: 0/0/0 buffer size: 0 vbv_delay: N/A
frame= 1 fps=0.0 q=0.0 size= 0kB time=00:00:00.00 bitrate=N/A speed= 0x 
frame= 47 fps=0.0 q=0.0 size= 0kB time=00:00:00.00 bitrate=N/A speed= 0x 
frame= 56 fps= 44 q=28.0 size= 0kB time=00:00:00.24 bitrate= 1.6kbits/s speed=0.187x 
frame= 65 fps= 35 q=28.0 size= 0kB time=00:00:00.60 bitrate= 0.6kbits/s speed=0.325x 
frame= 74 fps= 31 q=28.0 size= 0kB time=00:00:00.96 bitrate= 0.4kbits/s speed=0.399x 
Enter command: <target>|all <time>|-1 <command>[ <argument>]
Parse error, at least 3 arguments were expected, only 1 given in string 'V����Ҿ�#I���bv��oF��LxE��{��y5Jx�X�-f?2k�E~ہ��L��Y?�w���9?S�?�(q?��y��V8�=)�9'�?�-j?��?�3���Ŧ$��r���\��r}?zb?E��?��B}b4��2��[z�&�逋�Qk�ar�=y���'
frame= 82 fps= 28 q=28.0 size= 256kB time=00:00:01.28 bitrate=1638.6kbits/s speed=0.434x 
frame= 90 fps= 25 q=28.0 size= 256kB time=00:00:01.60 bitrate=1310.9kbits/s speed=0.442x 
frame= 98 fps= 23 q=28.0 size= 256kB time=00:00:01.92 bitrate=1092.4kbits/s speed=0.458x 
frame= 107 fps= 23 q=28.0 size= 256kB time=00:00:02.28 bitrate= 919.9kbits/s speed=0.48x 
frame= 115 fps= 22 q=28.0 size= 512kB time=00:00:02.60 bitrate=1613.3kbits/s speed=0.495x 
frame= 122 fps= 21 q=28.0 size= 512kB time=00:00:02.88 bitrate=1456.4kbits/s speed=0.499x 
[h264 @ 0x6b68c80] left block unavailable for requested intra mode
[h264 @ 0x6b68c80] error while decoding MB 0 19, bytestream 37403
[h264 @ 0x6b68c80] concealing 2129 DC, 2129 AC, 2129 MV errors in P frame
video00087.h264: corrupt decoded frame in stream 0
[h264 @ 0x6ab4080] left block unavailable for requested intra4x4 mode -1
[h264 @ 0x6ab4080] error while decoding MB 0 37, bytestream 13222
[h264 @ 0x6ab4080] concealing 689 DC, 689 AC, 689 MV errors in P frame
video00087.h264: corrupt decoded frame in stream 0
[h264 @ 0x6b68c80] concealing 1347 DC, 1347 AC, 1347 MV errors in P frame
frame= 130 fps= 21 q=28.0 size= 512kB time=00:00:03.20 bitrate=1310.8kbits/s speed=0.509x 
video00087.h264: corrupt decoded frame in stream 0
frame= 131 fps= 15 q=-1.0 Lsize= 1081kB time=00:00:05.12 bitrate=1729.6kbits/s speed=0.575x 
video:1079kB audio:0kB subtitle:0kB other streams:0kB global headers:0kB muxing overhead: 0.220914%
[libx264 @ 0x6aaf500] frame I:1 Avg QP:21.61 size: 37761
[libx264 @ 0x6aaf500] frame P:34 Avg QP:22.25 size: 18066
[libx264 @ 0x6aaf500] frame B:96 Avg QP:24.46 size: 4706
[libx264 @ 0x6aaf500] consecutive B-frames: 2.3% 0.0% 0.0% 97.7%
[libx264 @ 0x6aaf500] mb I I16..4: 15.2% 61.2% 23.6%
[libx264 @ 0x6aaf500] mb P I16..4: 8.4% 15.6% 1.2% P16..4: 39.2% 13.7% 6.9% 0.0% 0.0% skip:15.0%
[libx264 @ 0x6aaf500] mb B I16..4: 0.7% 1.8% 0.0% B16..8: 44.5% 4.5% 0.5% direct: 3.6% skip:44.4% L0:46.9% L1:48.0% BI: 5.1%
[libx264 @ 0x6aaf500] 8x8 transform intra:63.5% inter:83.1%
[libx264 @ 0x6aaf500] coded y,uvDC,uvAC intra: 22.1% 25.4% 2.8% inter: 11.6% 19.3% 1.2%
[libx264 @ 0x6aaf500] i16 v,h,dc,p: 4% 63% 8% 25%
[libx264 @ 0x6aaf500] i8 v,h,dc,ddl,ddr,vr,hd,vl,hu: 9% 26% 53% 1% 2% 1% 3% 1% 3%
[libx264 @ 0x6aaf500] i4 v,h,dc,ddl,ddr,vr,hd,vl,hu: 16% 44% 16% 4% 4% 3% 5% 4% 4%
[libx264 @ 0x6aaf500] i8c dc,h,v,p: 66% 24% 9% 1%
[libx264 @ 0x6aaf500] Weighted P-Frames: Y:0.0% UV:0.0%
[libx264 @ 0x6aaf500] ref P L0: 57.5% 16.8% 18.2% 7.5%
[libx264 @ 0x6aaf500] ref B L0: 89.8% 8.0% 2.2%
[libx264 @ 0x6aaf500] ref B L1: 96.0% 4.0%
[libx264 @ 0x6aaf500] kb/s:1685.21
END RequestId: 96e1031a-b1a2-4480-a59d-68de487671bd
REPORT RequestId: 96e1031a-b1a2-4480-a59d-68de487671bd Duration: 11721.77 ms Billed Duration: 11722 ms Memory Size: 2048 MB Max Memory Used: 494 MB Init Duration: 353.14 ms
</argument></command></time></target>


I've been struggling with this for a couple days now, any help would be amazing.


-
FFMpeg gpl (ffmpeg-4.2.1-win64-dev_and_shared) version give different decode result (cmd query vs code)
31 mai 2021, par Aleksey Timoshchenko*all the source img I put on my google drive due to SO restrictions (just click on links provided in the text)


The problem is that for
.h264
I use two implementations (cmd query and code) (depends on the tasks) that give me different results and I don't see any reason for this.

Before all I would like to give an explanation, I have
.bmp
bayer image, then I do debayering and compress it to.h264
(compress .h264) with the script

ffmpeg -y -hide_banner -i orig_bayer.bmp -vf format=gray -f rawvideo pipe: | ffmpeg -hide_banner -y -framerate 30 -f rawvideo -pixel_format bayer_rggb8 -video_size 4096x3000 -i pipe: -c:v hevc_nvenc -qp 0 -pix_fmt yuv444p res.h264




Then the first cmd query implementation of decoding (image result)


ffmpeg -y -i res.h264 -vframes 1 -f image2 gpl_script_res.bmp -hide_banner




The second implementation is code one and takes more lines (image result here)


Init ffmpeg


bool FFmpegDecoder::InitFFmpeg()
{
 m_pAVPkt = av_packet_alloc();
 m_pAVFrame = av_frame_alloc();
 m_pAVFrameRGB = av_frame_alloc();

 m_pAVFormatCtx = avformat_alloc_context();
 m_pIoCtx->initAVFormatContext(m_pAVFormatCtx);

 if (avformat_open_input(&m_pAVFormatCtx, "", nullptr, nullptr) != 0)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avformat_open_input\n");
 return false;
 }

 if (avformat_find_stream_info(m_pAVFormatCtx, nullptr) < 0)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avformat_find_stream_info\n");
 return false;
 }

 //av_dump_format(ctx_format, 0, "", false);
 for (int i = 0; i < (int)m_pAVFormatCtx->nb_streams; i++)
 {
 if (m_pAVFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO)
 {
 m_streamIdx = i;
 m_pAVStream = m_pAVFormatCtx->streams[i];
 break;
 }
 }
 if (m_pAVStream == nullptr)
 {
 printf("FFmpegDecoder::InitFFmpeg: failed to find video stream\n");
 return false;
 }

 m_pAVCodec = avcodec_find_decoder(m_pAVStream->codecpar->codec_id);
 if (!m_pAVCodec)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avcodec_find_decoder\n");
 return false;
 }

 m_pAVCodecCtx = avcodec_alloc_context3(m_pAVCodec);
 if (!m_pAVCodecCtx)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avcodec_alloc_context3\n");
 return false;
 }

 if (avcodec_parameters_to_context(m_pAVCodecCtx, m_pAVStream->codecpar) < 0)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avcodec_parameters_to_context\n");
 return false;
 }

 if (avcodec_open2(m_pAVCodecCtx, m_pAVCodec, nullptr) < 0)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in avcodec_open2\n");
 return false;
 }

 m_pAVFrameRGB->format = AV_PIX_FMT_BGR24;
 m_pAVFrameRGB->width = m_pAVCodecCtx->width;
 m_pAVFrameRGB->height = m_pAVCodecCtx->height;
 if (av_frame_get_buffer(m_pAVFrameRGB, 32) != 0)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in av_frame_get_buffer\n");
 return false;
 }

 m_streamRotationDegrees = GetAVStreamRotation(m_pAVStream);
 m_estimatedFramesCount = 0;
 assert(m_pAVFormatCtx->nb_streams > 0);
 if (m_pAVFormatCtx->nb_streams > 0)
 {
 m_estimatedFramesCount = m_pAVFormatCtx->streams[0]->nb_frames;
 }

 return InitConvertColorSpace(); 
}

bool FFmpegDecoder::InitConvertColorSpace()
{
 // Init converter from YUV420p to BGR:
 m_pSwsCtxConvertImg = sws_getContext(m_pAVCodecCtx->width, m_pAVCodecCtx->height, m_pAVCodecCtx->pix_fmt, m_pAVCodecCtx->width, m_pAVCodecCtx->height, AV_PIX_FMT_RGB24, SWS_FAST_BILINEAR, NULL, NULL, NULL);
 if (!m_pSwsCtxConvertImg)
 {
 printf("FFmpegDecoder::InitFFmpeg: error in sws_getContext\n");
 return false;
 }
 return true;
}



Decoding impl


bool FFmpegDecoder::DecodeContinue(int firstFrameIdx, int maxNumFrames)
{
 if (firstFrameIdx == FIRST_FRAME_IDX_BEGINNING)
 {
 firstFrameIdx = 0;
 }

 auto lastReportedFrameIdxTillNow = GetLastReportedFrameIdx();

 if (GetLastDecodedFrameIdx() >= 0 && firstFrameIdx <= GetLastDecodedFrameIdx())
 {
 printf("FFmpegDecoder::DecodeContinue FAILED: firstFrameIdx (%d) already passed decoded (Last decoded idx: %d)\n", firstFrameIdx, GetLastDecodedFrameIdx());
 return false;
 }

 bool bRes;
 int nRet = 0;
 bool bDecodeShouldEnd = false;

 if (m_pAVPkt != nullptr)
 {
 while (nRet >= 0)
 {
 m_bCurrentAVPktSentToCodec = false;
 nRet = av_read_frame(m_pAVFormatCtx, m_pAVPkt);
 if (nRet < 0)
 {
 break;
 }
 if (m_pAVPkt->stream_index == m_streamIdx)
 {
 bRes = DecodeCurrentAVPkt(firstFrameIdx, maxNumFrames, bDecodeShouldEnd);
 if (!bRes || m_bRequestedAbort)
 {
 av_packet_unref(m_pAVPkt);
 return false;
 }

 if (bDecodeShouldEnd)
 {
 av_packet_unref(m_pAVPkt);
 return true;
 }
 }

 av_packet_unref(m_pAVPkt);
 }
 m_bCurrentAVPktSentToCodec = false;
 m_pAVPkt = nullptr;
 }

 // drain:
 bRes = DecodeCurrentAVPkt(firstFrameIdx, maxNumFrames, bDecodeShouldEnd);
 if (!bRes)
 {
 return false;
 }

 if (lastReportedFrameIdxTillNow == GetLastReportedFrameIdx())
 {
 printf("FFmpegDecoder::DecodeContinue(firstFrameIdx==%d, maxNumFrames==%d) FAILED: no new frame was decoded\n", firstFrameIdx, maxNumFrames);
 return false;
 }

 return true;
}


bool FFmpegDecoder::DecodeCurrentAVPkt(int firstFrameIdx, int maxNumFrames, bool & bDecodeShouldEnd)
{
 bDecodeShouldEnd = false;

 int ret = 0;
 if (m_bCurrentAVPktSentToCodec == false)
 {
 ret = avcodec_send_packet(m_pAVCodecCtx, m_pAVPkt);
 m_bCurrentAVPktSentToCodec = true;
 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
 {
 printf("FFmpegDecoder::DecodeFrameImp: error EAGAIN/AVERROR_EOF in avcodec_send_packet\n");
 return false;
 }
 if (ret < 0)
 {
 if (ret == AVERROR_INVALIDDATA)
 {
 printf("FFmpegDecoder::DecodeFrameImp: error (%d - AVERROR_INVALIDDATA) in avcodec_send_packet\n", ret);
 }
 else
 {
 printf("FFmpegDecoder::DecodeFrameImp: error (%d) in avcodec_send_packet\n", ret);
 }
 return false;
 }
 }

 ret = 0;
 while (ret >= 0)
 {
 ret = avcodec_receive_frame(m_pAVCodecCtx, m_pAVFrame);
 if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
 {
 break;
 }

 IncrementLastDecodedFrameIdx();
 if (GetLastDecodedFrameIdx() < firstFrameIdx)
 {
 printf("FFmpegDecoder::DecodeCurrentAVPkt ignoring frame idx %d\n", GetLastDecodedFrameIdx());
 continue; // we don't need this frame
 }

 AVFrame * theFrame = m_pAVFrame; // default

 for (int j = 0; j < m_pAVFrame->nb_side_data; j++)
 {
 AVFrameSideData *sd = m_pAVFrame->side_data[j];
 if (sd->type == AV_FRAME_DATA_DISPLAYMATRIX) {
 auto ddd = av_display_rotation_get((int32_t *)sd->data);
 }
 }

 if (m_pSwsCtxConvertImg != nullptr)
 {
 {
 if (sws_scale(m_pSwsCtxConvertImg, theFrame->data, theFrame->linesize, 0, theFrame->height, m_pAVFrameRGB->data, m_pAVFrameRGB->linesize) == 0)
 {
 printf("FFmpegDecoder::DecodeFrameImp: error in sws_scale\n");
 return false;
 }
 }
 int numChannels = 3;
 FFmpegDecoderCallback::EPixelFormat pixFormat = FFmpegDecoderCallback::EPixelFormat::RGB;
 // Report frame to the client and update last reported frame idx:
 m_pCB->FFmpegDecoderCallback_HandleFrame(m_reqId, GetLastDecodedFrameIdx(), m_pAVFrameRGB->width, m_pAVFrameRGB->height, m_pAVFrameRGB->linesize[0], pixFormat, numChannels, m_pAVFrameRGB->data[0]);
 m_lastReportedFrameIdx = GetLastDecodedFrameIdx(); 
 }

 if (maxNumFrames != MAX_NUM_FRAMES_INFINITE && GetLastDecodedFrameIdx() >= (firstFrameIdx + maxNumFrames - 1))
 {
 bDecodeShouldEnd = true;
 return true;
 }
 }
 return true;
}

/*virtual*/ void FFmpegOneDecoderCtx::FFmpegDecoderCallback_HandleFrame(int reqId, int frameIdx0based, int width, int height, int widthStepBytes, EPixelFormat pixFormat, int numChannels, void * pData) /*override*/
{
 // We don't have metadata json => return the frame as is:
 m_pLastFrame->create(height, width, CV_8UC3);
 *m_pLastFrame = cv::Scalar(0, 0, 0);
 unsigned char * pSrc = reinterpret_cast<unsigned char="char">(pData);
 unsigned char *pDst = m_pLastFrame->data;
 auto dstStride = m_pLastFrame->step[0];
 for (int y = 0; y < height; ++y)
 {
 memcpy(pDst + y * dstStride, pSrc + y * widthStepBytes, numChannels*width);
 }
}
</unsigned>


And eventually usage looks like this


//>>>Get Frame
 FFmpegMultiDecoder decoder;
 decoder.HandleRequest_GetFrame(nullptr, filename, 1, image);
 //<<<

 //>>> Collor conversion from BGR to RGB
 cv::cvtColor(image, image, cv::COLOR_BGR2RGB);
 //<<<
 bool isOk = cv::imwrite(save_location, image);



The problem is that if you try to open two final decompressed images


- 

- one with code https://drive.google.com/file/d/1sfTnqvHKQ2DUy0uP8POZXDw2-u3oIRfZ/view?usp=sharing
- one with cmd query https://drive.google.com/file/d/1cwsOltk3DVtK86eLeyhiYjNeEXj0msES/view?usp=sharing






and try to flip from one image to other you'll see that image I got by cmd query a little bit brighter than that I got by code.


What is a possible problem here ?


If I missed smth feel free to ask.


-
FFMPEG Issue : Video breaks a lot hence the real time video gets distorted and gets a little delayed while streaming on a webpage from drone
26 mars 2022, par ashiyaa nunhuck****I am trying to detect a face from my drone camera in real time.The video streams successfully but it is delayed and breaks a lot. Is there any solution to this problem ? How can i have a smooth video streaming with little delay and no video breaking in order to succeed in detecting a face ? Your help will be much appreciated.
Also, this is printed while my code is running: :




INFO:werkzeug:127.0.0.1 - - [27/May/2021 15:16:14] "GET
/video/streaming HTTP/1.1" 200 -
INFO:drone_face_recognition_and_tracking.controllers.server :'action' :
'command', 'cmd' : 'takeOff'
INFO:drone_face_recognition_and_tracking.models.manage_drone :'action' :
'send_command', 'command' : 'takeoff' [h264 @ 0x55aa924a2e40] error
while decoding MB 45 38, bytestream -6 [h264 @ 0x55aa924a2e40]
concealing 424 DC, 424 AC, 424 MV errors in I frame [h264 @
0x55aa922a9a00] concealing 687 DC, 687 AC, 687 MV errors in P frame
[h264 @ 0x55aa923f79c0] left block unavailable for requested intra
mode [h264 @ 0x55aa923f79c0] error while decoding MB 0 34, bytestream
1347 [h264 @ 0x55aa923f79c0] concealing 709 DC, 709 AC, 709 MV errors
in P frame INFO:werkzeug:127.0.0.1 - - [27/May/2021 15:16:17] "POST
/api/command/ HTTP/1.1" 200 - pipe:0 : corrupt decoded frame in stream
0
Last message repeated 2 times [h264 @ 0x55aa922a9a00] error while decoding MB 49 30, bytestream -6 [h264 @ 0x55aa922a9a00] concealing
900 DC, 900 AC, 900 MV errors in P frame pipe:0 : corrupt decoded frame
in stream 0
INFO:drone_face_recognition_and_tracking.models.manage_drone :'action' :
'receive_response', 'response' : b'ok'
INFO:drone_face_recognition_and_tracking.controllers.server :'action' :
'command', 'cmd' : 'faceDetectAndTrack' INFO:werkzeug:127.0.0.1 - -
[27/May/2021 15:16:21] "POST /api/command/ HTTP/1.1" 200 - [h264 @
0x55aa924a2e40] left block unavailable for requested intra4x4 mode -1
[h264 @ 0x55aa924a2e40] error while decoding MB 0 30, bytestream 1624
[h264 @ 0x55aa924a2e40] concealing 949 DC, 949 AC, 949 MV errors in I
frame pipe:0 : corrupt decoded frame in stream 0 [h264 @
0x55aa9244d400] left block unavailable for requested intra mode [h264
@ 0x55aa9244d400] error while decoding MB 0 12, bytestream 2936 [h264
@ 0x55aa9244d400] concealing 2029 DC, 2029 AC, 2029 MV errors in I
frame pipe:0 : corrupt decoded frame in stream 0 [h264 @
0x55aa924bf700] concealing 1632 DC, 1632 AC, 1632 MV errors in P frame
pipe:0 : corrupt decoded frame in stream 0 [h264 @ 0x55aa92414280]
concealing 1571 DC, 1571 AC, 1571 MV errors in P frame




Here is my code :****


import logging
import contextlib
import os
import socket
import subprocess
import threading
import time
import cv2 as cv
import numpy as np

from drone_face_recognition_and_tracking.models.base import Singleton

logger = logging.getLogger(__name__)

DEFAULT_DISTANCE = 0.30
DEFAULT_SPEED = 10
DEFAULT_DEGREE = 10

FRAME_X = int(320) # try 640
FRAME_Y = int(240) # try 480
FRAME_AREA = FRAME_X * FRAME_Y

FRAME_SIZE = FRAME_AREA * 3
FRAME_CENTER_X = FRAME_X / 2
FRAME_CENTER_Y = FRAME_Y / 2

CMD_FFMPEG = (f'ffmpeg -probesize 32 -hwaccel auto -hwaccel_device opencl -i pipe:0 '
 f'-pix_fmt bgr24 -s {FRAME_X}x{FRAME_Y} -f rawvideo pipe:1')

FACE_DETECT_XML_FILE = './drone_face_recognition_and_tracking/models/haarcascade_frontalface_default.xml'


def receive_video(stop_event, pipe_in, host_ip, video_port):
 with socket.socket(socket.AF_INET, socket.SOCK_DGRAM) as sock_video:
 sock_video.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
 sock_video.settimeout(.5)
 sock_video.bind((host_ip, video_port))
 data = bytearray(2048)
 while not stop_event.is_set():
 try:
 size, addr = sock_video.recvfrom_into(data)
 # logger.info({'action': 'receive_video', 'data': data})
 except socket.timeout as ex:
 logger.warning({'action': 'receive_video', 'ex': ex})
 time.sleep(0.5)
 continue
 except socket.error as ex:
 logger.error({'action': 'receive_video', 'ex': ex})
 break

 try:
 pipe_in.write(data[:size])
 pipe_in.flush()
 except Exception as ex:
 logger.error({'action': 'receive_video', 'ex': ex})
 break


class Tello_Drone(metaclass=Singleton):
 def __init__(self, host_ip='192.168.10.2', host_port=8889,
 drone_ip='192.168.10.1', drone_port=8889,
 is_imperial=False, speed=DEFAULT_SPEED):
 self.host_ip = host_ip
 self.host_port = host_port
 self.drone_ip = drone_ip
 self.drone_port = drone_port
 self.drone_address = (drone_ip, drone_port)
 self.is_imperial = is_imperial
 self.speed = speed
 self.socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
 self.socket.bind((self.host_ip, self.host_port))

 self.response = None
 self.stop_event = threading.Event()
 self._response_thread = threading.Thread(target=self.receive_response, args=(self.stop_event, ))
 self._response_thread.start()

 self.proc = subprocess.Popen(CMD_FFMPEG.split(' '),
 stdin=subprocess.PIPE,
 stdout=subprocess.PIPE)
 self.proc_stdin = self.proc.stdin
 self.proc_stdout = self.proc.stdout

 self.video_port = 11111

 self._receive_video_thread = threading.Thread(
 target=receive_video,
 args=(self.stop_event, self.proc_stdin,
 self.host_ip, self.video_port,))
 self._receive_video_thread.start()

 self.face_cascade = cv.CascadeClassifier(FACE_DETECT_XML_FILE)
 self._is_enable_face_detect = False

 self.send_command('command')
 self.send_command('streamon')
 self.set_speed(self.speed)

 def receive_response(self, stop_event):
 while not stop_event.is_set():
 try:
 self.response, ip = self.socket.recvfrom(3000)
 logger.info({'action': 'receive_response',
 'response': self.response})
 except socket.error as ex:
 logger.error({'action': 'receive_response',
 'ex': ex})
 break

 def __dell__(self):
 self.stop()

 def stop(self):
 self.stop_event.set()
 retry = 0
 while self._response_thread.is_alive():
 time.sleep(0.3)
 if retry > 30:
 break
 retry += 1
 self.socket.close()
 os.kill(self.proc.pid, 9)

 def send_command(self, command):
 logger.info({'action': 'send_command', 'command': command})
 self.socket.sendto(command.encode('utf-8'), self.drone_address)

 retry = 0
 while self.response is None:
 time.sleep(0.3)
 if retry > 3:
 break
 retry += 1

 if self.response is None:
 response = None
 else:
 response = self.response.decode('utf-8')
 self.response = None
 return response

 def takeoff(self):
 return self.send_command('takeoff')

 def land(self):
 return self.send_command('land')

 def move(self, direction, distance):
 distance = float(distance)
 if self.is_imperial:
 distance = int(round(distance * 30.48))
 else:
 distance = int(round(distance * 100))
 return self.send_command(f'{direction} {distance}')

 def up(self, distance=DEFAULT_DISTANCE):
 return self.move('up', distance)

 def down(self, distance=DEFAULT_DISTANCE):
 return self.move('down', distance)

 def left(self, distance=DEFAULT_DISTANCE):
 return self.move('left', distance)

 def right(self, distance=DEFAULT_DISTANCE):
 return self.move('right', distance)

 def forward(self, distance=DEFAULT_DISTANCE):
 return self.move('forward', distance)

 def back(self, distance=DEFAULT_DISTANCE):
 return self.move('back', distance)

 def set_speed(self, speed):
 return self.send_command(f'speed {speed}')

 def clockwise(self, degree=DEFAULT_DEGREE):
 return self.send_command(f'cw {degree}')

 def counter_clockwise(self, degree=DEFAULT_DEGREE):
 return self.send_command(f'ccw {degree}')

 def video_binary_generator(self):
 while True:
 try:
 frame = self.proc_stdout.read(FRAME_SIZE)
 except Exception as ex:
 logger.error({'action': 'video_binary_generator', 'ex': ex})
 continue

 if not frame:
 continue

 frame = np.fromstring(frame, np.uint8).reshape(FRAME_Y, FRAME_X, 3)
 yield frame

 def enable_face_detect(self):
 self._is_enable_face_detect = True

 def disable_face_detect(self):
 self._is_enable_face_detect = False

 def video_jpeg_generator(self):
 for frame in self.video_binary_generator():
 if self._is_enable_face_detect:
 gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)
 faces = self.face_cascade.detectMultiScale(gray, 1.2, 4)
 for (x, y, w, h) in faces:
 cv.rectangle(frame, (x, y), (x+w, y+h), (0, 0, 255), 2)
 break

 _, jpeg = cv.imencode('.jpg', frame)
 jpeg_binary = jpeg.tobytes()
 yield jpeg_binary