hello_encode - bitrate control #114

Closed
Santa77 opened this Issue Oct 31, 2012 · 5 comments

Comments

Projects
None yet
3 participants

Santa77 commented Oct 31, 2012

Hello folks,
I have no idea how to sumbit patch to for that example file. I've made small patch, that allows to control output maximum bitrate. If you will find it usefull please commit it to main tree.

PATCH:

--- ../hello_encode/encode.c    2012-10-15 15:30:06.618947232 +0200
+++ encode.c    2012-10-31 14:38:29.912691857 +0100
@@ -72,7 +72,7 @@
 static void
 print_def(OMX_PARAM_PORTDEFINITIONTYPE def)
 {
-   printf("Port %lu: %s %lu/%lu %lu %lu %s,%s,%s %lux%lu %lux%lu @%lu %u\n",
+   printf("Port %lu: %s %lu/%lu %lu %lu %s,%s,%s %lux%lu %lux%lu @%lu %u at bitrate %lu\n",
          def.nPortIndex,
          def.eDir == OMX_DirInput ? "in" : "out",
          def.nBufferCountActual,
@@ -86,7 +86,8 @@
          def.format.video.nFrameHeight,
          def.format.video.nStride,
          def.format.video.nSliceHeight,
-         def.format.video.xFramerate, def.format.video.eColorFormat);
+         def.format.video.xFramerate, def.format.video.eColorFormat,
+         def.format.video.nBitrate);
 }

 static int
@@ -128,6 +129,7 @@
    }
    list[0] = video_encode;

+   // get current settings of video_encode component from port 200
    memset(&def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
    def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
    def.nVersion.nVersion = OMX_VERSION;
@@ -178,6 +180,41 @@
       exit(1);
    }

+   OMX_VIDEO_PARAM_BITRATETYPE bitrateType;
+   // set current bitrate to 1Mbit
+   memset(&bitrateType, 0, sizeof(OMX_VIDEO_PARAM_BITRATETYPE));
+   bitrateType.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+   bitrateType.nVersion.nVersion = OMX_VERSION;
+   bitrateType.eControlRate = OMX_Video_ControlRateVariable;
+   bitrateType.nTargetBitrate = 1000000;
+   bitrateType.nPortIndex = 201;
+   r = OMX_SetParameter(ILC_GET_HANDLE(video_encode),
+                       OMX_IndexParamVideoBitrate, &bitrateType);
+   if (r != OMX_ErrorNone) {
+      printf
+        ("%s:%d: OMX_SetParameter() for bitrate for video_encode port 201 failed with %x!\n",
+         __FUNCTION__, __LINE__, r);
+      exit(1);
+   }
+
+
+   // get current bitrate
+   memset(&bitrateType, 0, sizeof(OMX_VIDEO_PARAM_BITRATETYPE));
+   bitrateType.nSize = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
+   bitrateType.nVersion.nVersion = OMX_VERSION;
+   bitrateType.nPortIndex = 201;
+
+   if (OMX_GetParameter
+       (ILC_GET_HANDLE(video_encode), OMX_IndexParamVideoBitrate,
+       &bitrateType) != OMX_ErrorNone) {
+      printf("%s:%d: OMX_GetParameter() for video_encode for bitrate port 201 failed!\n",
+            __FUNCTION__, __LINE__);
+      exit(1);
+   }
+   printf("Current Bitrate=%lu\n",bitrateType.nTargetBitrate);
+
+
+
    printf("encode to idle...\n");
    if (ilclient_change_component_state(video_encode, OMX_StateIdle) == -1) {
       printf

Hi, can any one provide example of code that accept file name as input YUV ?
Now I get YUV from ffmpeg
ffmpeg -i 360p.mp4 -vcodec rawvideo -f rawvideo -pix_fmt yuv420p -y out.yuv
But on encoded video I have green lines, that wrong?
http://www.youtube.com/watch?v=U2W_D4LJbmc
http://www.youtube.com/watch?v=U2W_D4LJbmc

Contributor

popcornmix commented Jan 25, 2013

The YUV data needs padding to a width of 32. What is the resolution of your video? Can you try one with a more nicely aligned width? You can also get ffmpeg to resize it.

The other option is to "unpack" the YUV. memcpy each row to a nicely aligned stride.

I try different yuv with 640x360, and 740x400.
So, I got next result:
640x360 http://www.youtube.com/watch?v=uBfMOxrUdmM
But with 720x400 I havent nice pictures...
Please, tell me where I need padding of 32?

here:
#define NUMFRAMES 300
#define WIDTH 640
#define PITCH ((WIDTH+31)&~31)
#define HEIGHT ((WIDTH)*9/16)
#define HEIGHT16 ((HEIGHT+15)&~15)
#define SIZE ((WIDTH * HEIGHT16 * 3)/2)

or here:
// Port 200: in 1/1 115200 16 enabled,not pop.,not cont. 320x240 320x240 @1966080 20
def.format.video.nFrameWidth = WIDTH;
def.format.video.nFrameHeight = HEIGHT;
def.format.video.xFramerate = 30 << 16;
def.format.video.nSliceHeight = def.format.video.nFrameHeight;
def.format.video.nStride = def.format.video.nFrameWidth;
def.format.video.eColorFormat = OMX_COLOR_FormatYUV420PackedPlanar;

Ok, after I resized video with ffmpeg to original, in example 320x240, then color and video image are very good! (but video quality only 240p, so its bad to view him)
http://youtu.be/5E8gdU94Ef0
Very good this means that YUV from ffmpeg is normal to transfer to the OMX encoder.

Also, this is command to resize image and generate YUV
ffmpeg -i /home/pi/Videos/360p.mp4 -s 320x240 -vcodec rawvideo -pix_fmt yuv420p -y out.yuv

But, can any help me to modify code that accept different WxH yuv file?

Contributor

popcornmix commented Jun 7, 2013

popcornmix closed this Jun 7, 2013

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment