Hacking an Actions MP4 video player to show server statistics

The MP4 player is a small movie player that was used by real estate agents to advertise properties, typically by posting them to potential clients. I saw it on a friend’s desk at his house and asked about it, not being able to pass up an opportunity. Anything with electronics, screens, and batteries will always grab my attention. He had already removed it from its housing / box so I’ve got no idea what it originally looked like.

Initial Investigation

As someone else had already removed the video box from the housing, there wasn’t anything to do to tear it down.

Actions MP4 Video Player FrontActions MP4 Video Player Back

The PCB consists of a power section, Processor, Flash, and SDRAM. There is on-board support for a lot more switches, more power sections, and a microphone, all of which are unpopulated. Overlaying the Flash is a footprint for an SD-Card socket, only one of which can be fitted. The rear of the PCB contains no components, just a few test points. The single sided population would have been done to reduce assembly costs. It looks like this PCB is used in a variety of devices, probably all somewhat similar. A speaker, LCD, 850mAh Li-Ion battery, and USB socket round out the other components. My initial assumptions are that the USB socket is used for charging and uploading video.

Major Component Rundown

  • Hynix HY5DU561622CT 256Mb DDR SDRAM. Datasheet.
  • Hynix HY27UF082G2B 2Gb NAND Flash. Datasheet.
  • Actions ATJ2273B 450MHz MIPS32 SoC.
  • Gelivable GL043015C0-40 4.3″ LCD Screen. Datasheet.

I was expecting the SoC to be hard to find information on. 2 minutes of searching later I had a datasheet and a reference schematic.
PulkoMandy has a variety of information on this SOC, which will be helpful. It looks like a lot of people have received these devices in the mail and have had a look at them.

The PCB itself looks like a 2 or 4 layer board, with all traces routed on the top and bottom layers. This makes following a signal quite easy. Ideally, I’d have a second PCB, which I’d remove all the components from. But for now, a few high-res photos of the board will have to do.


The device enumerated as follows:

Bus 001 Device 004: ID 10d6:1101 Actions Semiconductor Co., Ltd D-Wave 2GB MP4 Player / AK1025 MP3/MP4 Player
Device Descriptor:
  bLength                18
  bDescriptorType         1
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  idVendor           0x10d6 Actions Semiconductor Co., Ltd
  idProduct          0x1101 D-Wave 2GB MP4 Player / AK1025 MP3/MP4 Player
  bcdDevice            1.00
  iManufacturer           1 actions
  iProduct                2 media-player
  iSerial                 3 ㈱㐳㘵㠷㜸㔶㌴ㄲ
  bNumConfigurations      1
  Configuration Descriptor:
    bLength                 9
    bDescriptorType         2
    wTotalLength           32
    bNumInterfaces          1
    bConfigurationValue     1
    iConfiguration          4 Bus-powered
    bmAttributes         0x80
      (Bus Powered)
    MaxPower              500mA
    Interface Descriptor:
      bLength                 9
      bDescriptorType         4
      bInterfaceNumber        0
      bAlternateSetting       0
      bNumEndpoints           2
      bInterfaceClass         8 Mass Storage
      bInterfaceSubClass      5 SFF-8070i
      bInterfaceProtocol     80 
      iInterface              5 Mass Storage
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x82  EP 2 IN
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               0
      Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x01  EP 1 OUT
        bmAttributes            2
          Transfer Type            Bulk
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0200  1x 512 bytes
        bInterval               1
Device Qualifier (for other device speed):
  bLength                10
  bDescriptorType         6
  bcdUSB               2.00
  bDeviceClass            0 (Defined at Interface level)
  bDeviceSubClass         0 
  bDeviceProtocol         0 
  bMaxPacketSize0        64
  bNumConfigurations      1
Device Status:     0x0000
  (Bus Powered)

It exposed a device formatted as VFAT, with no partitions, of 239992832 bytes. However, the NAND flash is 268435456 bytes without error correction. So there’s ~27Mb unaccounted for. My money is on some of that 27Mb being code, probably 8Mb – 16Mb. The code is more than likely to be located at the start of the flash. I’m guessing that there’s a way to update that code, probably using vendor/undocumented SCSI commands.


The goal is to reverse engineer the video player and turn it into a graphical display for showing statistics of my server. It will more than likely collect the stats over USB from a script running on the server.


There’s a lot of ground to cover in order to achieve the goal. Even at this early stage, I’m making assumptions about how this device works. These assumptions are partly based on experience and partly intuition. However, I run the risk of wasting a lot of time or bricking the device, if I don’t check these assumptions as soon as possible.


Before getting stuck into reverse engineering the video player, I’m assuming the following:

  1. There’s probably a serial console somewhere. Quite possibly on some of those test points.
  2. The datasheet for the SoC shows no pins for JTAG, so no low-level debug.
  3. There’s code in the space in the Flash that’s not used by the file system.
  4. There has to be a way to program the device after assembly. NAND flash can’t be programmed in an external programmer, the same way NOR flash can. The 0.5mm pitch also makes that fairly difficult. Keep in mind that some versions of the player can have an SD-Card in place of the NAND flash. If there is secondary code in the Flash, it will probably live in the SD-Card in those implementations.
  5. Therefore, there’s a bootloader on-chip, or the unpopulated SOP-8 footprint is for an SPI NOR Flash.
  6. As there’s no other USB interface other than a mass storage device, there’s probably a way to upload firmware using undocumented SCSI commands.

