3

I'm working on an app which encodes a movie using h.264 encoder to gallery and other targets. This app supports variable aspect ratios at output (1:1, 2:3, 3:2, 16:9, 3:4, 4:3). I'm using surface inputs for input/output from the 4.3 API.

The app works ok on many devices (tested on S3, Motorola G, Nexus 7 2012, Motorola X), however, I've hit a wall when running it on Nexus 7 2013.

Basically, some output resolutions work, some do not. 3:4 (720x960), 2:3 (720x1080) and 16:9 (1280x720) work as intended, but the rest (1:1 (960x960), 3:2 (1080x720) and 4:3 (960x720)) produce an output like this:

http://imageshack.com/a/img811/7984/dtgh.png

My guess is that there is some value hard coded in the encoder which treats its input surface as having a different width than it actually has - the pixel lines seem to "not line up correctly". However, I am at a loss at what can cause this and how to work around it.

There are no errors in the log and the video encoder codec outputs in the log the correct surface width and height when outputing the media format.

update: seems there are no issues when encoding with 360, 720 or 1280 width, with height having no impact. I haven't found any other widths below 1280 that work.

update2: seems there are more widths that work: 180, 240, 640, 700. Couldn't find any correlation between them.

Manfred Moser
  • 29,539
  • 13
  • 92
  • 123
  • Sounds like a mismatched stride problem. Usually if the width and height are multiples of 16 you're pretty safe (with an additional allowance for 1080), but you may have found some exceptions. – fadden Mar 24 '14 at 18:16
  • Thanks for replying.I tried converting width/height to 16 and 32 multiples as I've seen recommendations like this before, but it did not work. All the resolutions listed which don't work are a multiple of 16 anyway. Might be a manufacturer bug I guess. – user3449998 Mar 25 '14 at 20:00
  • I have had this same problem on the 2013 Nexus 7. It works for a lot of resolutions (Namely any widescreen resolution such as 1080p, 720p etc). It also works for some other random resolutions but I have not found any pattern to which ones it likes yet. I will post back if I learn anything else. You may have fixed this already as this post is pretty old. – Jim Aug 11 '14 at 19:49
  • No, I didn't fix it, but worked around it with a list of hardcoded widths (width is the only one that matters) and rounding up to closest one. – user3449998 Aug 14 '14 at 15:21

1 Answers1

0

I believe it has something to do with the device's chipset. I have the exact same problem with an old Motorola XT1058, which uses a Qualcomm Snapdragon S4 Pro, the same chipset as the Nexus 7.

Doing some research I discovered through another answer that in older Qualcomm devices YUV data needs to be aligned at a 2K boundary, yet I can't understand how to fix it when using a input surface instead of YUV buffers.

See the next accepted answer for the statement about the Qualcomm alignment requirements:

How to get stride and Y plane alignment values for MediaCodec encoder

My workaround is that for older devices I will use resolutions which I know will work, these are the ones that I can obtain by querying video profiles with the CamcorderProfile API.

The main problem is how to detect if a device is affected or not, as the MediaCodec API can give only the codec name but not its version.

PerracoLabs
  • 16,449
  • 15
  • 74
  • 127