If I was designing this for mass production, I’d want to test a variety of system parameters as quickly as possible. I’d also want to do any programming at the same time. The non-volatile storage would also be formatted at this stage. In order to keep costs down, it would make sense to have the test points required on a single side of the board. Finally, I’d want to be able to test the board after assembly and before the external components had been soldered on, discarding failures as quickly as possible. I’d allocate the test points as follows:

  1. Several would be for GND, in order to prevent ground bounce on measurements.
  2. There would be a power supply input, quite possibly the USB 5V.
  3. The generated power rails could be measured. In this case, that’s 1.2V, 1.8V, 2.4V, 3.1V and VBATT (for battery charging).
  4. All inputs and outputs could be exercised easily. The rear of the PCB shows that every connection on the edge of the board can be accessed via pogo pins. This includes USB.
  5. It could be worthwhile measuring the signal timings for the LCD.
  6. Some would be for programming the device, no matter what non-volatile storage it was assembled with. If this SoC can boot from SPI flash, I’d use that as it’s 4 pins (CS, CLK, MISO, MOSI), and be able to disable the onboard storage.
  7. A serial console for debug information.

Testing the assumptions

So now it’s time to see which assumptions are true, and which one’s aren’t. As I have a pinout for the SoC, this is a fairly easy matter of performing continuity tests between the known processor pins and the test points. A couple of high-quality photos of the PCB also aided the process. My eyesight isn’t what it used to be, and sadly, I’m not that old.

Unfortunately, there is no serial console on this device. The 2273B is the smallest package in this device family and most of the pins are dedicated to the LCD, NAND Flash and DDR SDRAM interfaces. It is possible to get a serial interface as the TX and RX lines can be multiplexed with the I2C bus, which isn’t used.

The SOP-8 pad and test points below it are definitely for an SPI Flash chip. There is also a boot loader (BROM in the datasheet) present in the device which allows booting from ‘NAND Flash, SD Card, SPI Flash, and some other storage devices.’ The SPI flash shares some pins with the NAND Flash, so it looks like both of these aren’t populated at the same time. However, I should be able to use it to recover the system in case (when?) I brick it by pulling the NAND Flash chip select high.

Before going much further, I made the device a bit more robust. This allowed me to hack on it without breaking it. I’d already re-soldered the speaker once and it was broken again.

Robust Platform

A combination of card stock, white glue, and double-sided tape made a robust platform for continuing work on the video player. I also took the opportunity to break out the SPI Flash connections, as well as the connections that could be used for a serial console. While I was in the process of testing assumptions, I thought I’d plug in the trusty Bus Pirate and see if I could get any info off UART1. Turns out there is, in fact, a serial console on UART 1.

[BOOT] Oct 24 2013 11:35:30 brec_entry.c 
PAD_DRV0[19:0] = 0xaaeaa
[BOOT] page size 0x4

No Need rebuild zonetbl.DieNo = 0.
[BOOT] inited=1
[BOOT] 13 296 
[BOOT] copy param for kernel, an<FF>serial is ok!OSInit, OS_TaskIdle ok
SM str..
PAD_DRV0 = 0xaaeaa.
OSStart, go ...cclk:360<4>-../vfs/symbol.c,231,kernel_sym--- symbol:is_de_blank_usable does NOT exist
error! _findenv_r,56:<B5><B1>ǰ<BD><F8><B3>̲<BB><B4><E6><D4>ڻ<B7><BE><B3><B1><E4>
before system: 82 
cclk:396<4>-../vfs/symbol.c,231,kernel_sym--- symbol:is_de_blank_usable does NOT exist
==== hantro_drv : ic type GL5009
wake_up_reason = nomal 
[alarm_time]= 0 0 
config_otg_detect_mode detect_mode=0x1
usbmonitor.c usb_init_no_vbus_check Error :gpio config

[card]: act_blk_register
init_card_gpio_cfg: en_gpio_test = 0.
p_get_ddrpll 0xc10006b0
mmm so ret = 0 
video_player.c mmm_vp_open start
video_player.c ictype 0x4309
cmd :2
DID err
cmd :15
cmd :9
open /mnt/disk0/Avanti - Stylish Parkside Residences by Polygon - Now Selling.avi, flag: 0, 0x0~~0x0
--- avi 1
--- avi 2
--- avi 3
--- avi 4
--- avi 5
--- avi 8--- avi 9---avi total_time 34733, v_time 34733, a_time 12595
sub_num: 0
audio_num: 1
media_type: 3
total_time: 34733
first_audio_time: 0
index_flag: 0
v codec: xvid
width: 480
height: 272
video init buf: 0x4e011dbc
frame_rate: 30
video_bitrate: 852832
v_max_pkt_size: 0
cmd :c
cmd :1
==== DEV_ADDR : dev_srami_config_HANTRO : SRAMI_CTL = 0x204
==== DEV_ADDR : dev_srami_config_HANTRO : SRAMI_CTL = 0x204
mp4decapi.c, 1332 XVID: hantro will be used in vlc mode
=============== MMM : cur_free_mem_bytes = 19505152 bytes
<E> 1012, "video_player", _subtitle_open() 152, call_addr 0x49404fd8.
<E> 1130, "advert", file_manager_record_counting() 802, call_addr 0x494008e8.
<E> 1137, "advert", _advert_appmsg_proc() 734, call_addr 0x47405720.
== DEV_ADDR : enable AE
video_decoder.c stopped1
video_out.c stopped1
video_out.c FBIOSET_END_VIDEO now
cmd :2
cmd :11
dispose ok
== DEV_ADDR: disable AE
rtc shut down

Sometimes it’s nice to be wrong. There’s some useful information in the console dump. However, the major takeaway here is to confirm the negative assumptions, as well as the positive ones.


For the moment that’s about all that can be done on the hardware. The next step is to see if the firmware can be dumped. Stay tuned for part 2.

, , , , ,

  1. No comments yet.
(will not be published)